diff -urN linux-2.4.32-600/Documentation/Configure.help linux-2.4.32-600-sk98_831/Documentation/Configure.help --- linux-2.4.32-600/Documentation/Configure.help Sun Feb 26 11:11:33 2006 +++ linux-2.4.32-600-sk98_831/Documentation/Configure.help Sun Feb 26 11:12:56 2006 @@ -12900,6 +12900,22 @@ by this driver: - 3Com 3C940 Gigabit LOM Ethernet Adapter - 3Com 3C941 Gigabit LOM Ethernet Adapter + - 88E8021 Marvell 1000 Mbit PCI-X, single Port Copper + - 88E8021 Marvell 1000 Mbit PCI-X, single Port Fiber LX + - 88E8021 Marvell 1000 Mbit PCI-X, single Port Fiber SX + - 88E8022 Marvell 1000 Mbit PCI-X, dual Port Copper + - 88E8022 Marvell 1000 Mbit PCI-X, dual Port Copper (Gateway) + - 88E8022 Marvell 1000 Mbit PCI-X, dual Port Fiber LX + - 88E8022 Marvell 1000 Mbit PCI-X, dual Port Fiber SX + - 88E8061 Marvell 1000 Mbit PCI-E, single Port Copper + - 88E8061 Marvell 1000 Mbit PCI-E, single Port Fiber LX + - 88E8061 Marvell 1000 Mbit PCI-E, single Port Fiber SX + - 88E8062 Marvell 1000 Mbit PCI-E, dual Port Copper + - 88E8062 Marvell 1000 Mbit PCI-E, dual Port Copper (Gateway) + - 88E8062 Marvell 1000 Mbit PCI-E, dual Port Fiber LX + - 88E8062 Marvell 1000 Mbit PCI-E, dual Port Fiber SX + - Abocom EFE3K - 10/100 Ethernet Expresscard + - Abocom EGE5K - Giga Ethernet Expresscard - Allied Telesyn AT-2970LX Gigabit Ethernet Adapter - Allied Telesyn AT-2970LX/2SC Gigabit Ethernet Adapter - Allied Telesyn AT-2970SX Gigabit Ethernet Adapter @@ -12908,30 +12924,83 @@ - Allied Telesyn AT-2970TX/2TX Gigabit Ethernet Adapter - Allied Telesyn AT-2971SX Gigabit Ethernet Adapter - Allied Telesyn AT-2971T Gigabit Ethernet Adapter + - Belkin Gigabit Desktop Card 10/100/1000Base-T Adapter, Copper RJ-45 - DGE-530T Gigabit Ethernet Adapter + - DGE-560T Gigabit Ethernet Adapter - EG1032 v2 Instant Gigabit Network Adapter - EG1064 v2 Instant Gigabit Network Adapter - - Marvell 88E8001 Gigabit LOM Ethernet Adapter (Abit) - - Marvell 88E8001 Gigabit LOM Ethernet Adapter (Albatron) - - Marvell 88E8001 Gigabit LOM Ethernet Adapter (Asus) - - Marvell 88E8001 Gigabit LOM Ethernet Adapter (ECS) - - Marvell 88E8001 Gigabit LOM Ethernet Adapter (Epox) - - Marvell 88E8001 Gigabit LOM Ethernet Adapter (Foxconn) - - Marvell 88E8001 Gigabit LOM Ethernet Adapter (Gigabyte) - - Marvell 88E8001 Gigabit LOM Ethernet Adapter (Iwill) + - Marvell 88E8001 Gigabit Ethernet Controller (Abit) + - Marvell 88E8001 Gigabit Ethernet Controller (Albatron) + - Marvell 88E8001 Gigabit Ethernet Controller (Asus) + - Marvell 88E8001 Gigabit Ethernet Controller (Chaintech) + - Marvell 88E8001 Gigabit Ethernet Controller (ECS) + - Marvell 88E8001 Gigabit Ethernet Controller (Epox) + - Marvell 88E8001 Gigabit Ethernet Controller (Foxconn) + - Marvell 88E8001 Gigabit Ethernet Controller (Gigabyte) + - Marvell 88E8001 Gigabit Ethernet Controller (Iwill) + - Marvell 88E8035 Fast Ethernet Controller (LGE) + - Marvell 88E8035 Fast Ethernet Controller (Toshiba) + - Marvell 88E8036 Fast Ethernet Controller (Arima) + - Marvell 88E8036 Fast Ethernet Controller (Compal) + - Marvell 88E8036 Fast Ethernet Controller (Inventec) + - Marvell 88E8036 Fast Ethernet Controller (LGE) + - Marvell 88E8036 Fast Ethernet Controller (Mitac) + - Marvell 88E8036 Fast Ethernet Controller (Panasonic) + - Marvell 88E8036 Fast Ethernet Controller (Quanta) + - Marvell 88E8036 Fast Ethernet Controller (Toshiba) + - Marvell 88E8036 Fast Ethernet Controller (Wistron) + - Marvell 88E8050 Gigabit Ethernet Controller (Gateway) + - Marvell 88E8050 Gigabit Ethernet Controller (Intel) + - Marvell 88E8052 Gigabit Ethernet Controller (ASRock) + - Marvell 88E8052 Gigabit Ethernet Controller (Aopen) + - Marvell 88E8052 Gigabit Ethernet Controller (Asus) + - Marvell 88E8052 Gigabit Ethernet Controller (Gateway) + - Marvell 88E8052 Gigabit Ethernet Controller (Gigabyte) + - Marvell 88E8052 Gigabit Ethernet Controller (MSI) + - Marvell 88E8052 Gigabit Ethernet Controller (Wistron) + - Marvell 88E8053 Gigabit Ethernet Controller (ASRock) + - Marvell 88E8053 Gigabit Ethernet Controller (Albatron) + - Marvell 88E8053 Gigabit Ethernet Controller (Aopen) + - Marvell 88E8053 Gigabit Ethernet Controller (Arima) + - Marvell 88E8053 Gigabit Ethernet Controller (Asus) + - Marvell 88E8053 Gigabit Ethernet Controller (Chaintech) + - Marvell 88E8053 Gigabit Ethernet Controller (Clevo) + - Marvell 88E8053 Gigabit Ethernet Controller (Compal) + - Marvell 88E8053 Gigabit Ethernet Controller (DFI) + - Marvell 88E8053 Gigabit Ethernet Controller (ECS) + - Marvell 88E8053 Gigabit Ethernet Controller (Epox) + - Marvell 88E8053 Gigabit Ethernet Controller (Gigabyte) + - Marvell 88E8053 Gigabit Ethernet Controller (Inventec) + - Marvell 88E8053 Gigabit Ethernet Controller (LGE) + - Marvell 88E8053 Gigabit Ethernet Controller (MSI) + - Marvell 88E8053 Gigabit Ethernet Controller (Mitac) + - Marvell 88E8053 Gigabit Ethernet Controller (Panasonic) + - Marvell 88E8053 Gigabit Ethernet Controller (Quanta) + - Marvell 88E8053 Gigabit Ethernet Controller (SOYO) + - Marvell 88E8053 Gigabit Ethernet Controller (Shuttle) + - Marvell 88E8053 Gigabit Ethernet Controller (Toshiba) + - Marvell 88E8053 Gigabit Ethernet Controller (Trigem) + - Marvell RDK-8001 - Marvell RDK-8001 Adapter - Marvell RDK-8002 Adapter + - Marvell RDK-8003 - Marvell RDK-8003 Adapter - Marvell RDK-8004 Adapter - Marvell RDK-8006 Adapter - Marvell RDK-8007 Adapter - Marvell RDK-8008 Adapter - Marvell RDK-8009 Adapter - - Marvell RDK-8010 Adapter + - Marvell RDK-8010 - Marvell RDK-8011 Adapter - Marvell RDK-8012 Adapter - - Marvell Yukon Gigabit Ethernet 10/100/1000Base-T Adapter (32 bit) - - Marvell Yukon Gigabit Ethernet 10/100/1000Base-T Adapter (64 bit) + - Marvell RDK-8035 + - Marvell RDK-8036 + - Marvell RDK-8052 + - Marvell RDK-8053 + - Marvell Yukon Gigabit Ethernet 10/100/1000Base-T Controller (32 bit) + - Marvell Yukon Gigabit Ethernet 10/100/1000Base-T Controller (64 bit) + - Marvell Yukon-EC Ultra, no ASF (Battery Power Service Support) + - Marvell Yukon-FE Fast Ethernet, Reduced Battery Power Service Support) - N-Way PCI-Bus Giga-Card 1000/100/10Mbps(L) - SK-9521 10/100/1000Base-T Adapter - SK-9521 V2.0 10/100/1000Base-T Adapter @@ -12951,6 +13020,14 @@ - SK-9871 Gigabit Ethernet Server Adapter (SK-NET GE-ZX) - SK-9871 V2.0 Gigabit Ethernet 1000Base-ZX Adapter - SK-9872 Gigabit Ethernet Server Adapter (SK-NET GE-ZX dual link) + - SK-9S21 Server Adapter + - SK-9S22 Server Adapter + - SK-9S24 Server Adapter + - SK-9S34 Server Adapter + - SK-9S81 Server Adapter + - SK-9S82 Server Adapter + - SK-9S91 Server Adapter + - SK-9S92 Server Adapter - SMC EZ Card 1000 (SMC9452TXV.2) The adapters support Jumbo Frames. @@ -12967,6 +13044,9 @@ say M here and read Documentation/modules.txt. This is recommended. The module will be called sk98lin.o. +CONFIG_SK98LIN_NAPI + NAPI is a new driver API designed to reduce CPU and interrupt load + when the driver is receiving lots of packets from the card. Sun GEM support CONFIG_SUNGEM diff -urN linux-2.4.32-600/Documentation/networking/sk98lin.txt linux-2.4.32-600-sk98_831/Documentation/networking/sk98lin.txt --- linux-2.4.32-600/Documentation/networking/sk98lin.txt Fri Feb 20 07:38:24 2004 +++ linux-2.4.32-600-sk98_831/Documentation/networking/sk98lin.txt Sun Feb 26 11:13:02 2006 @@ -1,38 +1,56 @@ -(C)Copyright 1999-2003 Marvell(R). -All rights reserved -=========================================================================== +(C)Copyright 1999-2006 Marvell(R). +All rights reserved. +================================================================================ -sk98lin.txt created 15-Dec-2003 +sk98lin.txt created 18-Jan-2006 -Readme File for sk98lin v6.21 -Marvell Yukon/SysKonnect SK-98xx Gigabit Ethernet Adapter family driver for LINUX +Readme File for sk98lin v8.31.2.3 +Marvell Yukon/SysKonnect SK-98xx Gigabit Ethernet Adapter driver for LINUX This file contains 1 Overview - 2 Required Files - 3 Installation - 3.1 Driver Installation - 3.2 Inclusion of adapter at system start - 4 Driver Parameters - 4.1 Per-Port Parameters - 4.2 Adapter Parameters - 5 Large Frame Support - 6 VLAN and Link Aggregation Support (IEEE 802.1, 802.1q, 802.3ad) - 7 Troubleshooting + 2 Supported Functions + 3 Required Files + 4 Installation + 4.1 Driver Installation + 4.2 Inclusion of adapter at system start + 5 Driver Parameters + 5.1 Per-Port Parameters + 5.2 Adapter Parameters + 6 Ethtool Support + 7 Large Frame Support + 8 VLAN and Link Aggregation Support (IEEE 802.1, 802.1q, 802.3ad) + 9 Wake on Lan support +10 Troubleshooting -=========================================================================== +================================================================================ 1 Overview =========== -The sk98lin driver supports the Marvell Yukon and SysKonnect -SK-98xx/SK-95xx compliant Gigabit Ethernet Adapter on Linux. It has -been tested with Linux on Intel/x86 machines. +The sk98lin driver supports the Marvell Yukon, Yukon EC/FE, Yukon 2 +and SysKonnect SK-98xx/SK-95xx compliant Gigabit Ethernet Adapter on Linux. +It has been tested with Linux on Intel/x86, x86_64 and IA64 machines. *** +2 Supported Functions +====================== + +The following functions are supported by the driver: -2 Required Files + NOTE 1: The hardware support depends on the used card + + - RX/TX HW Checksum + - Hardware interrupt moderation (static/dynamic) + - Transmit poll + - Zerocopy/Scatter-Gather + - Ethtool support + - Wake on Lan (Magic Packet only) (From suspend and APM only) + - DualNet + + +3 Required Files ================= The linux kernel source. @@ -40,16 +58,14 @@ *** -3 Installation +4 Installation =============== It is recommended to download the latest version of the driver from the -SysKonnect web site www.syskonnect.com. If you have downloaded the latest -driver, the Linux kernel has to be patched before the driver can be -installed. For details on how to patch a Linux kernel, refer to the -patch.txt file. +SysKonnect web site www.syskonnect.com. For details on Installation +Instructions for sk98lin Driver, please refer to the README.txt file. -3.1 Driver Installation +4.1 Driver Installation ------------------------ The following steps describe the actions that are required to install @@ -110,13 +126,13 @@ NOTE 1: If you have more than one Marvell Yukon or SysKonnect SK-98xx adapter installed, the adapters will be listed as 'eth0', - 'eth1', 'eth2', etc. - For each adapter, repeat steps 3 and 4 below. + 'eth1', 'eth2', etc. + For each adapter, repeat steps 3 and 4 below. NOTE 2: If you have other Ethernet adapters installed, your Marvell Yukon or SysKonnect SK-98xx adapter will be mapped to the - next available number, e.g. 'eth1'. The mapping is executed - automatically. + next available number, e.g. 'eth1'. The mapping is executed + automatically. The module installation message (displayed either in a system log file or on the console) prints a line for each adapter found containing the corresponding 'ethX'. @@ -153,7 +169,7 @@ 1. Execute the command "ifconfig eth0 down". 2. Execute the command "rmmod sk98lin". -3.2 Inclusion of adapter at system start +4.2 Inclusion of adapter at system start ----------------------------------------- Since a large number of different Linux distributions are @@ -165,7 +181,8 @@ *** -4 Driver Parameters + +5 Driver Parameters ==================== Parameters can be set at the command line after the module has been @@ -208,7 +225,7 @@ more adapters, adjust this and recompile. -4.1 Per-Port Parameters +5.1 Per-Port Parameters ------------------------ These settings are available for each port on the adapter. @@ -282,7 +299,7 @@ with this parameter. -4.2 Adapter Parameters +5.2 Adapter Parameters ----------------------- Connection Type (SK-98xx V2.0 copper adapters only) @@ -379,7 +396,6 @@ is tremendous. On the other hand, selecting a very short moderation time might compensate the use of any moderation being applied. - Preferred Port -------------- Parameter: PrefPort @@ -394,7 +410,7 @@ ------------------------------------------------ Parameter: RlmtMode Values: CheckLinkState,CheckLocalPort, CheckSeg, DualNet -Default: CheckLinkState +Default: CheckLinkState (DualNet on dual port adapters) RLMT monitors the status of the port. If the link of the active port fails, RLMT switches immediately to the standby link. The virtual link is @@ -429,10 +445,94 @@ where a network path between the ports on one adapter exists. Moreover, they are not designed to work where adapters are connected back-to-back. + +LowLatency +---------- +Parameter: LowLatency +Values: On, Off +Default: Off + +This is used to reduce the packet latency time of the adapter. Setting the +LowLatency parameter to 'On' forces the adapter to pass any received packet +immediately to upper network layers and to send out any transmit packet as +fast as possible. + +NOTE 1: The system load increases if LowLatency is set to 'On' and a lot + of data packets are transmitted and received. + +NOTE 2: This parameter is only used on adapters which are based on + PCI Express compatible chipsets. *** -5 Large Frame Support +6 Ethtool Support +================== + +The sk98lin driver provides built-in ethtool support. The ethtool +can be used to display or modify interface specific configurations. + +Ethtool commands are invoked using a single parameter which reflects +the requested ethtool command plus an optional number of parameters +which belong to the desired command. + +It is not the intention of this section to explain the ethtool command +line tool and all its options. For further information refer to the +manpage of the ethtool. This sections describes only the sk98lin +driver supported ethtool commands. + +Pause Parameters +---------------- +Query command: -a +Set command: -A [autoneg on|off] [rx on|off] [tx on|off] +Sample: ethtool -A eth0 rx off tx off + +Coalescing Parameters +--------------------- +Query command: -c +Set command: -C [sample-interval I] + [rx-usecs N] [tx-usecs N] + [rx-usecs-low N] [tx-usecs-low N] + [rx-usecs-high N] [tx-usecs-high N] +Parameter: I = Length of sample interval, in seconds + (supported values range from 1...10) + N = Length of coalescing interval, in microseconds + (supported values range from 25...33,333) +Sample: ethtool -C eth2 rx-usecs 500 tx-usecs 500 + +NOTE: The sk98lin driver does not support different settings + for the rx and tx interrupt coalescing parameters. + +Driver Information +------------------ +Query command: -i +Sample: ethtool -i eth1 + +Checksumming Parameters +----------------------- +Query command: -k +Set command: -K [rx on|off] [tx on|off] [sg on|off] +Sample: ethtool -K eth0 sg off + +Locate NIC Command +------------------ +Query command: -p [N] +Parameter: N = Amount of time to perform locate NIC command, in seconds +Sample: ethtool -p 10 eth1 + +Driver-specific Statistics +-------------------------- +Query command: -S +Sample: ethtool -S eth0 + +Setting Parameters +------------------ +Set command: -s [speed 10|100|1000] [duplex half|full] + [autoneg on|off] [wol gd] +Sample: ethtool -s eth2 wol d +*** + + +7 Large Frame Support ====================== The driver supports large frames (also called jumbo frames). Using large @@ -444,10 +544,10 @@ ifconfig eth0 mtu 9000 This will only work if you have two adapters connected back-to-back or if you use a switch that supports large frames. When using a switch, -it should be configured to allow large frames and auto-negotiation should -be set to OFF. The setting must be configured on all adapters that can be -reached by the large frames. If one adapter is not set to receive large -frames, it will simply drop them. +it should be configured to allow large frames. The setting must be +configured on all adapters that can be reached by the large frames. +If one adapter is not set to receive large frames, it will simply drop +them. You can switch back to the standard ethernet frame size by executing the following command: @@ -459,7 +559,7 @@ *** -6 VLAN and Link Aggregation Support (IEEE 802.1, 802.1q, 802.3ad) +8 VLAN and Link Aggregation Support (IEEE 802.1, 802.1q, 802.3ad) ================================================================== The Marvell Yukon/SysKonnect Linux drivers are able to support VLAN and @@ -477,8 +577,21 @@ cause problems when unloading the driver. -7 Troubleshooting -================== +9 Wake on Lan support +====================== + +The sk98lin driver supports wake up from suspend mode with MagicPacket +on APM systems. Wake on Lan support is enabled by default. To disable it +please use the ethtool. + +NOTE 1: APM support has to be enabled in BIOS and in the kernel. + +NOTE 2: Refer to the kernel documentation for additional requirements + regarding APM support. + + +10 Troubleshooting +=================== If any problems occur during the installation process, check the following list: diff -urN linux-2.4.32-600/drivers/net/Config.in linux-2.4.32-600-sk98_831/drivers/net/Config.in --- linux-2.4.32-600/drivers/net/Config.in Sun Feb 26 11:11:33 2006 +++ linux-2.4.32-600-sk98_831/drivers/net/Config.in Sun Feb 26 11:12:56 2006 @@ -279,6 +279,9 @@ tristate 'SB1250 Ethernet support' CONFIG_NET_SB1250_MAC fi dep_tristate 'Marvell Yukon Chipset / SysKonnect SK-98xx Support' CONFIG_SK98LIN $CONFIG_PCI +if [ "$CONFIG_SK98LIN" != "n" ]; then + bool ' Use Rx polling (NAPI)' CONFIG_SK98LIN_NAPI +fi dep_tristate 'Broadcom Tigon3 support' CONFIG_TIGON3 $CONFIG_PCI if [ "$CONFIG_MOMENCO_OCELOT_C" = "y" -o "$CONFIG_MOMENCO_JAGUAR_ATX" = "y" ]; then diff -urN linux-2.4.32-600/drivers/net/sk98lin/Makefile linux-2.4.32-600-sk98_831/drivers/net/sk98lin/Makefile --- linux-2.4.32-600/drivers/net/sk98lin/Makefile Fri Feb 20 07:38:29 2004 +++ linux-2.4.32-600-sk98_831/drivers/net/sk98lin/Makefile Sun Feb 26 11:12:56 2006 @@ -1,7 +1,60 @@ -# File: drivers/sk98lin/Makefile +#****************************************************************************** # -# Makefile for the SysKonnect SK-98xx device driver. +# Name: skge.c +# Project: GEnesis, PCI Gigabit Ethernet Adapter +# Version: $Revision: 1.9.2.1 $ +# Date: $Date: 2005/04/11 09:01:18 $ +# Purpose: The main driver source module # +#****************************************************************************** + +#****************************************************************************** +# +# (C)Copyright 1998-2002 SysKonnect GmbH. +# (C)Copyright 2002-2005 Marvell. +# +# Makefile for Marvell Yukon chipset and SysKonnect Gigabit Ethernet +# Server Adapter driver. (Kernel 2.4) +# +# Author: Mirko Lindner (mlindner@syskonnect.de) +# Ralph Roesler (rroesler@syskonnect.de) +# +# Address all question to: linux@syskonnect.de +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# The information in this file is provided "AS IS" without warranty. +# +#****************************************************************************** + +#****************************************************************************** +# +# History: +# +# $Log: Makefile2.4,v $ +# Revision 1.9.2.1 2005/04/11 09:01:18 mlindner +# Fix: Copyright year changed +# +# Revision 1.9 2004/07/13 15:54:50 rroesler +# Add: file skethtool.c +# Fix: corrected header regarding copyright +# Fix: minor typos corrected +# +# Revision 1.8 2004/06/08 08:40:36 mlindner +# Fix: Add CONFIG_SK98LIN_ZEROCOPY as default value +# +# Revision 1.7 2004/06/03 16:06:56 mlindner +# Fix: Added compile flag SK_DIAG_SUPPORT +# +# Revision 1.6 2004/06/02 08:02:59 mlindner +# Add: Changed header information and inserted a GPL statement +# +# +#****************************************************************************** + # # Standalone driver params @@ -14,13 +67,16 @@ obj-y := \ skge.o \ + sky2.o \ + skethtool.o \ + sky2le.o \ skdim.o \ skaddr.o \ skgehwt.o \ skgeinit.o \ skgepnmi.o \ skgesirq.o \ - ski2c.o \ + sktwsi.o \ sklm80.o \ skqueue.o \ skrlmt.o \ @@ -78,15 +134,13 @@ # SK_DBGCAT_DRV_INT_SRC 0x04000000 interrupts sources # SK_DBGCAT_DRV_EVENT 0x08000000 driver events -EXTRA_CFLAGS += -I. -DSK_DIAG_SUPPORT -DSK_USE_CSUM -DGENESIS -DYUKON $(DBGDEF) $(SKPARAM) +EXTRA_CFLAGS += -I. -DSK_USE_CSUM -DSK_DIAG_SUPPORT -DGENESIS \ + -DCONFIG_SK98LIN_ZEROCOPY -DYUKON -DYUK2 \ + $(DBGDEF) $(SKPARAM) include $(TOPDIR)/Rules.make clean: rm -f core *.o *.a *.s - - - - diff -urN linux-2.4.32-600/drivers/net/sk98lin/build_no.c linux-2.4.32-600-sk98_831/drivers/net/sk98lin/build_no.c --- linux-2.4.32-600/drivers/net/sk98lin/build_no.c Mon Apr 21 22:41:03 2003 +++ linux-2.4.32-600-sk98_831/drivers/net/sk98lin/build_no.c Thu Jan 1 01:00:00 1970 @@ -1,10 +0,0 @@ -/****************************************************************************** - * - * Name: Build_No.c - * Version: 1.01 - * - */ - -static const char SysKonnectBuildNumber[] = - "@(#)SK-BUILD: 6.02 (20021219) PL: ALL.01"; -^Z \ No newline at end of file diff -urN linux-2.4.32-600/drivers/net/sk98lin/h/lm80.h linux-2.4.32-600-sk98_831/drivers/net/sk98lin/h/lm80.h --- linux-2.4.32-600/drivers/net/sk98lin/h/lm80.h Sat Mar 20 10:08:19 2004 +++ linux-2.4.32-600-sk98_831/drivers/net/sk98lin/h/lm80.h Sun Feb 26 11:13:02 2006 @@ -2,6 +2,8 @@ * * Name: lm80.h * Project: Gigabit Ethernet Adapters, Common Modules + * Version: $Revision: 2.2 $ + * Date: $Date: 2005/12/14 16:11:35 $ * Purpose: Contains all defines for the LM80 Chip * (National Semiconductor). * @@ -9,6 +11,7 @@ /****************************************************************************** * + * LICENSE: * (C)Copyright 1998-2002 SysKonnect. * (C)Copyright 2002-2003 Marvell. * @@ -18,6 +21,7 @@ * (at your option) any later version. * * The information in this file is provided "AS IS" without warranty. + * /LICENSE * ******************************************************************************/ diff -urN linux-2.4.32-600/drivers/net/sk98lin/h/skaddr.h linux-2.4.32-600-sk98_831/drivers/net/sk98lin/h/skaddr.h --- linux-2.4.32-600/drivers/net/sk98lin/h/skaddr.h Sat Mar 20 10:08:19 2004 +++ linux-2.4.32-600-sk98_831/drivers/net/sk98lin/h/skaddr.h Sun Feb 26 11:12:56 2006 @@ -2,6 +2,8 @@ * * Name: skaddr.h * Project: Gigabit Ethernet Adapters, ADDR-Modul + * Version: $Revision: 2.1 $ + * Date: $Date: 2003/10/27 14:16:07 $ * Purpose: Header file for Address Management (MC, UC, Prom). * ******************************************************************************/ diff -urN linux-2.4.32-600/drivers/net/sk98lin/h/skcsum.h linux-2.4.32-600-sk98_831/drivers/net/sk98lin/h/skcsum.h --- linux-2.4.32-600/drivers/net/sk98lin/h/skcsum.h Sat Mar 20 10:08:19 2004 +++ linux-2.4.32-600-sk98_831/drivers/net/sk98lin/h/skcsum.h Sun Feb 26 11:12:56 2006 @@ -2,6 +2,8 @@ * * Name: skcsum.h * Project: GEnesis - SysKonnect SK-NET Gigabit Ethernet (SK-98xx) + * Version: $Revision: 2.2 $ + * Date: $Date: 2003/12/29 15:37:26 $ * Purpose: Store/verify Internet checksum in send/receive packets. * ******************************************************************************/ @@ -155,9 +157,7 @@ typedef struct s_Csum { /* Enabled receive SK_PROTO_XXX bit flags. */ unsigned ReceiveFlags[SK_MAX_NETS]; -#ifdef TX_CSUM unsigned TransmitFlags[SK_MAX_NETS]; -#endif /* TX_CSUM */ /* The protocol statistics structure; one per supported protocol. */ SKCS_PROTO_STATS ProtoStats[SK_MAX_NETS][SKCS_NUM_PROTOCOLS]; diff -urN linux-2.4.32-600/drivers/net/sk98lin/h/skdebug.h linux-2.4.32-600-sk98_831/drivers/net/sk98lin/h/skdebug.h --- linux-2.4.32-600/drivers/net/sk98lin/h/skdebug.h Sat Mar 20 10:08:19 2004 +++ linux-2.4.32-600-sk98_831/drivers/net/sk98lin/h/skdebug.h Sun Feb 26 11:13:02 2006 @@ -2,21 +2,24 @@ * * Name: skdebug.h * Project: Gigabit Ethernet Adapters, Common Modules + * Version: $Revision: 2.4 $ + * Date: $Date: 2005/12/14 16:11:35 $ * Purpose: SK specific DEBUG support * ******************************************************************************/ /****************************************************************************** * + * LICENSE: * (C)Copyright 1998-2002 SysKonnect. - * (C)Copyright 2002-2003 Marvell. + * (C)Copyright 2002-2005 Marvell. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. - * * The information in this file is provided "AS IS" without warranty. + * /LICENSE * ******************************************************************************/ @@ -26,9 +29,9 @@ #ifdef DEBUG #ifndef SK_DBG_MSG #define SK_DBG_MSG(pAC,comp,cat,arg) \ - if ( ((comp) & SK_DBG_CHKMOD(pAC)) && \ - ((cat) & SK_DBG_CHKCAT(pAC)) ) { \ - SK_DBG_PRINTF arg ; \ + if ( ((comp) & SK_DBG_CHKMOD(pAC)) && \ + ((cat) & SK_DBG_CHKCAT(pAC)) ) { \ + SK_DBG_PRINTF arg; \ } #endif #else @@ -56,6 +59,13 @@ #define SK_DBGMOD_ADDR 0x00000080L /* ADDR module */ #define SK_DBGMOD_PECP 0x00000100L /* PECP module */ #define SK_DBGMOD_POWM 0x00000200L /* Power Management module */ +#ifdef SK_ASF +#define SK_DBGMOD_ASF 0x00000400L /* ASF module */ +#endif +#ifdef SK_LBFO +#define SK_DBGMOD_LACP 0x00000800L /* link aggregation control protocol */ +#define SK_DBGMOD_FD 0x00001000L /* frame distributor (link aggregation) */ +#endif /* SK_LBFO */ /* Debug events */ diff -urN linux-2.4.32-600/drivers/net/sk98lin/h/skdrv1st.h linux-2.4.32-600-sk98_831/drivers/net/sk98lin/h/skdrv1st.h --- linux-2.4.32-600/drivers/net/sk98lin/h/skdrv1st.h Sat Mar 20 10:08:19 2004 +++ linux-2.4.32-600-sk98_831/drivers/net/sk98lin/h/skdrv1st.h Sun Feb 26 11:12:56 2006 @@ -2,6 +2,8 @@ * * Name: skdrv1st.h * Project: GEnesis, PCI Gigabit Ethernet Adapter + * Version: $Revision: 1.5.2.6 $ + * Date: $Date: 2005/08/09 07:14:29 $ * Purpose: First header file for driver and all other modules * ******************************************************************************/ @@ -9,7 +11,7 @@ /****************************************************************************** * * (C)Copyright 1998-2002 SysKonnect GmbH. - * (C)Copyright 2002-2003 Marvell. + * (C)Copyright 2002-2005 Marvell. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -20,20 +22,6 @@ * ******************************************************************************/ -/****************************************************************************** - * - * Description: - * - * This is the first include file of the driver, which includes all - * neccessary system header files and some of the GEnesis header files. - * It also defines some basic items. - * - * Include File Hierarchy: - * - * see skge.c - * - ******************************************************************************/ - #ifndef __INC_SKDRV1ST_H #define __INC_SKDRV1ST_H @@ -56,13 +44,9 @@ #define SK_ADDR_EQUAL(a1,a2) (!memcmp(a1,a2,6)) -#if !defined(__OPTIMIZE__) || !defined(__KERNEL__) -#warning You must compile this file with the correct options! -#warning See the last lines of the source file. -#error You must compile this driver with "-O". -#endif +#define SK_STRNCMP(s1,s2,len) strncmp(s1,s2,len) +#define SK_STRCPY(dest,src) strcpy(dest,src) -#include #include #include #include @@ -83,11 +67,7 @@ #include #define SK_CS_CALCULATE_CHECKSUM -#ifndef CONFIG_X86_64 -#define SkCsCalculateChecksum(p,l) ((~ip_compute_csum(p, l)) & 0xffff) -#else -#define SkCsCalculateChecksum(p,l) ((~ip_fast_csum(p, l)) & 0xffff) -#endif +#define SkCsCalculateChecksum(p,l) (~csum_fold(csum_partial(p, l, 0))) #include "h/sktypes.h" #include "h/skerror.h" @@ -95,10 +75,15 @@ #include "h/lm80.h" #include "h/xmac_ii.h" +#ifndef SK_BMU_RX_WM_PEX +#define SK_BMU_RX_WM_PEX 0x80 +#endif + #ifdef __LITTLE_ENDIAN #define SK_LITTLE_ENDIAN #else #define SK_BIG_ENDIAN +#define SK_USE_REV_DESC #endif #define SK_NET_DEVICE net_device @@ -193,3 +178,8 @@ #endif +/******************************************************************************* + * + * End of file + * + ******************************************************************************/ diff -urN linux-2.4.32-600/drivers/net/sk98lin/h/skdrv2nd.h linux-2.4.32-600-sk98_831/drivers/net/sk98lin/h/skdrv2nd.h --- linux-2.4.32-600/drivers/net/sk98lin/h/skdrv2nd.h Sat Mar 20 10:08:19 2004 +++ linux-2.4.32-600-sk98_831/drivers/net/sk98lin/h/skdrv2nd.h Sun Feb 26 11:13:02 2006 @@ -1,15 +1,17 @@ /****************************************************************************** * - * Name: skdrv2nd.h - * Project: GEnesis, PCI Gigabit Ethernet Adapter - * Purpose: Second header file for driver and all other modules + * Name: skdrv2nd.h + * Project: GEnesis, PCI Gigabit Ethernet Adapter + * Version: $Revision: 1.29.2.28 $ + * Date: $Date: 2005/11/14 15:22:08 $ + * Purpose: Second header file for driver and all other modules * ******************************************************************************/ /****************************************************************************** * * (C)Copyright 1998-2002 SysKonnect GmbH. - * (C)Copyright 2002-2003 Marvell. + * (C)Copyright 2002-2005 Marvell. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -40,10 +42,11 @@ #include "h/skqueue.h" #include "h/skgehwt.h" #include "h/sktimer.h" -#include "h/ski2c.h" +#include "h/sktwsi.h" #include "h/skgepnmi.h" #include "h/skvpd.h" #include "h/skgehw.h" +#include "h/sky2le.h" #include "h/skgeinit.h" #include "h/skaddr.h" #include "h/skgesirq.h" @@ -51,151 +54,191 @@ #include "h/skrlmt.h" #include "h/skgedrv.h" -#define SK_PCI_ISCOMPLIANT(result, pdev) { \ - result = SK_FALSE; /* default */ \ - /* 3Com (0x10b7) */ \ - if (pdev->vendor == 0x10b7) { \ - /* Gigabit Ethernet Adapter (0x1700) */ \ - if ((pdev->device == 0x1700)) { \ - result = SK_TRUE; \ - } \ - /* SysKonnect (0x1148) */ \ - } else if (pdev->vendor == 0x1148) { \ - /* SK-98xx Gigabit Ethernet Server Adapter (0x4300) */ \ - /* SK-98xx V2.0 Gigabit Ethernet Adapter (0x4320) */ \ - if ((pdev->device == 0x4300) || \ - (pdev->device == 0x4320)) { \ - result = SK_TRUE; \ - } \ - /* D-Link (0x1186) */ \ - } else if (pdev->vendor == 0x1186) { \ - /* Gigabit Ethernet Adapter (0x4c00) */ \ - if ((pdev->device == 0x4c00)) { \ - result = SK_TRUE; \ - } \ - /* Marvell (0x11ab) */ \ - } else if (pdev->vendor == 0x11ab) { \ - /* Gigabit Ethernet Adapter (0x4320) */ \ - if ((pdev->device == 0x4320)) { \ - result = SK_TRUE; \ - } \ - /* CNet (0x1371) */ \ - } else if (pdev->vendor == 0x1371) { \ - /* GigaCard Network Adapter (0x434e) */ \ - if ((pdev->device == 0x434e)) { \ - result = SK_TRUE; \ - } \ - /* Linksys (0x1737) */ \ - } else if (pdev->vendor == 0x1737) { \ - /* Gigabit Network Adapter (0x1032) */ \ - /* Gigabit Network Adapter (0x1064) */ \ - if ((pdev->device == 0x1032) || \ - (pdev->device == 0x1064)) { \ - result = SK_TRUE; \ - } \ - } else { \ - result = SK_FALSE; \ - } \ -} +/* Defines for the poll cotroller */ +#undef SK_NETDUMP_POLL + +#ifdef SK_NETDUMP_POLL +#ifdef HAVE_POLL_CONTROLLER +#define SK_POLL_CONTROLLER +#define CONFIG_SK98LIN_NAPI +#elif CONFIG_NET_POLL_CONTROLLER +#define SK_POLL_CONTROLLER +#define CONFIG_SK98LIN_NAPI +#endif +#endif -extern SK_MBUF *SkDrvAllocRlmtMbuf(SK_AC*, SK_IOC, unsigned); -extern void SkDrvFreeRlmtMbuf(SK_AC*, SK_IOC, SK_MBUF*); -extern SK_U64 SkOsGetTime(SK_AC*); -extern int SkPciReadCfgDWord(SK_AC*, int, SK_U32*); -extern int SkPciReadCfgWord(SK_AC*, int, SK_U16*); -extern int SkPciReadCfgByte(SK_AC*, int, SK_U8*); -extern int SkPciWriteCfgDWord(SK_AC*, int, SK_U32); -extern int SkPciWriteCfgWord(SK_AC*, int, SK_U16); -extern int SkPciWriteCfgByte(SK_AC*, int, SK_U8); -extern int SkDrvEvent(SK_AC*, SK_IOC IoC, SK_U32, SK_EVPARA); - -#ifdef SK_DIAG_SUPPORT -extern int SkDrvEnterDiagMode(SK_AC *pAc); -extern int SkDrvLeaveDiagMode(SK_AC *pAc); +/****************************************************************************** + * + * Generic driver defines + * + ******************************************************************************/ + +#define USE_TIST_FOR_RESET /* Use timestamp for reset */ +#define Y2_RECOVERY /* use specific recovery yukon2 functions */ +#define Y2_LE_CHECK /* activate check for LE order */ +#define Y2_SYNC_CHECK /* activate check for receiver in sync */ +#define SK_YUKON2 /* Enable Yukon2 dual net support */ +#define USE_SK_TX_CHECKSUM /* use the tx hw checksum driver functionality */ +#define USE_SK_RX_CHECKSUM /* use the rx hw checksum driver functionality */ +#define USE_SK_TSO_FEATURE /* use TCP segmentation offload if possible */ +#define SK_COPY_THRESHOLD 50 /* threshold for copying small RX frames; + * 0 avoids copying, 9001 copies all */ +#define SK_MAX_CARD_PARAM 16 /* number of adapters that can be configured via + * command line params */ +//#define USE_TX_COMPLETE /* use of a transmit complete interrupt */ +#define Y2_RX_CHECK /* RX Check timestamp */ + +/* + * use those defines for a compile-in version of the driver instead + * of command line parameters + */ +// #define LINK_SPEED_A {"Auto",} +// #define LINK_SPEED_B {"Auto",} +// #define AUTO_NEG_A {"Sense",} +// #define AUTO_NEG_B {"Sense"} +// #define DUP_CAP_A {"Both",} +// #define DUP_CAP_B {"Both",} +// #define FLOW_CTRL_A {"SymOrRem",} +// #define FLOW_CTRL_B {"SymOrRem",} +// #define ROLE_A {"Auto",} +// #define ROLE_B {"Auto",} +// #define PREF_PORT {"A",} +// #define CON_TYPE {"Auto",} +// #define RLMT_MODE {"CheckLinkState",} + +#ifdef Y2_RECOVERY +#define CHECK_TRANSMIT_TIMEOUT +#define Y2_RESYNC_WATERMARK 1000000L #endif + +/****************************************************************************** + * + * Generic ISR defines + * + ******************************************************************************/ + +#define SkIsrRetVar void +#define SkIsrRetNone NULL +#define SkIsrRetHandled NULL + +#define DEV_KFREE_SKB(skb) dev_kfree_skb(skb) +#define DEV_KFREE_SKB_IRQ(skb) dev_kfree_skb_irq(skb) +#define DEV_KFREE_SKB_ANY(skb) dev_kfree_skb_any(skb) + +/****************************************************************************** + * + * Global function prototypes + * + ******************************************************************************/ + +extern SK_MBUF *SkDrvAllocRlmtMbuf(SK_AC*, SK_IOC, unsigned); +extern void SkDrvFreeRlmtMbuf(SK_AC*, SK_IOC, SK_MBUF*); +extern SK_U64 SkOsGetTime(SK_AC*); +extern int SkPciReadCfgDWord(SK_AC*, int, SK_U32*); +extern int SkPciReadCfgWord(SK_AC*, int, SK_U16*); +extern int SkPciReadCfgByte(SK_AC*, int, SK_U8*); +extern int SkPciWriteCfgDWord(SK_AC*, int, SK_U32); +extern int SkPciWriteCfgWord(SK_AC*, int, SK_U16); +extern int SkPciWriteCfgByte(SK_AC*, int, SK_U8); +extern int SkDrvEvent(SK_AC*, SK_IOC IoC, SK_U32, SK_EVPARA); +extern int SkDrvEnterDiagMode(SK_AC *pAc); +extern int SkDrvLeaveDiagMode(SK_AC *pAc); + +/****************************************************************************** + * + * Linux specific RLMT buffer structure (SK_MBUF typedef in skdrv1st)! + * + ******************************************************************************/ + struct s_DrvRlmtMbuf { - SK_MBUF *pNext; /* Pointer to next RLMT Mbuf. */ - SK_U8 *pData; /* Data buffer (virtually contig.). */ - unsigned Size; /* Data buffer size. */ - unsigned Length; /* Length of packet (<= Size). */ - SK_U32 PortIdx; /* Receiving/transmitting port. */ + SK_MBUF *pNext; /* Pointer to next RLMT Mbuf. */ + SK_U8 *pData; /* Data buffer (virtually contig.). */ + unsigned Size; /* Data buffer size. */ + unsigned Length; /* Length of packet (<= Size). */ + SK_U32 PortIdx; /* Receiving/transmitting port. */ #ifdef SK_RLMT_MBUF_PRIVATE - SK_RLMT_MBUF Rlmt; /* Private part for RLMT. */ -#endif /* SK_RLMT_MBUF_PRIVATE */ - struct sk_buff *pOs; /* Pointer to message block */ + SK_RLMT_MBUF Rlmt; /* Private part for RLMT. */ +#endif + struct sk_buff *pOs; /* Pointer to message block */ }; +/****************************************************************************** + * + * Linux specific TIME defines + * + ******************************************************************************/ -/* - * Time macros - */ #if SK_TICKS_PER_SEC == 100 #define SK_PNMI_HUNDREDS_SEC(t) (t) #else -#define SK_PNMI_HUNDREDS_SEC(t) ((((unsigned long)t) * 100) / \ - (SK_TICKS_PER_SEC)) +#define SK_PNMI_HUNDREDS_SEC(t) ((((unsigned long)t)*100)/(SK_TICKS_PER_SEC)) #endif -/* - * New SkOsGetTime - */ #define SkOsGetTimeCurrent(pAC, pUsec) {\ + static struct timeval prev_t; \ struct timeval t;\ do_gettimeofday(&t);\ - *pUsec = ((((t.tv_sec) * 1000000L)+t.tv_usec)/10000);\ + if (prev_t.tv_sec == t.tv_sec) { \ + if (prev_t.tv_usec > t.tv_usec) { \ + t.tv_usec = prev_t.tv_usec; \ + } else { \ + prev_t.tv_usec = t.tv_usec; \ + } \ + } else { \ + prev_t = t; \ + } \ + *pUsec = ((t.tv_sec*100L)+(t.tv_usec/10000));\ } +/****************************************************************************** + * + * Linux specific IOCTL defines and typedefs + * + ******************************************************************************/ -/* - * ioctl definitions - */ -#define SK_IOCTL_BASE (SIOCDEVPRIVATE) -#define SK_IOCTL_GETMIB (SK_IOCTL_BASE + 0) -#define SK_IOCTL_SETMIB (SK_IOCTL_BASE + 1) -#define SK_IOCTL_PRESETMIB (SK_IOCTL_BASE + 2) -#define SK_IOCTL_GEN (SK_IOCTL_BASE + 3) -#define SK_IOCTL_DIAG (SK_IOCTL_BASE + 4) - -typedef struct s_IOCTL SK_GE_IOCTL; +#define SK_IOCTL_BASE (SIOCDEVPRIVATE) +#define SK_IOCTL_GETMIB (SK_IOCTL_BASE + 0) +#define SK_IOCTL_SETMIB (SK_IOCTL_BASE + 1) +#define SK_IOCTL_PRESETMIB (SK_IOCTL_BASE + 2) +#define SK_IOCTL_GEN (SK_IOCTL_BASE + 3) +#define SK_IOCTL_DIAG (SK_IOCTL_BASE + 4) +typedef struct s_IOCTL SK_GE_IOCTL; struct s_IOCTL { char* pData; unsigned int Len; }; +/****************************************************************************** + * + * Generic sizes and length definitions + * + ******************************************************************************/ -/* - * define sizes of descriptor rings in bytes - */ - -#define TX_RING_SIZE (8*1024) -#define RX_RING_SIZE (24*1024) - -/* - * Buffer size for ethernet packets - */ -#define ETH_BUF_SIZE 1540 -#define ETH_MAX_MTU 1514 -#define ETH_MIN_MTU 60 -#define ETH_MULTICAST_BIT 0x01 -#define SK_JUMBO_MTU 9000 - -/* - * transmit priority selects the queue: LOW=asynchron, HIGH=synchron - */ -#define TX_PRIO_LOW 0 -#define TX_PRIO_HIGH 1 +#define TX_RING_SIZE (24*1024) /* GEnesis/Yukon */ +#define RX_RING_SIZE (24*1024) /* GEnesis/Yukon */ +#define RX_MAX_NBR_BUFFERS 128 /* Yukon-EC/-II */ +#define TX_MAX_NBR_BUFFERS 128 /* Yukon-EC/-II */ +#define MAXIMUM_LOW_ADDRESS 0xFFFFFFFF /* Max. low address */ + +#define ETH_BUF_SIZE 1560 /* multiples of 8 bytes */ +#define ETH_MAX_MTU 1514 +#define ETH_MIN_MTU 60 +#define ETH_MULTICAST_BIT 0x01 +#define SK_JUMBO_MTU 9000 + +#define TX_PRIO_LOW 0 /* asynchronous queue */ +#define TX_PRIO_HIGH 1 /* synchronous queue */ +#define DESCR_ALIGN 64 /* alignment of Rx/Tx descriptors */ -/* - * alignment of rx/tx descriptors - */ -#define DESCR_ALIGN 64 +/****************************************************************************** + * + * PNMI related definitions + * + ******************************************************************************/ -/* - * definitions for pnmi. TODO - */ #define SK_DRIVER_RESET(pAC, IoC) 0 #define SK_DRIVER_SENDEVENT(pAC, IoC) 0 #define SK_DRIVER_SELFTEST(pAC, IoC) 0 @@ -204,20 +247,16 @@ #define SK_DRIVER_SET_MTU(pAc,IoC,i,v) 0 #define SK_DRIVER_PRESET_MTU(pAc,IoC,i,v) 0 -/* -** Interim definition of SK_DRV_TIMER placed in this file until -** common modules have boon finallized -*/ -#define SK_DRV_TIMER 11 -#define SK_DRV_MODERATION_TIMER 1 -#define SK_DRV_MODERATION_TIMER_LENGTH 1000000 /* 1 second */ -#define SK_DRV_RX_CLEANUP_TIMER 2 -#define SK_DRV_RX_CLEANUP_TIMER_LENGTH 1000000 /* 100 millisecs */ -/* -** Definitions regarding transmitting frames -** any calculating any checksum. -*/ +/****************************************************************************** + * + * Various offsets and sizes + * + ******************************************************************************/ + +#define SK_DRV_MODERATION_TIMER 1 /* id */ +#define SK_DRV_MODERATION_TIMER_LENGTH 1 /* 1 second */ + #define C_LEN_ETHERMAC_HEADER_DEST_ADDR 6 #define C_LEN_ETHERMAC_HEADER_SRC_ADDR 6 #define C_LEN_ETHERMAC_HEADER_LENTYPE 2 @@ -243,114 +282,445 @@ #define C_PROTO_ID_UDP 17 /* refer to RFC 790 or Stevens' */ #define C_PROTO_ID_TCP 6 /* TCP/IP illustrated for details */ -/* TX and RX descriptors *****************************************************/ +/****************************************************************************** + * + * Tx and Rx descriptor definitions + * + ******************************************************************************/ typedef struct s_RxD RXD; /* the receive descriptor */ - struct s_RxD { - volatile SK_U32 RBControl; /* Receive Buffer Control */ - SK_U32 VNextRxd; /* Next receive descriptor,low dword */ - SK_U32 VDataLow; /* Receive buffer Addr, low dword */ - SK_U32 VDataHigh; /* Receive buffer Addr, high dword */ - SK_U32 FrameStat; /* Receive Frame Status word */ - SK_U32 TimeStamp; /* Time stamp from XMAC */ - SK_U32 TcpSums; /* TCP Sum 2 / TCP Sum 1 */ - SK_U32 TcpSumStarts; /* TCP Sum Start 2 / TCP Sum Start 1 */ - RXD *pNextRxd; /* Pointer to next Rxd */ - struct sk_buff *pMBuf; /* Pointer to Linux' socket buffer */ + volatile SK_U32 RBControl; /* Receive Buffer Control */ + SK_U32 VNextRxd; /* Next receive descriptor,low dword */ + SK_U32 VDataLow; /* Receive buffer Addr, low dword */ + SK_U32 VDataHigh; /* Receive buffer Addr, high dword */ + SK_U32 FrameStat; /* Receive Frame Status word */ + SK_U32 TimeStamp; /* Time stamp from XMAC */ + SK_U32 TcpSums; /* TCP Sum 2 / TCP Sum 1 */ + SK_U32 TcpSumStarts; /* TCP Sum Start 2 / TCP Sum Start 1 */ + RXD *pNextRxd; /* Pointer to next Rxd */ + struct sk_buff *pMBuf; /* Pointer to Linux' socket buffer */ }; typedef struct s_TxD TXD; /* the transmit descriptor */ - struct s_TxD { - volatile SK_U32 TBControl; /* Transmit Buffer Control */ - SK_U32 VNextTxd; /* Next transmit descriptor,low dword */ - SK_U32 VDataLow; /* Transmit Buffer Addr, low dword */ - SK_U32 VDataHigh; /* Transmit Buffer Addr, high dword */ - SK_U32 FrameStat; /* Transmit Frame Status Word */ - SK_U32 TcpSumOfs; /* Reserved / TCP Sum Offset */ - SK_U16 TcpSumSt; /* TCP Sum Start */ - SK_U16 TcpSumWr; /* TCP Sum Write */ - SK_U32 TcpReserved; /* not used */ - TXD *pNextTxd; /* Pointer to next Txd */ - struct sk_buff *pMBuf; /* Pointer to Linux' socket buffer */ + volatile SK_U32 TBControl; /* Transmit Buffer Control */ + SK_U32 VNextTxd; /* Next transmit descriptor,low dword */ + SK_U32 VDataLow; /* Transmit Buffer Addr, low dword */ + SK_U32 VDataHigh; /* Transmit Buffer Addr, high dword */ + SK_U32 FrameStat; /* Transmit Frame Status Word */ + SK_U32 TcpSumOfs; /* Reserved / TCP Sum Offset */ + SK_U16 TcpSumSt; /* TCP Sum Start */ + SK_U16 TcpSumWr; /* TCP Sum Write */ + SK_U32 TcpReserved; /* not used */ + TXD *pNextTxd; /* Pointer to next Txd */ + struct sk_buff *pMBuf; /* Pointer to Linux' socket buffer */ +}; + +/****************************************************************************** + * + * Generic Yukon-II defines + * + ******************************************************************************/ + +#define LE_SIZE sizeof(SK_HWLE) +#define MAX_NUM_FRAGS (MAX_SKB_FRAGS + 1) +#define MIN_LEN_OF_LE_TAB 128 +#define MAX_LEN_OF_LE_TAB 4096 +#define MAX_UNUSED_RX_LE_WORKING 8 +#ifdef MAX_FRAG_OVERHEAD +#undef MAX_FRAG_OVERHEAD +#define MAX_FRAG_OVERHEAD 4 +#endif +// as we have a maximum of 16 physical fragments, +// maximum 1 ADDR64 per physical fragment +// maximum 4 LEs for VLAN, Csum, LargeSend, Packet +#define MIN_LE_FREE_REQUIRED ((16*2) + 4) +#define IS_GMAC(pAc) (!pAc->GIni.GIGenesis) +#ifdef USE_SYNC_TX_QUEUE +#define TXS_MAX_LE 256 +#else /* !USE_SYNC_TX_QUEUE */ +#define TXS_MAX_LE 0 +#endif + +#define ETHER_MAC_HDR_LEN (6+6+2) // MAC SRC ADDR, MAC DST ADDR, TYPE +#define IP_HDR_LEN 20 +#define TCP_CSUM_OFFS 0x10 +#define UDP_CSUM_OFFS 0x06 +#define TXA_MAX_LE 256 +#define RX_MAX_LE 256 +#define ST_MAX_LE (SK_MAX_MACS)*((3*RX_MAX_LE)+(TXA_MAX_LE)+(TXS_MAX_LE)) + +#if (defined (Y2_RECOVERY) || defined (Y2_LE_CHECK)) +/* event for recovery from tx hang or rx out of sync */ +#define SK_DRV_RECOVER 17 +#endif +/****************************************************************************** + * + * Structures specific for Yukon-II + * + ******************************************************************************/ + +typedef struct s_frag SK_FRAG; +struct s_frag { + SK_FRAG *pNext; + char *pVirt; + SK_U64 pPhys; + unsigned int FragLen; }; -/* Used interrupt bits in the interrupts source register *********************/ +typedef struct s_packet SK_PACKET; +struct s_packet { + /* Common infos: */ + SK_PACKET *pNext; /* pointer for packet queues */ + unsigned int PacketLen; /* length of packet */ + unsigned int NumFrags; /* nbr of fragments (for Rx always 1) */ + SK_FRAG *pFrag; /* fragment list */ + SK_FRAG FragArray[MAX_NUM_FRAGS]; /* TX fragment array */ + unsigned int NextLE; /* next LE to use for the next packet */ + + /* Private infos: */ + struct sk_buff *pMBuf; /* Pointer to Linux' socket buffer */ +}; + +typedef struct s_queue SK_PKT_QUEUE; +struct s_queue { + SK_PACKET *pHead; + SK_PACKET *pTail; + spinlock_t QueueLock; /* serialize packet accesses */ +}; + +/******************************************************************************* + * + * Macros specific for Yukon-II queues + * + ******************************************************************************/ + +#define IS_Q_EMPTY(pQueue) ((pQueue)->pHead != NULL) ? SK_FALSE : SK_TRUE +#define IS_Q_LOCKED(pQueue) spin_is_locked(&((pQueue)->QueueLock)) + +#define PLAIN_POP_FIRST_PKT_FROM_QUEUE(pQueue, pPacket) { \ + if ((pQueue)->pHead != NULL) { \ + (pPacket) = (pQueue)->pHead; \ + (pQueue)->pHead = (pPacket)->pNext; \ + if ((pQueue)->pHead == NULL) { \ + (pQueue)->pTail = NULL; \ + } \ + (pPacket)->pNext = NULL; \ + } else { \ + (pPacket) = NULL; \ + } \ +} + +#define PLAIN_PUSH_PKT_AS_FIRST_IN_QUEUE(pQueue, pPacket) { \ + if ((pQueue)->pHead != NULL) { \ + (pPacket)->pNext = (pQueue)->pHead; \ + } else { \ + (pPacket)->pNext = NULL; \ + (pQueue)->pTail = (pPacket); \ + } \ + (pQueue)->pHead = (pPacket); \ +} + +#define PLAIN_PUSH_PKT_AS_LAST_IN_QUEUE(pQueue, pPacket) { \ + (pPacket)->pNext = NULL; \ + if ((pQueue)->pTail != NULL) { \ + (pQueue)->pTail->pNext = (pPacket); \ + } else { \ + (pQueue)->pHead = (pPacket); \ + } \ + (pQueue)->pTail = (pPacket); \ +} + +#define PLAIN_PUSH_MULTIPLE_PKT_AS_LAST_IN_QUEUE(pQueue,pPktGrpStart,pPktGrpEnd) { \ + if ((pPktGrpStart) != NULL) { \ + if ((pQueue)->pTail != NULL) { \ + (pQueue)->pTail->pNext = (pPktGrpStart); \ + } else { \ + (pQueue)->pHead = (pPktGrpStart); \ + } \ + (pQueue)->pTail = (pPktGrpEnd); \ + } \ +} + +/* Required: 'Flags' */ +#define POP_FIRST_PKT_FROM_QUEUE(pQueue, pPacket) { \ + spin_lock_irqsave(&((pQueue)->QueueLock), Flags); \ + if ((pQueue)->pHead != NULL) { \ + (pPacket) = (pQueue)->pHead; \ + (pQueue)->pHead = (pPacket)->pNext; \ + if ((pQueue)->pHead == NULL) { \ + (pQueue)->pTail = NULL; \ + } \ + (pPacket)->pNext = NULL; \ + } else { \ + (pPacket) = NULL; \ + } \ + spin_unlock_irqrestore(&((pQueue)->QueueLock), Flags); \ +} + +/* Required: 'Flags' */ +#define PUSH_PKT_AS_FIRST_IN_QUEUE(pQueue, pPacket) { \ + spin_lock_irqsave(&(pQueue)->QueueLock, Flags); \ + if ((pQueue)->pHead != NULL) { \ + (pPacket)->pNext = (pQueue)->pHead; \ + } else { \ + (pPacket)->pNext = NULL; \ + (pQueue)->pTail = (pPacket); \ + } \ + (pQueue)->pHead = (pPacket); \ + spin_unlock_irqrestore(&(pQueue)->QueueLock, Flags); \ +} + +/* Required: 'Flags' */ +#define PUSH_PKT_AS_LAST_IN_QUEUE(pQueue, pPacket) { \ + (pPacket)->pNext = NULL; \ + spin_lock_irqsave(&(pQueue)->QueueLock, Flags); \ + if ((pQueue)->pTail != NULL) { \ + (pQueue)->pTail->pNext = (pPacket); \ + } else { \ + (pQueue)->pHead = (pPacket); \ + } \ + (pQueue)->pTail = (pPacket); \ + spin_unlock_irqrestore(&(pQueue)->QueueLock, Flags); \ +} + +/* Required: 'Flags' */ +#define PUSH_MULTIPLE_PKT_AS_LAST_IN_QUEUE(pQueue,pPktGrpStart,pPktGrpEnd) { \ + if ((pPktGrpStart) != NULL) { \ + spin_lock_irqsave(&(pQueue)->QueueLock, Flags); \ + if ((pQueue)->pTail != NULL) { \ + (pQueue)->pTail->pNext = (pPktGrpStart); \ + } else { \ + (pQueue)->pHead = (pPktGrpStart); \ + } \ + (pQueue)->pTail = (pPktGrpEnd); \ + spin_unlock_irqrestore(&(pQueue)->QueueLock, Flags); \ + } \ +} + +/* + *Check if the low address (32 bit) is near the 4G limit or over it. + * Set the high address to a wrong value. + * Doing so we force to write the ADDR64 LE. + */ +#define CHECK_LOW_ADDRESS( _HighAddress, _LowAddress , _Length) { \ + if ((~0-_LowAddress) <_Length) { \ + _HighAddress= MAXIMUM_LOW_ADDRESS; \ + SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_TX_PROGRESS, \ + ("High Address must be set for HW. LowAddr = %d Length = %d\n", \ + _LowAddress, _Length)); \ + } \ +} + +/******************************************************************************* + * + * Macros specific for Yukon-II queues (tist) + * + ******************************************************************************/ + +#ifdef USE_TIST_FOR_RESET +/* port is fully operational */ +#define SK_PSTATE_NOT_WAITING_FOR_TIST 0 +/* port in reset until any tist LE */ +#define SK_PSTATE_WAITING_FOR_ANY_TIST BIT_0 +/* port in reset until timer reaches pAC->MinTistLo */ +#define SK_PSTATE_WAITING_FOR_SPECIFIC_TIST BIT_1 +#define SK_PSTATE_PORT_SHIFT 4 +#define SK_PSTATE_PORT_MASK ((1 << SK_PSTATE_PORT_SHIFT) - 1) + +/* use this + Port to build OP_MOD_TXINDEX_NO_PORT_A|B */ +#define OP_MOD_TXINDEX 0x71 +/* opcode for a TX_INDEX LE in which Port A has to be ignored */ +#define OP_MOD_TXINDEX_NO_PORT_A 0x71 +/* opcode for a TX_INDEX LE in which Port B has to be ignored */ +#define OP_MOD_TXINDEX_NO_PORT_B 0x72 +/* opcode for LE to be ignored because port is still in reset */ +#define OP_MOD_LE 0x7F + +/* set tist wait mode Bit for port */ +#define SK_SET_WAIT_BIT_FOR_PORT(pAC, Bit, Port) \ + { \ + (pAC)->AdapterResetState |= ((Bit) << (SK_PSTATE_PORT_SHIFT * Port)); \ + } + +/* reset tist waiting for specified port */ +#define SK_CLR_STATE_FOR_PORT(pAC, Port) \ + { \ + (pAC)->AdapterResetState &= \ + ~(SK_PSTATE_PORT_MASK << (SK_PSTATE_PORT_SHIFT * Port)); \ + } + +/* return SK_TRUE when port is in reset waiting for tist */ +#define SK_PORT_WAITING_FOR_TIST(pAC, Port) \ + ((((pAC)->AdapterResetState >> (SK_PSTATE_PORT_SHIFT * Port)) & \ + SK_PSTATE_PORT_MASK) != SK_PSTATE_NOT_WAITING_FOR_TIST) + +/* return SK_TRUE when port is in reset waiting for any tist */ +#define SK_PORT_WAITING_FOR_ANY_TIST(pAC, Port) \ + ((((pAC)->AdapterResetState >> (SK_PSTATE_PORT_SHIFT * Port)) & \ + SK_PSTATE_WAITING_FOR_ANY_TIST) == SK_PSTATE_WAITING_FOR_ANY_TIST) + +/* return SK_TRUE when port is in reset waiting for a specific tist */ +#define SK_PORT_WAITING_FOR_SPECIFIC_TIST(pAC, Port) \ + ((((pAC)->AdapterResetState >> (SK_PSTATE_PORT_SHIFT * Port)) & \ + SK_PSTATE_WAITING_FOR_SPECIFIC_TIST) == \ + SK_PSTATE_WAITING_FOR_SPECIFIC_TIST) + +/* return whether adapter is expecting a tist LE */ +#define SK_ADAPTER_WAITING_FOR_TIST(pAC) ((pAC)->AdapterResetState != 0) + +/* enable timestamp timer and force creation of tist LEs */ +#define Y2_ENABLE_TIST(IoC) \ + SK_OUT8(IoC, GMAC_TI_ST_CTRL, (SK_U8) GMT_ST_START) + +/* disable timestamp timer and stop creation of tist LEs */ +#define Y2_DISABLE_TIST(IoC) \ + SK_OUT8(IoC, GMAC_TI_ST_CTRL, (SK_U8) GMT_ST_STOP) + +/* get current value of timestamp timer */ +#define Y2_GET_TIST_LOW_VAL(IoC, pVal) \ + SK_IN32(IoC, GMAC_TI_ST_VAL, pVal) -#define DRIVER_IRQS ((IS_IRQ_SW) | \ - (IS_R1_F) |(IS_R2_F) | \ - (IS_XS1_F) |(IS_XA1_F) | \ - (IS_XS2_F) |(IS_XA2_F)) - -#define SPECIAL_IRQS ((IS_HW_ERR) |(IS_I2C_READY) | \ - (IS_EXT_REG) |(IS_TIMINT) | \ - (IS_PA_TO_RX1) |(IS_PA_TO_RX2) | \ - (IS_PA_TO_TX1) |(IS_PA_TO_TX2) | \ - (IS_MAC1) |(IS_LNK_SYNC_M1)| \ - (IS_MAC2) |(IS_LNK_SYNC_M2)| \ - (IS_R1_C) |(IS_R2_C) | \ - (IS_XS1_C) |(IS_XA1_C) | \ - (IS_XS2_C) |(IS_XA2_C)) - -#define IRQ_MASK ((IS_IRQ_SW) | \ - (IS_R1_B) |(IS_R1_F) |(IS_R2_B) |(IS_R2_F) | \ - (IS_XS1_B) |(IS_XS1_F) |(IS_XA1_B)|(IS_XA1_F)| \ - (IS_XS2_B) |(IS_XS2_F) |(IS_XA2_B)|(IS_XA2_F)| \ - (IS_HW_ERR) |(IS_I2C_READY)| \ - (IS_EXT_REG) |(IS_TIMINT) | \ - (IS_PA_TO_RX1) |(IS_PA_TO_RX2)| \ - (IS_PA_TO_TX1) |(IS_PA_TO_TX2)| \ - (IS_MAC1) |(IS_MAC2) | \ - (IS_R1_C) |(IS_R2_C) | \ - (IS_XS1_C) |(IS_XA1_C) | \ - (IS_XS2_C) |(IS_XA2_C)) +#endif -#define IRQ_HWE_MASK (IS_ERR_MSK) /* enable all HW irqs */ + +/******************************************************************************* + * + * Used interrupt bits in the interrupts source register + * + ******************************************************************************/ + +#define DRIVER_IRQS ((IS_IRQ_SW) | \ + (IS_R1_F) | (IS_R2_F) | \ + (IS_XS1_F) | (IS_XA1_F) | \ + (IS_XS2_F) | (IS_XA2_F)) + +#define TX_COMPL_IRQS ((IS_XS1_B) | (IS_XS1_F) | \ + (IS_XA1_B) | (IS_XA1_F) | \ + (IS_XS2_B) | (IS_XS2_F) | \ + (IS_XA2_B) | (IS_XA2_F)) + +#define NAPI_DRV_IRQS ((IS_R1_F) | (IS_R2_F) | \ + (IS_XS1_F) | (IS_XA1_F)| \ + (IS_XS2_F) | (IS_XA2_F)) + +#define Y2_DRIVER_IRQS ((Y2_IS_STAT_BMU) | (Y2_IS_IRQ_SW) | (Y2_IS_POLL_CHK)) + +#define SPECIAL_IRQS ((IS_HW_ERR) |(IS_I2C_READY) | \ + (IS_EXT_REG) |(IS_TIMINT) | \ + (IS_PA_TO_RX1) |(IS_PA_TO_RX2) | \ + (IS_PA_TO_TX1) |(IS_PA_TO_TX2) | \ + (IS_MAC1) |(IS_LNK_SYNC_M1)| \ + (IS_MAC2) |(IS_LNK_SYNC_M2)| \ + (IS_R1_C) |(IS_R2_C) | \ + (IS_XS1_C) |(IS_XA1_C) | \ + (IS_XS2_C) |(IS_XA2_C)) + +#define Y2_SPECIAL_IRQS ((Y2_IS_HW_ERR) |(Y2_IS_ASF) | \ + (Y2_IS_TWSI_RDY) |(Y2_IS_TIMINT) | \ + (Y2_IS_IRQ_PHY2) |(Y2_IS_IRQ_MAC2) | \ + (Y2_IS_CHK_RX2) |(Y2_IS_CHK_TXS2) | \ + (Y2_IS_CHK_TXA2) |(Y2_IS_IRQ_PHY1) | \ + (Y2_IS_IRQ_MAC1) |(Y2_IS_CHK_RX1) | \ + (Y2_IS_CHK_TXS1) |(Y2_IS_CHK_TXA1)) + +#define IRQ_MASK ((IS_IRQ_SW) | \ + (IS_R1_F) |(IS_R2_F) | \ + (IS_XS1_F) |(IS_XA1_F) | \ + (IS_XS2_F) |(IS_XA2_F) | \ + (IS_HW_ERR) |(IS_I2C_READY)| \ + (IS_EXT_REG) |(IS_TIMINT) | \ + (IS_PA_TO_RX1) |(IS_PA_TO_RX2)| \ + (IS_PA_TO_TX1) |(IS_PA_TO_TX2)| \ + (IS_MAC1) |(IS_MAC2) | \ + (IS_R1_C) |(IS_R2_C) | \ + (IS_XS1_C) |(IS_XA1_C) | \ + (IS_XS2_C) |(IS_XA2_C)) + +#define Y2_IRQ_MASK ((Y2_DRIVER_IRQS) | (Y2_SPECIAL_IRQS)) + +#define IRQ_HWE_MASK (IS_ERR_MSK) /* enable all HW irqs */ +#define Y2_IRQ_HWE_MASK (Y2_HWE_ALL_MSK) /* enable all HW irqs */ typedef struct s_DevNet DEV_NET; struct s_DevNet { - struct proc_dir_entry *proc; - int PortNr; - int NetNr; - int Mtu; - int Up; - SK_AC *pAC; + struct proc_dir_entry *proc; + int PortNr; + int NetNr; + char InitialDevName[20]; + SK_BOOL NetConsoleMode; +#ifdef Y2_RECOVERY + struct timer_list KernelTimer; /* Kernel timer struct */ + int TransmitTimeoutTimer; /* Transmit timer */ + SK_BOOL TimerExpired; /* Transmit timer */ + SK_BOOL InRecover; /* Recover flag */ +#ifdef Y2_RX_CHECK + SK_U32 PreviousMACFifoRP; /* Backup of the FRP */ + SK_U32 PreviousMACFifoRLev; /* Backup of the FRL */ + SK_U32 PreviousRXFifoRP; /* Backup of the RX FRP */ + SK_U8 PreviousRXFifoRLev; /* Backup of the RX FRL */ + SK_U32 LastJiffies; /* Backup of the jiffies*/ +#endif +#endif + SK_AC *pAC; }; -typedef struct s_TxPort TX_PORT; +/******************************************************************************* + * + * Rx/Tx Port structures + * + ******************************************************************************/ -struct s_TxPort { - /* the transmit descriptor rings */ - caddr_t pTxDescrRing; /* descriptor area memory */ - SK_U64 VTxDescrRing; /* descr. area bus virt. addr. */ - TXD *pTxdRingHead; /* Head of Tx rings */ - TXD *pTxdRingTail; /* Tail of Tx rings */ - TXD *pTxdRingPrev; /* descriptor sent previously */ - int TxdRingFree; /* # of free entrys */ - spinlock_t TxDesRingLock; /* serialize descriptor accesses */ - caddr_t HwAddr; /* bmu registers address */ - int PortIndex; /* index number of port (0 or 1) */ +typedef struct s_TxPort TX_PORT; +struct s_TxPort { /* the transmit descriptor rings */ + caddr_t pTxDescrRing; /* descriptor area memory */ + SK_U64 VTxDescrRing; /* descr. area bus virt. addr. */ + TXD *pTxdRingHead; /* Head of Tx rings */ + TXD *pTxdRingTail; /* Tail of Tx rings */ + TXD *pTxdRingPrev; /* descriptor sent previously */ + int TxdRingPrevFree;/* previously # of free entrys */ + int TxdRingFree; /* # of free entrys */ + spinlock_t TxDesRingLock; /* serialize descriptor accesses */ + caddr_t HwAddr; /* bmu registers address */ + int PortIndex; /* index number of port (0 or 1) */ + SK_PACKET *TransmitPacketTable; + SK_LE_TABLE TxALET; /* tx (async) list element table */ + SK_LE_TABLE TxSLET; /* tx (sync) list element table */ + SK_PKT_QUEUE TxQ_free; + SK_PKT_QUEUE TxAQ_waiting; + SK_PKT_QUEUE TxSQ_waiting; + SK_PKT_QUEUE TxAQ_working; + SK_PKT_QUEUE TxSQ_working; + unsigned LastDone; }; -typedef struct s_RxPort RX_PORT; - -struct s_RxPort { - /* the receive descriptor rings */ - caddr_t pRxDescrRing; /* descriptor area memory */ - SK_U64 VRxDescrRing; /* descr. area bus virt. addr. */ - RXD *pRxdRingHead; /* Head of Rx rings */ - RXD *pRxdRingTail; /* Tail of Rx rings */ - RXD *pRxdRingPrev; /* descriptor given to BMU previously */ - int RxdRingFree; /* # of free entrys */ - spinlock_t RxDesRingLock; /* serialize descriptor accesses */ - int RxFillLimit; /* limit for buffers in ring */ - caddr_t HwAddr; /* bmu registers address */ - int PortIndex; /* index number of port (0 or 1) */ +typedef struct s_RxPort RX_PORT; +struct s_RxPort { /* the receive descriptor rings */ + caddr_t pRxDescrRing; /* descriptor area memory */ + SK_U64 VRxDescrRing; /* descr. area bus virt. addr. */ + RXD *pRxdRingHead; /* Head of Rx rings */ + RXD *pRxdRingTail; /* Tail of Rx rings */ + RXD *pRxdRingPrev; /* descr given to BMU previously */ + int RxdRingFree; /* # of free entrys */ + spinlock_t RxDesRingLock; /* serialize descriptor accesses */ + int RxFillLimit; /* limit for buffers in ring */ + caddr_t HwAddr; /* bmu registers address */ + int PortIndex; /* index number of port (0 or 1) */ + SK_BOOL UseRxCsum; /* use Rx checksumming (yes/no) */ + SK_PACKET *ReceivePacketTable; + SK_LE_TABLE RxLET; /* rx list element table */ + SK_PKT_QUEUE RxQ_working; + SK_PKT_QUEUE RxQ_waiting; + int RxBufSize; }; -/* Definitions needed for interrupt moderation *******************************/ +/******************************************************************************* + * + * Interrupt masks used in combination with interrupt moderation + * + ******************************************************************************/ #define IRQ_EOF_AS_TX ((IS_XA1_F) | (IS_XA2_F)) #define IRQ_EOF_SY_TX ((IS_XS1_F) | (IS_XS2_F)) @@ -362,139 +732,151 @@ #define IRQ_MASK_SP_TX ((SPECIAL_IRQS) | (IRQ_MASK_TX_ONLY)) #define IRQ_MASK_RX_TX_SP ((SPECIAL_IRQS) | (IRQ_MASK_TX_RX)) -#define C_INT_MOD_NONE 1 -#define C_INT_MOD_STATIC 2 -#define C_INT_MOD_DYNAMIC 4 - -#define C_CLK_FREQ_GENESIS 53215000 /* shorter: 53.125 MHz */ -#define C_CLK_FREQ_YUKON 78215000 /* shorter: 78.125 MHz */ - -#define C_INTS_PER_SEC_DEFAULT 2000 -#define C_INT_MOD_ENABLE_PERCENTAGE 50 /* if higher 50% enable */ -#define C_INT_MOD_DISABLE_PERCENTAGE 50 /* if lower 50% disable */ -#define C_INT_MOD_IPS_LOWER_RANGE 30 -#define C_INT_MOD_IPS_UPPER_RANGE 40000 - - -typedef struct s_DynIrqModInfo DIM_INFO; -struct s_DynIrqModInfo { - unsigned long PrevTimeVal; - unsigned int PrevSysLoad; - unsigned int PrevUsedTime; - unsigned int PrevTotalTime; - int PrevUsedDescrRatio; - int NbrProcessedDescr; - SK_U64 PrevPort0RxIntrCts; - SK_U64 PrevPort1RxIntrCts; - SK_U64 PrevPort0TxIntrCts; - SK_U64 PrevPort1TxIntrCts; - SK_BOOL ModJustEnabled; /* Moderation just enabled yes/no */ - - int MaxModIntsPerSec; /* Moderation Threshold */ - int MaxModIntsPerSecUpperLimit; /* Upper limit for DIM */ - int MaxModIntsPerSecLowerLimit; /* Lower limit for DIM */ - - long MaskIrqModeration; /* ModIrqType (eg. 'TxRx') */ - SK_BOOL DisplayStats; /* Stats yes/no */ - SK_BOOL AutoSizing; /* Resize DIM-timer on/off */ - int IntModTypeSelect; /* EnableIntMod (eg. 'dynamic') */ +#define IRQ_MASK_Y2_TX_ONLY (Y2_IS_STAT_BMU) +#define IRQ_MASK_Y2_RX_ONLY (Y2_IS_STAT_BMU) +#define IRQ_MASK_Y2_SP_ONLY (SPECIAL_IRQS) +#define IRQ_MASK_Y2_TX_RX ((IRQ_MASK_TX_ONLY)| (IRQ_MASK_RX_ONLY)) +#define IRQ_MASK_Y2_SP_RX ((SPECIAL_IRQS) | (IRQ_MASK_RX_ONLY)) +#define IRQ_MASK_Y2_SP_TX ((SPECIAL_IRQS) | (IRQ_MASK_TX_ONLY)) +#define IRQ_MASK_Y2_RX_TX_SP ((SPECIAL_IRQS) | (IRQ_MASK_TX_RX)) - SK_TIMER ModTimer; /* just some timer */ -}; +/******************************************************************************* + * + * Defines and typedefs regarding interrupt moderation + * + ******************************************************************************/ -typedef struct s_PerStrm PER_STRM; +#define C_INT_MOD_NONE 1 +#define C_INT_MOD_STATIC 2 +#define C_INT_MOD_DYNAMIC 4 + +#define C_CLK_FREQ_GENESIS 53215000 /* or: 53.125 MHz */ +#define C_CLK_FREQ_YUKON 78215000 /* or: 78.125 MHz */ +#define C_CLK_FREQ_YUKON_EC 125000000 /* or: 125.000 MHz */ + +#define C_Y2_INTS_PER_SEC_DEFAULT 5000 +#define C_INTS_PER_SEC_DEFAULT 2000 +#define C_INT_MOD_IPS_LOWER_RANGE 30 /* in IRQs/second */ +#define C_INT_MOD_IPS_UPPER_RANGE 40000 /* in IRQs/second */ + +typedef struct s_DynIrqModInfo { + SK_U64 PrevPort0RxIntrCts; + SK_U64 PrevPort1RxIntrCts; + SK_U64 PrevPort0TxIntrCts; + SK_U64 PrevPort1TxIntrCts; + SK_U64 PrevPort0StatusLeIntrCts; + SK_U64 PrevPort1StatusLeIntrCts; + int MaxModIntsPerSec; /* Moderation Threshold */ + int MaxModIntsPerSecUpperLimit; /* Upper limit for DIM */ + int MaxModIntsPerSecLowerLimit; /* Lower limit for DIM */ + long MaskIrqModeration; /* IRQ Mask (eg. 'TxRx') */ + int IntModTypeSelect; /* Type (eg. 'dynamic') */ + int DynIrqModSampleInterval; /* expressed in seconds! */ + SK_TIMER ModTimer; /* Timer for dynamic mod. */ +} DIM_INFO; -#define SK_ALLOC_IRQ 0x00000001 +/******************************************************************************* + * + * Defines and typedefs regarding wake-on-lan + * + ******************************************************************************/ + +typedef struct s_WakeOnLanInfo { + SK_U32 SupportedWolOptions; /* e.g. WAKE_PHY... */ + SK_U32 ConfiguredWolOptions; /* e.g. WAKE_PHY... */ +} WOL_INFO; -#ifdef SK_DIAG_SUPPORT +#define SK_ALLOC_IRQ 0x00000001 #define DIAG_ACTIVE 1 #define DIAG_NOTACTIVE 0 -#endif /**************************************************************************** + * * Per board structure / Adapter Context structure: - * Allocated within attach(9e) and freed within detach(9e). - * Contains all 'per device' necessary handles, flags, locks etc.: - */ + * Contains all 'per device' necessary handles, flags, locks etc.: + * + ******************************************************************************/ + struct s_AC { - SK_GEINIT GIni; /* GE init struct */ - SK_PNMI Pnmi; /* PNMI data struct */ - SK_VPD vpd; /* vpd data struct */ - SK_QUEUE Event; /* Event queue */ - SK_HWT Hwt; /* Hardware Timer control struct */ - SK_TIMCTRL Tim; /* Software Timer control struct */ - SK_I2C I2c; /* I2C relevant data structure */ - SK_ADDR Addr; /* for Address module */ - SK_CSUM Csum; /* for checksum module */ - SK_RLMT Rlmt; /* for rlmt module */ - spinlock_t SlowPathLock; /* Normal IRQ lock */ - SK_PNMI_STRUCT_DATA PnmiStruct; /* structure to get all Pnmi-Data */ - int RlmtMode; /* link check mode to set */ - int RlmtNets; /* Number of nets */ - - SK_IOC IoBase; /* register set of adapter */ - int BoardLevel; /* level of active hw init (0-2) */ - char DeviceStr[80]; /* adapter string from vpd */ - SK_U32 AllocFlag; /* flag allocation of resources */ - struct pci_dev *PciDev; /* for access to pci config space */ - SK_U32 PciDevId; /* pci device id */ - struct SK_NET_DEVICE *dev[2]; /* pointer to device struct */ - char Name[30]; /* driver name */ - struct SK_NET_DEVICE *Next; /* link all devices (for clearing) */ - int RxBufSize; /* length of receive buffers */ - struct net_device_stats stats; /* linux 'netstat -i' statistics */ - int Index; /* internal board index number */ - - /* adapter RAM sizes for queues of active port */ - int RxQueueSize; /* memory used for receive queue */ - int TxSQueueSize; /* memory used for sync. tx queue */ - int TxAQueueSize; /* memory used for async. tx queue */ - - int PromiscCount; /* promiscuous mode counter */ - int AllMultiCount; /* allmulticast mode counter */ - int MulticCount; /* number of different MC */ - /* addresses for this board */ - /* (may be more than HW can)*/ - - int HWRevision; /* Hardware revision */ - int ActivePort; /* the active XMAC port */ - int MaxPorts; /* number of activated ports */ - int TxDescrPerRing; /* # of descriptors per tx ring */ - int RxDescrPerRing; /* # of descriptors per rx ring */ - - caddr_t pDescrMem; /* Pointer to the descriptor area */ - dma_addr_t pDescrMemDMA; /* PCI DMA address of area */ - - /* the port structures with descriptor rings */ - TX_PORT TxPort[SK_MAX_MACS][2]; - RX_PORT RxPort[SK_MAX_MACS]; - - unsigned int CsOfs1; /* for checksum calculation */ - unsigned int CsOfs2; /* for checksum calculation */ - SK_U32 CsOfs; /* for checksum calculation */ - - SK_BOOL CheckQueue; /* check event queue soon */ - SK_TIMER DrvCleanupTimer;/* to check for pending descriptors */ - DIM_INFO DynIrqModInfo; /* all data related to DIM */ - - /* Only for tests */ - int PortUp; - int PortDown; - int ChipsetType; /* Chipset family type - * 0 == Genesis family support - * 1 == Yukon family support - */ -#ifdef SK_DIAG_SUPPORT - SK_U32 DiagModeActive; /* is diag active? */ - SK_BOOL DiagFlowCtrl; /* for control purposes */ - SK_PNMI_STRUCT_DATA PnmiBackup; /* backup structure for all Pnmi-Data */ - SK_BOOL WasIfUp[SK_MAX_MACS]; /* for OpenClose while - * DIAG is busy with NIC - */ + SK_GEINIT GIni; /* GE init struct */ + SK_PNMI Pnmi; /* PNMI data struct */ + SK_VPD vpd; /* vpd data struct */ + SK_QUEUE Event; /* Event queue */ + SK_HWT Hwt; /* Hardware Timer ctrl struct */ + SK_TIMCTRL Tim; /* Software Timer ctrl struct */ + SK_I2C I2c; /* I2C relevant data structure*/ + SK_ADDR Addr; /* for Address module */ + SK_CSUM Csum; /* for checksum module */ + SK_RLMT Rlmt; /* for rlmt module */ + spinlock_t SlowPathLock; /* Normal IRQ lock */ + spinlock_t InitLock; /* Init lock */ + spinlock_t TxQueueLock; /* TX Queue lock */ + SK_PNMI_STRUCT_DATA PnmiStruct; /* struct for all Pnmi-Data */ + int RlmtMode; /* link check mode to set */ + int RlmtNets; /* Number of nets */ + SK_IOC IoBase; /* register set of adapter */ + int BoardLevel; /* level of hw init (0-2) */ + char DeviceStr[80]; /* adapter string from vpd */ + SK_U32 AllocFlag; /* alloc flag of resources */ + struct pci_dev *PciDev; /* for access to pci cfg space*/ + SK_U32 PciDevId; /* pci device id */ + struct SK_NET_DEVICE *dev[2]; /* pointer to device struct */ + char Name[30]; /* driver name */ + struct SK_NET_DEVICE *Next; /* link all devs for cleanup */ + struct net_device_stats stats; /* linux 'netstat -i' stats */ + int Index; /* internal board idx number */ + int RxQueueSize; /* memory used for RX queue */ + int TxSQueueSize; /* memory used for TXS queue */ + int TxAQueueSize; /* memory used for TXA queue */ + int PromiscCount; /* promiscuous mode counter */ + int AllMultiCount; /* allmulticast mode counter */ + int MulticCount; /* number of MC addresses used*/ + int HWRevision; /* Hardware revision */ + int ActivePort; /* the active XMAC port */ + int MaxPorts; /* number of activated ports */ + int TxDescrPerRing;/* # of descriptors TX ring */ + int RxDescrPerRing;/* # of descriptors RX ring */ + caddr_t pDescrMem; /* Ptr to the descriptor area */ + dma_addr_t pDescrMemDMA; /* PCI DMA address of area */ + SK_U32 PciState[16]; /* PCI state */ + TX_PORT TxPort[SK_MAX_MACS][2]; + RX_PORT RxPort[SK_MAX_MACS]; + SK_LE_TABLE StatusLETable; + unsigned SizeOfAlignedLETables; + spinlock_t SetPutIndexLock; + int MaxUnusedRxLeWorking; + unsigned int CsOfs1; /* for checksum calculation */ + unsigned int CsOfs2; /* for checksum calculation */ + SK_U32 CsOfs; /* for checksum calculation */ + SK_BOOL CheckQueue; /* check event queue soon */ + DIM_INFO DynIrqModInfo; /* all data related to IntMod */ + WOL_INFO WolInfo; /* all info regarding WOL */ + int ChipsetType; /* 0=GENESIS; 1=Yukon */ + SK_BOOL LowLatency; /* LowLatency optimization on?*/ + SK_U32 DiagModeActive;/* is diag active? */ + SK_BOOL DiagFlowCtrl; /* for control purposes */ + SK_PNMI_STRUCT_DATA PnmiBackup; /* backup structure for PNMI */ + SK_BOOL WasIfUp[SK_MAX_MACS]; +#ifdef USE_TIST_FOR_RESET + int AdapterResetState; + SK_U32 MinTistLo; + SK_U32 MinTistHi; +#endif +#ifdef Y2_RECOVERY + int LastPort; /* port for curr. handled rx */ + int LastOpc; /* last rx LEs opcode */ +#endif +#ifdef Y2_SYNC_CHECK + unsigned long FramesWithoutSyncCheck; /* since last check */ #endif - }; -#endif /* __INC_SKDRV2ND_H */ +#endif + +/******************************************************************************* + * + * End of file + * + ******************************************************************************/ diff -urN linux-2.4.32-600/drivers/net/sk98lin/h/skerror.h linux-2.4.32-600-sk98_831/drivers/net/sk98lin/h/skerror.h --- linux-2.4.32-600/drivers/net/sk98lin/h/skerror.h Sat Mar 20 10:08:19 2004 +++ linux-2.4.32-600-sk98_831/drivers/net/sk98lin/h/skerror.h Sun Feb 26 11:13:02 2006 @@ -2,21 +2,24 @@ * * Name: skerror.h * Project: Gigabit Ethernet Adapters, Common Modules + * Version: $Revision: 2.3 $ + * Date: $Date: 2005/12/14 16:11:35 $ * Purpose: SK specific Error log support * ******************************************************************************/ /****************************************************************************** * + * LICENSE: * (C)Copyright 1998-2002 SysKonnect. - * (C)Copyright 2002-2003 Marvell. + * (C)Copyright 2002-2004 Marvell. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. - * * The information in this file is provided "AS IS" without warranty. + * /LICENSE * ******************************************************************************/ @@ -34,7 +37,6 @@ #define SK_ERRCL_HW (1L<<4) /* Hardware Failure */ #define SK_ERRCL_COMM (1L<<5) /* Communication error */ - /* * Define Error Code Bases */ @@ -47,7 +49,9 @@ #define SK_ERRBASE_I2C 700 /* Base Error number for I2C module */ #define SK_ERRBASE_QUEUE 800 /* Base Error number for Scheduler */ #define SK_ERRBASE_ADDR 900 /* Base Error number for Address module */ -#define SK_ERRBASE_PECP 1000 /* Base Error number for PECP */ +#define SK_ERRBASE_PECP 1000 /* Base Error number for PECP */ #define SK_ERRBASE_DRV 1100 /* Base Error number for Driver */ +#define SK_ERRBASE_ASF 1200 /* Base Error number for ASF */ #endif /* _INC_SKERROR_H_ */ + diff -urN linux-2.4.32-600/drivers/net/sk98lin/h/skgedrv.h linux-2.4.32-600-sk98_831/drivers/net/sk98lin/h/skgedrv.h --- linux-2.4.32-600/drivers/net/sk98lin/h/skgedrv.h Sat Mar 20 10:08:19 2004 +++ linux-2.4.32-600-sk98_831/drivers/net/sk98lin/h/skgedrv.h Sun Feb 26 11:13:02 2006 @@ -2,21 +2,24 @@ * * Name: skgedrv.h * Project: Gigabit Ethernet Adapters, Common Modules + * Version: $Revision: 2.3 $ + * Date: $Date: 2005/12/14 16:11:35 $ * Purpose: Interface with the driver * ******************************************************************************/ /****************************************************************************** * + * LICENSE: * (C)Copyright 1998-2002 SysKonnect. - * (C)Copyright 2002-2003 Marvell. + * (C)Copyright 2002-2005 Marvell. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. - * * The information in this file is provided "AS IS" without warranty. + * /LICENSE * ******************************************************************************/ @@ -31,7 +34,7 @@ * In case of the driver we put the definition of the events here. */ #define SK_DRV_PORT_RESET 1 /* The port needs to be reset */ -#define SK_DRV_NET_UP 2 /* The net is operational */ +#define SK_DRV_NET_UP 2 /* The net is operational */ #define SK_DRV_NET_DOWN 3 /* The net is down */ #define SK_DRV_SWITCH_SOFT 4 /* Ports switch with both links connected */ #define SK_DRV_SWITCH_HARD 5 /* Port switch due to link failure */ @@ -42,8 +45,9 @@ #define SK_DRV_POWER_DOWN 10 /* Power down mode */ #define SK_DRV_TIMER 11 /* Timer for free use */ #ifdef SK_NO_RLMT -#define SK_DRV_LINK_UP 12 /* Link Up event for driver */ +#define SK_DRV_LINK_UP 12 /* Link Up event for driver */ #define SK_DRV_LINK_DOWN 13 /* Link Down event for driver */ #endif #define SK_DRV_DOWNSHIFT_DET 14 /* Downshift 4-Pair / 2-Pair (YUKON only) */ +#define SK_DRV_RX_OVERFLOW 15 /* Receive Overflow */ #endif /* __INC_SKGEDRV_H_ */ diff -urN linux-2.4.32-600/drivers/net/sk98lin/h/skgehw.h linux-2.4.32-600-sk98_831/drivers/net/sk98lin/h/skgehw.h --- linux-2.4.32-600/drivers/net/sk98lin/h/skgehw.h Sat Mar 20 10:08:19 2004 +++ linux-2.4.32-600-sk98_831/drivers/net/sk98lin/h/skgehw.h Sun Feb 26 11:13:02 2006 @@ -2,21 +2,24 @@ * * Name: skgehw.h * Project: Gigabit Ethernet Adapters, Common Modules + * Version: $Revision: 2.62 $ + * Date: $Date: 2005/12/14 16:11:35 $ * Purpose: Defines and Macros for the Gigabit Ethernet Adapter Product Family * ******************************************************************************/ /****************************************************************************** * + * LICENSE: * (C)Copyright 1998-2002 SysKonnect. - * (C)Copyright 2002-2003 Marvell. + * (C)Copyright 2002-2005 Marvell. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. - * * The information in this file is provided "AS IS" without warranty. + * /LICENSE * ******************************************************************************/ @@ -112,6 +115,16 @@ #define SHIFT1(x) ((x) << 1) #define SHIFT0(x) ((x) << 0) +/* Macro for arbitrary alignment of a given pointer */ +#define ALIGN_ADDR( ADDRESS, GRANULARITY ) { \ + SK_UPTR addr = (SK_UPTR)(ADDRESS); \ + if (addr & ((GRANULARITY)-1)) { \ + addr += (GRANULARITY); \ + addr &= ~(SK_UPTR)((GRANULARITY)-1); \ + ADDRESS = (void *)addr; \ + }\ +} + /* * Configuration Space header * Since this module is used for different OS', those may be @@ -130,34 +143,81 @@ #define PCI_BIST 0x0f /* 8 bit Built-in selftest */ #define PCI_BASE_1ST 0x10 /* 32 bit 1st Base address */ #define PCI_BASE_2ND 0x14 /* 32 bit 2nd Base address */ - /* Byte 0x18..0x2b: reserved */ + /* Bytes 0x18..0x2b: reserved */ #define PCI_SUB_VID 0x2c /* 16 bit Subsystem Vendor ID */ #define PCI_SUB_ID 0x2e /* 16 bit Subsystem ID */ #define PCI_BASE_ROM 0x30 /* 32 bit Expansion ROM Base Address */ -#define PCI_CAP_PTR 0x34 /* 8 bit Capabilities Ptr */ - /* Byte 0x35..0x3b: reserved */ +#define PCI_CAP_PTR 0x34 /* 8 bit Capabilities Pointer */ + /* Bytes 0x35..0x3b: reserved */ #define PCI_IRQ_LINE 0x3c /* 8 bit Interrupt Line */ #define PCI_IRQ_PIN 0x3d /* 8 bit Interrupt Pin */ #define PCI_MIN_GNT 0x3e /* 8 bit Min_Gnt */ #define PCI_MAX_LAT 0x3f /* 8 bit Max_Lat */ /* Device Dependent Region */ -#define PCI_OUR_REG_1 0x40 /* 32 bit Our Register 1 */ -#define PCI_OUR_REG_2 0x44 /* 32 bit Our Register 2 */ +#define PCI_OUR_REG_1 0x40 /* 32 bit Our Register 1 */ +#define PCI_OUR_REG_2 0x44 /* 32 bit Our Register 2 */ /* Power Management Region */ -#define PCI_PM_CAP_ID 0x48 /* 8 bit Power Management Cap. ID */ -#define PCI_PM_NITEM 0x49 /* 8 bit Next Item Ptr */ -#define PCI_PM_CAP_REG 0x4a /* 16 bit Power Management Capabilities */ -#define PCI_PM_CTL_STS 0x4c /* 16 bit Power Manag. Control/Status */ +#define PCI_PM_CAP_ID 0x48 /* 8 bit Power Management Cap. ID */ +#define PCI_PM_NITEM 0x49 /* 8 bit PM Next Item Pointer */ +#define PCI_PM_CAP_REG 0x4a /* 16 bit Power Management Capabilities */ +#define PCI_PM_CTL_STS 0x4c /* 16 bit Power Manag. Control/Status */ /* Byte 0x4e: reserved */ -#define PCI_PM_DAT_REG 0x4f /* 8 bit Power Manag. Data Register */ +#define PCI_PM_DAT_REG 0x4f /* 8 bit Power Manag. Data Register */ /* VPD Region */ -#define PCI_VPD_CAP_ID 0x50 /* 8 bit VPD Cap. ID */ -#define PCI_VPD_NITEM 0x51 /* 8 bit Next Item Ptr */ -#define PCI_VPD_ADR_REG 0x52 /* 16 bit VPD Address Register */ -#define PCI_VPD_DAT_REG 0x54 /* 32 bit VPD Data Register */ - /* Byte 0x58..0x59: reserved */ -#define PCI_SER_LD_CTRL 0x5a /* 16 bit SEEPROM Loader Ctrl (YUKON only) */ - /* Byte 0x5c..0xff: reserved */ +#define PCI_VPD_CAP_ID 0x50 /* 8 bit VPD Cap. ID */ +#define PCI_VPD_NITEM 0x51 /* 8 bit VPD Next Item Pointer */ +#define PCI_VPD_ADR_REG 0x52 /* 16 bit VPD Address Register */ +#define PCI_VPD_DAT_REG 0x54 /* 32 bit VPD Data Register */ + /* Bytes 0x58..0x59: reserved */ +#define PCI_SER_LD_CTRL 0x5a /* 16 bit SEEPROM Loader Ctrl (YUKON only) */ + /* Bytes 0x5c..0xfc: used by Yukon-2 */ +#define PCI_MSI_CAP_ID 0x5c /* 8 bit MSI Capability ID Register */ +#define PCI_MSI_NITEM 0x5d /* 8 bit MSI Next Item Pointer */ +#define PCI_MSI_CTRL 0x5e /* 16 bit MSI Message Control */ +#define PCI_MSI_ADR_LO 0x60 /* 32 bit MSI Message Address (Lower) */ +#define PCI_MSI_ADR_HI 0x64 /* 32 bit MSI Message Address (Upper) */ +#define PCI_MSI_DATA 0x68 /* 16 bit MSI Message Data */ + /* Bytes 0x6a..0x6b: reserved */ +#define PCI_X_CAP_ID 0x6c /* 8 bit PCI-X Capability ID Register */ +#define PCI_X_NITEM 0x6d /* 8 bit PCI-X Next Item Pointer */ +#define PCI_X_COMMAND 0x6e /* 16 bit PCI-X Command */ +#define PCI_X_PE_STAT 0x70 /* 32 bit PCI-X / PE Status */ +#define PCI_CAL_CTRL 0x74 /* 16 bit PCI Calibration Control Register */ +#define PCI_CAL_STAT 0x76 /* 16 bit PCI Calibration Status Register */ +#define PCI_DISC_CNT 0x78 /* 16 bit PCI Discard Counter */ +#define PCI_RETRY_CNT 0x7a /* 8 bit PCI Retry Counter */ + /* Byte 0x7b: reserved */ +#define PCI_OUR_STATUS 0x7c /* 32 bit Adapter Status Register */ +#define PCI_OUR_REG_3 0x80 /* 32 bit Our Register 3 (Yukon-ECU only) */ +#define PCI_OUR_REG_4 0x84 /* 32 bit Our Register 4 (Yukon-ECU only) */ +#define PCI_OUR_REG_5 0x88 /* 32 bit Our Register 5 (Yukon-ECU only) */ + /* Bytes 0x8c..0xdf: reserved */ + +/* PCI Express Capability */ +#define PEX_CAP_ID 0xe0 /* 8 bit PEX Capability ID */ +#define PEX_NITEM 0xe1 /* 8 bit PEX Next Item Pointer */ +#define PEX_CAP_REG 0xe2 /* 16 bit PEX Capability Register */ +#define PEX_DEV_CAP 0xe4 /* 32 bit PEX Device Capabilities */ +#define PEX_DEV_CTRL 0xe8 /* 16 bit PEX Device Control */ +#define PEX_DEV_STAT 0xea /* 16 bit PEX Device Status */ +#define PEX_LNK_CAP 0xec /* 32 bit PEX Link Capabilities */ +#define PEX_LNK_CTRL 0xf0 /* 16 bit PEX Link Control */ +#define PEX_LNK_STAT 0xf2 /* 16 bit PEX Link Status */ + /* Bytes 0xf4..0xff: reserved */ + +/* PCI Express Extended Capabilities */ +#define PEX_ADV_ERR_REP 0x100 /* 32 bit PEX Advanced Error Reporting */ +#define PEX_UNC_ERR_STAT 0x104 /* 32 bit PEX Uncorr. Errors Status */ +#define PEX_UNC_ERR_MASK 0x108 /* 32 bit PEX Uncorr. Errors Mask */ +#define PEX_UNC_ERR_SEV 0x10c /* 32 bit PEX Uncorr. Errors Severity */ +#define PEX_COR_ERR_STAT 0x110 /* 32 bit PEX Correc. Errors Status */ +#define PEX_COR_ERR_MASK 0x114 /* 32 bit PEX Correc. Errors Mask */ +#define PEX_ADV_ERR_CAP_C 0x118 /* 32 bit PEX Advanced Error Cap./Ctrl */ +#define PEX_HEADER_LOG 0x11c /* 4x32 bit PEX Header Log Register */ + +/* PCI Express Ack Timer for 1x Link */ +#define PEX_ACK_LAT_TOX1 0x228 /* 16 bit PEX Ack Latency Timeout x1 */ +#define PEX_ACK_RPLY_TOX1 0x22a /* 16 bit PEX Ack Reply Timeout val x1 */ /* * I2C Address (PCI Config) @@ -178,13 +238,13 @@ #define PCI_ADSTEP BIT_7S /* Address Stepping */ #define PCI_PERREN BIT_6S /* Parity Report Response enable */ #define PCI_VGA_SNOOP BIT_5S /* VGA palette snoop */ -#define PCI_MWIEN BIT_4S /* Memory write an inv cycl ena */ +#define PCI_MWIEN BIT_4S /* Memory write an inv cycl enable */ #define PCI_SCYCEN BIT_3S /* Special Cycle enable */ #define PCI_BMEN BIT_2S /* Bus Master enable */ #define PCI_MEMEN BIT_1S /* Memory Space Access enable */ #define PCI_IOEN BIT_0S /* I/O Space Access enable */ -#define PCI_COMMAND_VAL (PCI_FBTEN | PCI_SERREN | PCI_PERREN | PCI_MWIEN |\ +#define PCI_COMMAND_VAL (PCI_INT_DIS | PCI_SERREN | PCI_PERREN | \ PCI_BMEN | PCI_MEMEN | PCI_IOEN) /* PCI_STATUS 16 bit Status */ @@ -218,7 +278,7 @@ /* PCI_HEADER_T 8 bit Header Type */ #define PCI_HD_MF_DEV BIT_7S /* 0= single, 1= multi-func dev */ -#define PCI_HD_TYPE 0x7f /* Bit 6..0: Header Layout 0= normal */ +#define PCI_HD_TYPE 0x7f /* Bit 6..0: Header Layout (0=normal) */ /* PCI_BIST 8 bit Built-in selftest */ /* Built-in Self test not supported (optional) */ @@ -227,33 +287,42 @@ #define PCI_MEMSIZE 0x4000L /* use 16 kB Memory Base */ #define PCI_MEMBASE_MSK 0xffffc000L /* Bit 31..14: Memory Base Address */ #define PCI_MEMSIZE_MSK 0x00003ff0L /* Bit 13.. 4: Memory Size Req. */ -#define PCI_PREFEN BIT_3 /* Prefetchable */ -#define PCI_MEM_TYP (3L<<2) /* Bit 2.. 1: Memory Type */ +#define PCI_PREFEN BIT_3 /* Prefetch enable */ +#define PCI_MEM_TYP_MSK (3L<<1) /* Bit 2.. 1: Memory Type Mask */ +#define PCI_MEMSPACE BIT_0 /* Memory Space Indicator */ + #define PCI_MEM32BIT (0L<<1) /* Base addr anywhere in 32 Bit range */ #define PCI_MEM1M (1L<<1) /* Base addr below 1 MegaByte */ #define PCI_MEM64BIT (2L<<1) /* Base addr anywhere in 64 Bit range */ -#define PCI_MEMSPACE BIT_0 /* Memory Space Indicator */ /* PCI_BASE_2ND 32 bit 2nd Base address */ #define PCI_IOBASE 0xffffff00L /* Bit 31.. 8: I/O Base address */ #define PCI_IOSIZE 0x000000fcL /* Bit 7.. 2: I/O Size Requirements */ - /* Bit 1: reserved */ + /* Bit 1: reserved */ #define PCI_IOSPACE BIT_0 /* I/O Space Indicator */ /* PCI_BASE_ROM 32 bit Expansion ROM Base Address */ #define PCI_ROMBASE_MSK 0xfffe0000L /* Bit 31..17: ROM Base address */ #define PCI_ROMBASE_SIZ (0x1cL<<14) /* Bit 16..14: Treat as Base or Size */ #define PCI_ROMSIZE (0x38L<<11) /* Bit 13..11: ROM Size Requirements */ - /* Bit 10.. 1: reserved */ + /* Bit 10.. 1: reserved */ #define PCI_ROMEN BIT_0 /* Address Decode enable */ /* Device Dependent Region */ /* PCI_OUR_REG_1 32 bit Our Register 1 */ - /* Bit 31..29: reserved */ + /* Bit 31..29: reserved */ #define PCI_PHY_COMA BIT_28 /* Set PHY to Coma Mode (YUKON only) */ #define PCI_TEST_CAL BIT_27 /* Test PCI buffer calib. (YUKON only) */ #define PCI_EN_CAL BIT_26 /* Enable PCI buffer calib. (YUKON only) */ #define PCI_VIO BIT_25 /* PCI I/O Voltage, 0 = 3.3V, 1 = 5V */ +/* Yukon-2 */ +#define PCI_Y2_PIG_ENA BIT_31 /* Enable Plug-in-Go (YUKON-2) */ +#define PCI_Y2_DLL_DIS BIT_30 /* Disable PCI DLL (YUKON-2) */ +#define PCI_Y2_PHY2_COMA BIT_29 /* Set PHY 2 to Coma Mode (YUKON-2) */ +#define PCI_Y2_PHY1_COMA BIT_28 /* Set PHY 1 to Coma Mode (YUKON-2) */ +#define PCI_Y2_PHY2_POWD BIT_27 /* Set PHY 2 to Power Down (YUKON-2) */ +#define PCI_Y2_PHY1_POWD BIT_26 /* Set PHY 1 to Power Down (YUKON-2) */ + /* Bit 25: reserved */ #define PCI_DIS_BOOT BIT_24 /* Disable BOOT via ROM */ #define PCI_EN_IO BIT_23 /* Mapping to I/O space */ #define PCI_EN_FPROM BIT_22 /* Enable FLASH mapping to memory */ @@ -264,9 +333,10 @@ #define PCI_PAGE_32K (1L<<20) /* 32 k pages */ #define PCI_PAGE_64K (2L<<20) /* 64 k pages */ #define PCI_PAGE_128K (3L<<20) /* 128 k pages */ - /* Bit 19: reserved */ -#define PCI_PAGEREG (7L<<16) /* Bit 18..16: Page Register */ + /* Bit 19: reserved */ +#define PCI_PAGEREG (7L<<16) /* Bit 18..16: Page Register */ #define PCI_NOTAR BIT_15 /* No turnaround cycle */ +#define PCI_PEX_LEGNAT BIT_15 /* PEX PM legacy/native mode (YUKON-2) */ #define PCI_FORCE_BE BIT_14 /* Assert all BEs on MR */ #define PCI_DIS_MRL BIT_13 /* Disable Mem Read Line */ #define PCI_DIS_MRM BIT_12 /* Disable Mem Read Multiple */ @@ -276,13 +346,21 @@ #define PCI_DIS_PCI_CLK BIT_8 /* Disable PCI clock driving */ #define PCI_SKEW_DAS (0xfL<<4) /* Bit 7.. 4: Skew Ctrl, DAS Ext */ #define PCI_SKEW_BASE 0xfL /* Bit 3.. 0: Skew Ctrl, Base */ +#define PCI_CLS_OPT BIT_3 /* Cache Line Size opt. PCI-X (YUKON-2) */ +/* Yukon-EC Ultra only */ + /* Bit 14..10: reserved */ +#define PCI_PHY_LNK_TIM_MSK (3L<<8) /* Bit 9.. 8: GPHY Link Trigger Timer */ +#define PCI_ENA_L1_EVENT BIT_7 /* Enable PEX L1 Event */ +#define PCI_ENA_GPHY_LNK BIT_6 /* Enable PEX L1 on GPHY Link down */ +#define PCI_FORCE_PEX_L1 BIT_5 /* Force to PEX L1 */ + /* Bit 4.. 0: reserved */ /* PCI_OUR_REG_2 32 bit Our Register 2 */ #define PCI_VPD_WR_THR (0xffL<<24) /* Bit 31..24: VPD Write Threshold */ #define PCI_DEV_SEL (0x7fL<<17) /* Bit 23..17: EEPROM Device Select */ #define PCI_VPD_ROM_SZ (7L<<14) /* Bit 16..14: VPD ROM Size */ - /* Bit 13..12: reserved */ + /* Bit 13..12: reserved */ #define PCI_PATCH_DIR (0xfL<<8) /* Bit 11.. 8: Ext Patches dir 3..0 */ #define PCI_PATCH_DIR_3 BIT_11 #define PCI_PATCH_DIR_2 BIT_10 @@ -294,22 +372,21 @@ #define PCI_EXT_PATCH_1 BIT_5 #define PCI_EXT_PATCH_0 BIT_4 #define PCI_EN_DUMMY_RD BIT_3 /* Enable Dummy Read */ -#define PCI_REV_DESC BIT_2 /* Reverse Desc. Bytes */ - /* Bit 1: reserved */ +#define PCI_REV_DESC BIT_2 /* Reverse Descriptor Bytes */ + /* Bit 1: reserved */ #define PCI_USEDATA64 BIT_0 /* Use 64Bit Data bus ext */ - -/* Power Management Region */ +/* Power Management (PM) Region */ /* PCI_PM_CAP_REG 16 bit Power Management Capabilities */ -#define PCI_PME_SUP_MSK (0x1f<<11) /* Bit 15..11: PM Event Support Mask */ -#define PCI_PME_D3C_SUP BIT_15S /* PME from D3cold Support (if Vaux) */ +#define PCI_PME_SUP_MSK (0x1f<<11) /* Bit 15..11: PM Event (PME) Supp. Mask */ +#define PCI_PME_D3C_SUP BIT_15S /* PME from D3cold Support (if VAUX) */ #define PCI_PME_D3H_SUP BIT_14S /* PME from D3hot Support */ #define PCI_PME_D2_SUP BIT_13S /* PME from D2 Support */ #define PCI_PME_D1_SUP BIT_12S /* PME from D1 Support */ #define PCI_PME_D0_SUP BIT_11S /* PME from D0 Support */ #define PCI_PM_D2_SUP BIT_10S /* D2 Support in 33 MHz mode */ #define PCI_PM_D1_SUP BIT_9S /* D1 Support */ - /* Bit 8.. 6: reserved */ + /* Bit 8.. 6: reserved */ #define PCI_PM_DSI BIT_5S /* Device Specific Initialization */ #define PCI_PM_APS BIT_4S /* Auxialiary Power Source */ #define PCI_PME_CLOCK BIT_3S /* PM Event Clock */ @@ -320,7 +397,7 @@ #define PCI_PM_DAT_SCL (3<<13) /* Bit 14..13: Data Reg. scaling factor */ #define PCI_PM_DAT_SEL (0xf<<9) /* Bit 12.. 9: PM data selector field */ #define PCI_PME_EN BIT_8S /* Enable PME# generation (YUKON only) */ - /* Bit 7.. 2: reserved */ + /* Bit 7.. 2: reserved */ #define PCI_PM_STATE_MSK 3 /* Bit 1.. 0: Power Management State */ #define PCI_PM_STATE_D0 0 /* D0: Operational (default) */ @@ -331,7 +408,144 @@ /* VPD Region */ /* PCI_VPD_ADR_REG 16 bit VPD Address Register */ #define PCI_VPD_FLAG BIT_15S /* starts VPD rd/wr cycle */ -#define PCI_VPD_ADR_MSK 0x7fffL /* Bit 14.. 0: VPD address mask */ +#define PCI_VPD_ADR_MSK 0x7fffL /* Bit 14.. 0: VPD Address Mask */ + +/* PCI_OUR_STATUS 32 bit Adapter Status Register (Yukon-2) */ +#define PCI_OS_PCI64B BIT_31 /* Conventional PCI 64 bits Bus */ +#define PCI_OS_PCIX BIT_30 /* PCI-X Bus */ +#define PCI_OS_MODE_MSK (3L<<28) /* Bit 29..28: PCI-X Bus Mode Mask */ +#define PCI_OS_PCI66M BIT_27 /* PCI 66 MHz Bus */ +#define PCI_OS_PCI_X BIT_26 /* PCI/PCI-X Bus (0 = PEX) */ +#define PCI_OS_DLLE_MSK (3L<<24) /* Bit 25..24: DLL Status Indication */ +#define PCI_OS_DLLR_MSK (0xfL<<20) /* Bit 23..20: DLL Row Counters Values */ +#define PCI_OS_DLLC_MSK (0xfL<<16) /* Bit 19..16: DLL Col. Counters Values */ + /* Bit 15.. 8: reserved */ + +#define PCI_OS_SPEED(val) ((val & PCI_OS_MODE_MSK) >> 28) /* PCI-X Speed */ +/* possible values for the speed field of the register */ +#define PCI_OS_SPD_PCI 0 /* PCI Conventional Bus */ +#define PCI_OS_SPD_X66 1 /* PCI-X 66MHz Bus */ +#define PCI_OS_SPD_X100 2 /* PCI-X 100MHz Bus */ +#define PCI_OS_SPD_X133 3 /* PCI-X 133MHz Bus */ + +/* PCI_OUR_REG_3 32 bit Our Register 3 (Yukon-ECU only) */ + /* Bit 31..18: reserved */ +#define P_CLK_COR_REGS_D0_DIS BIT_17 /* Disable Clock Core Regs in D0 */ +#define P_CLK_PCI_REGS_D0_DIS BIT_16 /* Disable Clock PCI Regs in D0 */ +#define P_CLK_COR_YTB_ARB_DIS BIT_15 /* Disable Clock YTB Arbiter */ +#define P_CLK_MAC_LNK1_D3_DIS BIT_14 /* Disable Clock MAC Link1 in D3 */ +#define P_CLK_COR_LNK1_D0_DIS BIT_13 /* Disable Clock Core Link1 in D0 */ +#define P_CLK_MAC_LNK1_D0_DIS BIT_12 /* Disable Clock MAC Link1 in D0 */ +#define P_CLK_COR_LNK1_D3_DIS BIT_11 /* Disable Clock Core Link1 in D3 */ +#define P_CLK_PCI_MST_ARB_DIS BIT_10 /* Disable Clock PCI Master Arb. */ +#define P_CLK_COR_REGS_D3_DIS BIT_9 /* Disable Clock Core Regs in D3 */ +#define P_CLK_PCI_REGS_D3_DIS BIT_8 /* Disable Clock PCI Regs in D3 */ +#define P_CLK_REF_LNK1_GM_DIS BIT_7 /* Disable Clock Ref. Link1 GMAC */ +#define P_CLK_COR_LNK1_GM_DIS BIT_6 /* Disable Clock Core Link1 GMAC */ +#define P_CLK_PCI_COMMON_DIS BIT_5 /* Disable Clock PCI Common */ +#define P_CLK_COR_COMMON_DIS BIT_4 /* Disable Clock Core Common */ +#define P_CLK_PCI_LNK1_BMU_DIS BIT_3 /* Disable Clock PCI Link1 BMU */ +#define P_CLK_COR_LNK1_BMU_DIS BIT_2 /* Disable Clock Core Link1 BMU */ +#define P_CLK_PCI_LNK1_BIU_DIS BIT_1 /* Disable Clock PCI Link1 BIU */ +#define P_CLK_COR_LNK1_BIU_DIS BIT_0 /* Disable Clock Core Link1 BIU */ + +/* PCI_OUR_REG_4 32 bit Our Register 4 (Yukon-ECU only) */ +#define P_PEX_LTSSM_STAT_MSK (0x7fL<<25) /* Bit 31..25: PEX LTSSM Mask */ + /* (Link Training & Status State Machine) */ + /* Bit 24: reserved */ +#define P_TIMER_VALUE_MSK (0xffL<<16) /* Bit 23..16: Timer Value Mask */ +#define P_FORCE_ASPM_REQUEST BIT_15 /* Force ASPM Request (A1 only) */ + /* (Active State Power Management) */ + /* Bit 14..12: Force ASPM on Event */ +#define P_ASPM_GPHY_LINK_DOWN BIT_14 /* GPHY Link Down (A1 only) */ +#define P_ASPM_INT_FIFO_EMPTY BIT_13 /* Internal FIFO Empty (A1 only) */ +#define P_ASPM_CLKRUN_REQUEST BIT_12 /* CLKRUN Request (A1 only) */ + /* Bit 11.. 4: reserved */ +#define P_ASPM_FORCE_CLKREQ_ENA BIT_4 /* Force CLKREQ Enable (A1b only) */ +#define P_ASPM_CLKREQ_PAD_CTL BIT_3 /* CLKREQ PAD Control (A1 only) */ +#define P_ASPM_A1_MODE_SELECT BIT_2 /* A1 Mode Select (A1 only) */ +#define P_CLK_GATE_PEX_UNIT_ENA BIT_1 /* Enable Gate PEX Unit Clock */ +#define P_CLK_GATE_ROOT_COR_ENA BIT_0 /* Enable Gate Root Core Clock */ + +#define P_PEX_LTSSM_STAT(x) (SHIFT25(x) & P_PEX_LTSSM_STAT_MSK) +#define P_PEX_LTSSM_L1_STAT 0x34 +#define P_PEX_LTSSM_DET_STAT 0x01 + +#define P_ASPM_CONTROL_MSK (P_FORCE_ASPM_REQUEST | P_ASPM_GPHY_LINK_DOWN | \ + P_ASPM_CLKRUN_REQUEST | P_ASPM_INT_FIFO_EMPTY) + +/* PCI_OUR_REG_5 32 bit Our Register 5 (Yukon-ECU only) */ + /* Bit 31..27: reserved */ + /* Bit 26..16: Release Clock on Event */ +#define P_REL_PCIE_RST_DE_ASS BIT_26 /* PCIe Reset De-Asserted */ +#define P_REL_GPHY_REC_PACKET BIT_25 /* GPHY Received Packet */ +#define P_REL_INT_FIFO_N_EMPTY BIT_24 /* Internal FIFO Not Empty */ +#define P_REL_MAIN_PWR_AVAIL BIT_23 /* Main Power Available */ +#define P_REL_CLKRUN_REQ_REL BIT_22 /* CLKRUN Request Release */ +#define P_REL_PCIE_RESET_ASS BIT_21 /* PCIe Reset Asserted */ +#define P_REL_PME_ASSERTED BIT_20 /* PME Asserted */ +#define P_REL_PCIE_EXIT_L1_ST BIT_19 /* PCIe Exit L1 State */ +#define P_REL_LOADER_NOT_FIN BIT_18 /* EPROM Loader Not Finished */ +#define P_REL_PCIE_RX_EX_IDLE BIT_17 /* PCIe Rx Exit Electrical Idle State */ +#define P_REL_GPHY_LINK_UP BIT_16 /* GPHY Link Up */ + /* Bit 15..11: reserved */ + /* Bit 10.. 0: Mask for Gate Clock */ +#define P_GAT_PCIE_RST_DE_ASS BIT_10 /* PCIe Reset De-Asserted */ +#define P_GAT_GPHY_N_REC_PACKET BIT_9 /* GPHY Not Received Packet */ +#define P_GAT_INT_FIFO_EMPTY BIT_8 /* Internal FIFO Empty */ +#define P_GAT_MAIN_PWR_N_AVAIL BIT_7 /* Main Power Not Available */ +#define P_GAT_CLKRUN_REQ_REL BIT_6 /* CLKRUN Not Requested */ +#define P_GAT_PCIE_RESET_ASS BIT_5 /* PCIe Reset Asserted */ +#define P_GAT_PME_DE_ASSERTED BIT_4 /* PME De-Asserted */ +#define P_GAT_PCIE_ENTER_L1_ST BIT_3 /* PCIe Enter L1 State */ +#define P_GAT_LOADER_FINISHED BIT_2 /* EPROM Loader Finished */ +#define P_GAT_PCIE_RX_EL_IDLE BIT_1 /* PCIe Rx Electrical Idle State */ +#define P_GAT_GPHY_LINK_DOWN BIT_0 /* GPHY Link Down */ + +/* PEX_DEV_CTRL 16 bit PEX Device Control (Yukon-2) */ + /* Bit 15 reserved */ +#define PEX_DC_MAX_RRS_MSK (7<<12) /* Bit 14..12: Max. Read Request Size */ +#define PEX_DC_EN_NO_SNOOP BIT_11S /* Enable No Snoop */ +#define PEX_DC_EN_AUX_POW BIT_10S /* Enable AUX Power */ +#define PEX_DC_EN_PHANTOM BIT_9S /* Enable Phantom Functions */ +#define PEX_DC_EN_EXT_TAG BIT_8S /* Enable Extended Tag Field */ +#define PEX_DC_MAX_PLS_MSK (7<<5) /* Bit 7.. 5: Max. Payload Size Mask */ +#define PEX_DC_EN_REL_ORD BIT_4S /* Enable Relaxed Ordering */ +#define PEX_DC_EN_UNS_RQ_RP BIT_3S /* Enable Unsupported Request Reporting */ +#define PEX_DC_EN_FAT_ER_RP BIT_2S /* Enable Fatal Error Reporting */ +#define PEX_DC_EN_NFA_ER_RP BIT_1S /* Enable Non-Fatal Error Reporting */ +#define PEX_DC_EN_COR_ER_RP BIT_0S /* Enable Correctable Error Reporting */ + +#define PEX_DC_MAX_RD_RQ_SIZE(x) (SHIFT12(x) & PEX_DC_MAX_RRS_MSK) + +/* PEX_LNK_CTRL 16 bit PEX Link Control (Yukon-2) */ +#define PEX_LC_CLK_PM_ENA BIT_8S /* Enable Clock Power Management (CLKREQ) */ + +/* PEX_LNK_STAT 16 bit PEX Link Status (Yukon-2) */ + /* Bit 15..13 reserved */ +#define PEX_LS_SLOT_CLK_CFG BIT_12S /* Slot Clock Config */ +#define PEX_LS_LINK_TRAIN BIT_11S /* Link Training */ +#define PEX_LS_TRAIN_ERROR BIT_10S /* Training Error */ +#define PEX_LS_LINK_WI_MSK (0x3f<<4) /* Bit 9.. 4: Neg. Link Width Mask */ +#define PEX_LS_LINK_SP_MSK 0x0f /* Bit 3.. 0: Link Speed Mask */ + +/* PEX_UNC_ERR_STAT 16 bit PEX Uncorrectable Errors Status (Yukon-2) */ + /* Bit 31..21 reserved */ +#define PEX_UNSUP_REQ BIT_20 /* Unsupported Request Error */ + /* ECRC Error (not supported) */ +#define PEX_MALFOR_TLP BIT_18 /* Malformed TLP */ + /* Receiver Overflow (not supported) */ +#define PEX_UNEXP_COMP BIT_16 /* Unexpected Completion */ + /* Completer Abort (not supported) */ +#define PEX_COMP_TO BIT_14 /* Completion Timeout */ +#define PEX_FLOW_CTRL_P BIT_13 /* Flow Control Protocol Error */ +#define PEX_POIS_TLP BIT_12 /* Poisoned TLP */ + /* Bit 11.. 5: reserved */ +#define PEX_DATA_LINK_P BIT_4 /* Data Link Protocol Error */ + /* Bit 3.. 1: reserved */ + /* Training Error (not supported) */ + +#define PEX_FATAL_ERRORS (PEX_MALFOR_TLP | PEX_FLOW_CTRL_P | PEX_DATA_LINK_P) /* Control Register File (Address Map) */ @@ -347,8 +561,14 @@ #define B0_IMSK 0x000c /* 32 bit Interrupt Mask Register */ #define B0_HWE_ISRC 0x0010 /* 32 bit HW Error Interrupt Src Reg */ #define B0_HWE_IMSK 0x0014 /* 32 bit HW Error Interrupt Mask Reg */ -#define B0_SP_ISRC 0x0018 /* 32 bit Special Interrupt Source Reg */ - /* 0x001c: reserved */ +#define B0_SP_ISRC 0x0018 /* 32 bit Special Interrupt Source Reg 1 */ + +/* Special ISR registers (Yukon-2 only) */ +#define B0_Y2_SP_ISRC2 0x001c /* 32 bit Special Interrupt Source Reg 2 */ +#define B0_Y2_SP_ISRC3 0x0020 /* 32 bit Special Interrupt Source Reg 3 */ +#define B0_Y2_SP_EISR 0x0024 /* 32 bit Enter ISR Reg */ +#define B0_Y2_SP_LISR 0x0028 /* 32 bit Leave ISR Reg */ +#define B0_Y2_SP_ICR 0x002c /* 32 bit Interrupt Control Reg */ /* B0 XMAC 1 registers (GENESIS only) */ #define B0_XM1_IMSK 0x0020 /* 16 bit r/w XMAC 1 Interrupt Mask Register*/ @@ -370,7 +590,7 @@ #define B0_XM2_PHY_DATA 0x0054 /* 16 bit r/w XMAC 2 PHY Data Register */ /* 0x0056 - 0x005f: reserved */ -/* BMU Control Status Registers */ +/* BMU Control Status Registers (Yukon and Genesis) */ #define B0_R1_CSR 0x0060 /* 32 bit BMU Ctrl/Stat Rx Queue 1 */ #define B0_R2_CSR 0x0064 /* 32 bit BMU Ctrl/Stat Rx Queue 2 */ #define B0_XS1_CSR 0x0068 /* 32 bit BMU Ctrl/Stat Sync Tx Queue 1 */ @@ -388,7 +608,7 @@ /* * Bank 2 */ -/* NA reg = 48 bit Network Address Register, 3x16 or 8x8 bit readable */ +/* NA reg = 48 bit Network Address Register, 3x16 or 6x8 bit readable */ #define B2_MAC_1 0x0100 /* NA reg MAC Address 1 */ /* 0x0106 - 0x0107: reserved */ #define B2_MAC_2 0x0108 /* NA reg MAC Address 2 */ @@ -398,14 +618,23 @@ #define B2_CONN_TYP 0x0118 /* 8 bit Connector type */ #define B2_PMD_TYP 0x0119 /* 8 bit PMD type */ #define B2_MAC_CFG 0x011a /* 8 bit MAC Configuration / Chip Revision */ -#define B2_CHIP_ID 0x011b /* 8 bit Chip Identification Number */ - /* Eprom registers are currently of no use */ +#define B2_CHIP_ID 0x011b /* 8 bit Chip Identification Number */ + /* Eprom registers */ #define B2_E_0 0x011c /* 8 bit EPROM Byte 0 (ext. SRAM size */ +/* Yukon and Genesis */ #define B2_E_1 0x011d /* 8 bit EPROM Byte 1 (PHY type) */ #define B2_E_2 0x011e /* 8 bit EPROM Byte 2 */ +/* Yukon-2 */ +#define B2_Y2_CLK_GATE 0x011d /* 8 bit Clock Gating (Yukon-2) */ +#define B2_Y2_HW_RES 0x011e /* 8 bit HW Resources (Yukon-2) */ + #define B2_E_3 0x011f /* 8 bit EPROM Byte 3 */ + +/* Yukon and Genesis */ #define B2_FAR 0x0120 /* 32 bit Flash-Prom Addr Reg/Cnt */ #define B2_FDP 0x0124 /* 8 bit Flash-Prom Data Port */ +/* Yukon-2 */ +#define B2_Y2_CLK_CTRL 0x0120 /* 32 bit Core Clock Frequency Control */ /* 0x0125 - 0x0127: reserved */ #define B2_LD_CTRL 0x0128 /* 8 bit EPROM loader control register */ #define B2_LD_TEST 0x0129 /* 8 bit EPROM loader test register */ @@ -437,6 +666,10 @@ #define B2_BSC_CTRL 0x0178 /* 8 bit Blink Source Counter Control */ #define B2_BSC_STAT 0x0179 /* 8 bit Blink Source Counter Status */ #define B2_BSC_TST 0x017a /* 16 bit Blink Source Counter Test Reg */ + +/* Yukon-2 */ +#define Y2_PEX_PHY_DATA 0x0170 /* 16 bit PEX PHY Data Register */ +#define Y2_PEX_PHY_ADDR 0x0172 /* 16 bit PEX PHY Address Register */ /* 0x017c - 0x017f: reserved */ /* @@ -446,9 +679,14 @@ #define B3_RAM_ADDR 0x0180 /* 32 bit RAM Address, to read or write */ #define B3_RAM_DATA_LO 0x0184 /* 32 bit RAM Data Word (low dWord) */ #define B3_RAM_DATA_HI 0x0188 /* 32 bit RAM Data Word (high dWord) */ +#define B3_RAM_PARITY 0x018c /* 8 bit RAM Parity (Yukon-ECU A1) */ + +#define SELECT_RAM_BUFFER(rb, addr) (addr | (rb << 6)) /* Yukon-2 only */ + /* 0x018c - 0x018f: reserved */ /* RAM Interface Registers */ +/* Yukon-2: use SELECT_RAM_BUFFER() to access the RAM buffer */ /* * The HW-Spec. calls this registers Timeout Value 0..11. But this names are * not usable in SW. Please notice these are NOT real timeouts, these are @@ -515,8 +753,8 @@ /* 0x01ea - 0x01eb: reserved */ #define B3_PA_TOVAL_TX2 0x01ec /* 16 bit Timeout Val Tx Path MAC 2 */ /* 0x01ee - 0x01ef: reserved */ -#define B3_PA_CTRL 0x01f0 /* 16 bit Packet Arbiter Ctrl Register */ -#define B3_PA_TEST 0x01f2 /* 16 bit Packet Arbiter Test Register */ +#define B3_PA_CTRL 0x01f0 /* 16 bit Packet Arbiter Ctrl Register */ +#define B3_PA_TEST 0x01f2 /* 16 bit Packet Arbiter Test Register */ /* 0x01f4 - 0x01ff: reserved */ /* @@ -530,7 +768,16 @@ #define TXA_CTRL 0x0210 /* 8 bit Tx Arbiter Control Register */ #define TXA_TEST 0x0211 /* 8 bit Tx Arbiter Test Register */ #define TXA_STAT 0x0212 /* 8 bit Tx Arbiter Status Register */ - /* 0x0213 - 0x027f: reserved */ + /* 0x0213 - 0x021f: reserved */ + + /* RSS key registers for Yukon-2 Family */ +#define B4_RSS_KEY 0x0220 /* 4x32 bit RSS Key register (Yukon-2) */ + /* RSS key register offsets */ +#define KEY_IDX_0 0 /* offset for location of KEY 0 */ +#define KEY_IDX_1 4 /* offset for location of KEY 1 */ +#define KEY_IDX_2 8 /* offset for location of KEY 2 */ +#define KEY_IDX_3 12 /* offset for location of KEY 3 */ + /* 0x0280 - 0x0292: MAC 2 */ /* 0x0213 - 0x027f: reserved */ @@ -554,10 +801,10 @@ /* Queue Register Offsets, use Q_ADDR() to access */ #define Q_D 0x00 /* 8*32 bit Current Descriptor */ -#define Q_DA_L 0x20 /* 32 bit Current Descriptor Address Low dWord */ -#define Q_DA_H 0x24 /* 32 bit Current Descriptor Address High dWord */ -#define Q_AC_L 0x28 /* 32 bit Current Address Counter Low dWord */ -#define Q_AC_H 0x2c /* 32 bit Current Address Counter High dWord */ +#define Q_DA_L 0x20 /* 32 bit Current Descriptor Address Low DWord */ +#define Q_DA_H 0x24 /* 32 bit Current Descriptor Address High DWord */ +#define Q_AC_L 0x28 /* 32 bit Current Address Counter Low DWord */ +#define Q_AC_H 0x2c /* 32 bit Current Address Counter High DWord */ #define Q_BC 0x30 /* 32 bit Current Byte Counter */ #define Q_CSR 0x34 /* 32 bit BMU Control/Status Register */ #define Q_F 0x38 /* 32 bit Flag Register */ @@ -568,8 +815,56 @@ #define Q_T1_SV 0x3f /* 8 bit Test Register 1 Supervisor SM */ #define Q_T2 0x40 /* 32 bit Test Register 2 */ #define Q_T3 0x44 /* 32 bit Test Register 3 */ + +/* Yukon-2 */ +#define Q_DONE 0x24 /* 16 bit Done Index */ + +#define Q_WM 0x40 /* 16 bit FIFO Watermark */ +#define Q_AL 0x42 /* 8 bit FIFO Alignment */ + /* 0x43: reserved */ +/* RX Queue */ +#define Q_RX_RSP 0x44 /* 16 bit FIFO Read Shadow Pointer */ +#define Q_RX_RSL 0x46 /* 8 bit FIFO Read Shadow Level */ + /* 0x47: reserved */ +#define Q_RX_RP 0x48 /* 8 bit FIFO Read Pointer */ + /* 0x49: reserved */ +#define Q_RX_RL 0x4a /* 8 bit FIFO Read Level */ + /* 0x4b: reserved */ +#define Q_RX_WP 0x4c /* 8 bit FIFO Write Pointer */ +#define Q_RX_WSP 0x4d /* 8 bit FIFO Write Shadow Pointer */ +#define Q_RX_WL 0x4e /* 8 bit FIFO Write Level */ +#define Q_RX_WSL 0x4f /* 8 bit FIFO Write Shadow Level */ +/* TX Queue */ +#define Q_TX_WSP 0x44 /* 16 bit FIFO Write Shadow Pointer */ +#define Q_TX_WSL 0x46 /* 8 bit FIFO Write Shadow Level */ + /* 0x47: reserved */ +#define Q_TX_WP 0x48 /* 8 bit FIFO Write Pointer */ + /* 0x49: reserved */ +#define Q_TX_WL 0x4a /* 8 bit FIFO Write Level */ + /* 0x4b: reserved */ +#define Q_TX_RP 0x4c /* 8 bit FIFO Read Pointer */ + /* 0x4d: reserved */ +#define Q_TX_RL 0x4e /* 8 bit FIFO Read Level */ + /* 0x4f: reserved */ + /* 0x48 - 0x7f: reserved */ +/* Queue Prefetch Unit Offsets, use Y2_PREF_Q_ADDR() to address (Yukon-2 only)*/ +#define Y2_B8_PREF_REGS 0x0450 + +#define PREF_UNIT_CTRL_REG 0x00 /* 32 bit Prefetch Control register */ +#define PREF_UNIT_LAST_IDX_REG 0x04 /* 16 bit Last Index */ +#define PREF_UNIT_ADDR_LOW_REG 0x08 /* 32 bit List start addr, low part */ +#define PREF_UNIT_ADDR_HI_REG 0x0c /* 32 bit List start addr, high part*/ +#define PREF_UNIT_GET_IDX_REG 0x10 /* 16 bit Get Index */ +#define PREF_UNIT_PUT_IDX_REG 0x14 /* 16 bit Put Index */ +#define PREF_UNIT_FIFO_WP_REG 0x20 /* 8 bit FIFO write pointer */ +#define PREF_UNIT_FIFO_RP_REG 0x24 /* 8 bit FIFO read pointer */ +#define PREF_UNIT_FIFO_WM_REG 0x28 /* 8 bit FIFO watermark */ +#define PREF_UNIT_FIFO_LEV_REG 0x2c /* 8 bit FIFO level */ + +#define PREF_UNIT_MASK_IDX 0x0fff + /* * Bank 16 - 23 */ @@ -581,17 +876,17 @@ #define RB_END 0x04 /* 32 bit RAM Buffer End Address */ #define RB_WP 0x08 /* 32 bit RAM Buffer Write Pointer */ #define RB_RP 0x0c /* 32 bit RAM Buffer Read Pointer */ -#define RB_RX_UTPP 0x10 /* 32 bit Rx Upper Threshold, Pause Pack */ -#define RB_RX_LTPP 0x14 /* 32 bit Rx Lower Threshold, Pause Pack */ +#define RB_RX_UTPP 0x10 /* 32 bit Rx Upper Threshold, Pause Packet */ +#define RB_RX_LTPP 0x14 /* 32 bit Rx Lower Threshold, Pause Packet */ #define RB_RX_UTHP 0x18 /* 32 bit Rx Upper Threshold, High Prio */ #define RB_RX_LTHP 0x1c /* 32 bit Rx Lower Threshold, High Prio */ /* 0x10 - 0x1f: reserved at Tx RAM Buffer Registers */ #define RB_PC 0x20 /* 32 bit RAM Buffer Packet Counter */ #define RB_LEV 0x24 /* 32 bit RAM Buffer Level Register */ -#define RB_CTRL 0x28 /* 8 bit RAM Buffer Control Register */ +#define RB_CTRL 0x28 /* 32 bit RAM Buffer Control Register */ #define RB_TST1 0x29 /* 8 bit RAM Buffer Test Register 1 */ -#define RB_TST2 0x2A /* 8 bit RAM Buffer Test Register 2 */ - /* 0x2c - 0x7f: reserved */ +#define RB_TST2 0x2a /* 8 bit RAM Buffer Test Register 2 */ + /* 0x2b - 0x7f: reserved */ /* * Bank 24 @@ -601,7 +896,7 @@ * use MR_ADDR() to access */ #define RX_MFF_EA 0x0c00 /* 32 bit Receive MAC FIFO End Address */ -#define RX_MFF_WP 0x0c04 /* 32 bit Receive MAC FIFO Write Pointer */ +#define RX_MFF_WP 0x0c04 /* 32 bit Receive MAC FIFO Write Pointer */ /* 0x0c08 - 0x0c0b: reserved */ #define RX_MFF_RP 0x0c0c /* 32 bit Receive MAC FIFO Read Pointer */ #define RX_MFF_PC 0x0c10 /* 32 bit Receive MAC FIFO Packet Cnt */ @@ -626,20 +921,23 @@ #define LNK_LED_REG 0x0c3c /* 8 bit Link LED Register */ /* 0x0c3d - 0x0c3f: reserved */ -/* Receive GMAC FIFO (YUKON only), use MR_ADDR() to access */ +/* Receive GMAC FIFO (YUKON and Yukon-2), use MR_ADDR() to access */ #define RX_GMF_EA 0x0c40 /* 32 bit Rx GMAC FIFO End Address */ #define RX_GMF_AF_THR 0x0c44 /* 32 bit Rx GMAC FIFO Almost Full Thresh. */ #define RX_GMF_CTRL_T 0x0c48 /* 32 bit Rx GMAC FIFO Control/Test */ #define RX_GMF_FL_MSK 0x0c4c /* 32 bit Rx GMAC FIFO Flush Mask */ #define RX_GMF_FL_THR 0x0c50 /* 32 bit Rx GMAC FIFO Flush Threshold */ - /* 0x0c54 - 0x0c5f: reserved */ -#define RX_GMF_WP 0x0c60 /* 32 bit Rx GMAC FIFO Write Pointer */ +#define RX_GMF_TR_THR 0x0c54 /* 32 bit Rx Truncation Threshold (Yukon-2) */ +#define RX_GMF_UP_THR 0x0c58 /* 16 bit Rx Upper Pause Thr (Yukon-EC_U) */ +#define RX_GMF_LP_THR 0x0c5a /* 16 bit Rx Lower Pause Thr (Yukon-EC_U) */ +#define RX_GMF_VLAN 0x0c5c /* 32 bit Rx VLAN Type Register (Yukon-2) */ +#define RX_GMF_WP 0x0c60 /* 32 bit Rx GMAC FIFO Write Pointer */ /* 0x0c64 - 0x0c67: reserved */ -#define RX_GMF_WLEV 0x0c68 /* 32 bit Rx GMAC FIFO Write Level */ +#define RX_GMF_WLEV 0x0c68 /* 32 bit Rx GMAC FIFO Write Level */ /* 0x0c6c - 0x0c6f: reserved */ -#define RX_GMF_RP 0x0c70 /* 32 bit Rx GMAC FIFO Read Pointer */ +#define RX_GMF_RP 0x0c70 /* 32 bit Rx GMAC FIFO Read Pointer */ /* 0x0c74 - 0x0c77: reserved */ -#define RX_GMF_RLEV 0x0c78 /* 32 bit Rx GMAC FIFO Read Level */ +#define RX_GMF_RLEV 0x0c78 /* 32 bit Rx GMAC FIFO Read Level */ /* 0x0c7c - 0x0c7f: reserved */ /* @@ -656,7 +954,7 @@ * use MR_ADDR() to access */ #define TX_MFF_EA 0x0d00 /* 32 bit Transmit MAC FIFO End Address */ -#define TX_MFF_WP 0x0d04 /* 32 bit Transmit MAC FIFO WR Pointer */ +#define TX_MFF_WP 0x0d04 /* 32 bit Transmit MAC FIFO WR Pointer */ #define TX_MFF_WSP 0x0d08 /* 32 bit Transmit MAC FIFO WR Shadow Ptr */ #define TX_MFF_RP 0x0d0c /* 32 bit Transmit MAC FIFO RD Pointer */ #define TX_MFF_PC 0x0d10 /* 32 bit Transmit MAC FIFO Packet Cnt */ @@ -674,18 +972,19 @@ #define TX_LED_TST 0x0d29 /* 8 bit Transmit LED Cnt Test Reg */ /* 0x0d2a - 0x0d3f: reserved */ -/* Transmit GMAC FIFO (YUKON only), use MR_ADDR() to access */ +/* Transmit GMAC FIFO (YUKON and Yukon-2), use MR_ADDR() to access */ #define TX_GMF_EA 0x0d40 /* 32 bit Tx GMAC FIFO End Address */ -#define TX_GMF_AE_THR 0x0d44 /* 32 bit Tx GMAC FIFO Almost Empty Thresh.*/ +#define TX_GMF_AE_THR 0x0d44 /* 32 bit Tx GMAC FIFO Almost Empty Thresh. */ #define TX_GMF_CTRL_T 0x0d48 /* 32 bit Tx GMAC FIFO Control/Test */ - /* 0x0d4c - 0x0d5f: reserved */ -#define TX_GMF_WP 0x0d60 /* 32 bit Tx GMAC FIFO Write Pointer */ -#define TX_GMF_WSP 0x0d64 /* 32 bit Tx GMAC FIFO Write Shadow Ptr. */ -#define TX_GMF_WLEV 0x0d68 /* 32 bit Tx GMAC FIFO Write Level */ + /* 0x0d4c - 0x0d5b: reserved */ +#define TX_GMF_VLAN 0x0d5c /* 32 bit Tx VLAN Type Register (Yukon-2) */ +#define TX_GMF_WP 0x0d60 /* 32 bit Tx GMAC FIFO Write Pointer */ +#define TX_GMF_WSP 0x0d64 /* 32 bit Tx GMAC FIFO Write Shadow Pointer */ +#define TX_GMF_WLEV 0x0d68 /* 32 bit Tx GMAC FIFO Write Level */ /* 0x0d6c - 0x0d6f: reserved */ -#define TX_GMF_RP 0x0d70 /* 32 bit Tx GMAC FIFO Read Pointer */ -#define TX_GMF_RSTP 0x0d74 /* 32 bit Tx GMAC FIFO Restart Pointer */ -#define TX_GMF_RLEV 0x0d78 /* 32 bit Tx GMAC FIFO Read Level */ +#define TX_GMF_RP 0x0d70 /* 32 bit Tx GMAC FIFO Read Pointer */ +#define TX_GMF_RSTP 0x0d74 /* 32 bit Tx GMAC FIFO Restart Pointer */ +#define TX_GMF_RLEV 0x0d78 /* 32 bit Tx GMAC FIFO Read Level */ /* 0x0d7c - 0x0d7f: reserved */ /* @@ -711,12 +1010,84 @@ #define GMAC_TI_ST_CTRL 0x0e18 /* 8 bit Time Stamp Timer Ctrl Reg */ /* 0x0e19: reserved */ #define GMAC_TI_ST_TST 0x0e1a /* 8 bit Time Stamp Timer Test Reg */ - /* 0x0e1b - 0x0e7f: reserved */ + /* 0x0e1b - 0x0e1f: reserved */ + +/* Polling Unit Registers (Yukon-2 only) */ +#define POLL_CTRL 0x0e20 /* 32 bit Polling Unit Control Reg */ +#define POLL_LAST_IDX 0x0e24 /* 16 bit Polling Unit List Last Index */ + /* 0x0e26 - 0x0e27: reserved */ +#define POLL_LIST_ADDR_LO 0x0e28 /* 32 bit Poll. List Start Addr (low) */ +#define POLL_LIST_ADDR_HI 0x0e2c /* 32 bit Poll. List Start Addr (high) */ + /* 0x0e30 - 0x0e3f: reserved */ + +/* ASF Subsystem Registers (Yukon-2 only) */ +#define B28_Y2_SMB_CONFIG 0x0e40 /* 32 bit ASF SMBus Config Register */ +#define B28_Y2_SMB_CSD_REG 0x0e44 /* 32 bit ASF SMB Control/Status/Data */ + /* 0x0e48 - 0x0e5f: reserved */ +#define B28_Y2_ASF_IRQ_V_BASE 0x0e60 /* 32 bit ASF IRQ Vector Base */ + /* 0x0e64 - 0x0e67: reserved */ +#define B28_Y2_ASF_STAT_CMD 0x0e68 /* 32 bit ASF Status and Command Reg */ +#define B28_Y2_ASF_HOST_COM 0x0e6c /* 32 bit ASF Host Communication Reg */ +#define B28_Y2_DATA_REG_1 0x0e70 /* 32 bit ASF/Host Data Register 1 */ +#define B28_Y2_DATA_REG_2 0x0e74 /* 32 bit ASF/Host Data Register 2 */ +#define B28_Y2_DATA_REG_3 0x0e78 /* 32 bit ASF/Host Data Register 3 */ +#define B28_Y2_DATA_REG_4 0x0e7c /* 32 bit ASF/Host Data Register 4 */ /* * Bank 29 */ - /* 0x0e80 - 0x0efc: reserved */ + +/* Status BMU Registers (Yukon-2 only)*/ +#define STAT_CTRL 0x0e80 /* 32 bit Status BMU Control Reg */ +#define STAT_LAST_IDX 0x0e84 /* 16 bit Status BMU Last Index */ + /* 0x0e85 - 0x0e86: reserved */ +#define STAT_LIST_ADDR_LO 0x0e88 /* 32 bit Status List Start Addr (low) */ +#define STAT_LIST_ADDR_HI 0x0e8c /* 32 bit Status List Start Addr (high) */ +#define STAT_TXA1_RIDX 0x0e90 /* 16 bit Status TxA1 Report Index Reg */ +#define STAT_TXS1_RIDX 0x0e92 /* 16 bit Status TxS1 Report Index Reg */ +#define STAT_TXA2_RIDX 0x0e94 /* 16 bit Status TxA2 Report Index Reg */ +#define STAT_TXS2_RIDX 0x0e96 /* 16 bit Status TxS2 Report Index Reg */ +#define STAT_TX_IDX_TH 0x0e98 /* 16 bit Status Tx Index Threshold Reg */ + /* 0x0e9a - 0x0e9b: reserved */ +#define STAT_PUT_IDX 0x0e9c /* 16 bit Status Put Index Reg */ + /* 0x0e9e - 0x0e9f: reserved */ + +/* FIFO Control/Status Registers (Yukon-2 only) */ +#define STAT_FIFO_WP 0x0ea0 /* 8 bit Status FIFO Write Pointer Reg */ + /* 0x0ea1 - 0x0ea3: reserved */ +#define STAT_FIFO_RP 0x0ea4 /* 8 bit Status FIFO Read Pointer Reg */ + /* 0x0ea5: reserved */ +#define STAT_FIFO_RSP 0x0ea6 /* 8 bit Status FIFO Read Shadow Ptr */ + /* 0x0ea7: reserved */ +#define STAT_FIFO_LEVEL 0x0ea8 /* 8 bit Status FIFO Level Reg */ + /* 0x0ea9: reserved */ +#define STAT_FIFO_SHLVL 0x0eaa /* 8 bit Status FIFO Shadow Level Reg */ + /* 0x0eab: reserved */ +#define STAT_FIFO_WM 0x0eac /* 8 bit Status FIFO Watermark Reg */ +#define STAT_FIFO_ISR_WM 0x0ead /* 8 bit Status FIFO ISR Watermark Reg */ + /* 0x0eae - 0x0eaf: reserved */ + +/* Level and ISR Timer Registers (Yukon-2 only) */ +#define STAT_LEV_TIMER_INI 0x0eb0 /* 32 bit Level Timer Init. Value Reg */ +#define STAT_LEV_TIMER_CNT 0x0eb4 /* 32 bit Level Timer Counter Reg */ +#define STAT_LEV_TIMER_CTRL 0x0eb8 /* 8 bit Level Timer Control Reg */ +#define STAT_LEV_TIMER_TEST 0x0eb9 /* 8 bit Level Timer Test Reg */ + /* 0x0eba - 0x0ebf: reserved */ +#define STAT_TX_TIMER_INI 0x0ec0 /* 32 bit Tx Timer Init. Value Reg */ +#define STAT_TX_TIMER_CNT 0x0ec4 /* 32 bit Tx Timer Counter Reg */ +#define STAT_TX_TIMER_CTRL 0x0ec8 /* 8 bit Tx Timer Control Reg */ +#define STAT_TX_TIMER_TEST 0x0ec9 /* 8 bit Tx Timer Test Reg */ + /* 0x0eca - 0x0ecf: reserved */ +#define STAT_ISR_TIMER_INI 0x0ed0 /* 32 bit ISR Timer Init. Value Reg */ +#define STAT_ISR_TIMER_CNT 0x0ed4 /* 32 bit ISR Timer Counter Reg */ +#define STAT_ISR_TIMER_CTRL 0x0ed8 /* 8 bit ISR Timer Control Reg */ +#define STAT_ISR_TIMER_TEST 0x0ed9 /* 8 bit ISR Timer Test Reg */ + /* 0x0eda - 0x0eff: reserved */ + +#define ST_LAST_IDX_MASK 0x007f /* Last Index Mask */ +#define ST_TXRP_IDX_MASK 0x0fff /* Tx Report Index Mask */ +#define ST_TXTH_IDX_MASK 0x0fff /* Tx Threshold Index Mask */ +#define ST_WM_IDX_MASK 0x3f /* FIFO Watermark Index Mask */ /* * Bank 30 @@ -740,11 +1111,9 @@ #define WOL_MATCH_RES 0x0f23 /* 8 bit WOL Match Result Reg */ #define WOL_MAC_ADDR_LO 0x0f24 /* 32 bit WOL MAC Address Low */ #define WOL_MAC_ADDR_HI 0x0f28 /* 16 bit WOL MAC Address High */ -#define WOL_PATT_RPTR 0x0f2c /* 8 bit WOL Pattern Read Ptr */ - -/* use this macro to access above registers */ -#define WOL_REG(Reg) ((Reg) + (pAC->GIni.GIWolOffs)) - +#define WOL_PATT_PME 0x0f2a /* 8 bit WOL PME Match Enable (Yukon-2) */ +#define WOL_PATT_ASFM 0x0f2b /* 8 bit WOL ASF Match Enable (Yukon-2) */ +#define WOL_PATT_RPTR 0x0f2c /* 8 bit WOL Pattern Read Pointer */ /* WOL Pattern Length Registers (YUKON only) */ @@ -762,11 +1131,22 @@ */ /* 0x0f80 - 0x0fff: reserved */ +/* WOL registers link 2 */ + +/* use this macro to access WOL registers */ +#define WOL_REG(Port, Reg) ((Reg) + ((Port)*0x80) + (pAC->GIni.GIWolOffs)) + /* * Bank 32 - 33 */ #define WOL_PATT_RAM_1 0x1000 /* WOL Pattern RAM Link 1 */ +#define WOL_PATT_RAM_2 0x1400 /* WOL Pattern RAM Link 2 */ + +/* use this macro to retrieve the pattern ram base address */ +#define WOL_PATT_RAM_BASE(Port) (WOL_PATT_RAM_1 + (Port)*0x400) +/* offset to configuration space on Yukon-2 */ +#define Y2_CFG_SPC 0x1c00 /* * Bank 0x22 - 0x3f */ @@ -798,13 +1178,27 @@ */ /* B0_RAP 8 bit Register Address Port */ /* Bit 7: reserved */ -#define RAP_RAP 0x3f /* Bit 6..0: 0 = block 0,..,6f = block 6f */ +#define RAP_MSK 0x7f /* Bit 6..0: 0 = block 0,..,6f = block 6f */ + +/* B0_CTST 24 bit Control/Status register */ + /* Bit 23..18: reserved */ +#define Y2_VMAIN_AVAIL BIT_17 /* VMAIN available (YUKON-2 only) */ +#define Y2_VAUX_AVAIL BIT_16 /* VAUX available (YUKON-2 only) */ +#define Y2_HW_WOL_ON BIT_15S /* HW WOL On (Yukon-EC Ultra A1 only) */ +#define Y2_HW_WOL_OFF BIT_14S /* HW WOL Off (Yukon-EC Ultra A1 only) */ +#define Y2_ASF_ENABLE BIT_13S /* ASF Unit Enable (YUKON-2 only) */ +#define Y2_ASF_DISABLE BIT_12S /* ASF Unit Disable (YUKON-2 only) */ +#define Y2_CLK_RUN_ENA BIT_11S /* CLK_RUN Enable (YUKON-2 only) */ +#define Y2_CLK_RUN_DIS BIT_10S /* CLK_RUN Disable (YUKON-2 only) */ +#define Y2_LED_STAT_ON BIT_9S /* Status LED On (YUKON-2 only) */ +#define Y2_LED_STAT_OFF BIT_8S /* Status LED Off (YUKON-2 only) */ + /* Bit 7.. 0: same as below */ /* B0_CTST 16 bit Control/Status register */ /* Bit 15..14: reserved */ -#define CS_CLK_RUN_HOT BIT_13S /* CLK_RUN hot m. (YUKON-Lite only) */ -#define CS_CLK_RUN_RST BIT_12S /* CLK_RUN reset (YUKON-Lite only) */ -#define CS_CLK_RUN_ENA BIT_11S /* CLK_RUN enable (YUKON-Lite only) */ +#define CS_CLK_RUN_HOT BIT_13S /* CLK_RUN Hot m. (YUKON-Lite only) */ +#define CS_CLK_RUN_RST BIT_12S /* CLK_RUN Reset (YUKON-Lite only) */ +#define CS_CLK_RUN_ENA BIT_11S /* CLK_RUN Enable (YUKON-Lite only) */ #define CS_VAUX_AVAIL BIT_10S /* VAUX available (YUKON only) */ #define CS_BUS_CLOCK BIT_9S /* Bus Clock 0/1 = 33/66 MHz */ #define CS_BUS_SLOT_SZ BIT_8S /* Slot Size 0/1 = 32/64 bit slot */ @@ -812,26 +1206,27 @@ #define CS_CL_SW_IRQ BIT_6S /* Clear IRQ SW Request */ #define CS_STOP_DONE BIT_5S /* Stop Master is finished */ #define CS_STOP_MAST BIT_4S /* Command Bit to stop the master */ -#define CS_MRST_CLR BIT_3S /* Clear Master reset */ -#define CS_MRST_SET BIT_2S /* Set Master reset */ -#define CS_RST_CLR BIT_1S /* Clear Software reset */ -#define CS_RST_SET BIT_0S /* Set Software reset */ +#define CS_MRST_CLR BIT_3S /* Clear Master Reset */ +#define CS_MRST_SET BIT_2S /* Set Master Reset */ +#define CS_RST_CLR BIT_1S /* Clear Software Reset */ +#define CS_RST_SET BIT_0S /* Set Software Reset */ -/* B0_LED 8 Bit LED register */ +/* B0_LED 8 Bit LED register (GENESIS only)*/ /* Bit 7.. 2: reserved */ -#define LED_STAT_ON BIT_1S /* Status LED on */ -#define LED_STAT_OFF BIT_0S /* Status LED off */ +#define LED_STAT_ON BIT_1S /* Status LED On */ +#define LED_STAT_OFF BIT_0S /* Status LED Off */ /* B0_POWER_CTRL 8 Bit Power Control reg (YUKON only) */ #define PC_VAUX_ENA BIT_7 /* Switch VAUX Enable */ -#define PC_VAUX_DIS BIT_6 /* Switch VAUX Disable */ -#define PC_VCC_ENA BIT_5 /* Switch VCC Enable */ -#define PC_VCC_DIS BIT_4 /* Switch VCC Disable */ -#define PC_VAUX_ON BIT_3 /* Switch VAUX On */ -#define PC_VAUX_OFF BIT_2 /* Switch VAUX Off */ -#define PC_VCC_ON BIT_1 /* Switch VCC On */ -#define PC_VCC_OFF BIT_0 /* Switch VCC Off */ +#define PC_VAUX_DIS BIT_6 /* Switch VAUX Disable */ +#define PC_VCC_ENA BIT_5 /* Switch VCC Enable */ +#define PC_VCC_DIS BIT_4 /* Switch VCC Disable */ +#define PC_VAUX_ON BIT_3 /* Switch VAUX On */ +#define PC_VAUX_OFF BIT_2 /* Switch VAUX Off */ +#define PC_VCC_ON BIT_1 /* Switch VCC On */ +#define PC_VCC_OFF BIT_0 /* Switch VCC Off */ +/* Yukon and Genesis */ /* B0_ISRC 32 bit Interrupt Source Register */ /* B0_IMSK 32 bit Interrupt Mask Register */ /* B0_SP_ISRC 32 bit Special Interrupt Source Reg */ @@ -877,12 +1272,51 @@ #define IS_XA2_F BIT_1 /* Q_XA2 End of Frame */ #define IS_XA2_C BIT_0 /* Q_XA2 Encoding Error */ +/* Yukon-2 */ +/* B0_ISRC 32 bit Interrupt Source Register */ +/* B0_IMSK 32 bit Interrupt Mask Register */ +/* B0_SP_ISRC 32 bit Special Interrupt Source Reg */ +/* B2_IRQM_MSK 32 bit IRQ Moderation Mask */ +/* B0_Y2_SP_ISRC2 32 bit Special Interrupt Source Reg 2 */ +/* B0_Y2_SP_ISRC3 32 bit Special Interrupt Source Reg 3 */ +/* B0_Y2_SP_EISR 32 bit Enter ISR Reg */ +/* B0_Y2_SP_LISR 32 bit Leave ISR Reg */ +#define Y2_IS_PORT_MASK(Port, Mask) ((Mask) << (Port*8)) +#define Y2_IS_HW_ERR BIT_31 /* Interrupt HW Error */ +#define Y2_IS_STAT_BMU BIT_30 /* Status BMU Interrupt */ +#define Y2_IS_ASF BIT_29 /* ASF subsystem Interrupt */ + /* Bit 28: reserved */ +#define Y2_IS_POLL_CHK BIT_27 /* Check IRQ from polling unit */ +#define Y2_IS_TWSI_RDY BIT_26 /* IRQ on end of TWSI Tx */ +#define Y2_IS_IRQ_SW BIT_25 /* SW forced IRQ */ +#define Y2_IS_TIMINT BIT_24 /* IRQ from Timer */ + /* Bit 23..16 reserved */ + /* Link 2 Interrupts */ +#define Y2_IS_IRQ_PHY2 BIT_12 /* Interrupt from PHY 2 */ +#define Y2_IS_IRQ_MAC2 BIT_11 /* Interrupt from MAC 2 */ +#define Y2_IS_CHK_RX2 BIT_10 /* Descriptor error Rx 2 */ +#define Y2_IS_CHK_TXS2 BIT_9 /* Descriptor error TXS 2 */ +#define Y2_IS_CHK_TXA2 BIT_8 /* Descriptor error TXA 2 */ + /* Bit 7.. 5 reserved */ + /* Link 1 interrupts */ +#define Y2_IS_IRQ_PHY1 BIT_4 /* Interrupt from PHY 1 */ +#define Y2_IS_IRQ_MAC1 BIT_3 /* Interrupt from MAC 1 */ +#define Y2_IS_CHK_RX1 BIT_2 /* Descriptor error Rx 1 */ +#define Y2_IS_CHK_TXS1 BIT_1 /* Descriptor error TXS 1 */ +#define Y2_IS_CHK_TXA1 BIT_0 /* Descriptor error TXA 1 */ + +#define Y2_IS_L1_MASK 0x0000001fUL /* IRQ Mask for port 1 */ + +#define Y2_IS_L2_MASK 0x00001f00UL /* IRQ Mask for port 2 */ + +#define Y2_IS_ALL_MSK 0xef001f1fUL /* All Interrupt bits */ +/* Yukon and Genesis */ /* B0_HWE_ISRC 32 bit HW Error Interrupt Src Reg */ /* B0_HWE_IMSK 32 bit HW Error Interrupt Mask Reg */ /* B2_IRQM_HWE_MSK 32 bit IRQ Moderation HW Error Mask */ #define IS_ERR_MSK 0x00000fffL /* All Error bits */ - /* Bit 31..14: reserved */ + /* Bit 31..14: reserved */ #define IS_IRQ_TIST_OV BIT_13 /* Time Stamp Timer Overflow (YUKON only) */ #define IS_IRQ_SENSOR BIT_12 /* IRQ from Sensor (YUKON only) */ #define IS_IRQ_MST_ERR BIT_11 /* IRQ master error detected */ @@ -898,6 +1332,43 @@ #define IS_R1_PAR_ERR BIT_1 /* Queue R1 Parity Error */ #define IS_R2_PAR_ERR BIT_0 /* Queue R2 Parity Error */ +/* Yukon-2 */ +/* B0_HWE_ISRC 32 bit HW Error Interrupt Src Reg */ +/* B0_HWE_IMSK 32 bit HW Error Interrupt Mask Reg */ +/* B2_IRQM_HWE_MSK 32 bit IRQ Moderation HW Error Mask */ + /* Bit: 31..30 reserved */ +#define Y2_IS_TIST_OV BIT_29 /* Time Stamp Timer overflow interrupt */ +#define Y2_IS_SENSOR BIT_28 /* Sensor interrupt */ +#define Y2_IS_MST_ERR BIT_27 /* Master error interrupt */ +#define Y2_IS_IRQ_STAT BIT_26 /* Status exception interrupt */ +#define Y2_IS_PCI_EXP BIT_25 /* PCI-Express interrupt */ +#define Y2_IS_PCI_NEXP BIT_24 /* Bus Abort detected */ + /* Bit: 23..14 reserved */ + /* Link 2 */ +#define Y2_IS_PAR_RD2 BIT_13 /* Read RAM parity error interrupt */ +#define Y2_IS_PAR_WR2 BIT_12 /* Write RAM parity error interrupt */ +#define Y2_IS_PAR_MAC2 BIT_11 /* MAC hardware fault interrupt */ +#define Y2_IS_PAR_RX2 BIT_10 /* Parity Error Rx Queue 2 */ +#define Y2_IS_TCP_TXS2 BIT_9 /* TCP length mismatch sync Tx queue IRQ */ +#define Y2_IS_TCP_TXA2 BIT_8 /* TCP length mismatch async Tx queue IRQ */ + /* Bit: 9.. 6 reserved */ + /* Link 1 */ +#define Y2_IS_PAR_RD1 BIT_5 /* Read RAM parity error interrupt */ +#define Y2_IS_PAR_WR1 BIT_4 /* Write RAM parity error interrupt */ +#define Y2_IS_PAR_MAC1 BIT_3 /* MAC hardware fault interrupt */ +#define Y2_IS_PAR_RX1 BIT_2 /* Parity Error Rx Queue 1 */ +#define Y2_IS_TCP_TXS1 BIT_1 /* TCP length mismatch sync Tx queue IRQ */ +#define Y2_IS_TCP_TXA1 BIT_0 /* TCP length mismatch async Tx queue IRQ */ + +#define Y2_HWE_L1_MASK (Y2_IS_PAR_RD1 | Y2_IS_PAR_WR1 | Y2_IS_PAR_MAC1 |\ + Y2_IS_PAR_RX1 | Y2_IS_TCP_TXS1| Y2_IS_TCP_TXA1) +#define Y2_HWE_L2_MASK (Y2_IS_PAR_RD2 | Y2_IS_PAR_WR2 | Y2_IS_PAR_MAC2 |\ + Y2_IS_PAR_RX2 | Y2_IS_TCP_TXS2| Y2_IS_TCP_TXA2) + +#define Y2_HWE_ALL_MSK (Y2_IS_TIST_OV | /* Y2_IS_SENSOR | */ Y2_IS_MST_ERR |\ + Y2_IS_IRQ_STAT | Y2_IS_PCI_EXP |\ + Y2_HWE_L1_MASK | Y2_HWE_L2_MASK) + /* B2_CONN_TYP 8 bit Connector type */ /* B2_PMD_TYP 8 bit PMD type */ /* Values of connector and PMD type comply to SysKonnect internal std */ @@ -906,19 +1377,74 @@ #define CFG_CHIP_R_MSK (0xf<<4) /* Bit 7.. 4: Chip Revision */ /* Bit 3.. 2: reserved */ #define CFG_DIS_M2_CLK BIT_1S /* Disable Clock for 2nd MAC */ -#define CFG_SNG_MAC BIT_0S /* MAC Config: 0=2 MACs / 1=1 MAC*/ +#define CFG_SNG_MAC BIT_0S /* MAC Config: 0 = 2 MACs; 1 = 1 MAC */ -/* B2_CHIP_ID 8 bit Chip Identification Number */ +/* B2_CHIP_ID 8 bit Chip Identification Number */ #define CHIP_ID_GENESIS 0x0a /* Chip ID for GENESIS */ #define CHIP_ID_YUKON 0xb0 /* Chip ID for YUKON */ #define CHIP_ID_YUKON_LITE 0xb1 /* Chip ID for YUKON-Lite (Rev. A1-A3) */ #define CHIP_ID_YUKON_LP 0xb2 /* Chip ID for YUKON-LP */ +#define CHIP_ID_YUKON_XL 0xb3 /* Chip ID for YUKON-2 XL */ +#define CHIP_ID_YUKON_EC_U 0xb4 /* Chip ID for YUKON-2 EC Ultra */ +#define CHIP_ID_YUKON_EC 0xb6 /* Chip ID for YUKON-2 EC */ +#define CHIP_ID_YUKON_FE 0xb7 /* Chip ID for YUKON-2 FE */ #define CHIP_REV_YU_LITE_A1 3 /* Chip Rev. for YUKON-Lite A1,A2 */ #define CHIP_REV_YU_LITE_A3 7 /* Chip Rev. for YUKON-Lite A3 */ +#define CHIP_REV_YU_XL_A0 0 /* Chip Rev. for Yukon-2 A0 */ +#define CHIP_REV_YU_XL_A1 1 /* Chip Rev. for Yukon-2 A1 */ +#define CHIP_REV_YU_XL_A2 2 /* Chip Rev. for Yukon-2 A2 */ +#define CHIP_REV_YU_XL_A3 3 /* Chip Rev. for Yukon-2 A3 */ + +#define CHIP_REV_YU_EC_A1 0 /* Chip Rev. for Yukon-EC A0,A1 */ +#define CHIP_REV_YU_EC_A2 1 /* Chip Rev. for Yukon-EC A2 */ +#define CHIP_REV_YU_EC_A3 2 /* Chip Rev. for Yukon-EC A3 */ + +#define CHIP_REV_YU_EC_U_A0 1 /* Chip Rev. for Yukon-EC Ultra A0 */ +#define CHIP_REV_YU_EC_U_A1 2 /* Chip Rev. for Yukon-EC Ultra A1 */ + +/* B2_Y2_CLK_GATE 8 bit Clock Gating (Yukon-2 only) */ +#define Y2_STATUS_LNK2_INAC BIT_7S /* Status Link 2 inactiv (0 = activ) */ +#define Y2_CLK_GAT_LNK2_DIS BIT_6S /* Disable PHY clock for Link 2 */ +#define Y2_COR_CLK_LNK2_DIS BIT_5S /* Disable Core clock Link 2 */ +#define Y2_PCI_CLK_LNK2_DIS BIT_4S /* Disable PCI clock Link 2 */ +#define Y2_STATUS_LNK1_INAC BIT_3S /* Status Link 1 inactiv (0 = activ) */ +#define Y2_CLK_GAT_LNK1_DIS BIT_2S /* Disable PHY clock for Link 1 */ +#define Y2_COR_CLK_LNK1_DIS BIT_1S /* Disable Core clock Link 1 */ +#define Y2_PCI_CLK_LNK1_DIS BIT_0S /* Disable PCI clock Link 1 */ + +/* B2_Y2_HW_RES 8 bit HW Resources (Yukon-2 only) */ + /* Bit 7.. 5: reserved */ +#define CFG_LED_MODE_MSK (7<<2) /* Bit 4.. 2: LED Mode Mask */ +#define CFG_LINK_2_AVAIL BIT_1S /* Link 2 available */ +#define CFG_LINK_1_AVAIL BIT_0S /* Link 1 available */ + +#define CFG_LED_MODE(x) (((x) & CFG_LED_MODE_MSK) >> 2) +#define CFG_DUAL_MAC_MSK (CFG_LINK_2_AVAIL | CFG_LINK_1_AVAIL) + +#define CFG_LED_SING_ACT_LNK 0 /* Single LED ACT/LNK mode */ +#define CFG_LED_DUAL_ACT_LNK 1 /* Dual LED ACT/LNK mode */ + +/* B2_E_3 8 bit lower 4 bits used for HW self test result */ +#define B2_E3_RES_MASK 0x0f + /* B2_FAR 32 bit Flash-Prom Addr Reg/Cnt */ -#define FAR_ADDR 0x1ffffL /* Bit 16.. 0: FPROM Address mask */ +#define FAR_ADDR 0x1ffffL /* Bit 16.. 0: FPROM Address Mask */ + +/* B2_Y2_CLK_CTRL 32 bit Core Clock Frequency Control Register (Yukon-2/EC) */ + /* Bit 31..24: reserved */ +/* Yukon-EC/FE */ +#define Y2_CLK_DIV_VAL_MSK (0xffL<<16) /* Bit 23..16: Clock Divisor Value */ +#define Y2_CLK_DIV_VAL(x) (SHIFT16(x) & Y2_CLK_DIV_VAL_MSK) +/* Yukon-2 */ +#define Y2_CLK_DIV_VAL2_MSK (7L<<21) /* Bit 23..21: Clock Divisor Value */ +#define Y2_CLK_SELECT2_MSK (0x1fL<<16) /* Bit 20..16: Clock Select */ +#define Y2_CLK_DIV_VAL_2(x) (SHIFT21(x) & Y2_CLK_DIV_VAL2_MSK) +#define Y2_CLK_SEL_VAL_2(x) (SHIFT16(x) & Y2_CLK_SELECT2_MSK) + /* Bit 15.. 2: reserved */ +#define Y2_CLK_DIV_ENA BIT_1S /* Enable Core Clock Division */ +#define Y2_CLK_DIV_DIS BIT_0S /* Disable Core Clock Division */ /* B2_LD_CTRL 8 bit EPROM loader control register */ /* Bits are currently reserved */ @@ -958,9 +1484,6 @@ #define DPT_START BIT_1S /* Start Descriptor Poll Timer */ #define DPT_STOP BIT_0S /* Stop Descriptor Poll Timer */ -/* B2_E_3 8 bit lower 4 bits used for HW self test result */ -#define B2_E3_RES_MASK 0x0f - /* B2_TST_CTRL1 8 bit Test Control Register 1 */ #define TST_FRC_DPERR_MR BIT_7S /* force DATAPERR on MST RD */ #define TST_FRC_DPERR_MW BIT_6S /* force DATAPERR on MST WR */ @@ -973,14 +1496,14 @@ /* B2_TST_CTRL2 8 bit Test Control Register 2 */ /* Bit 7.. 4: reserved */ - /* force the following error on the next master read/write */ + /* force the following error on the next master read/write */ #define TST_FRC_DPERR_MR64 BIT_3S /* DataPERR RD 64 */ #define TST_FRC_DPERR_MW64 BIT_2S /* DataPERR WR 64 */ #define TST_FRC_APERR_1M64 BIT_1S /* AddrPERR on 1. phase */ #define TST_FRC_APERR_2M64 BIT_0S /* AddrPERR on 2. phase */ /* B2_GP_IO 32 bit General Purpose I/O Register */ - /* Bit 31..26: reserved */ + /* Bit 31..26: reserved */ #define GP_DIR_9 BIT_25 /* IO_9 direct, 0=In/1=Out */ #define GP_DIR_8 BIT_24 /* IO_8 direct, 0=In/1=Out */ #define GP_DIR_7 BIT_23 /* IO_7 direct, 0=In/1=Out */ @@ -1007,15 +1530,15 @@ #define I2C_FLAG BIT_31 /* Start read/write if WR */ #define I2C_ADDR (0x7fffL<<16) /* Bit 30..16: Addr to be RD/WR */ #define I2C_DEV_SEL (0x7fL<<9) /* Bit 15.. 9: I2C Device Select */ - /* Bit 8.. 5: reserved */ + /* Bit 8.. 5: reserved */ #define I2C_BURST_LEN BIT_4 /* Burst Len, 1/4 bytes */ -#define I2C_DEV_SIZE (7<<1) /* Bit 3.. 1: I2C Device Size */ -#define I2C_025K_DEV (0<<1) /* 0: 256 Bytes or smal. */ -#define I2C_05K_DEV (1<<1) /* 1: 512 Bytes */ -#define I2C_1K_DEV (2<<1) /* 2: 1024 Bytes */ -#define I2C_2K_DEV (3<<1) /* 3: 2048 Bytes */ -#define I2C_4K_DEV (4<<1) /* 4: 4096 Bytes */ -#define I2C_8K_DEV (5<<1) /* 5: 8192 Bytes */ +#define I2C_DEV_SIZE (7<<1) /* Bit 3.. 1: I2C Device Size */ +#define I2C_025K_DEV (0<<1) /* 0: 256 Bytes or smaller */ +#define I2C_05K_DEV (1<<1) /* 1: 512 Bytes */ +#define I2C_1K_DEV (2<<1) /* 2: 1024 Bytes */ +#define I2C_2K_DEV (3<<1) /* 3: 2048 Bytes */ +#define I2C_4K_DEV (4<<1) /* 4: 4096 Bytes */ +#define I2C_8K_DEV (5<<1) /* 5: 8192 Bytes */ #define I2C_16K_DEV (6<<1) /* 6: 16384 Bytes */ #define I2C_32K_DEV (7<<1) /* 7: 32768 Bytes */ #define I2C_STOP BIT_0 /* Interrupt I2C transfer */ @@ -1024,16 +1547,14 @@ /* Bit 31.. 1 reserved */ #define I2C_CLR_IRQ BIT_0 /* Clear I2C IRQ */ -/* B2_I2C_SW 32 bit (8 bit access) I2C HW SW Port Register */ +/* B2_I2C_SW 32 bit (8 bit access) I2C SW Port Register */ /* Bit 7.. 3: reserved */ #define I2C_DATA_DIR BIT_2S /* direction of I2C_DATA */ -#define I2C_DATA BIT_1S /* I2C Data Port */ -#define I2C_CLK BIT_0S /* I2C Clock Port */ +#define I2C_DATA BIT_1S /* I2C Data Port */ +#define I2C_CLK BIT_0S /* I2C Clock Port */ -/* - * I2C Address - */ -#define I2C_SENS_ADDR LM80_ADDR /* I2C Sensor Address, (Volt and Temp)*/ +/* I2C Address */ +#define I2C_SENS_ADDR LM80_ADDR /* I2C Sensor Address (Volt and Temp) */ /* B2_BSC_CTRL 8 bit Blink Source Counter Control */ @@ -1050,16 +1571,20 @@ #define BSC_T_OFF BIT_1S /* Test mode off */ #define BSC_T_STEP BIT_0S /* Test step */ +/* Y2_PEX_PHY_ADDR/DATA PEX PHY address and data reg (Yukon-2 only) */ +#define PEX_RD_ACCESS BIT_31 /* Access Mode Read = 1, Write = 0 */ +#define PEX_DB_ACCESS BIT_30 /* Access to debug register */ + /* B3_RAM_ADDR 32 bit RAM Address, to read or write */ /* Bit 31..19: reserved */ #define RAM_ADR_RAN 0x0007ffffL /* Bit 18.. 0: RAM Address Range */ /* RAM Interface Registers */ -/* B3_RI_CTRL 16 bit RAM Iface Control Register */ +/* B3_RI_CTRL 16 bit RAM Interface Control Register */ /* Bit 15..10: reserved */ -#define RI_CLR_RD_PERR BIT_9S /* Clear IRQ RAM Read Parity Err */ -#define RI_CLR_WR_PERR BIT_8S /* Clear IRQ RAM Write Parity Err*/ +#define RI_CLR_RD_PERR BIT_9S /* Clear IRQ RAM Read Parity Err */ +#define RI_CLR_WR_PERR BIT_8S /* Clear IRQ RAM Write Parity Err */ /* Bit 7.. 2: reserved */ #define RI_RST_CLR BIT_1S /* Clear RAM Interface Reset */ #define RI_RST_SET BIT_0S /* Set RAM Interface Reset */ @@ -1169,7 +1694,7 @@ /* Bit 31..16: reserved */ #define BC_MAX 0xffff /* Bit 15.. 0: Byte counter */ -/* BMU Control Status Registers */ +/* BMU Control / Status Registers (Yukon and Genesis) */ /* B0_R1_CSR 32 bit BMU Ctrl/Stat Rx Queue 1 */ /* B0_R2_CSR 32 bit BMU Ctrl/Stat Rx Queue 2 */ /* B0_XA1_CSR 32 bit BMU Ctrl/Stat Sync Tx Queue 1 */ @@ -1210,13 +1735,48 @@ CSR_SV_RUN | CSR_DREAD_RUN | CSR_DWRITE_RUN |\ CSR_TRANS_RUN) +/* Rx BMU Control / Status Registers (Yukon-2) */ +#define BMU_IDLE BIT_31 /* BMU Idle State */ +#define BMU_RX_TCP_PKT BIT_30 /* Rx TCP Packet (when RSS Hash enabled) */ +#define BMU_RX_IP_PKT BIT_29 /* Rx IP Packet (when RSS Hash enabled) */ + /* Bit 28..16: reserved */ +#define BMU_ENA_RX_RSS_HASH BIT_15 /* Enable Rx RSS Hash */ +#define BMU_DIS_RX_RSS_HASH BIT_14 /* Disable Rx RSS Hash */ +#define BMU_ENA_RX_CHKSUM BIT_13 /* Enable Rx TCP/IP Checksum Check */ +#define BMU_DIS_RX_CHKSUM BIT_12 /* Disable Rx TCP/IP Checksum Check */ +#define BMU_CLR_IRQ_PAR BIT_11 /* Clear IRQ on Parity errors (Rx) */ +#define BMU_CLR_IRQ_TCP BIT_11 /* Clear IRQ on TCP segmen. error (Tx) */ +#define BMU_CLR_IRQ_CHK BIT_10 /* Clear IRQ Check */ +#define BMU_STOP BIT_9 /* Stop Rx/Tx Queue */ +#define BMU_START BIT_8 /* Start Rx/Tx Queue */ +#define BMU_FIFO_OP_ON BIT_7 /* FIFO Operational On */ +#define BMU_FIFO_OP_OFF BIT_6 /* FIFO Operational Off */ +#define BMU_FIFO_ENA BIT_5 /* Enable FIFO */ +#define BMU_FIFO_RST BIT_4 /* Reset FIFO */ +#define BMU_OP_ON BIT_3 /* BMU Operational On */ +#define BMU_OP_OFF BIT_2 /* BMU Operational Off */ +#define BMU_RST_CLR BIT_1 /* Clear BMU Reset (Enable) */ +#define BMU_RST_SET BIT_0 /* Set BMU Reset */ + +#define BMU_CLR_RESET (BMU_FIFO_RST | BMU_OP_OFF | BMU_RST_CLR) +#define BMU_OPER_INIT (BMU_CLR_IRQ_PAR | BMU_CLR_IRQ_CHK | BMU_START | \ + BMU_FIFO_ENA | BMU_OP_ON) + +/* Tx BMU Control / Status Registers (Yukon-2) */ + /* Bit 31: same as for Rx */ + /* Bit 30..14: reserved */ +#define BMU_TX_IPIDINCR_ON BIT_13 /* Enable IP ID Increment */ +#define BMU_TX_IPIDINCR_OFF BIT_12 /* Disable IP ID Increment */ +#define BMU_TX_CLR_IRQ_TCP BIT_11 /* Clear IRQ on TCP segm. length mism. */ + /* Bit 10..0: same as for Rx */ + /* Q_F 32 bit Flag Register */ /* Bit 31..28: reserved */ #define F_ALM_FULL BIT_27 /* Rx FIFO: almost full */ #define F_EMPTY BIT_27 /* Tx FIFO: empty flag */ #define F_FIFO_EOF BIT_26 /* Tag (EOF Flag) bit in FIFO */ #define F_WM_REACHED BIT_25 /* Watermark reached */ - /* reserved */ +#define F_M_RX_RAM_DIS BIT_24 /* MAC Rx RAM Read Port disable */ #define F_FIFO_LEVEL (0x1fL<<16) /* Bit 23..16: # of Qwords in FIFO */ /* Bit 15..11: reserved */ #define F_WATER_MARK 0x0007ffL /* Bit 10.. 0: Watermark */ @@ -1258,6 +1818,13 @@ /* Bit 3: reserved */ #define T3_VRAM_MSK 7 /* Bit 2.. 0: Virtual RAM Buffer Address */ +/* Queue Prefetch Unit Offsets, use Y2_PREF_Q_ADDR() to address (Yukon-2 only)*/ +/* PREF_UNIT_CTRL_REG 32 bit Prefetch Control register */ +#define PREF_UNIT_OP_ON BIT_3 /* prefetch unit operational */ +#define PREF_UNIT_OP_OFF BIT_2 /* prefetch unit not operational */ +#define PREF_UNIT_RST_CLR BIT_1 /* Clear Prefetch Unit Reset */ +#define PREF_UNIT_RST_SET BIT_0 /* Set Prefetch Unit Reset */ + /* RAM Buffer Register Offsets, use RB_ADDR(Queue, Offs) to access */ /* RB_START 32 bit RAM Buffer Start Address */ /* RB_END 32 bit RAM Buffer End Address */ @@ -1273,24 +1840,24 @@ #define RB_MSK 0x0007ffff /* Bit 18.. 0: RAM Buffer Pointer Bits */ /* RB_TST2 8 bit RAM Buffer Test Register 2 */ - /* Bit 7.. 4: reserved */ -#define RB_PC_DEC BIT_3S /* Packet Counter Decrem */ + /* Bit 7.. 4: reserved */ +#define RB_PC_DEC BIT_3S /* Packet Counter Decrement */ #define RB_PC_T_ON BIT_2S /* Packet Counter Test On */ -#define RB_PC_T_OFF BIT_1S /* Packet Counter Tst Off */ -#define RB_PC_INC BIT_0S /* Packet Counter Increm */ +#define RB_PC_T_OFF BIT_1S /* Packet Counter Test Off */ +#define RB_PC_INC BIT_0S /* Packet Counter Increment */ /* RB_TST1 8 bit RAM Buffer Test Register 1 */ /* Bit 7: reserved */ #define RB_WP_T_ON BIT_6S /* Write Pointer Test On */ #define RB_WP_T_OFF BIT_5S /* Write Pointer Test Off */ -#define RB_WP_INC BIT_4S /* Write Pointer Increm */ +#define RB_WP_INC BIT_4S /* Write Pointer Increment */ /* Bit 3: reserved */ #define RB_RP_T_ON BIT_2S /* Read Pointer Test On */ #define RB_RP_T_OFF BIT_1S /* Read Pointer Test Off */ -#define RB_RP_DEC BIT_0S /* Read Pointer Decrement */ +#define RB_RP_INC BIT_0S /* Read Pointer Increment */ /* RB_CTRL 8 bit RAM Buffer Control Register */ - /* Bit 7.. 6: reserved */ + /* Bit 7.. 6: reserved */ #define RB_ENA_STFWD BIT_5S /* Enable Store & Forward */ #define RB_DIS_STFWD BIT_4S /* Disable Store & Forward */ #define RB_ENA_OP_MD BIT_3S /* Enable Operation Mode */ @@ -1298,16 +1865,31 @@ #define RB_RST_CLR BIT_1S /* Clear RAM Buf STM Reset */ #define RB_RST_SET BIT_0S /* Set RAM Buf STM Reset */ +/* Yukon-2 */ + /* Bit 31..20: reserved */ +#define RB_CNT_DOWN BIT_19 /* Packet Counter Decrement */ +#define RB_CNT_TST_ON BIT_18 /* Packet Counter Test On */ +#define RB_CNT_TST_OFF BIT_17 /* Packet Counter Test Off */ +#define RB_CNT_UP BIT_16 /* Packet Counter Increment */ + /* Bit 15: reserved */ +#define RB_WP_TST_ON BIT_14 /* Write Pointer Test On */ +#define RB_WP_TST_OFF BIT_13 /* Write Pointer Test Off */ +#define RB_WP_UP BIT_12 /* Write Pointer Increment */ + /* Bit 11: reserved */ +#define RB_RP_TST_ON BIT_10 /* Read Pointer Test On */ +#define RB_RP_TST_OFF BIT_9 /* Read Pointer Test Off */ +#define RB_RP_UP BIT_8 /* Read Pointer Increment */ + /* Receive and Transmit MAC FIFO Registers (GENESIS only) */ /* RX_MFF_EA 32 bit Receive MAC FIFO End Address */ -/* RX_MFF_WP 32 bit Receive MAC FIFO Write Pointer */ +/* RX_MFF_WP 32 bit Receive MAC FIFO Write Pointer */ /* RX_MFF_RP 32 bit Receive MAC FIFO Read Pointer */ /* RX_MFF_PC 32 bit Receive MAC FIFO Packet Counter */ /* RX_MFF_LEV 32 bit Receive MAC FIFO Level */ /* TX_MFF_EA 32 bit Transmit MAC FIFO End Address */ -/* TX_MFF_WP 32 bit Transmit MAC FIFO Write Pointer */ +/* TX_MFF_WP 32 bit Transmit MAC FIFO Write Pointer */ /* TX_MFF_WSP 32 bit Transmit MAC FIFO WR Shadow Pointer */ /* TX_MFF_RP 32 bit Transmit MAC FIFO Read Pointer */ /* TX_MFF_PC 32 bit Transmit MAC FIFO Packet Cnt */ @@ -1357,9 +1939,9 @@ /* RX_MFF_TST2 8 bit Receive MAC FIFO Test Register 2 */ /* TX_MFF_TST2 8 bit Transmit MAC FIFO Test Register 2 */ /* Bit 7: reserved */ -#define MFF_WSP_T_ON BIT_6S /* Tx: Write Shadow Ptr TestOn */ -#define MFF_WSP_T_OFF BIT_5S /* Tx: Write Shadow Ptr TstOff */ -#define MFF_WSP_INC BIT_4S /* Tx: Write Shadow Ptr Increment */ +#define MFF_WSP_T_ON BIT_6S /* Tx: Write Shadow Pointer Test On */ +#define MFF_WSP_T_OFF BIT_5S /* Tx: Write Shadow Pointer Test Off */ +#define MFF_WSP_INC BIT_4S /* Tx: Write Shadow Pointer Increment */ #define MFF_PC_DEC BIT_3S /* Packet Counter Decrement */ #define MFF_PC_T_ON BIT_2S /* Packet Counter Test On */ #define MFF_PC_T_OFF BIT_1S /* Packet Counter Test Off */ @@ -1370,7 +1952,7 @@ /* Bit 7: reserved */ #define MFF_WP_T_ON BIT_6S /* Write Pointer Test On */ #define MFF_WP_T_OFF BIT_5S /* Write Pointer Test Off */ -#define MFF_WP_INC BIT_4S /* Write Pointer Increm */ +#define MFF_WP_INC BIT_4S /* Write Pointer Increment */ /* Bit 3: reserved */ #define MFF_RP_T_ON BIT_2S /* Read Pointer Test On */ #define MFF_RP_T_OFF BIT_1S /* Read Pointer Test Off */ @@ -1389,12 +1971,16 @@ /* RX_LED_CTRL 8 bit Receive LED Cnt Control Reg */ /* TX_LED_CTRL 8 bit Transmit LED Cnt Control Reg */ + /* Bit 7.. 3: reserved */ +#define LED_START BIT_2S /* Start Counter */ +#define LED_STOP BIT_1S /* Stop Counter */ +#define LED_STATE BIT_0S /* Rx/Tx: LED State, 1=LED On */ + /* LNK_SYNC_CTRL 8 bit Link Sync Cnt Control Register */ /* Bit 7.. 3: reserved */ -#define LED_START BIT_2S /* Start Timer */ -#define LED_STOP BIT_1S /* Stop Timer */ -#define LED_STATE BIT_0S /* Rx/Tx: LED State, 1=LED on */ -#define LED_CLR_IRQ BIT_0S /* Lnk: Clear Link IRQ */ +#define LNK_START BIT_2S /* Start Counter */ +#define LNK_STOP BIT_1S /* Stop Counter */ +#define LNK_CLR_IRQ BIT_0S /* Clear Link IRQ */ /* RX_LED_TST 8 bit Receive LED Cnt Test Register */ /* TX_LED_TST 8 bit Transmit LED Cnt Test Register */ @@ -1405,86 +1991,142 @@ #define LED_T_STEP BIT_0S /* LED Counter Step */ /* LNK_LED_REG 8 bit Link LED Register */ - /* Bit 7.. 6: reserved */ + /* Bit 7.. 6: reserved */ #define LED_BLK_ON BIT_5S /* Link LED Blinking On */ #define LED_BLK_OFF BIT_4S /* Link LED Blinking Off */ #define LED_SYNC_ON BIT_3S /* Use Sync Wire to switch LED */ #define LED_SYNC_OFF BIT_2S /* Disable Sync Wire Input */ -#define LED_ON BIT_1S /* switch LED on */ -#define LED_OFF BIT_0S /* switch LED off */ +#define LED_ON BIT_1S /* Switch LED On */ +#define LED_OFF BIT_0S /* Switch LED Off */ /* Receive and Transmit GMAC FIFO Registers (YUKON only) */ /* RX_GMF_EA 32 bit Rx GMAC FIFO End Address */ /* RX_GMF_AF_THR 32 bit Rx GMAC FIFO Almost Full Thresh. */ -/* RX_GMF_WP 32 bit Rx GMAC FIFO Write Pointer */ -/* RX_GMF_WLEV 32 bit Rx GMAC FIFO Write Level */ -/* RX_GMF_RP 32 bit Rx GMAC FIFO Read Pointer */ -/* RX_GMF_RLEV 32 bit Rx GMAC FIFO Read Level */ +/* RX_GMF_WP 32 bit Rx GMAC FIFO Write Pointer */ +/* RX_GMF_WLEV 32 bit Rx GMAC FIFO Write Level */ +/* RX_GMF_RP 32 bit Rx GMAC FIFO Read Pointer */ +/* RX_GMF_RLEV 32 bit Rx GMAC FIFO Read Level */ /* TX_GMF_EA 32 bit Tx GMAC FIFO End Address */ /* TX_GMF_AE_THR 32 bit Tx GMAC FIFO Almost Empty Thresh.*/ -/* TX_GMF_WP 32 bit Tx GMAC FIFO Write Pointer */ -/* TX_GMF_WSP 32 bit Tx GMAC FIFO Write Shadow Ptr. */ -/* TX_GMF_WLEV 32 bit Tx GMAC FIFO Write Level */ -/* TX_GMF_RP 32 bit Tx GMAC FIFO Read Pointer */ -/* TX_GMF_RSTP 32 bit Tx GMAC FIFO Restart Pointer */ -/* TX_GMF_RLEV 32 bit Tx GMAC FIFO Read Level */ +/* TX_GMF_WP 32 bit Tx GMAC FIFO Write Pointer */ +/* TX_GMF_WSP 32 bit Tx GMAC FIFO Write Shadow Pointer */ +/* TX_GMF_WLEV 32 bit Tx GMAC FIFO Write Level */ +/* TX_GMF_RP 32 bit Tx GMAC FIFO Read Pointer */ +/* TX_GMF_RSTP 32 bit Tx GMAC FIFO Restart Pointer */ +/* TX_GMF_RLEV 32 bit Tx GMAC FIFO Read Level */ /* RX_GMF_CTRL_T 32 bit Rx GMAC FIFO Control/Test */ - /* Bits 31..15: reserved */ -#define GMF_WP_TST_ON BIT_14 /* Write Pointer Test On */ -#define GMF_WP_TST_OFF BIT_13 /* Write Pointer Test Off */ -#define GMF_WP_STEP BIT_12 /* Write Pointer Step/Increment */ + /* Bit 31..28 reserved */ +#define RX_TRUNC_ON BIT_27 /* Enable Packet Truncation */ +#define RX_TRUNC_OFF BIT_26 /* Disable Packet Truncation */ +#define RX_VLAN_STRIP_ON BIT_25 /* Enable VLAN Stripping */ +#define RX_VLAN_STRIP_OFF BIT_24 /* Disable VLAN Stripping */ + /* Bit 23..15 reserved */ +#define GMF_WP_TST_ON BIT_14 /* Write Pointer Test On */ +#define GMF_WP_TST_OFF BIT_13 /* Write Pointer Test Off */ +#define GMF_WP_STEP BIT_12 /* Write Pointer Step/Increment */ /* Bit 11: reserved */ -#define GMF_RP_TST_ON BIT_10 /* Read Pointer Test On */ -#define GMF_RP_TST_OFF BIT_9 /* Read Pointer Test Off */ -#define GMF_RP_STEP BIT_8 /* Read Pointer Step/Increment */ -#define GMF_RX_F_FL_ON BIT_7 /* Rx FIFO Flush Mode On */ -#define GMF_RX_F_FL_OFF BIT_6 /* Rx FIFO Flush Mode Off */ -#define GMF_CLI_RX_FO BIT_5 /* Clear IRQ Rx FIFO Overrun */ -#define GMF_CLI_RX_FC BIT_4 /* Clear IRQ Rx Frame Complete */ -#define GMF_OPER_ON BIT_3 /* Operational Mode On */ -#define GMF_OPER_OFF BIT_2 /* Operational Mode Off */ -#define GMF_RST_CLR BIT_1 /* Clear GMAC FIFO Reset */ -#define GMF_RST_SET BIT_0 /* Set GMAC FIFO Reset */ - -/* TX_GMF_CTRL_T 32 bit Tx GMAC FIFO Control/Test */ - /* Bits 31..19: reserved */ -#define GMF_WSP_TST_ON BIT_18 /* Write Shadow Pointer Test On */ -#define GMF_WSP_TST_OFF BIT_17 /* Write Shadow Pointer Test Off */ -#define GMF_WSP_STEP BIT_16 /* Write Shadow Pointer Step/Increment */ - /* Bits 15..7: same as for RX_GMF_CTRL_T */ -#define GMF_CLI_TX_FU BIT_6 /* Clear IRQ Tx FIFO Underrun */ -#define GMF_CLI_TX_FC BIT_5 /* Clear IRQ Tx Frame Complete */ -#define GMF_CLI_TX_PE BIT_4 /* Clear IRQ Tx Parity Error */ +#define GMF_RP_TST_ON BIT_10 /* Read Pointer Test On */ +#define GMF_RP_TST_OFF BIT_9 /* Read Pointer Test Off */ +#define GMF_RP_STEP BIT_8 /* Read Pointer Step/Increment */ +#define GMF_RX_F_FL_ON BIT_7 /* Rx FIFO Flush Mode On */ +#define GMF_RX_F_FL_OFF BIT_6 /* Rx FIFO Flush Mode Off */ +#define GMF_CLI_RX_FO BIT_5 /* Clear IRQ Rx FIFO Overrun */ +#define GMF_CLI_RX_FC BIT_4 /* Clear IRQ Rx Frame Complete */ +#define GMF_OPER_ON BIT_3 /* Operational Mode On */ +#define GMF_OPER_OFF BIT_2 /* Operational Mode Off */ +#define GMF_RST_CLR BIT_1 /* Clear GMAC FIFO Reset */ +#define GMF_RST_SET BIT_0 /* Set GMAC FIFO Reset */ + +/* TX_GMF_CTRL_T 32 bit Tx GMAC FIFO Control/Test (YUKON and Yukon-2) */ +#define TX_STFW_DIS BIT_31 /* Disable Store & Forward (Yukon-EC Ultra) */ +#define TX_STFW_ENA BIT_30 /* Enable Store & Forward (Yukon-EC Ultra) */ + /* Bits 29..26: reserved */ +#define TX_VLAN_TAG_ON BIT_25 /* Enable VLAN tagging */ +#define TX_VLAN_TAG_OFF BIT_24 /* Disable VLAN tagging */ +#define TX_PCI_JUM_ENA BIT_23 /* Enable PCI Jumbo Mode (Yukon-EC Ultra) */ +#define TX_PCI_JUM_DIS BIT_22 /* Disable PCI Jumbo Mode (Yukon-EC Ultra) */ + /* Bits 21..19: reserved */ +#define GMF_WSP_TST_ON BIT_18 /* Write Shadow Pointer Test On */ +#define GMF_WSP_TST_OFF BIT_17 /* Write Shadow Pointer Test Off */ +#define GMF_WSP_STEP BIT_16 /* Write Shadow Pointer Step/Increment */ + /* Bits 15..8: same as for RX_GMF_CTRL_T */ + /* Bit 7: reserved */ +#define GMF_CLI_TX_FU BIT_6 /* Clear IRQ Tx FIFO Underrun */ +#define GMF_CLI_TX_FC BIT_5 /* Clear IRQ Tx Frame Complete */ +#define GMF_CLI_TX_PE BIT_4 /* Clear IRQ Tx Parity Error */ /* Bits 3..0: same as for RX_GMF_CTRL_T */ #define GMF_RX_CTRL_DEF (GMF_OPER_ON | GMF_RX_F_FL_ON) #define GMF_TX_CTRL_DEF GMF_OPER_ON +#define RX_GMF_AF_THR_MIN 0x0c /* Rx GMAC FIFO Almost Full Thresh. min. */ #define RX_GMF_FL_THR_DEF 0x0a /* Rx GMAC FIFO Flush Threshold default */ /* GMAC_TI_ST_CTRL 8 bit Time Stamp Timer Ctrl Reg (YUKON only) */ - /* Bit 7.. 3: reserved */ -#define GMT_ST_START BIT_2S /* Start Time Stamp Timer */ -#define GMT_ST_STOP BIT_1S /* Stop Time Stamp Timer */ -#define GMT_ST_CLR_IRQ BIT_0S /* Clear Time Stamp Timer IRQ */ - + /* Bit 7.. 3: reserved */ +#define GMT_ST_START BIT_2S /* Start Time Stamp Timer */ +#define GMT_ST_STOP BIT_1S /* Stop Time Stamp Timer */ +#define GMT_ST_CLR_IRQ BIT_0S /* Clear Time Stamp Timer IRQ */ + +/* POLL_CTRL 32 bit Polling Unit control register (Yukon-2 only) */ + /* Bit 31.. 6: reserved */ +#define PC_CLR_IRQ_CHK BIT_5 /* Clear IRQ Check */ +#define PC_POLL_RQ BIT_4 /* Poll Request Start */ +#define PC_POLL_OP_ON BIT_3 /* Operational Mode On */ +#define PC_POLL_OP_OFF BIT_2 /* Operational Mode Off */ +#define PC_POLL_RST_CLR BIT_1 /* Clear Polling Unit Reset (Enable) */ +#define PC_POLL_RST_SET BIT_0 /* Set Polling Unit Reset */ + + +/* The bit definition of the following registers is still missing! */ +/* B28_Y2_SMB_CONFIG 32 bit ASF SMBus Config Register */ +/* B28_Y2_SMB_CSD_REG 32 bit ASF SMB Control/Status/Data */ +/* B28_Y2_ASF_IRQ_V_BASE 32 bit ASF IRQ Vector Base */ + +/* B28_Y2_ASF_STAT_CMD 32 bit ASF Status and Command Reg */ +/* This register is used by the host driver software */ + /* Bit 31.. 5 reserved */ +#define Y2_ASF_OS_PRES BIT_4S /* ASF operation system present */ +#define Y2_ASF_RESET BIT_3S /* ASF system in reset state */ +#define Y2_ASF_RUNNING BIT_2S /* ASF system operational */ +#define Y2_ASF_CLR_HSTI BIT_1S /* Clear ASF IRQ */ +#define Y2_ASF_IRQ BIT_0S /* Issue an IRQ to ASF system */ + +#define Y2_ASF_UC_STATE (3<<2) /* ASF uC State */ +#define Y2_ASF_CLK_HALT 0 /* ASF system clock stopped */ + +/* B28_Y2_ASF_HOST_COM 32 bit ASF Host Communication Reg */ +/* This register is used by the ASF firmware */ + /* Bit 31.. 2 reserved */ +#define Y2_ASF_CLR_ASFI BIT_1 /* Clear host IRQ */ +#define Y2_ASF_HOST_IRQ BIT_0 /* Issue an IRQ to HOST system */ + + +/* STAT_CTRL 32 bit Status BMU control register (Yukon-2 only) */ + /* Bit 7.. 5: reserved */ +#define SC_STAT_CLR_IRQ BIT_4 /* Status Burst IRQ clear */ +#define SC_STAT_OP_ON BIT_3 /* Operational Mode On */ +#define SC_STAT_OP_OFF BIT_2 /* Operational Mode Off */ +#define SC_STAT_RST_CLR BIT_1 /* Clear Status Unit Reset (Enable) */ +#define SC_STAT_RST_SET BIT_0 /* Set Status Unit Reset */ + /* GMAC_CTRL 32 bit GMAC Control Reg (YUKON only) */ /* Bits 31.. 8: reserved */ -#define GMC_H_BURST_ON BIT_7 /* Half Duplex Burst Mode On */ -#define GMC_H_BURST_OFF BIT_6 /* Half Duplex Burst Mode Off */ -#define GMC_F_LOOPB_ON BIT_5 /* FIFO Loopback On */ -#define GMC_F_LOOPB_OFF BIT_4 /* FIFO Loopback Off */ -#define GMC_PAUSE_ON BIT_3 /* Pause On */ -#define GMC_PAUSE_OFF BIT_2 /* Pause Off */ -#define GMC_RST_CLR BIT_1 /* Clear GMAC Reset */ -#define GMC_RST_SET BIT_0 /* Set GMAC Reset */ +#define GMC_H_BURST_ON BIT_7 /* Half Duplex Burst Mode On */ +#define GMC_H_BURST_OFF BIT_6 /* Half Duplex Burst Mode Off */ +#define GMC_F_LOOPB_ON BIT_5 /* FIFO Loopback On */ +#define GMC_F_LOOPB_OFF BIT_4 /* FIFO Loopback Off */ +#define GMC_PAUSE_ON BIT_3 /* Pause On */ +#define GMC_PAUSE_OFF BIT_2 /* Pause Off */ +#define GMC_RST_CLR BIT_1 /* Clear GMAC Reset */ +#define GMC_RST_SET BIT_0 /* Set GMAC Reset */ /* GPHY_CTRL 32 bit GPHY Control Reg (YUKON only) */ /* Bits 31..29: reserved */ #define GPC_SEL_BDT BIT_28 /* Select Bi-Dir. Transfer for MDC/MDIO */ -#define GPC_INT_POL_HI BIT_27 /* IRQ Polarity is Active HIGH */ +#define GPC_INT_POL BIT_27 /* IRQ Polarity is Active Low */ #define GPC_75_OHM BIT_26 /* Use 75 Ohm Termination instead of 50 */ #define GPC_DIS_FC BIT_25 /* Disable Automatic Fiber/Copper Detection */ #define GPC_DIS_SLEEP BIT_24 /* Disable Energy Detect */ @@ -1508,6 +2150,13 @@ #define GPC_RST_CLR BIT_1 /* Clear GPHY Reset */ #define GPC_RST_SET BIT_0 /* Set GPHY Reset */ +/* Yukon-EC Ultra only */ +#define GPC_PD_125M_CLK_OFF BIT_5 /* Disable Power Down Clock 125 MHz */ +#define GPC_PD_125M_CLK_ON BIT_4 /* Enable Power Down Clock 125 MHz */ +#define GPC_DPLL_RST_SET BIT_3 /* Set GPHY's DPLL Reset */ +#define GPC_DPLL_RST_CLR BIT_2 /* Clear GPHY's DPLL Reset */ + /* (DPLL = Digital Phase Lock Loop) */ + #define GPC_HWCFG_GMII_COP (GPC_HWCFG_M_3 | GPC_HWCFG_M_2 | \ GPC_HWCFG_M_1 | GPC_HWCFG_M_0) @@ -1538,14 +2187,14 @@ /* GMAC_IRQ_SRC 8 bit GMAC Interrupt Source Reg (YUKON only) */ /* GMAC_IRQ_MSK 8 bit GMAC Interrupt Mask Reg (YUKON only) */ -#define GM_IS_TX_CO_OV BIT_5 /* Transmit Counter Overflow IRQ */ -#define GM_IS_RX_CO_OV BIT_4 /* Receive Counter Overflow IRQ */ -#define GM_IS_TX_FF_UR BIT_3 /* Transmit FIFO Underrun */ -#define GM_IS_TX_COMPL BIT_2 /* Frame Transmission Complete */ -#define GM_IS_RX_FF_OR BIT_1 /* Receive FIFO Overrun */ -#define GM_IS_RX_COMPL BIT_0 /* Frame Reception Complete */ +#define GM_IS_RX_CO_OV BIT_5S /* Receive Counter Overflow IRQ */ +#define GM_IS_TX_CO_OV BIT_4S /* Transmit Counter Overflow IRQ */ +#define GM_IS_TX_FF_UR BIT_3S /* Transmit FIFO Underrun */ +#define GM_IS_TX_COMPL BIT_2S /* Frame Transmission Complete */ +#define GM_IS_RX_FF_OR BIT_1S /* Receive FIFO Overrun */ +#define GM_IS_RX_COMPL BIT_0S /* Frame Reception Complete */ -#define GMAC_DEF_MSK (GM_IS_TX_CO_OV | GM_IS_RX_CO_OV | \ +#define GMAC_DEF_MSK (GM_IS_RX_CO_OV | GM_IS_TX_CO_OV | \ GM_IS_TX_FF_UR) /* GMAC_LINK_CTRL 16 bit GMAC Link Control Reg (YUKON only) */ @@ -1577,15 +2226,19 @@ #define WOL_CTL_DEFAULT \ (WOL_CTL_DIS_PME_ON_LINK_CHG | \ - WOL_CTL_DIS_PME_ON_PATTERN | \ - WOL_CTL_DIS_PME_ON_MAGIC_PKT | \ - WOL_CTL_DIS_LINK_CHG_UNIT | \ - WOL_CTL_DIS_PATTERN_UNIT | \ - WOL_CTL_DIS_MAGIC_PKT_UNIT) + WOL_CTL_DIS_PME_ON_PATTERN | \ + WOL_CTL_DIS_PME_ON_MAGIC_PKT | \ + WOL_CTL_DIS_LINK_CHG_UNIT | \ + WOL_CTL_DIS_PATTERN_UNIT | \ + WOL_CTL_DIS_MAGIC_PKT_UNIT) /* WOL_MATCH_CTL 8 bit WOL Match Control Reg */ #define WOL_CTL_PATT_ENA(x) (BIT_0 << (x)) +/* WOL_PATT_PME 8 bit WOL PME Match Enable (Yukon-2) */ +#define WOL_PATT_FORCE_PME BIT_7 /* Generates a PME */ +#define WOL_PATT_MATCH_PME_ALL 0x7f + #define SK_NUM_WOL_PATTERN 7 #define SK_PATTERN_PER_WORD 4 #define SK_BITMASK_PATTERN 7 @@ -1595,26 +2248,28 @@ #define WOL_LENGTH_SHIFT 8 +/* typedefs ******************************************************************/ + /* Receive and Transmit Descriptors ******************************************/ /* Transmit Descriptor struct */ typedef struct s_HwTxd { SK_U32 volatile TxCtrl; /* Transmit Buffer Control Field */ SK_U32 TxNext; /* Physical Address Pointer to the next TxD */ - SK_U32 TxAdrLo; /* Physical Tx Buffer Address lower dword */ - SK_U32 TxAdrHi; /* Physical Tx Buffer Address upper dword */ + SK_U32 TxAdrLo; /* Physical Tx Buffer Address lower DWord */ + SK_U32 TxAdrHi; /* Physical Tx Buffer Address upper DWord */ SK_U32 TxStat; /* Transmit Frame Status Word */ -#ifndef SK_USE_REV_DESC +#ifndef SK_USE_REV_DESC SK_U16 TxTcpOffs; /* TCP Checksum Calculation Start Value */ SK_U16 TxRes1; /* 16 bit reserved field */ SK_U16 TxTcpWp; /* TCP Checksum Write Position */ SK_U16 TxTcpSp; /* TCP Checksum Calculation Start Position */ -#else /* SK_USE_REV_DESC */ +#else /* SK_USE_REV_DESC */ SK_U16 TxRes1; /* 16 bit reserved field */ SK_U16 TxTcpOffs; /* TCP Checksum Calculation Start Value */ SK_U16 TxTcpSp; /* TCP Checksum Calculation Start Position */ SK_U16 TxTcpWp; /* TCP Checksum Write Position */ -#endif /* SK_USE_REV_DESC */ +#endif /* SK_USE_REV_DESC */ SK_U32 TxRes2; /* 32 bit reserved field */ } SK_HWTXD; @@ -1622,33 +2277,266 @@ typedef struct s_HwRxd { SK_U32 volatile RxCtrl; /* Receive Buffer Control Field */ SK_U32 RxNext; /* Physical Address Pointer to the next RxD */ - SK_U32 RxAdrLo; /* Physical Rx Buffer Address lower dword */ - SK_U32 RxAdrHi; /* Physical Rx Buffer Address upper dword */ + SK_U32 RxAdrLo; /* Physical Rx Buffer Address lower DWord */ + SK_U32 RxAdrHi; /* Physical Rx Buffer Address upper DWord */ SK_U32 RxStat; /* Receive Frame Status Word */ SK_U32 RxTiSt; /* Receive Time Stamp (from XMAC on GENESIS) */ -#ifndef SK_USE_REV_DESC - SK_U16 RxTcpSum1; /* TCP Checksum 1 */ - SK_U16 RxTcpSum2; /* TCP Checksum 2 */ +#ifndef SK_USE_REV_DESC + SK_U16 RxTcpSum1; /* Rx TCP Checksum 1 */ + SK_U16 RxTcpSum2; /* Rx TCP Checksum 2 */ SK_U16 RxTcpSp1; /* TCP Checksum Calculation Start Position 1 */ SK_U16 RxTcpSp2; /* TCP Checksum Calculation Start Position 2 */ -#else /* SK_USE_REV_DESC */ - SK_U16 RxTcpSum2; /* TCP Checksum 2 */ - SK_U16 RxTcpSum1; /* TCP Checksum 1 */ +#else /* SK_USE_REV_DESC */ + SK_U16 RxTcpSum2; /* Rx TCP Checksum 2 */ + SK_U16 RxTcpSum1; /* Rx TCP Checksum 1 */ SK_U16 RxTcpSp2; /* TCP Checksum Calculation Start Position 2 */ SK_U16 RxTcpSp1; /* TCP Checksum Calculation Start Position 1 */ -#endif /* SK_USE_REV_DESC */ +#endif /* SK_USE_REV_DESC */ } SK_HWRXD; /* * Drivers which use the reverse descriptor feature (PCI_OUR_REG_2) * should set the define SK_USE_REV_DESC. - * Structures are 'normaly' not endianess dependent. But in - * this case the SK_U16 fields are bound to bit positions inside the - * descriptor. RxTcpSum1 e.g. must start at bit 0 within the 6.th DWord. + * Structures are 'normally' not endianess dependent. But in this case + * the SK_U16 fields are bound to bit positions inside the descriptor. + * RxTcpSum1 e.g. must start at bit 0 within the 7.th DWord. * The bit positions inside a DWord are of course endianess dependent and - * swaps if the DWord is swapped by the hardware. + * swap if the DWord is swapped by the hardware. */ +/* YUKON-2 descriptors ******************************************************/ + +typedef struct _TxChksum { +#ifndef SK_USE_REV_DESC + SK_U16 TxTcpWp; /* TCP Checksum Write Position */ + SK_U16 TxTcpSp; /* TCP Checksum Calculation Start Position */ +#else /* SK_USE_REV_DESC */ + SK_U16 TxTcpSp; /* TCP Checksum Calculation Start Position */ + SK_U16 TxTcpWp; /* TCP Checksum Write Position */ +#endif /* SK_USE_REV_DESC */ +} SK_HWTXCS; + +typedef struct _LargeSend { +#ifndef SK_USE_REV_DESC + SK_U16 Length; /* Large Send Segment Length */ + SK_U16 Reserved; /* reserved */ +#else /* SK_USE_REV_DESC */ + SK_U16 Reserved; /* reserved */ + SK_U16 Length; /* Large Send Segment Length */ +#endif /* SK_USE_REV_DESC */ +} SK_HWTXLS; + +typedef union u_HwTxBuf { + SK_U16 BufLen; /* Tx Buffer Length */ + SK_U16 VlanTag; /* VLAN Tag */ + SK_U16 InitCsum; /* Init. Checksum */ +} SK_HWTXBUF; + +/* Tx List Element structure */ +typedef struct s_HwLeTx { + union { + SK_U32 BufAddr; /* Tx LE Buffer Address high/low */ + SK_HWTXCS ChkSum; /* Tx LE TCP Checksum parameters */ + SK_HWTXLS LargeSend;/* Large Send length */ + } TxUn; +#ifndef SK_USE_REV_DESC + SK_HWTXBUF Send; + SK_U8 ControlFlags; /* Tx LE Control field or Lock Number */ + SK_U8 Opcode; /* Tx LE Opcode field */ +#else /* SK_USE_REV_DESC */ + SK_U8 Opcode; /* Tx LE Opcode field */ + SK_U8 ControlFlags; /* Tx LE Control field or Lock Number */ + SK_HWTXBUF Send; +#endif /* SK_USE_REV_DESC */ +} SK_HWLETX; + +typedef struct _RxChkSum{ +#ifndef SK_USE_REV_DESC + SK_U16 RxTcpSp1; /* TCP Checksum Calculation Start Position 1 */ + SK_U16 RxTcpSp2; /* TCP Checksum Calculation Start Position 2 */ +#else /* SK_USE_REV_DESC */ + SK_U16 RxTcpSp2; /* TCP Checksum Calculation Start Position 2 */ + SK_U16 RxTcpSp1; /* TCP Checksum Calculation Start Position 1 */ +#endif /* SK_USE_REV_DESC */ +} SK_HWRXCS; + +/* Rx List Element structure */ +typedef struct s_HwLeRx { + union { + SK_U32 BufAddr; /* Rx LE Buffer Address high/low */ + SK_HWRXCS ChkSum; /* Rx LE TCP Checksum parameters */ + } RxUn; +#ifndef SK_USE_REV_DESC + SK_U16 BufferLength; /* Rx LE Buffer Length field */ + SK_U8 ControlFlags; /* Rx LE Control field */ + SK_U8 Opcode; /* Rx LE Opcode field */ +#else /* SK_USE_REV_DESC */ + SK_U8 Opcode; /* Rx LE Opcode field */ + SK_U8 ControlFlags; /* Rx LE Control field */ + SK_U16 BufferLength; /* Rx LE Buffer Length field */ +#endif /* SK_USE_REV_DESC */ +} SK_HWLERX; + +typedef struct s_StRxTCPChkSum { +#ifndef SK_USE_REV_DESC + SK_U16 RxTCPSum1; /* Rx TCP Checksum 1 */ + SK_U16 RxTCPSum2; /* Rx TCP Checksum 2 */ +#else /* SK_USE_REV_DESC */ + SK_U16 RxTCPSum2; /* Rx TCP Checksum 2 */ + SK_U16 RxTCPSum1; /* Rx TCP Checksum 1 */ +#endif /* SK_USE_REV_DESC */ +} SK_HWSTCS; + +typedef struct s_StRxRssFlags { +#ifndef SK_USE_REV_DESC + SK_U8 FlagField; /* contains TCP and IP flags */ + SK_U8 reserved; /* reserved */ +#else /* SK_USE_REV_DESC */ + SK_U8 reserved; /* reserved */ + SK_U8 FlagField; /* contains TCP and IP flags */ +#endif /* SK_USE_REV_DESC */ +} SK_HWSTRSS; + +/* bit definition of RSS LE bit 32/33 (SK_HWSTRSS.FlagField) */ + /* bit 7..2 reserved */ +#define RSS_TCP_FLAG BIT_1S /* RSS value related to TCP area */ +#define RSS_IP_FLAG BIT_0S /* RSS value related to IP area */ +/* StRxRssValue is valid if at least RSS_IP_FLAG is set */ +/* For protocol errors or other protocols an empty RSS LE is generated */ + +typedef union u_HwStBuf { + SK_U16 BufLen; /* Rx Buffer Length */ + SK_U16 VlanTag; /* VLAN Tag */ + SK_U16 StTxStatHi; /* Tx Queue Status (high) */ + SK_HWSTRSS Rss; /* Flag Field for TCP and IP protocol */ +} SK_HWSTBUF; + +/* Status List Element structure */ +typedef struct s_HwLeSt { + union { + SK_U32 StRxStatWord; /* Rx Status Dword */ + SK_U32 StRxTimeStamp; /* Rx Timestamp */ + SK_HWSTCS StRxTCPCSum; /* Rx TCP Checksum */ + SK_U32 StTxStatLow; /* Tx Queue Status (low) */ + SK_U32 StRxRssValue; /* Rx RSS value */ + } StUn; +#ifndef SK_USE_REV_DESC + SK_HWSTBUF Stat; + SK_U8 Link; /* Status LE Link field */ + SK_U8 Opcode; /* Status LE Opcode field */ +#else /* SK_USE_REV_DESC */ + SK_U8 Opcode; /* Status LE Opcode field */ + SK_U8 Link; /* Status LE Link field */ + SK_HWSTBUF Stat; +#endif /* SK_USE_REV_DESC */ +} SK_HWLEST; + +/* Special Action List Element */ +typedef struct s_HwLeSa { +#ifndef SK_USE_REV_DESC + SK_U16 TxAIdxVld; /* Special Action LE TxA Put Index field */ + SK_U16 TxSIdxVld; /* Special Action LE TxS Put Index field */ + SK_U16 RxIdxVld; /* Special Action LE Rx Put Index field */ + SK_U8 Link; /* Special Action LE Link field */ + SK_U8 Opcode; /* Special Action LE Opcode field */ +#else /* SK_USE_REV_DESC */ + SK_U16 TxSIdxVld; /* Special Action LE TxS Put Index field */ + SK_U16 TxAIdxVld; /* Special Action LE TxA Put Index field */ + SK_U8 Opcode; /* Special Action LE Opcode field */ + SK_U8 Link; /* Special Action LE Link field */ + SK_U16 RxIdxVld; /* Special Action LE Rx Put Index field */ +#endif /* SK_USE_REV_DESC */ +} SK_HWLESA; + +/* Common List Element union */ +typedef union u_HwLeTxRxSt { + /* Transmit List Element Structure */ + SK_HWLETX Tx; + /* Receive List Element Structure */ + SK_HWLERX Rx; + /* Status List Element Structure */ + SK_HWLEST St; + /* Special Action List Element Structure */ + SK_HWLESA Sa; + /* Full List Element */ + SK_U64 Full; +} SK_HWLE; + +/* mask and shift value to get Tx async queue status for port 1 */ +#define STLE_TXA1_MSKL 0x00000fff +#define STLE_TXA1_SHIFTL 0 + +/* mask and shift value to get Tx sync queue status for port 1 */ +#define STLE_TXS1_MSKL 0x00fff000 +#define STLE_TXS1_SHIFTL 12 + +/* mask and shift value to get Tx async queue status for port 2 */ +#define STLE_TXA2_MSKL 0xff000000 +#define STLE_TXA2_SHIFTL 24 +#define STLE_TXA2_MSKH 0x000f +/* this one shifts up */ +#define STLE_TXA2_SHIFTH 8 + +/* mask and shift value to get Tx sync queue status for port 2 */ +#define STLE_TXS2_MSKL 0x00000000 +#define STLE_TXS2_SHIFTL 0 +#define STLE_TXS2_MSKH 0xfff0 +#define STLE_TXS2_SHIFTH 4 + +/* YUKON-2 bit values */ +#define HW_OWNER BIT_7 +#define SW_OWNER 0 + +#define PU_PUTIDX_VALID BIT_12 + +/* YUKON-2 Control flags */ +#define UDPTCP BIT_0S +#define CALSUM BIT_1S +#define WR_SUM BIT_2S +#define INIT_SUM BIT_3S +#define LOCK_SUM BIT_4S +#define INS_VLAN BIT_5S +#define FRC_STAT BIT_6S +#define EOP BIT_7S + +#define TX_LOCK BIT_8S +#define BUF_SEND BIT_9S +#define PACKET_SEND BIT_10S + +#define NO_WARNING BIT_14S +#define NO_UPDATE BIT_15S + +/* YUKON-2 Rx/Tx opcodes defines */ +#define OP_TCPWRITE 0x11 +#define OP_TCPSTART 0x12 +#define OP_TCPINIT 0x14 +#define OP_TCPLCK 0x18 +#define OP_TCPCHKSUM OP_TCPSTART +#define OP_TCPIS (OP_TCPINIT | OP_TCPSTART) +#define OP_TCPLW (OP_TCPLCK | OP_TCPWRITE) +#define OP_TCPLSW (OP_TCPLCK | OP_TCPSTART | OP_TCPWRITE) +#define OP_TCPLISW (OP_TCPLCK | OP_TCPINIT | OP_TCPSTART | OP_TCPWRITE) +#define OP_ADDR64 0x21 +#define OP_VLAN 0x22 +#define OP_ADDR64VLAN (OP_ADDR64 | OP_VLAN) +#define OP_LRGLEN 0x24 +#define OP_LRGLENVLAN (OP_LRGLEN | OP_VLAN) +#define OP_BUFFER 0x40 +#define OP_PACKET 0x41 +#define OP_LARGESEND 0x43 + +/* YUKON-2 STATUS opcodes defines */ +#define OP_RXSTAT 0x60 +#define OP_RXTIMESTAMP 0x61 +#define OP_RXVLAN 0x62 +#define OP_RXCHKS 0x64 +#define OP_RXCHKSVLAN (OP_RXCHKS | OP_RXVLAN) +#define OP_RXTIMEVLAN (OP_RXTIMESTAMP | OP_RXVLAN) +#define OP_RSS_HASH 0x65 +#define OP_TXINDEXLE 0x68 + +/* YUKON-2 SPECIAL opcodes defines */ +#define OP_PUTIDX 0x70 /* Descriptor Bit Definition */ /* TxCtrl Transmit Buffer Control Field */ @@ -1683,6 +2571,10 @@ /* macros ********************************************************************/ +/* Macro for accessing the key registers */ +#define RSS_KEY_ADDR(Port, KeyIndex) \ + ((B4_RSS_KEY | ( ((Port) == 0) ? 0 : 0x80)) + (KeyIndex)) + /* Receive and Transmit Queues */ #define Q_R1 0x0000 /* Receive Queue 1 */ #define Q_R2 0x0080 /* Receive Queue 2 */ @@ -1691,6 +2583,10 @@ #define Q_XS2 0x0300 /* Synchronous Transmit Queue 2 */ #define Q_XA2 0x0380 /* Asynchronous Transmit Queue 2 */ +#define Q_ASF_R1 0x100 /* ASF Rx Queue 1 */ +#define Q_ASF_R2 0x180 /* ASF Rx Queue 2 */ +#define Q_ASF_T1 0x140 /* ASF Tx Queue 1 */ +#define Q_ASF_T2 0x1c0 /* ASF Tx Queue 2 */ /* * Macro Q_ADDR() * @@ -1702,11 +2598,27 @@ * Offs Queue register offset. * Values: Q_D, Q_DA_L ... Q_T2, Q_T3 * - * usage SK_IN32(pAC, Q_ADDR(Q_R2, Q_BC), pVal) + * usage SK_IN32(IoC, Q_ADDR(Q_R2, Q_BC), pVal) */ #define Q_ADDR(Queue, Offs) (B8_Q_REGS + (Queue) + (Offs)) /* + * Macro Y2_PREF_Q_ADDR() + * + * Use this macro to access the Prefetch Units of the receive and + * transmit queues of Yukon-2. + * + * para: + * Queue Queue to access. + * Values: Q_R1, Q_R2, Q_XS1, Q_XA1, Q_XS2, Q_XA2, + * Offs Queue register offset. + * Values: PREF_UNIT_CTRL_REG ... PREF_UNIT_FIFO_LEV_REG + * + * usage SK_IN16(IoC, Y2_Q_ADDR(Q_R2, PREF_UNIT_GET_IDX_REG), pVal) + */ +#define Y2_PREF_Q_ADDR(Queue, Offs) (Y2_B8_PREF_REGS + (Queue) + (Offs)) + +/* * Macro RB_ADDR() * * Use this macro to access the RAM Buffer Registers. @@ -1717,14 +2629,14 @@ * Offs Queue register offset. * Values: RB_START, RB_END ... RB_LEV, RB_CTRL * - * usage SK_IN32(pAC, RB_ADDR(Q_R2, RB_RP), pVal) + * usage SK_IN32(IoC, RB_ADDR(Q_R2, RB_RP), pVal) */ #define RB_ADDR(Queue, Offs) (B16_RAM_REGS + (Queue) + (Offs)) /* MAC Related Registers */ -#define MAC_1 0 /* belongs to the port near the slot */ -#define MAC_2 1 /* belongs to the port far away from the slot */ +#define MAC_1 0 /* 1st port */ +#define MAC_2 1 /* 2nd port */ /* * Macro MR_ADDR() @@ -1738,19 +2650,10 @@ * Values: RX_MFF_EA, RX_MFF_WP ... LNK_LED_REG, * TX_MFF_EA, TX_MFF_WP ... TX_LED_TST * - * usage SK_IN32(pAC, MR_ADDR(MAC_1, TX_MFF_EA), pVal) + * usage SK_IN32(IoC, MR_ADDR(MAC_1, TX_MFF_EA), pVal) */ #define MR_ADDR(Mac, Offs) (((Mac) << 7) + (Offs)) -#ifdef SK_LITTLE_ENDIAN -#define XM_WORD_LO 0 -#define XM_WORD_HI 1 -#else /* !SK_LITTLE_ENDIAN */ -#define XM_WORD_LO 1 -#define XM_WORD_HI 0 -#endif /* !SK_LITTLE_ENDIAN */ - - /* * macros to access the XMAC (GENESIS only) * @@ -1775,22 +2678,31 @@ #define XMA(Mac, Reg) \ ((BASE_XMAC_1 + (Mac) * (BASE_XMAC_2 - BASE_XMAC_1)) | ((Reg) << 1)) -#define XM_IN16(IoC, Mac, Reg, pVal) \ - SK_IN16((IoC), XMA((Mac), (Reg)), (pVal)) +#define XM_IN16(IoC, Mac, Reg, pVal) \ + SK_IN16(IoC, XMA(Mac, Reg), pVal) + +#define XM_OUT16(IoC, Mac, Reg, Val) \ + SK_OUT16(IoC, XMA(Mac, Reg), Val) + +#ifdef SK_LITTLE_ENDIAN -#define XM_OUT16(IoC, Mac, Reg, Val) \ - SK_OUT16((IoC), XMA((Mac), (Reg)), (Val)) +#define XM_IN32(IoC, Mac, Reg, pVal) { \ + SK_IN16(IoC, XMA(Mac, Reg), (SK_U16 SK_FAR *)(pVal)); \ + SK_IN16(IoC, XMA(Mac, (Reg) + 2), (SK_U16 SK_FAR *)(pVal) + 1); \ +} + +#else /* !SK_LITTLE_ENDIAN */ -#define XM_IN32(IoC, Mac, Reg, pVal) { \ - SK_IN16((IoC), XMA((Mac), (Reg)), \ - (SK_U16 SK_FAR*)&((SK_U16 SK_FAR*)(pVal))[XM_WORD_LO]); \ - SK_IN16((IoC), XMA((Mac), (Reg+2)), \ - (SK_U16 SK_FAR*)&((SK_U16 SK_FAR*)(pVal))[XM_WORD_HI]); \ +#define XM_IN32(IoC, Mac, Reg, pVal) { \ + SK_IN16(IoC, XMA(Mac, Reg), (SK_U16 SK_FAR *)(pVal) + 1); \ + SK_IN16(IoC, XMA(Mac, (Reg) + 2), (SK_U16 SK_FAR *)(pVal)); \ } +#endif /* !SK_LITTLE_ENDIAN */ + #define XM_OUT32(IoC, Mac, Reg, Val) { \ - SK_OUT16((IoC), XMA((Mac), (Reg)), (SK_U16)((Val) & 0xffffL)); \ - SK_OUT16((IoC), XMA((Mac), (Reg+2)), (SK_U16)(((Val) >> 16) & 0xffffL));\ + SK_OUT16(IoC, XMA(Mac, Reg), (SK_U16)((Val) & 0xffffL)); \ + SK_OUT16(IoC, XMA(Mac, (Reg) + 2), (SK_U16)(((Val) >> 16) & 0xffffL)); \ } /* Remember: we are always writing to / reading from LITTLE ENDIAN memory */ @@ -1800,13 +2712,13 @@ SK_U8 *pByte; \ pByte = (SK_U8 *)&((SK_U8 *)(pVal))[0]; \ SK_IN16((IoC), XMA((Mac), (Reg)), &Word); \ - pByte[0] = (SK_U8)(Word & 0x00ff); \ + pByte[0] = (SK_U8)(Word & 0x00ff); \ pByte[1] = (SK_U8)((Word >> 8) & 0x00ff); \ - SK_IN16((IoC), XMA((Mac), (Reg+2)), &Word); \ - pByte[2] = (SK_U8)(Word & 0x00ff); \ + SK_IN16((IoC), XMA((Mac), (Reg) + 2), &Word); \ + pByte[2] = (SK_U8)(Word & 0x00ff); \ pByte[3] = (SK_U8)((Word >> 8) & 0x00ff); \ - SK_IN16((IoC), XMA((Mac), (Reg+4)), &Word); \ - pByte[4] = (SK_U8)(Word & 0x00ff); \ + SK_IN16((IoC), XMA((Mac), (Reg) + 4), &Word); \ + pByte[4] = (SK_U8)(Word & 0x00ff); \ pByte[5] = (SK_U8)((Word >> 8) & 0x00ff); \ } @@ -1816,10 +2728,10 @@ SK_OUT16((IoC), XMA((Mac), (Reg)), (SK_U16) \ (((SK_U16)(pByte[0]) & 0x00ff) | \ (((SK_U16)(pByte[1]) << 8) & 0xff00))); \ - SK_OUT16((IoC), XMA((Mac), (Reg+2)), (SK_U16) \ + SK_OUT16((IoC), XMA((Mac), (Reg) + 2), (SK_U16) \ (((SK_U16)(pByte[2]) & 0x00ff) | \ (((SK_U16)(pByte[3]) << 8) & 0xff00))); \ - SK_OUT16((IoC), XMA((Mac), (Reg+4)), (SK_U16) \ + SK_OUT16((IoC), XMA((Mac), (Reg) + 4), (SK_U16) \ (((SK_U16)(pByte[4]) & 0x00ff) | \ (((SK_U16)(pByte[5]) << 8) & 0xff00))); \ } @@ -1829,16 +2741,16 @@ SK_U8 SK_FAR *pByte; \ pByte = (SK_U8 SK_FAR *)&((SK_U8 SK_FAR *)(pVal))[0]; \ SK_IN16((IoC), XMA((Mac), (Reg)), &Word); \ - pByte[0] = (SK_U8)(Word & 0x00ff); \ + pByte[0] = (SK_U8)(Word & 0x00ff); \ pByte[1] = (SK_U8)((Word >> 8) & 0x00ff); \ - SK_IN16((IoC), XMA((Mac), (Reg+2)), &Word); \ - pByte[2] = (SK_U8)(Word & 0x00ff); \ + SK_IN16((IoC), XMA((Mac), (Reg) + 2), &Word); \ + pByte[2] = (SK_U8)(Word & 0x00ff); \ pByte[3] = (SK_U8)((Word >> 8) & 0x00ff); \ - SK_IN16((IoC), XMA((Mac), (Reg+4)), &Word); \ - pByte[4] = (SK_U8)(Word & 0x00ff); \ + SK_IN16((IoC), XMA((Mac), (Reg) + 4), &Word); \ + pByte[4] = (SK_U8)(Word & 0x00ff); \ pByte[5] = (SK_U8)((Word >> 8) & 0x00ff); \ - SK_IN16((IoC), XMA((Mac), (Reg+6)), &Word); \ - pByte[6] = (SK_U8)(Word & 0x00ff); \ + SK_IN16((IoC), XMA((Mac), (Reg) + 6), &Word); \ + pByte[6] = (SK_U8)(Word & 0x00ff); \ pByte[7] = (SK_U8)((Word >> 8) & 0x00ff); \ } @@ -1848,13 +2760,13 @@ SK_OUT16((IoC), XMA((Mac), (Reg)), (SK_U16) \ (((SK_U16)(pByte[0]) & 0x00ff)| \ (((SK_U16)(pByte[1]) << 8) & 0xff00))); \ - SK_OUT16((IoC), XMA((Mac), (Reg+2)), (SK_U16) \ + SK_OUT16((IoC), XMA((Mac), (Reg) + 2), (SK_U16) \ (((SK_U16)(pByte[2]) & 0x00ff)| \ (((SK_U16)(pByte[3]) << 8) & 0xff00))); \ - SK_OUT16((IoC), XMA((Mac), (Reg+4)), (SK_U16) \ + SK_OUT16((IoC), XMA((Mac), (Reg) + 4), (SK_U16) \ (((SK_U16)(pByte[4]) & 0x00ff)| \ (((SK_U16)(pByte[5]) << 8) & 0xff00))); \ - SK_OUT16((IoC), XMA((Mac), (Reg+6)), (SK_U16) \ + SK_OUT16((IoC), XMA((Mac), (Reg) + 6), (SK_U16) \ (((SK_U16)(pByte[6]) & 0x00ff)| \ (((SK_U16)(pByte[7]) << 8) & 0xff00))); \ } @@ -1864,7 +2776,7 @@ * * GM_IN16(), to read a 16 bit register (e.g. GM_GP_STAT) * GM_OUT16(), to write a 16 bit register (e.g. GM_GP_CTRL) - * GM_IN32(), to read a 32 bit register (e.g. GM_) + * GM_IN32(), to read a 32 bit register (e.g. GM_RXF_UC_OK) * GM_OUT32(), to write a 32 bit register (e.g. GM_) * GM_INADDR(), to read a network address register (e.g. GM_SRC_ADDR_1L) * GM_OUTADDR(), to write a network address register (e.g. GM_SRC_ADDR_2L) @@ -1883,22 +2795,31 @@ #define GMA(Mac, Reg) \ ((BASE_GMAC_1 + (Mac) * (BASE_GMAC_2 - BASE_GMAC_1)) | (Reg)) -#define GM_IN16(IoC, Mac, Reg, pVal) \ - SK_IN16((IoC), GMA((Mac), (Reg)), (pVal)) +#define GM_IN16(IoC, Mac, Reg, pVal) \ + SK_IN16(IoC, GMA(Mac, Reg), pVal) + +#define GM_OUT16(IoC, Mac, Reg, Val) \ + SK_OUT16(IoC, GMA(Mac, Reg), Val) + +#ifdef SK_LITTLE_ENDIAN + +#define GM_IN32(IoC, Mac, Reg, pVal) { \ + SK_IN16(IoC, GMA(Mac, Reg), (SK_U16 SK_FAR *)(pVal)); \ + SK_IN16((IoC), GMA(Mac, (Reg) + 4), (SK_U16 SK_FAR *)(pVal) + 1); \ +} -#define GM_OUT16(IoC, Mac, Reg, Val) \ - SK_OUT16((IoC), GMA((Mac), (Reg)), (Val)) +#else /* !SK_LITTLE_ENDIAN */ -#define GM_IN32(IoC, Mac, Reg, pVal) { \ - SK_IN16((IoC), GMA((Mac), (Reg)), \ - (SK_U16 SK_FAR*)&((SK_U16 SK_FAR*)(pVal))[XM_WORD_LO]); \ - SK_IN16((IoC), GMA((Mac), (Reg+4)), \ - (SK_U16 SK_FAR*)&((SK_U16 SK_FAR*)(pVal))[XM_WORD_HI]); \ +#define GM_IN32(IoC, Mac, Reg, pVal) { \ + SK_IN16(IoC, GMA(Mac, Reg), (SK_U16 SK_FAR *)(pVal) + 1); \ + SK_IN16(IoC, GMA(Mac, (Reg) + 4), (SK_U16 SK_FAR *)(pVal)); \ } +#endif /* !SK_LITTLE_ENDIAN */ + #define GM_OUT32(IoC, Mac, Reg, Val) { \ - SK_OUT16((IoC), GMA((Mac), (Reg)), (SK_U16)((Val) & 0xffffL)); \ - SK_OUT16((IoC), GMA((Mac), (Reg+4)), (SK_U16)(((Val) >> 16) & 0xffffL));\ + SK_OUT16(IoC, GMA(Mac, Reg), (SK_U16)((Val) & 0xffffL)); \ + SK_OUT16(IoC, GMA(Mac, (Reg) + 4), (SK_U16)(((Val) >> 16) & 0xffffL)); \ } #define GM_INADDR(IoC, Mac, Reg, pVal) { \ @@ -1906,13 +2827,13 @@ SK_U8 *pByte; \ pByte = (SK_U8 *)&((SK_U8 *)(pVal))[0]; \ SK_IN16((IoC), GMA((Mac), (Reg)), &Word); \ - pByte[0] = (SK_U8)(Word & 0x00ff); \ + pByte[0] = (SK_U8)(Word & 0x00ff); \ pByte[1] = (SK_U8)((Word >> 8) & 0x00ff); \ - SK_IN16((IoC), GMA((Mac), (Reg+4)), &Word); \ - pByte[2] = (SK_U8)(Word & 0x00ff); \ + SK_IN16((IoC), GMA((Mac), (Reg) + 4), &Word); \ + pByte[2] = (SK_U8)(Word & 0x00ff); \ pByte[3] = (SK_U8)((Word >> 8) & 0x00ff); \ - SK_IN16((IoC), GMA((Mac), (Reg+8)), &Word); \ - pByte[4] = (SK_U8)(Word & 0x00ff); \ + SK_IN16((IoC), GMA((Mac), (Reg) + 8), &Word); \ + pByte[4] = (SK_U8)(Word & 0x00ff); \ pByte[5] = (SK_U8)((Word >> 8) & 0x00ff); \ } @@ -1922,10 +2843,10 @@ SK_OUT16((IoC), GMA((Mac), (Reg)), (SK_U16) \ (((SK_U16)(pByte[0]) & 0x00ff) | \ (((SK_U16)(pByte[1]) << 8) & 0xff00))); \ - SK_OUT16((IoC), GMA((Mac), (Reg+4)), (SK_U16) \ + SK_OUT16((IoC), GMA((Mac), (Reg) + 4), (SK_U16) \ (((SK_U16)(pByte[2]) & 0x00ff) | \ (((SK_U16)(pByte[3]) << 8) & 0xff00))); \ - SK_OUT16((IoC), GMA((Mac), (Reg+8)), (SK_U16) \ + SK_OUT16((IoC), GMA((Mac), (Reg) + 8), (SK_U16) \ (((SK_U16)(pByte[4]) & 0x00ff) | \ (((SK_U16)(pByte[5]) << 8) & 0xff00))); \ } @@ -1935,16 +2856,16 @@ SK_U8 *pByte; \ pByte = (SK_U8 *)&((SK_U8 *)(pVal))[0]; \ SK_IN16((IoC), GMA((Mac), (Reg)), &Word); \ - pByte[0] = (SK_U8)(Word & 0x00ff); \ + pByte[0] = (SK_U8)(Word & 0x00ff); \ pByte[1] = (SK_U8)((Word >> 8) & 0x00ff); \ - SK_IN16((IoC), GMA((Mac), (Reg+4)), &Word); \ - pByte[2] = (SK_U8)(Word & 0x00ff); \ + SK_IN16((IoC), GMA((Mac), (Reg) + 4), &Word); \ + pByte[2] = (SK_U8)(Word & 0x00ff); \ pByte[3] = (SK_U8)((Word >> 8) & 0x00ff); \ - SK_IN16((IoC), GMA((Mac), (Reg+8)), &Word); \ - pByte[4] = (SK_U8)(Word & 0x00ff); \ + SK_IN16((IoC), GMA((Mac), (Reg) + 8), &Word); \ + pByte[4] = (SK_U8)(Word & 0x00ff); \ pByte[5] = (SK_U8)((Word >> 8) & 0x00ff); \ - SK_IN16((IoC), GMA((Mac), (Reg+12)), &Word); \ - pByte[6] = (SK_U8)(Word & 0x00ff); \ + SK_IN16((IoC), GMA((Mac), (Reg) + 12), &Word); \ + pByte[6] = (SK_U8)(Word & 0x00ff); \ pByte[7] = (SK_U8)((Word >> 8) & 0x00ff); \ } @@ -1954,13 +2875,13 @@ SK_OUT16((IoC), GMA((Mac), (Reg)), (SK_U16) \ (((SK_U16)(pByte[0]) & 0x00ff)| \ (((SK_U16)(pByte[1]) << 8) & 0xff00))); \ - SK_OUT16((IoC), GMA((Mac), (Reg+4)), (SK_U16) \ + SK_OUT16((IoC), GMA((Mac), (Reg) + 4), (SK_U16) \ (((SK_U16)(pByte[2]) & 0x00ff)| \ (((SK_U16)(pByte[3]) << 8) & 0xff00))); \ - SK_OUT16((IoC), GMA((Mac), (Reg+8)), (SK_U16) \ + SK_OUT16((IoC), GMA((Mac), (Reg) + 8), (SK_U16) \ (((SK_U16)(pByte[4]) & 0x00ff)| \ (((SK_U16)(pByte[5]) << 8) & 0xff00))); \ - SK_OUT16((IoC), GMA((Mac), (Reg+12)), (SK_U16) \ + SK_OUT16((IoC), GMA((Mac), (Reg) + 12), (SK_U16) \ (((SK_U16)(pByte[6]) & 0x00ff)| \ (((SK_U16)(pByte[7]) << 8) & 0xff00))); \ } @@ -1978,8 +2899,8 @@ #define SK_PHY_BCOM 1 /* Broadcom BCM5400 */ #define SK_PHY_LONE 2 /* Level One LXT1000 */ #define SK_PHY_NAT 3 /* National DP83891 */ -#define SK_PHY_MARV_COPPER 4 /* Marvell 88E1011S */ -#define SK_PHY_MARV_FIBER 5 /* Marvell 88E1011S working on fiber */ +#define SK_PHY_MARV_COPPER 4 /* Marvell 88E1040S */ +#define SK_PHY_MARV_FIBER 5 /* Marvell 88E1040S working on fiber */ /* * PHY addresses (bits 12..8 of PHY address reg) @@ -2008,30 +2929,30 @@ * * usage: PHY_READ(IoC, pPort, MAC_1, PHY_CTRL, Value); * Warning: a PHY_READ on an uninitialized PHY (PHY still in reset) never - * comes back. This is checked in DEBUG mode. + * comes back. This is checked in DEBUG mode. */ #ifndef DEBUG #define PHY_READ(IoC, pPort, Mac, PhyReg, pVal) { \ - SK_U16 Mmu; \ + SK_U16 Mmu; \ \ XM_OUT16((IoC), (Mac), XM_PHY_ADDR, (PhyReg) | (pPort)->PhyAddr); \ XM_IN16((IoC), (Mac), XM_PHY_DATA, (pVal)); \ if ((pPort)->PhyType != SK_PHY_XMAC) { \ - do { \ + do { \ XM_IN16((IoC), (Mac), XM_MMU_CMD, &Mmu); \ } while ((Mmu & XM_MMU_PHY_RDY) == 0); \ XM_IN16((IoC), (Mac), XM_PHY_DATA, (pVal)); \ - } \ + } \ } #else #define PHY_READ(IoC, pPort, Mac, PhyReg, pVal) { \ - SK_U16 Mmu; \ + SK_U16 Mmu; \ int __i = 0; \ \ XM_OUT16((IoC), (Mac), XM_PHY_ADDR, (PhyReg) | (pPort)->PhyAddr); \ XM_IN16((IoC), (Mac), XM_PHY_DATA, (pVal)); \ if ((pPort)->PhyType != SK_PHY_XMAC) { \ - do { \ + do { \ XM_IN16((IoC), (Mac), XM_MMU_CMD, &Mmu); \ __i++; \ if (__i > 100000) { \ @@ -2042,7 +2963,7 @@ } \ } while ((Mmu & XM_MMU_PHY_RDY) == 0); \ XM_IN16((IoC), (Mac), XM_PHY_DATA, (pVal)); \ - } \ + } \ } #endif /* DEBUG */ @@ -2050,17 +2971,17 @@ SK_U16 Mmu; \ \ if ((pPort)->PhyType != SK_PHY_XMAC) { \ - do { \ + do { \ XM_IN16((IoC), (Mac), XM_MMU_CMD, &Mmu); \ } while ((Mmu & XM_MMU_PHY_BUSY) != 0); \ - } \ + } \ XM_OUT16((IoC), (Mac), XM_PHY_ADDR, (PhyReg) | (pPort)->PhyAddr); \ XM_OUT16((IoC), (Mac), XM_PHY_DATA, (Val)); \ if ((pPort)->PhyType != SK_PHY_XMAC) { \ - do { \ + do { \ XM_IN16((IoC), (Mac), XM_MMU_CMD, &Mmu); \ } while ((Mmu & XM_MMU_PHY_BUSY) != 0); \ - } \ + } \ } /* @@ -2069,12 +2990,14 @@ * Use this macro to access PCI config register from the I/O space. * * para: + * pAC Pointer to adapter context * Addr PCI configuration register to access. * Values: PCI_VENDOR_ID ... PCI_VPD_ADR_REG, * - * usage SK_IN16(pAC, PCI_C(PCI_VENDOR_ID), pVal); + * usage SK_IN16(IoC, PCI_C(pAC, PCI_VENDOR_ID), pVal); */ -#define PCI_C(Addr) (B7_CFG_SPC + (Addr)) /* PCI Config Space */ +#define PCI_C(p, Addr) \ + (((CHIP_ID_YUKON_2(p)) ? Y2_CFG_SPC : B7_CFG_SPC) + (Addr)) /* * Macro SK_HW_ADDR(Base, Addr) @@ -2086,7 +3009,7 @@ * Addr Address offset * * usage: May be used in SK_INxx and SK_OUTxx macros - * #define SK_IN8(pAC, Addr, pVal) ...\ + * #define SK_IN8(IoC, Addr, pVal) ...\ * *pVal = (SK_U8)inp(SK_HW_ADDR(pAC->Hw.Iop, Addr))) */ #ifdef SK_MEM_MAPPED_IO @@ -2105,20 +3028,31 @@ * para: * pAC Pointer to adapter context struct * IoC I/O context needed for SK I/O macros - * Port Port number + * Port Port number * Mode Mode to set for this LED */ #define SK_HWAC_LINK_LED(pAC, IoC, Port, Mode) \ SK_OUT8(IoC, MR_ADDR(Port, LNK_LED_REG), Mode); +#define SK_SET_GP_IO(IoC, Bit) { \ + SK_U32 DWord; \ + SK_IN32(IoC, B2_GP_IO, &DWord); \ + DWord |= ((GP_DIR_0 | GP_IO_0) << (Bit));\ + SK_OUT32(IoC, B2_GP_IO, DWord); \ +} -/* typedefs *******************************************************************/ - +#define SK_CLR_GP_IO(IoC, Bit) { \ + SK_U32 DWord; \ + SK_IN32(IoC, B2_GP_IO, &DWord); \ + DWord &= ~((GP_DIR_0 | GP_IO_0) << (Bit));\ + SK_OUT32(IoC, B2_GP_IO, DWord); \ +} -/* function prototypes ********************************************************/ +#define SK_GE_PCI_FIFO_SIZE 1600 /* PCI FIFO Size */ #ifdef __cplusplus } #endif /* __cplusplus */ #endif /* __INC_SKGEHW_H */ + diff -urN linux-2.4.32-600/drivers/net/sk98lin/h/skgehwt.h linux-2.4.32-600-sk98_831/drivers/net/sk98lin/h/skgehwt.h --- linux-2.4.32-600/drivers/net/sk98lin/h/skgehwt.h Sat Mar 20 10:08:19 2004 +++ linux-2.4.32-600-sk98_831/drivers/net/sk98lin/h/skgehwt.h Sun Feb 26 11:12:56 2006 @@ -2,6 +2,8 @@ * * Name: skhwt.h * Project: Gigabit Ethernet Adapters, Event Scheduler Module + * Version: $Revision: 2.1 $ + * Date: $Date: 2003/10/27 14:16:09 $ * Purpose: Defines for the hardware timer functions * ******************************************************************************/ diff -urN linux-2.4.32-600/drivers/net/sk98lin/h/skgei2c.h linux-2.4.32-600-sk98_831/drivers/net/sk98lin/h/skgei2c.h --- linux-2.4.32-600/drivers/net/sk98lin/h/skgei2c.h Sat Mar 20 10:08:19 2004 +++ linux-2.4.32-600-sk98_831/drivers/net/sk98lin/h/skgei2c.h Thu Jan 1 01:00:00 1970 @@ -1,208 +0,0 @@ -/****************************************************************************** - * - * Name: skgei2c.h - * Project: Gigabit Ethernet Adapters, TWSI-Module - * Purpose: Special defines for TWSI - * - ******************************************************************************/ - -/****************************************************************************** - * - * (C)Copyright 1998-2002 SysKonnect. - * (C)Copyright 2002-2003 Marvell. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * The information in this file is provided "AS IS" without warranty. - * - ******************************************************************************/ - -/* - * SKGEI2C.H contains all SK-98xx specific defines for the TWSI handling - */ - -#ifndef _INC_SKGEI2C_H_ -#define _INC_SKGEI2C_H_ - -/* - * Macros to access the B2_I2C_CTRL - */ -#define SK_I2C_CTL(IoC, flag, dev, dev_size, reg, burst) \ - SK_OUT32(IoC, B2_I2C_CTRL,\ - (flag ? 0x80000000UL : 0x0L) | \ - (((SK_U32)reg << 16) & I2C_ADDR) | \ - (((SK_U32)dev << 9) & I2C_DEV_SEL) | \ - (dev_size & I2C_DEV_SIZE) | \ - ((burst << 4) & I2C_BURST_LEN)) - -#define SK_I2C_STOP(IoC) { \ - SK_U32 I2cCtrl; \ - SK_IN32(IoC, B2_I2C_CTRL, &I2cCtrl); \ - SK_OUT32(IoC, B2_I2C_CTRL, I2cCtrl | I2C_STOP); \ -} - -#define SK_I2C_GET_CTL(IoC, pI2cCtrl) SK_IN32(IoC, B2_I2C_CTRL, pI2cCtrl) - -/* - * Macros to access the TWSI SW Registers - */ -#define SK_I2C_SET_BIT(IoC, SetBits) { \ - SK_U8 OrgBits; \ - SK_IN8(IoC, B2_I2C_SW, &OrgBits); \ - SK_OUT8(IoC, B2_I2C_SW, OrgBits | (SK_U8)(SetBits)); \ -} - -#define SK_I2C_CLR_BIT(IoC, ClrBits) { \ - SK_U8 OrgBits; \ - SK_IN8(IoC, B2_I2C_SW, &OrgBits); \ - SK_OUT8(IoC, B2_I2C_SW, OrgBits & ~((SK_U8)(ClrBits))); \ -} - -#define SK_I2C_GET_SW(IoC, pI2cSw) SK_IN8(IoC, B2_I2C_SW, pI2cSw) - -/* - * define the possible sensor states - */ -#define SK_SEN_IDLE 0 /* Idle: sensor not read */ -#define SK_SEN_VALUE 1 /* Value Read cycle */ -#define SK_SEN_VALEXT 2 /* Extended Value Read cycle */ - -/* - * Conversion factor to convert read Voltage sensor to milli Volt - * Conversion factor to convert read Temperature sensor to 10th degree Celsius - */ -#define SK_LM80_VT_LSB 22 /* 22mV LSB resolution */ -#define SK_LM80_TEMP_LSB 10 /* 1 degree LSB resolution */ -#define SK_LM80_TEMPEXT_LSB 5 /* 0.5 degree LSB resolution for ext. val. */ - -/* - * formula: counter = (22500*60)/(rpm * divisor * pulses/2) - * assuming: 6500rpm, 4 pulses, divisor 1 - */ -#define SK_LM80_FAN_FAKTOR ((22500L*60)/(1*2)) - -/* - * Define sensor management data - * Maximum is reached on Genesis copper dual port and Yukon-64 - * Board specific maximum is in pAC->I2c.MaxSens - */ -#define SK_MAX_SENSORS 8 /* maximal no. of installed sensors */ -#define SK_MIN_SENSORS 5 /* minimal no. of installed sensors */ - -/* - * To watch the state machine (SM) use the timer in two ways - * instead of one as hitherto - */ -#define SK_TIMER_WATCH_SM 0 /* Watch the SM to finish in a spec. time */ -#define SK_TIMER_NEW_GAUGING 1 /* Start a new gauging when timer expires */ - -/* - * Defines for the individual thresholds - */ - -/* Temperature sensor */ -#define SK_SEN_TEMP_HIGH_ERR 800 /* Temperature High Err Threshold */ -#define SK_SEN_TEMP_HIGH_WARN 700 /* Temperature High Warn Threshold */ -#define SK_SEN_TEMP_LOW_WARN 100 /* Temperature Low Warn Threshold */ -#define SK_SEN_TEMP_LOW_ERR 0 /* Temperature Low Err Threshold */ - -/* VCC which should be 5 V */ -#define SK_SEN_PCI_5V_HIGH_ERR 5588 /* Voltage PCI High Err Threshold */ -#define SK_SEN_PCI_5V_HIGH_WARN 5346 /* Voltage PCI High Warn Threshold */ -#define SK_SEN_PCI_5V_LOW_WARN 4664 /* Voltage PCI Low Warn Threshold */ -#define SK_SEN_PCI_5V_LOW_ERR 4422 /* Voltage PCI Low Err Threshold */ - -/* - * VIO may be 5 V or 3.3 V. Initialization takes two parts: - * 1. Initialize lowest lower limit and highest higher limit. - * 2. After the first value is read correct the upper or the lower limit to - * the appropriate C constant. - * - * Warning limits are +-5% of the exepected voltage. - * Error limits are +-10% of the expected voltage. - */ - -/* Bug fix AF: 16.Aug.2001: Correct the init base of LM80 sensor */ - -#define SK_SEN_PCI_IO_5V_HIGH_ERR 5566 /* + 10% V PCI-IO High Err Threshold */ -#define SK_SEN_PCI_IO_5V_HIGH_WARN 5324 /* + 5% V PCI-IO High Warn Threshold */ - /* 5000 mVolt */ -#define SK_SEN_PCI_IO_5V_LOW_WARN 4686 /* - 5% V PCI-IO Low Warn Threshold */ -#define SK_SEN_PCI_IO_5V_LOW_ERR 4444 /* - 10% V PCI-IO Low Err Threshold */ - -#define SK_SEN_PCI_IO_RANGE_LIMITER 4000 /* 4000 mV range delimiter */ - -/* correction values for the second pass */ -#define SK_SEN_PCI_IO_3V3_HIGH_ERR 3850 /* + 15% V PCI-IO High Err Threshold */ -#define SK_SEN_PCI_IO_3V3_HIGH_WARN 3674 /* + 10% V PCI-IO High Warn Threshold */ - /* 3300 mVolt */ -#define SK_SEN_PCI_IO_3V3_LOW_WARN 2926 /* - 10% V PCI-IO Low Warn Threshold */ -#define SK_SEN_PCI_IO_3V3_LOW_ERR 2772 /* - 15% V PCI-IO Low Err Threshold */ - -/* - * VDD voltage - */ -#define SK_SEN_VDD_HIGH_ERR 3630 /* Voltage ASIC High Err Threshold */ -#define SK_SEN_VDD_HIGH_WARN 3476 /* Voltage ASIC High Warn Threshold */ -#define SK_SEN_VDD_LOW_WARN 3146 /* Voltage ASIC Low Warn Threshold */ -#define SK_SEN_VDD_LOW_ERR 2970 /* Voltage ASIC Low Err Threshold */ - -/* - * PHY PLL 3V3 voltage - */ -#define SK_SEN_PLL_3V3_HIGH_ERR 3630 /* Voltage PMA High Err Threshold */ -#define SK_SEN_PLL_3V3_HIGH_WARN 3476 /* Voltage PMA High Warn Threshold */ -#define SK_SEN_PLL_3V3_LOW_WARN 3146 /* Voltage PMA Low Warn Threshold */ -#define SK_SEN_PLL_3V3_LOW_ERR 2970 /* Voltage PMA Low Err Threshold */ - -/* - * VAUX (YUKON only) - */ -#define SK_SEN_VAUX_3V3_HIGH_ERR 3630 /* Voltage VAUX High Err Threshold */ -#define SK_SEN_VAUX_3V3_HIGH_WARN 3476 /* Voltage VAUX High Warn Threshold */ -#define SK_SEN_VAUX_3V3_LOW_WARN 3146 /* Voltage VAUX Low Warn Threshold */ -#define SK_SEN_VAUX_3V3_LOW_ERR 2970 /* Voltage VAUX Low Err Threshold */ -#define SK_SEN_VAUX_0V_WARN_ERR 0 /* if VAUX not present */ -#define SK_SEN_VAUX_RANGE_LIMITER 1000 /* 1000 mV range delimiter */ - -/* - * PHY 2V5 voltage - */ -#define SK_SEN_PHY_2V5_HIGH_ERR 2750 /* Voltage PHY High Err Threshold */ -#define SK_SEN_PHY_2V5_HIGH_WARN 2640 /* Voltage PHY High Warn Threshold */ -#define SK_SEN_PHY_2V5_LOW_WARN 2376 /* Voltage PHY Low Warn Threshold */ -#define SK_SEN_PHY_2V5_LOW_ERR 2222 /* Voltage PHY Low Err Threshold */ - -/* - * ASIC Core 1V5 voltage (YUKON only) - */ -#define SK_SEN_CORE_1V5_HIGH_ERR 1650 /* Voltage ASIC Core High Err Threshold */ -#define SK_SEN_CORE_1V5_HIGH_WARN 1575 /* Voltage ASIC Core High Warn Threshold */ -#define SK_SEN_CORE_1V5_LOW_WARN 1425 /* Voltage ASIC Core Low Warn Threshold */ -#define SK_SEN_CORE_1V5_LOW_ERR 1350 /* Voltage ASIC Core Low Err Threshold */ - -/* - * FAN 1 speed - */ -/* assuming: 6500rpm +-15%, 4 pulses, - * warning at: 80 % - * error at: 70 % - * no upper limit - */ -#define SK_SEN_FAN_HIGH_ERR 20000 /* FAN Speed High Err Threshold */ -#define SK_SEN_FAN_HIGH_WARN 20000 /* FAN Speed High Warn Threshold */ -#define SK_SEN_FAN_LOW_WARN 5200 /* FAN Speed Low Warn Threshold */ -#define SK_SEN_FAN_LOW_ERR 4550 /* FAN Speed Low Err Threshold */ - -/* - * Some Voltages need dynamic thresholds - */ -#define SK_SEN_DYN_INIT_NONE 0 /* No dynamic init of thresholds */ -#define SK_SEN_DYN_INIT_PCI_IO 10 /* Init PCI-IO with new thresholds */ -#define SK_SEN_DYN_INIT_VAUX 11 /* Init VAUX with new thresholds */ - -extern int SkLm80ReadSensor(SK_AC *pAC, SK_IOC IoC, SK_SENSOR *pSen); -#endif /* n_INC_SKGEI2C_H */ diff -urN linux-2.4.32-600/drivers/net/sk98lin/h/skgeinit.h linux-2.4.32-600-sk98_831/drivers/net/sk98lin/h/skgeinit.h --- linux-2.4.32-600/drivers/net/sk98lin/h/skgeinit.h Sat Mar 20 10:08:19 2004 +++ linux-2.4.32-600-sk98_831/drivers/net/sk98lin/h/skgeinit.h Sun Feb 26 11:13:02 2006 @@ -2,21 +2,24 @@ * * Name: skgeinit.h * Project: Gigabit Ethernet Adapters, Common Modules + * Version: $Revision: 2.48 $ + * Date: $Date: 2005/12/14 16:11:35 $ * Purpose: Structures and prototypes for the GE Init Module * ******************************************************************************/ /****************************************************************************** * + * LICENSE: * (C)Copyright 1998-2002 SysKonnect. - * (C)Copyright 2002-2003 Marvell. + * (C)Copyright 2002-2005 Marvell. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. - * * The information in this file is provided "AS IS" without warranty. + * /LICENSE * ******************************************************************************/ @@ -58,14 +61,17 @@ #define SK_XMIT_DUR 0x002faf08UL /* 50 ms */ #define SK_BLK_DUR 0x01dcd650UL /* 500 ms */ -#define SK_DPOLL_DEF 0x00ee6b28UL /* 250 ms at 62.5 MHz */ +#define SK_DPOLL_DEF 0x00ee6b28UL /* 250 ms at 62.5 MHz (Genesis) */ +#define SK_DPOLL_DEF_Y2 0x0000124fUL /* 75 us (Yukon-2) */ #define SK_DPOLL_MAX 0x00ffffffUL /* 268 ms at 62.5 MHz */ - /* 215 ms at 78.12 MHz */ + /* 215 ms at 78.12 MHz (Yukon) */ #define SK_FACT_62 100 /* is given in percent */ -#define SK_FACT_53 85 /* on GENESIS: 53.12 MHz */ +#define SK_FACT_53 85 /* on GENESIS: 53.12 MHz */ #define SK_FACT_78 125 /* on YUKON: 78.12 MHz */ +#define SK_FACT_100 161 /* on YUKON-FE: 100 MHz */ +#define SK_FACT_125 202 /* on YUKON-EC: 125 MHz */ /* Timeout values */ #define SK_MAC_TO_53 72 /* MAC arbiter timeout */ @@ -80,11 +86,23 @@ #define SK_RB_LLPP_S (10 * 1024) /* Lower Level for small Queues */ #define SK_RB_LLPP_B (16 * 1024) /* Lower Level for big Queues */ +/* Threshold values for Yukon-EC Ultra */ +#define SK_ECU_ULPP 0x0080 /* Upper Pause Threshold (multiples of 8) */ +#define SK_ECU_LLPP 0x0060 /* Lower Pause Threshold (multiples of 8) */ +#define SK_ECU_AE_THR 0x0180 /* Almost Empty Threshold */ +#define SK_ECU_TXFF_LEV 0x01a0 /* Tx BMU FIFO Level */ + #ifndef SK_BMU_RX_WM -#define SK_BMU_RX_WM 0x600 /* BMU Rx Watermark */ +#define SK_BMU_RX_WM 0x600 /* BMU Rx Watermark */ #endif + #ifndef SK_BMU_TX_WM -#define SK_BMU_TX_WM 0x600 /* BMU Tx Watermark */ +#define SK_BMU_TX_WM 0x600 /* BMU Tx Watermark */ +#endif + +/* performance sensitive drivers should set this define to 0x80 */ +#ifndef SK_BMU_RX_WM_PEX +#define SK_BMU_RX_WM_PEX 0x600 /* BMU Rx Watermark for PEX */ #endif /* XMAC II Rx High Watermark */ @@ -96,37 +114,31 @@ #define SK_XM_THR_MULL 0x01fb /* .. for multiple link usage */ #define SK_XM_THR_JUMBO 0x03fc /* .. for jumbo frame usage */ -/* values for GIPortUsage */ +/* values for PortUsage */ #define SK_RED_LINK 1 /* redundant link usage */ #define SK_MUL_LINK 2 /* multiple link usage */ #define SK_JUMBO_LINK 3 /* driver uses jumbo frames */ /* Minimum RAM Buffer Rx Queue Size */ -#define SK_MIN_RXQ_SIZE 16 /* 16 kB */ +#define SK_MIN_RXQ_SIZE (((pAC)->GIni.GIYukon2) ? 10 : 16) /* 10/16 kB */ /* Minimum RAM Buffer Tx Queue Size */ -#define SK_MIN_TXQ_SIZE 16 /* 16 kB */ +#define SK_MIN_TXQ_SIZE (((pAC)->GIni.GIYukon2) ? 10 : 16) /* 10/16 kB */ -/* Queue Size units */ -#define QZ_UNITS 0x7 +/* Queue Size units (Genesis/Yukon) */ +#define QZ_UNITS 7 #define QZ_STEP 8 +/* Queue Size units (Yukon-2) */ +#define QZ_STEP_Y2 1 + /* Percentage of queue size from whole memory */ /* 80 % for receive */ -#define RAM_QUOTA_RX 80L -/* 0% for sync transfer */ -#define RAM_QUOTA_SYNC 0L +#define RAM_QUOTA_RX 80 +/* 0 % for sync transfer */ +#define RAM_QUOTA_SYNC 0 /* the rest (20%) is taken for async transfer */ -/* Get the rounded queue size in Bytes in 8k steps */ -#define ROUND_QUEUE_SIZE(SizeInBytes) \ - ((((unsigned long) (SizeInBytes) + (QZ_STEP*1024L)-1) / 1024) & \ - ~(QZ_STEP-1)) - -/* Get the rounded queue size in KBytes in 8k steps */ -#define ROUND_QUEUE_SIZE_KB(Kilobytes) \ - ROUND_QUEUE_SIZE((Kilobytes) * 1024L) - /* Types of RAM Buffer Queues */ #define SK_RX_SRAM_Q 1 /* small receive queue */ #define SK_RX_BRAM_Q 2 /* big receive queue */ @@ -165,11 +177,11 @@ /* Link Speed Capabilities */ -#define SK_LSPEED_CAP_AUTO (1<<0) /* Automatic resolution */ -#define SK_LSPEED_CAP_10MBPS (1<<1) /* 10 Mbps */ -#define SK_LSPEED_CAP_100MBPS (1<<2) /* 100 Mbps */ -#define SK_LSPEED_CAP_1000MBPS (1<<3) /* 1000 Mbps */ -#define SK_LSPEED_CAP_INDETERMINATED (1<<4) /* indeterminated */ +#define SK_LSPEED_CAP_AUTO BIT_0S /* Automatic resolution */ +#define SK_LSPEED_CAP_10MBPS BIT_1S /* 10 Mbps */ +#define SK_LSPEED_CAP_100MBPS BIT_2S /* 100 Mbps */ +#define SK_LSPEED_CAP_1000MBPS BIT_3S /* 1000 Mbps */ +#define SK_LSPEED_CAP_INDETERMINATED BIT_4S /* indeterminated */ /* Link Speed Parameter */ #define SK_LSPEED_AUTO 1 /* Automatic resolution */ @@ -187,11 +199,11 @@ /* Link Capability Parameter */ -#define SK_LMODE_CAP_HALF (1<<0) /* Half Duplex Mode */ -#define SK_LMODE_CAP_FULL (1<<1) /* Full Duplex Mode */ -#define SK_LMODE_CAP_AUTOHALF (1<<2) /* AutoHalf Duplex Mode */ -#define SK_LMODE_CAP_AUTOFULL (1<<3) /* AutoFull Duplex Mode */ -#define SK_LMODE_CAP_INDETERMINATED (1<<4) /* indeterminated */ +#define SK_LMODE_CAP_HALF BIT_0S /* Half Duplex Mode */ +#define SK_LMODE_CAP_FULL BIT_1S /* Full Duplex Mode */ +#define SK_LMODE_CAP_AUTOHALF BIT_2S /* AutoHalf Duplex Mode */ +#define SK_LMODE_CAP_AUTOFULL BIT_3S /* AutoFull Duplex Mode */ +#define SK_LMODE_CAP_INDETERMINATED BIT_4S /* indeterminated */ /* Link Mode Current State */ #define SK_LMODE_STAT_UNKNOWN 1 /* Unknown Duplex Mode */ @@ -218,10 +230,10 @@ #define SK_FLOW_STAT_INDETERMINATED 5 /* indeterminated */ /* Master/Slave Mode Capabilities */ -#define SK_MS_CAP_AUTO (1<<0) /* Automatic resolution */ -#define SK_MS_CAP_MASTER (1<<1) /* This station is master */ -#define SK_MS_CAP_SLAVE (1<<2) /* This station is slave */ -#define SK_MS_CAP_INDETERMINATED (1<<3) /* indeterminated */ +#define SK_MS_CAP_AUTO BIT_0S /* Automatic resolution */ +#define SK_MS_CAP_MASTER BIT_1S /* This station is master */ +#define SK_MS_CAP_SLAVE BIT_2S /* This station is slave */ +#define SK_MS_CAP_INDETERMINATED BIT_3S /* indeterminated */ /* Set Master/Slave Mode Parameter (and capabilities) */ #define SK_MS_MODE_AUTO 1 /* Automatic resolution */ @@ -236,25 +248,25 @@ #define SK_MS_STAT_FAULT 4 /* M/S resolution failed */ #define SK_MS_STAT_INDETERMINATED 5 /* indeterminated */ -/* parameter 'Mode' when calling SkXmSetRxCmd() */ -#define SK_STRIP_FCS_ON (1<<0) /* Enable FCS stripping of Rx frames */ -#define SK_STRIP_FCS_OFF (1<<1) /* Disable FCS stripping of Rx frames */ -#define SK_STRIP_PAD_ON (1<<2) /* Enable pad byte stripping of Rx fr */ -#define SK_STRIP_PAD_OFF (1<<3) /* Disable pad byte stripping of Rx fr */ -#define SK_LENERR_OK_ON (1<<4) /* Don't chk fr for in range len error */ -#define SK_LENERR_OK_OFF (1<<5) /* Check frames for in range len error */ -#define SK_BIG_PK_OK_ON (1<<6) /* Don't set Rx Error bit for big frames */ -#define SK_BIG_PK_OK_OFF (1<<7) /* Set Rx Error bit for big frames */ -#define SK_SELF_RX_ON (1<<8) /* Enable Rx of own packets */ -#define SK_SELF_RX_OFF (1<<9) /* Disable Rx of own packets */ +/* parameter 'Mode' when calling SkMacSetRxCmd() */ +#define SK_STRIP_FCS_ON BIT_0S /* Enable FCS stripping of Rx frames */ +#define SK_STRIP_FCS_OFF BIT_1S /* Disable FCS stripping of Rx frames */ +#define SK_STRIP_PAD_ON BIT_2S /* Enable pad byte stripping of Rx fr */ +#define SK_STRIP_PAD_OFF BIT_3S /* Disable pad byte stripping of Rx fr */ +#define SK_LENERR_OK_ON BIT_4S /* Don't chk fr for in range len error */ +#define SK_LENERR_OK_OFF BIT_5S /* Check frames for in range len error */ +#define SK_BIG_PK_OK_ON BIT_6S /* Don't set Rx Error bit for big frames */ +#define SK_BIG_PK_OK_OFF BIT_7S /* Set Rx Error bit for big frames */ +#define SK_SELF_RX_ON BIT_8S /* Enable Rx of own packets */ +#define SK_SELF_RX_OFF BIT_9S /* Disable Rx of own packets */ /* parameter 'Para' when calling SkMacSetRxTxEn() */ -#define SK_MAC_LOOPB_ON (1<<0) /* Enable MAC Loopback Mode */ -#define SK_MAC_LOOPB_OFF (1<<1) /* Disable MAC Loopback Mode */ -#define SK_PHY_LOOPB_ON (1<<2) /* Enable PHY Loopback Mode */ -#define SK_PHY_LOOPB_OFF (1<<3) /* Disable PHY Loopback Mode */ -#define SK_PHY_FULLD_ON (1<<4) /* Enable GMII Full Duplex */ -#define SK_PHY_FULLD_OFF (1<<5) /* Disable GMII Full Duplex */ +#define SK_MAC_LOOPB_ON BIT_0S /* Enable MAC Loopback Mode */ +#define SK_MAC_LOOPB_OFF BIT_1S /* Disable MAC Loopback Mode */ +#define SK_PHY_LOOPB_ON BIT_2S /* Enable PHY Loopback Mode */ +#define SK_PHY_LOOPB_OFF BIT_3S /* Disable PHY Loopback Mode */ +#define SK_PHY_FULLD_ON BIT_4S /* Enable GMII Full Duplex */ +#define SK_PHY_FULLD_OFF BIT_5S /* Disable GMII Full Duplex */ /* States of PState */ #define SK_PRT_RESET 0 /* the port is reset */ @@ -264,18 +276,24 @@ /* PHY power down modes */ #define PHY_PM_OPERATIONAL_MODE 0 /* PHY operational mode */ -#define PHY_PM_DEEP_SLEEP 1 /* coma mode --> minimal power */ +#define PHY_PM_DEEP_SLEEP 1 /* Coma mode --> minimal power */ #define PHY_PM_IEEE_POWER_DOWN 2 /* IEEE 22.2.4.1.5 compl. power down */ -#define PHY_PM_ENERGY_DETECT 3 /* energy detect */ -#define PHY_PM_ENERGY_DETECT_PLUS 4 /* energy detect plus */ +#define PHY_PM_ENERGY_DETECT 3 /* Energy detect */ +#define PHY_PM_ENERGY_DETECT_PLUS 4 /* Energy detect plus */ + +/* PCI Bus Types */ +#define SK_PCI_BUS BIT_0S /* normal PCI bus */ +#define SK_PCIX_BUS BIT_1S /* PCI-X bus */ +#define SK_PEX_BUS BIT_2S /* PCI-Express bus */ /* Default receive frame limit for Workaround of XMAC Errata */ #define SK_DEF_RX_WA_LIM SK_CONSTU64(100) /* values for GILedBlinkCtrl (LED Blink Control) */ -#define SK_ACT_LED_BLINK (1<<0) /* Active LED blinking */ -#define SK_DUP_LED_NORMAL (1<<1) /* Duplex LED normal */ -#define SK_LED_LINK100_ON (1<<2) /* Link 100M LED on */ +#define SK_ACT_LED_BLINK BIT_0S /* Active LED blinking */ +#define SK_DUP_LED_NORMAL BIT_1S /* Duplex LED normal */ +#define SK_LED_LINK100_ON BIT_2S /* Link 100M LED on */ +#define SK_DUAL_LED_ACT_LNK BIT_3S /* Dual LED ACT/LNK configuration */ /* Link Partner Status */ #define SK_LIPA_UNKNOWN 0 /* Link partner is in unknown state */ @@ -288,18 +306,173 @@ /* Max. Auto-neg. timeouts before link detection in sense mode is reset */ #define SK_MAX_ANEG_TO 10 /* Max. 10 times the sense mode is reset */ + +/****************************************************************************** + * + * HW_FEATURE() macro + */ + +/* DWORD 0: Features */ +#define HWF_CLK_GATING_ENABLE 0x02000000UL /* Enable Clock Gating */ +#define HWF_RED_CORE_CLK_SUP 0x01000000UL /* Reduced Core Clock supp. */ +#define HWF_SYNC_TX_SUP 0x00800000UL /* Synch. Tx Queue available */ +#define HWF_SINGLE_PORT_DEVICE 0x00400000UL /* Device has only one LAN IF */ +#define HWF_JUMBO_FRAMES_SUP 0x00200000UL /* Jumbo Frames supported */ +#define HWF_TX_TCP_CSUM_SUP 0x00100000UL /* TCP Tx checksum supported */ +#define HWF_TX_UDP_CSUM_SUP 0x00080000UL /* UDP Tx checksum supported */ +#define HWF_RX_CSUM_SUP 0x00040000UL /* RX checksum supported */ +#define HWF_TCP_SEGM_SUP 0x00020000UL /* TCP segmentation supported */ +#define HWF_RSS_HASH_SUP 0x00010000UL /* RSS Hash supported */ +#define HWF_PORT_VLAN_SUP 0x00008000UL /* VLAN can be config per port*/ +#define HWF_ROLE_PARAM_SUP 0x00004000UL /* Role parameter supported */ +#define HWF_LOW_PMODE_SUP 0x00002000UL /* Low Power Mode supported */ +#define HWF_ENERGIE_DEMO_SUP 0x00001000UL /* Energy Detect mode supp. */ +#define HWF_SPEED1000_SUP 0x00000800UL /* Line Speed 1000 supported */ +#define HWF_SPEED100_SUP 0x00000400UL /* Line Speed 100 supported */ +#define HWF_SPEED10_SUP 0x00000200UL /* Line Speed 10 supported */ +#define HWF_AUTONEGSENSE_SUP 0x00000100UL /* Autoneg Sense supported */ +#define HWF_PHY_LOOPB_MD_SUP 0x00000080UL /* PHY loopback mode supp. */ +#define HWF_ASF_SUP 0x00000040UL /* ASF support possible */ +#define HWF_QS_STEPS_1KB 0x00000020UL /* The Rx/Tx queues can be */ + /* configured with 1 kB res. */ +#define HWF_OWN_RAM_PER_PORT 0x00000010UL /* Each port has a separate */ + /* RAM buffer */ +#define HWF_MIN_LED_IF 0x00000008UL /* Minimal LED interface */ + /* (e.g. for Yukon-EC) */ +#define HWF_LIST_ELEMENTS_USED 0x00000004UL /* HW uses list elements */ + /* (otherwise desc. are used) */ +#define HWF_GMAC_INSIDE 0x00000002UL /* Device contains GMAC */ +#define HWF_TWSI_PRESENT 0x00000001UL /* TWSI sensor bus present */ + +/*-RMV- DWORD 1: Deviations */ +#define HWF_WA_DEV_4200 0x10200000UL /*-RMV- 4.200 (D3 Blue Screen)*/ +#define HWF_WA_DEV_4185CS 0x10100000UL /*-RMV- 4.185 (ECU 100 CS cal)*/ +#define HWF_WA_DEV_4185 0x10080000UL /*-RMV- 4.185 (ECU Tx h check)*/ +#define HWF_WA_DEV_4167 0x10040000UL /*-RMV- 4.167 (Rx OvSize Hang)*/ +#define HWF_WA_DEV_4152 0x10020000UL /*-RMV- 4.152 (RSS issue) */ +#define HWF_WA_DEV_4115 0x10010000UL /*-RMV- 4.115 (Rx MAC FIFO) */ +#define HWF_WA_DEV_4109 0x10008000UL /*-RMV- 4.109 (BIU hang) */ +#define HWF_WA_DEV_483 0x10004000UL /*-RMV- 4.83 (Rx TCP wrong) */ +#define HWF_WA_DEV_479 0x10002000UL /*-RMV- 4.79 (Rx BMU hang II) */ +#define HWF_WA_DEV_472 0x10001000UL /*-RMV- 4.72 (GPHY2 MDC clk) */ +#define HWF_WA_DEV_463 0x10000800UL /*-RMV- 4.63 (Rx BMU hang I) */ +#define HWF_WA_DEV_427 0x10000400UL /*-RMV- 4.27 (Tx Done Rep) */ +#define HWF_WA_DEV_42 0x10000200UL /*-RMV- 4.2 (pref unit burst) */ +#define HWF_WA_DEV_46 0x10000100UL /*-RMV- 4.6 (CPU crash II) */ +#define HWF_WA_DEV_43_418 0x10000080UL /*-RMV- 4.3 & 4.18 (PCI unexp */ + /*-RMV- compl&Stat BMU deadl) */ +#define HWF_WA_DEV_420 0x10000040UL /*-RMV- 4.20 (Status BMU ov) */ +#define HWF_WA_DEV_423 0x10000020UL /*-RMV- 4.23 (TCP Segm Hang) */ +#define HWF_WA_DEV_424 0x10000010UL /*-RMV- 4.24 (MAC reg overwr) */ +#define HWF_WA_DEV_425 0x10000008UL /*-RMV- 4.25 (Magic packet */ + /*-RMV- with odd offset) */ +#define HWF_WA_DEV_428 0x10000004UL /*-RMV- 4.28 (Poll-U &BigEndi)*/ +#define HWF_WA_FIFO_FLUSH_YLA0 0x10000002UL /*-RMV- dis Rx GMAC FIFO Flush*/ + /*-RMV- for Yu-L Rev. A0 only */ +#define HWF_WA_COMA_MODE 0x10000001UL /*-RMV- Coma Mode WA req */ + +/* DWORD 2: still unused */ +/* DWORD 3: still unused */ + + +/* + * HW_FEATURE() - returns whether the feature is serviced or not + */ +#define HW_FEATURE(pAC, ReqFeature) \ + (((pAC)->GIni.HwF.Features[((ReqFeature) & 0x30000000UL) >> 28] &\ + ((ReqFeature) & 0x0fffffffUL)) != 0) + +#define HW_FEAT_LIST 0 +#define HW_DEV_LIST 1 + +#define SET_HW_FEATURE_MASK(pAC, List, OffMaskValue, OnMaskValue) { \ + if ((List) == HW_FEAT_LIST || (List) == HW_DEV_LIST) { \ + (pAC)->GIni.HwF.OffMask[List] = (OffMaskValue); \ + (pAC)->GIni.HwF.OnMask[List] = (OnMaskValue); \ + } \ +} + +/* driver access macros for GIni structure ***********************************/ + +#define CHIP_ID_YUKON_2(pAC) ((pAC)->GIni.GIYukon2) + +#define HW_SYNC_TX_SUPPORTED(pAC) \ + ((pAC)->GIni.GIChipId != CHIP_ID_YUKON_EC && \ + (pAC)->GIni.GIChipId != CHIP_ID_YUKON_FE && \ + (pAC)->GIni.GIChipId != CHIP_ID_YUKON_EC_U) + +#define HW_MS_TO_TICKS(pAC, MsTime) \ + ((MsTime) * (62500L/100) * (pAC)->GIni.GIHstClkFact) + +#ifdef XXX +/* still under construction */ +#define HW_IS_SINGLE_PORT(pAC) ((pAC)->GIni.GIMacsFound == 1) +#define HW_NUMBER_OF_PORTS(pAC) ((pAC)->GIni.GIMacsFound) + +#define HW_TX_UDP_CSUM_SUPPORTED(pAC) \ + ((((pAC)->GIni.GIChipId >= CHIP_ID_YUKON) && ((pAC)->GIni.GIChipRev != 0)) + +#define HW_DEFAULT_LINESPEED(pAC) \ + ((!(pAC)->GIni.GIGenesis && (pAC)->GIni.GICopperType) ? \ + SK_LSPEED_AUTO : SK_LSPEED_1000MBPS) + +#define HW_ROLE_PARAM_SUPPORTED(pAC) ((pAC)->GIni.GICopperType) + +#define HW_SPEED1000_SUPPORTED(pAC, Port) \ + ((pAC)->GIni.GP[Port].PLinkSpeedCap & SK_LSPEED_CAP_1000MBPS) + +#define HW_SPEED100_SUPPORTED(pAC, Port) \ + ((pAC)->GIni.GP[Port].PLinkSpeedCap & SK_LSPEED_CAP_100MBPS) + +#define HW_SPEED10_SUPPORTED(pAC, Port) \ + ((pAC)->GIni.GP[Port].PLinkSpeedCap & SK_LSPEED_CAP_10MBPS) + +#define HW_AUTONEGSENSE_SUPPORTED(pAC) ((pAC)->GIni.GP[0].PhyType==SK_PHY_XMAC) + +#define HW_FREQ_TO_CARD_TICKS(pAC, AdapterClkSpeed, Freq) \ + (((AdapterClkSpeed / 100) * (pAC)->GIni.GIHstClkFact) / Freq) + +#define HW_IS_LINK_UP(pAC, Port) ((pAC)->GIni.GP[Port].PHWLinkUp) +#define HW_LINK_SPEED_USED(pAC, Port) ((pAC)->GIni.GP[Port].PLinkSpeedUsed) +#define HW_RAM_SIZE(pAC) ((pAC)->GIni.GIRamSize) + +#define HW_PHY_LP_MODE_SUPPORTED(pAC) (pAC0->??? +#define HW_ASF_ACTIVE(pAC) ??? +#define RAWIO_OUT32(pAC, pAC->RegIrqMask, pAC->GIni.GIValIrqMask)... + +/* macro to check whether Tx checksum is supported */ +#define HW_TX_CSUM_SUPPORTED(pAC) ((pAC)->GIni.GIChipId != CHIP_ID_GENESIS) + +BMU_UDP_CHECK : BMU_TCP_CHECK; + +/* macro for - Own Bit mirrored to DWORD7 (Yukon LP receive descriptor) */ +#endif /* 0 */ + + /* structures *****************************************************************/ /* + * HW Feature structure + */ +typedef struct s_HwFeatures { + SK_U32 Features[4]; /* Feature list */ + SK_U32 OffMask[4]; /* Off Mask */ + SK_U32 OnMask[4]; /* On Mask */ +} SK_HW_FEATURES; + +/* * MAC specific functions */ typedef struct s_GeMacFunc { - int (*pFnMacUpdateStats)(SK_AC *pAC, SK_IOC IoC, unsigned int Port); - int (*pFnMacStatistic)(SK_AC *pAC, SK_IOC IoC, unsigned int Port, - SK_U16 StatAddr, SK_U32 SK_FAR *pVal); - int (*pFnMacResetCounter)(SK_AC *pAC, SK_IOC IoC, unsigned int Port); - int (*pFnMacOverflow)(SK_AC *pAC, SK_IOC IoC, unsigned int Port, - SK_U16 IStatus, SK_U64 SK_FAR *pVal); + int (*pFnMacUpdateStats)(SK_AC *, SK_IOC, unsigned int); + int (*pFnMacStatistic)(SK_AC *, SK_IOC, unsigned int, SK_U16, SK_U32 SK_FAR *); + int (*pFnMacResetCounter)(SK_AC *, SK_IOC, unsigned int); + int (*pFnMacOverflow)(SK_AC *, SK_IOC, unsigned int, SK_U16, SK_U64 SK_FAR *); + void (*pSkGeSirqIsr)(SK_AC *, SK_IOC, SK_U32); +#ifdef SK_DIAG + int (*pFnMacPhyRead)(SK_AC *, SK_IOC, int, int, SK_U16 SK_FAR *); + int (*pFnMacPhyWrite)(SK_AC *, SK_IOC, int, int, SK_U16); +#endif /* SK_DIAG */ } SK_GEMACFUNC; /* @@ -309,7 +482,7 @@ #ifndef SK_DIAG SK_TIMER PWaTimer; /* Workaround Timer */ SK_TIMER HalfDupChkTimer; -#endif /* SK_DIAG */ +#endif /* !SK_DIAG */ SK_U32 PPrevShorts; /* Previous Short Counter checking */ SK_U32 PPrevFcs; /* Previous FCS Error Counter checking */ SK_U64 PPrevRx; /* Previous RxOk Counter checking */ @@ -333,6 +506,7 @@ int PXaQOff; /* Asynchronous Tx Queue Address Offset */ int PhyType; /* PHY used on this port */ int PState; /* Port status (reset, stop, init, run) */ + int PPortUsage; /* Driver Port Usage */ SK_U16 PhyId1; /* PHY Id1 on this port */ SK_U16 PhyAddr; /* MDIO/MDC PHY address */ SK_U16 PIsave; /* Saved Interrupt status word */ @@ -365,7 +539,10 @@ int PMacJamLen; /* MAC Jam length */ int PMacJamIpgVal; /* MAC Jam IPG */ int PMacJamIpgData; /* MAC IPG Jam to Data */ + int PMacBackOffLim; /* MAC Back-off Limit */ + int PMacDataBlind; /* MAC Data Blinder */ int PMacIpgData; /* MAC Data IPG */ + SK_U16 PMacAddr[3]; /* MAC address */ SK_BOOL PMacLimit4; /* reset collision counter and backoff algorithm */ } SK_GEPORT; @@ -377,27 +554,37 @@ int GIChipId; /* Chip Identification Number */ int GIChipRev; /* Chip Revision Number */ SK_U8 GIPciHwRev; /* PCI HW Revision Number */ + SK_U8 GIPciBus; /* PCI Bus Type (PCI / PCI-X / PCI-Express) */ + SK_U8 GIPciMode; /* PCI / PCI-X Mode @ Clock */ + SK_U8 GIPexWidth; /* PCI-Express Negotiated Link Width */ SK_BOOL GIGenesis; /* Genesis adapter ? */ - SK_BOOL GIYukon; /* YUKON-A1/Bx chip */ + SK_BOOL GIYukon; /* YUKON family (1 and 2) */ SK_BOOL GIYukonLite; /* YUKON-Lite chip */ + SK_BOOL GIYukon2; /* YUKON-2 chip (-XL, -EC or -FE) */ + SK_U8 GIConTyp; /* Connector Type */ + SK_U8 GIPmdTyp; /* PMD Type */ SK_BOOL GICopperType; /* Copper Type adapter ? */ SK_BOOL GIPciSlot64; /* 64-bit PCI Slot */ SK_BOOL GIPciClock66; /* 66 MHz PCI Clock */ SK_BOOL GIVauxAvail; /* VAUX available (YUKON) */ SK_BOOL GIYukon32Bit; /* 32-Bit YUKON adapter */ + SK_BOOL GIAsfEnabled; /* ASF subsystem enabled */ + SK_BOOL GIAsfRunning; /* ASF subsystem running */ SK_U16 GILedBlinkCtrl; /* LED Blink Control */ int GIMacsFound; /* Number of MACs found on this adapter */ int GIMacType; /* MAC Type used on this adapter */ - int GIHstClkFact; /* Host Clock Factor (62.5 / HstClk * 100) */ - int GIPortUsage; /* Driver Port Usage */ + int GIChipCap; /* Adapter's Capabilities */ + int GIHstClkFact; /* Host Clock Factor (HstClk / 62.5 * 100) */ int GILevel; /* Initialization Level completed */ int GIRamSize; /* The RAM size of the adapter in kB */ int GIWolOffs; /* WOL Register Offset (HW-Bug in Rev. A) */ SK_U32 GIRamOffs; /* RAM Address Offset for addr calculation */ SK_U32 GIPollTimerVal; /* Descr. Poll Timer Init Val (HstClk ticks) */ SK_U32 GIValIrqMask; /* Value for Interrupt Mask */ + SK_U32 GIValHwIrqMask; /* Value for Interrupt Mask */ SK_U32 GITimeStampCnt; /* Time Stamp High Counter (YUKON only) */ SK_GEPORT GP[SK_MAX_MACS];/* Port Dependent Information */ + SK_HW_FEATURES HwF; /* HW Features struct */ SK_GEMACFUNC GIFunc; /* MAC depedent functions */ } SK_GEINIT; @@ -415,7 +602,7 @@ #define SKERR_HWI_E005 (SKERR_HWI_E004+1) #define SKERR_HWI_E005MSG "SkGeInitPort(): cannot init running ports" #define SKERR_HWI_E006 (SKERR_HWI_E005+1) -#define SKERR_HWI_E006MSG "SkGeMacInit(): PState does not match HW state" +#define SKERR_HWI_E006MSG "SkGeInit() called with illegal Chip Id" #define SKERR_HWI_E007 (SKERR_HWI_E006+1) #define SKERR_HWI_E007MSG "SkXmInitDupMd() called with invalid Dup Mode" #define SKERR_HWI_E008 (SKERR_HWI_E007+1) @@ -431,11 +618,11 @@ #define SKERR_HWI_E013 (SKERR_HWI_E012+1) #define SKERR_HWI_E013MSG "SkGeInitPort(): cfg changed for running queue" #define SKERR_HWI_E014 (SKERR_HWI_E013+1) -#define SKERR_HWI_E014MSG "SkGeInitPort(): unknown GIPortUsage specified" +#define SKERR_HWI_E014MSG "SkGeInitPort(): unknown PortUsage specified" #define SKERR_HWI_E015 (SKERR_HWI_E014+1) -#define SKERR_HWI_E015MSG "Illegal Link mode parameter" +#define SKERR_HWI_E015MSG "Illegal Link Mode parameter" #define SKERR_HWI_E016 (SKERR_HWI_E015+1) -#define SKERR_HWI_E016MSG "Illegal Flow control mode parameter" +#define SKERR_HWI_E016MSG "Illegal Flow Control Mode parameter" #define SKERR_HWI_E017 (SKERR_HWI_E016+1) #define SKERR_HWI_E017MSG "Illegal value specified for GIPollTimerVal" #define SKERR_HWI_E018 (SKERR_HWI_E017+1) @@ -445,9 +632,9 @@ #define SKERR_HWI_E020 (SKERR_HWI_E019+1) #define SKERR_HWI_E020MSG "Illegal Master/Slave parameter" #define SKERR_HWI_E021 (SKERR_HWI_E020+1) -#define SKERR_HWI_E021MSG "MacUpdateStats(): cannot update statistic counter" -#define SKERR_HWI_E022 (SKERR_HWI_E021+1) -#define SKERR_HWI_E022MSG "MacStatistic(): illegal statistic base address" +#define SKERR_HWI_E021MSG "MacUpdateStats(): cannot update statistic counter" +#define SKERR_HWI_E022 (SKERR_HWI_E021+1) +#define SKERR_HWI_E022MSG "MacStatistic(): illegal statistic base address" #define SKERR_HWI_E023 (SKERR_HWI_E022+1) #define SKERR_HWI_E023MSG "SkGeInitPort(): Transmit Queue Size too small" #define SKERR_HWI_E024 (SKERR_HWI_E023+1) @@ -462,6 +649,24 @@ /* * public functions in skgeinit.c */ +extern void SkGePortVlan( + SK_AC *pAC, + SK_IOC IoC, + int Port, + SK_BOOL Enable); + +extern void SkGeRxRss( + SK_AC *pAC, + SK_IOC IoC, + int Port, + SK_BOOL Enable); + +extern void SkGeRxCsum( + SK_AC *pAC, + SK_IOC IoC, + int Port, + SK_BOOL Enable); + extern void SkGePollRxD( SK_AC *pAC, SK_IOC IoC, @@ -526,9 +731,14 @@ extern int SkGeInitAssignRamToQueues( SK_AC *pAC, - int ActivePort, + int Port, SK_BOOL DualNet); +extern int SkYuk2RestartRxBmu( + SK_AC *pAC, + SK_IOC IoC, + int Port); + /* * public functions in skxmac2.c */ @@ -599,13 +809,13 @@ int Port, SK_U16 IStatus); -extern void SkMacSetRxTxEn( +extern void SkMacSetRxTxEn( SK_AC *pAC, SK_IOC IoC, int Port, int Para); -extern int SkMacRxTxEnable( +extern int SkMacRxTxEnable( SK_AC *pAC, SK_IOC IoC, int Port); @@ -622,28 +832,28 @@ int Port, SK_BOOL Enable); -extern void SkXmPhyRead( +extern int SkXmPhyRead( SK_AC *pAC, SK_IOC IoC, int Port, int Addr, SK_U16 SK_FAR *pVal); -extern void SkXmPhyWrite( +extern int SkXmPhyWrite( SK_AC *pAC, SK_IOC IoC, int Port, int Addr, SK_U16 Val); -extern void SkGmPhyRead( +extern int SkGmPhyRead( SK_AC *pAC, SK_IOC IoC, int Port, int Addr, SK_U16 SK_FAR *pVal); -extern void SkGmPhyWrite( +extern int SkGmPhyWrite( SK_AC *pAC, SK_IOC IoC, int Port, @@ -711,7 +921,7 @@ SK_AC *pAC, SK_IOC IoC, unsigned int Port, - SK_U16 IStatus, + SK_U16 IStatus, SK_U64 SK_FAR *pStatus); extern int SkGmOverflowStatus( @@ -727,6 +937,7 @@ int Port, SK_BOOL StartTest); +#ifdef SK_PHY_LP_MODE extern int SkGmEnterLowPowerMode( SK_AC *pAC, SK_IOC IoC, @@ -737,6 +948,7 @@ SK_AC *pAC, SK_IOC IoC, int Port); +#endif /* SK_PHY_LP_MODE */ #ifdef SK_DIAG extern void SkGePhyRead( @@ -792,31 +1004,35 @@ extern void SkGeXmitLED(); extern void SkGeInitRamIface(); extern int SkGeInitAssignRamToQueues(); +extern void SkGePortVlan(); +extern void SkGeRxCsum(); +extern void SkGeRxRss(); +extern int SkYuk2RestartRxBmu(); /* * public functions in skxmac2.c */ -extern void SkMacRxTxDisable(); +extern void SkMacRxTxDisable(); extern void SkMacSoftRst(); extern void SkMacHardRst(); extern void SkMacClearRst(); -extern void SkMacInitPhy(); -extern int SkMacRxTxEnable(); -extern void SkMacPromiscMode(); -extern void SkMacHashing(); -extern void SkMacIrqDisable(); +extern void SkMacInitPhy(); +extern int SkMacRxTxEnable(); +extern void SkMacPromiscMode(); +extern void SkMacHashing(); +extern void SkMacIrqDisable(); extern void SkMacFlushTxFifo(); extern void SkMacFlushRxFifo(); extern void SkMacIrq(); extern int SkMacAutoNegDone(); extern void SkMacAutoNegLipaPhy(); -extern void SkMacSetRxTxEn(); +extern void SkMacSetRxTxEn(); extern void SkXmInitMac(); -extern void SkXmPhyRead(); -extern void SkXmPhyWrite(); +extern int SkXmPhyRead(); +extern int SkXmPhyWrite(); extern void SkGmInitMac(); -extern void SkGmPhyRead(); -extern void SkGmPhyWrite(); +extern int SkGmPhyRead(); +extern int SkGmPhyWrite(); extern void SkXmClrExactAddr(); extern void SkXmInitDupMd(); extern void SkXmInitPauseMd(); @@ -830,8 +1046,10 @@ extern int SkXmOverflowStatus(); extern int SkGmOverflowStatus(); extern int SkGmCableDiagStatus(); +#ifdef SK_PHY_LP_MODE extern int SkGmEnterLowPowerMode(); extern int SkGmLeaveLowPowerMode(); +#endif /* SK_PHY_LP_MODE */ #ifdef SK_DIAG extern void SkGePhyRead(); @@ -842,10 +1060,11 @@ extern void SkXmSendCont(); #endif /* SK_DIAG */ -#endif /* SK_KR_PROTO */ +#endif /* SK_KR_PROTO */ #ifdef __cplusplus } #endif /* __cplusplus */ #endif /* __INC_SKGEINIT_H_ */ + diff -urN linux-2.4.32-600/drivers/net/sk98lin/h/skgepnm2.h linux-2.4.32-600-sk98_831/drivers/net/sk98lin/h/skgepnm2.h --- linux-2.4.32-600/drivers/net/sk98lin/h/skgepnm2.h Sat Mar 20 10:08:19 2004 +++ linux-2.4.32-600-sk98_831/drivers/net/sk98lin/h/skgepnm2.h Sun Feb 26 11:13:02 2006 @@ -1,332 +1,339 @@ -/***************************************************************************** - * - * Name: skgepnm2.h - * Project: GEnesis, PCI Gigabit Ethernet Adapter - * Purpose: Defines for Private Network Management Interface - * - ****************************************************************************/ - -/****************************************************************************** - * - * (C)Copyright 1998-2002 SysKonnect GmbH. - * (C)Copyright 2002-2003 Marvell. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * The information in this file is provided "AS IS" without warranty. - * - ******************************************************************************/ - -#ifndef _SKGEPNM2_H_ -#define _SKGEPNM2_H_ - -/* - * General definitions - */ -#define SK_PNMI_CHIPSET_XMAC 1 /* XMAC11800FP */ -#define SK_PNMI_CHIPSET_YUKON 2 /* YUKON */ - -#define SK_PNMI_BUS_PCI 1 /* PCI bus*/ - -/* - * Actions - */ -#define SK_PNMI_ACT_IDLE 1 -#define SK_PNMI_ACT_RESET 2 -#define SK_PNMI_ACT_SELFTEST 3 -#define SK_PNMI_ACT_RESETCNT 4 - -/* - * VPD releated defines - */ - -#define SK_PNMI_VPD_RW 1 -#define SK_PNMI_VPD_RO 2 - -#define SK_PNMI_VPD_OK 0 -#define SK_PNMI_VPD_NOTFOUND 1 -#define SK_PNMI_VPD_CUT 2 -#define SK_PNMI_VPD_TIMEOUT 3 -#define SK_PNMI_VPD_FULL 4 -#define SK_PNMI_VPD_NOWRITE 5 -#define SK_PNMI_VPD_FATAL 6 - -#define SK_PNMI_VPD_IGNORE 0 -#define SK_PNMI_VPD_CREATE 1 -#define SK_PNMI_VPD_DELETE 2 - - -/* - * RLMT related defines - */ -#define SK_PNMI_DEF_RLMT_CHG_THRES 240 /* 4 changes per minute */ - - -/* - * VCT internal status values - */ -#define SK_PNMI_VCT_PENDING 32 -#define SK_PNMI_VCT_TEST_DONE 64 -#define SK_PNMI_VCT_LINK 128 - -/* - * Internal table definitions - */ -#define SK_PNMI_GET 0 -#define SK_PNMI_PRESET 1 -#define SK_PNMI_SET 2 - -#define SK_PNMI_RO 0 -#define SK_PNMI_RW 1 -#define SK_PNMI_WO 2 - -typedef struct s_OidTabEntry { - SK_U32 Id; - SK_U32 InstanceNo; - unsigned int StructSize; - unsigned int Offset; - int Access; - int (* Func)(SK_AC *pAc, SK_IOC pIo, int action, - SK_U32 Id, char* pBuf, unsigned int* pLen, - SK_U32 Instance, unsigned int TableIndex, - SK_U32 NetNumber); - SK_U16 Param; -} SK_PNMI_TAB_ENTRY; - - -/* - * Trap lengths - */ -#define SK_PNMI_TRAP_SIMPLE_LEN 17 -#define SK_PNMI_TRAP_SENSOR_LEN_BASE 46 -#define SK_PNMI_TRAP_RLMT_CHANGE_LEN 23 -#define SK_PNMI_TRAP_RLMT_PORT_LEN 23 - -/* - * Number of MAC types supported - */ -#define SK_PNMI_MAC_TYPES (SK_MAC_GMAC + 1) - -/* - * MAC statistic data list (overall set for MAC types used) - */ -enum SK_MACSTATS { - SK_PNMI_HTX = 0, - SK_PNMI_HTX_OCTET, - SK_PNMI_HTX_OCTETHIGH = SK_PNMI_HTX_OCTET, - SK_PNMI_HTX_OCTETLOW, - SK_PNMI_HTX_BROADCAST, - SK_PNMI_HTX_MULTICAST, - SK_PNMI_HTX_UNICAST, - SK_PNMI_HTX_BURST, - SK_PNMI_HTX_PMACC, - SK_PNMI_HTX_MACC, - SK_PNMI_HTX_COL, - SK_PNMI_HTX_SINGLE_COL, - SK_PNMI_HTX_MULTI_COL, - SK_PNMI_HTX_EXCESS_COL, - SK_PNMI_HTX_LATE_COL, - SK_PNMI_HTX_DEFFERAL, - SK_PNMI_HTX_EXCESS_DEF, - SK_PNMI_HTX_UNDERRUN, - SK_PNMI_HTX_CARRIER, - SK_PNMI_HTX_UTILUNDER, - SK_PNMI_HTX_UTILOVER, - SK_PNMI_HTX_64, - SK_PNMI_HTX_127, - SK_PNMI_HTX_255, - SK_PNMI_HTX_511, - SK_PNMI_HTX_1023, - SK_PNMI_HTX_MAX, - SK_PNMI_HTX_LONGFRAMES, - SK_PNMI_HTX_SYNC, - SK_PNMI_HTX_SYNC_OCTET, - SK_PNMI_HTX_RESERVED, - - SK_PNMI_HRX, - SK_PNMI_HRX_OCTET, - SK_PNMI_HRX_OCTETHIGH = SK_PNMI_HRX_OCTET, - SK_PNMI_HRX_OCTETLOW, - SK_PNMI_HRX_BADOCTET, - SK_PNMI_HRX_BADOCTETHIGH = SK_PNMI_HRX_BADOCTET, - SK_PNMI_HRX_BADOCTETLOW, - SK_PNMI_HRX_BROADCAST, - SK_PNMI_HRX_MULTICAST, - SK_PNMI_HRX_UNICAST, - SK_PNMI_HRX_PMACC, - SK_PNMI_HRX_MACC, - SK_PNMI_HRX_PMACC_ERR, - SK_PNMI_HRX_MACC_UNKWN, - SK_PNMI_HRX_BURST, - SK_PNMI_HRX_MISSED, - SK_PNMI_HRX_FRAMING, - SK_PNMI_HRX_UNDERSIZE, - SK_PNMI_HRX_OVERFLOW, - SK_PNMI_HRX_JABBER, - SK_PNMI_HRX_CARRIER, - SK_PNMI_HRX_IRLENGTH, - SK_PNMI_HRX_SYMBOL, - SK_PNMI_HRX_SHORTS, - SK_PNMI_HRX_RUNT, - SK_PNMI_HRX_TOO_LONG, - SK_PNMI_HRX_FCS, - SK_PNMI_HRX_CEXT, - SK_PNMI_HRX_UTILUNDER, - SK_PNMI_HRX_UTILOVER, - SK_PNMI_HRX_64, - SK_PNMI_HRX_127, - SK_PNMI_HRX_255, - SK_PNMI_HRX_511, - SK_PNMI_HRX_1023, - SK_PNMI_HRX_MAX, - SK_PNMI_HRX_LONGFRAMES, - - SK_PNMI_HRX_RESERVED, - - SK_PNMI_MAX_IDX /* NOTE: Ensure SK_PNMI_CNT_NO is set to this value */ -}; - -/* - * MAC specific data - */ -typedef struct s_PnmiStatAddr { - SK_U16 Reg; /* MAC register containing the value */ - SK_BOOL GetOffset; /* TRUE: Offset managed by PNMI (call GetStatVal())*/ -} SK_PNMI_STATADDR; - - -/* - * SK_PNMI_STRUCT_DATA copy offset evaluation macros - */ -#define SK_PNMI_OFF(e) ((SK_U32)(SK_UPTR)&(((SK_PNMI_STRUCT_DATA *)0)->e)) -#define SK_PNMI_MAI_OFF(e) ((SK_U32)(SK_UPTR)&(((SK_PNMI_STRUCT_DATA *)0)->e)) -#define SK_PNMI_VPD_OFF(e) ((SK_U32)(SK_UPTR)&(((SK_PNMI_VPD *)0)->e)) -#define SK_PNMI_SEN_OFF(e) ((SK_U32)(SK_UPTR)&(((SK_PNMI_SENSOR *)0)->e)) -#define SK_PNMI_CHK_OFF(e) ((SK_U32)(SK_UPTR)&(((SK_PNMI_CHECKSUM *)0)->e)) -#define SK_PNMI_STA_OFF(e) ((SK_U32)(SK_UPTR)&(((SK_PNMI_STAT *)0)->e)) -#define SK_PNMI_CNF_OFF(e) ((SK_U32)(SK_UPTR)&(((SK_PNMI_CONF *)0)->e)) -#define SK_PNMI_RLM_OFF(e) ((SK_U32)(SK_UPTR)&(((SK_PNMI_RLMT *)0)->e)) -#define SK_PNMI_MON_OFF(e) ((SK_U32)(SK_UPTR)&(((SK_PNMI_RLMT_MONITOR *)0)->e)) -#define SK_PNMI_TRP_OFF(e) ((SK_U32)(SK_UPTR)&(((SK_PNMI_TRAP *)0)->e)) - -#define SK_PNMI_SET_STAT(b,s,o) {SK_U32 Val32; char *pVal; \ - Val32 = (s); \ - pVal = (char *)(b) + ((SK_U32)(SK_UPTR) \ - &(((SK_PNMI_STRUCT_DATA *)0)-> \ - ReturnStatus.ErrorStatus)); \ - SK_PNMI_STORE_U32(pVal, Val32); \ - Val32 = (o); \ - pVal = (char *)(b) + ((SK_U32)(SK_UPTR) \ - &(((SK_PNMI_STRUCT_DATA *)0)-> \ - ReturnStatus.ErrorOffset)); \ - SK_PNMI_STORE_U32(pVal, Val32);} - -/* - * Time macros - */ -#ifndef SK_PNMI_HUNDREDS_SEC -#if SK_TICKS_PER_SEC == 100 -#define SK_PNMI_HUNDREDS_SEC(t) (t) -#else -#define SK_PNMI_HUNDREDS_SEC(t) (((t) * 100) / (SK_TICKS_PER_SEC)) -#endif /* !SK_TICKS_PER_SEC */ -#endif /* !SK_PNMI_HUNDREDS_SEC */ - -/* - * Macros to work around alignment problems - */ -#ifndef SK_PNMI_STORE_U16 -#define SK_PNMI_STORE_U16(p,v) {*(char *)(p) = *((char *)&(v)); \ - *((char *)(p) + 1) = \ - *(((char *)&(v)) + 1);} -#endif - -#ifndef SK_PNMI_STORE_U32 -#define SK_PNMI_STORE_U32(p,v) {*(char *)(p) = *((char *)&(v)); \ - *((char *)(p) + 1) = \ - *(((char *)&(v)) + 1); \ - *((char *)(p) + 2) = \ - *(((char *)&(v)) + 2); \ - *((char *)(p) + 3) = \ - *(((char *)&(v)) + 3);} -#endif - -#ifndef SK_PNMI_STORE_U64 -#define SK_PNMI_STORE_U64(p,v) {*(char *)(p) = *((char *)&(v)); \ - *((char *)(p) + 1) = \ - *(((char *)&(v)) + 1); \ - *((char *)(p) + 2) = \ - *(((char *)&(v)) + 2); \ - *((char *)(p) + 3) = \ - *(((char *)&(v)) + 3); \ - *((char *)(p) + 4) = \ - *(((char *)&(v)) + 4); \ - *((char *)(p) + 5) = \ - *(((char *)&(v)) + 5); \ - *((char *)(p) + 6) = \ - *(((char *)&(v)) + 6); \ - *((char *)(p) + 7) = \ - *(((char *)&(v)) + 7);} -#endif - -#ifndef SK_PNMI_READ_U16 -#define SK_PNMI_READ_U16(p,v) {*((char *)&(v)) = *(char *)(p); \ - *(((char *)&(v)) + 1) = \ - *((char *)(p) + 1);} -#endif - -#ifndef SK_PNMI_READ_U32 -#define SK_PNMI_READ_U32(p,v) {*((char *)&(v)) = *(char *)(p); \ - *(((char *)&(v)) + 1) = \ - *((char *)(p) + 1); \ - *(((char *)&(v)) + 2) = \ - *((char *)(p) + 2); \ - *(((char *)&(v)) + 3) = \ - *((char *)(p) + 3);} -#endif - -#ifndef SK_PNMI_READ_U64 -#define SK_PNMI_READ_U64(p,v) {*((char *)&(v)) = *(char *)(p); \ - *(((char *)&(v)) + 1) = \ - *((char *)(p) + 1); \ - *(((char *)&(v)) + 2) = \ - *((char *)(p) + 2); \ - *(((char *)&(v)) + 3) = \ - *((char *)(p) + 3); \ - *(((char *)&(v)) + 4) = \ - *((char *)(p) + 4); \ - *(((char *)&(v)) + 5) = \ - *((char *)(p) + 5); \ - *(((char *)&(v)) + 6) = \ - *((char *)(p) + 6); \ - *(((char *)&(v)) + 7) = \ - *((char *)(p) + 7);} -#endif - -/* - * Macros for Debug - */ -#ifdef DEBUG - -#define SK_PNMI_CHECKFLAGS(vSt) {if (pAC->Pnmi.MacUpdatedFlag > 0 || \ - pAC->Pnmi.RlmtUpdatedFlag > 0 || \ - pAC->Pnmi.SirqUpdatedFlag > 0) { \ - SK_DBG_MSG(pAC, \ - SK_DBGMOD_PNMI, \ - SK_DBGCAT_CTRL, \ - ("PNMI: ERR: %s MacUFlag=%d, RlmtUFlag=%d, SirqUFlag=%d\n", \ - vSt, \ - pAC->Pnmi.MacUpdatedFlag, \ - pAC->Pnmi.RlmtUpdatedFlag, \ - pAC->Pnmi.SirqUpdatedFlag))}} - -#else /* !DEBUG */ - -#define SK_PNMI_CHECKFLAGS(vSt) /* Nothing */ - -#endif /* !DEBUG */ - -#endif /* _SKGEPNM2_H_ */ +/***************************************************************************** + * + * Name: skgepnm2.h + * Project: GEnesis, PCI Gigabit Ethernet Adapter + * Version: $Revision: 2.4 $ + * Date: $Date: 2005/05/03 06:42:43 $ + * Purpose: Defines for Private Network Management Interface + * + ****************************************************************************/ + +/****************************************************************************** + * + * (C)Copyright 1998-2002 SysKonnect GmbH. + * (C)Copyright 2002-2003 Marvell. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * The information in this file is provided "AS IS" without warranty. + * + ******************************************************************************/ + +#ifndef _SKGEPNM2_H_ +#define _SKGEPNM2_H_ + +/* + * General definitions + */ +#define SK_PNMI_CHIPSET_XMAC 1 /* XMAC11800FP */ +#define SK_PNMI_CHIPSET_YUKON 2 /* YUKON */ +#define SK_PNMI_CHIPSET_YUKON_LITE 3 /* YUKON-Lite (Rev. A1-A3) */ +#define SK_PNMI_CHIPSET_YUKON_LP 4 /* YUKON-LP */ +#define SK_PNMI_CHIPSET_YUKON_XL 5 /* YUKON-2 XL */ +#define SK_PNMI_CHIPSET_YUKON_EC 6 /* YUKON-2 EC */ +#define SK_PNMI_CHIPSET_YUKON_FE 7 /* YUKON-2 FE */ + +#define SK_PNMI_BUS_PCI 1 /* PCI bus*/ + +/* + * Actions + */ +#define SK_PNMI_ACT_IDLE 1 +#define SK_PNMI_ACT_RESET 2 +#define SK_PNMI_ACT_SELFTEST 3 +#define SK_PNMI_ACT_RESETCNT 4 + +/* + * VPD releated defines + */ + +#define SK_PNMI_VPD_RW 1 +#define SK_PNMI_VPD_RO 2 + +#define SK_PNMI_VPD_OK 0 +#define SK_PNMI_VPD_NOTFOUND 1 +#define SK_PNMI_VPD_CUT 2 +#define SK_PNMI_VPD_TIMEOUT 3 +#define SK_PNMI_VPD_FULL 4 +#define SK_PNMI_VPD_NOWRITE 5 +#define SK_PNMI_VPD_FATAL 6 + +#define SK_PNMI_VPD_IGNORE 0 +#define SK_PNMI_VPD_CREATE 1 +#define SK_PNMI_VPD_DELETE 2 + + +/* + * RLMT related defines + */ +#define SK_PNMI_DEF_RLMT_CHG_THRES 240 /* 4 changes per minute */ + + +/* + * VCT internal status values + */ +#define SK_PNMI_VCT_PENDING 0x20 +#define SK_PNMI_VCT_TEST_DONE 0x40 +#define SK_PNMI_VCT_LINK 0x80 + +/* + * Internal table definitions + */ +#define SK_PNMI_GET 0 +#define SK_PNMI_PRESET 1 +#define SK_PNMI_SET 2 + +#define SK_PNMI_RO 0 +#define SK_PNMI_RW 1 +#define SK_PNMI_WO 2 + +typedef struct s_OidTabEntry { + SK_U32 Id; + SK_U32 InstanceNo; + unsigned int StructSize; + unsigned int Offset; + int Access; + int (* Func)(SK_AC *pAc, SK_IOC pIo, int action, + SK_U32 Id, char* pBuf, unsigned int* pLen, + SK_U32 Instance, unsigned int TableIndex, + SK_U32 NetNumber); + SK_U16 Param; +} SK_PNMI_TAB_ENTRY; + + +/* + * Trap lengths + */ +#define SK_PNMI_TRAP_SIMPLE_LEN 17 +#define SK_PNMI_TRAP_SENSOR_LEN_BASE 46 +#define SK_PNMI_TRAP_RLMT_CHANGE_LEN 23 +#define SK_PNMI_TRAP_RLMT_PORT_LEN 23 + +/* + * Number of MAC types supported + */ +#define SK_PNMI_MAC_TYPES (SK_MAC_GMAC + 1) + +/* + * MAC statistic data list (overall set for MAC types used) + */ +enum SK_MACSTATS { + SK_PNMI_HTX = 0, + SK_PNMI_HTX_OCTET, + SK_PNMI_HTX_OCTETHIGH = SK_PNMI_HTX_OCTET, + SK_PNMI_HTX_OCTETLOW, + SK_PNMI_HTX_BROADCAST, + SK_PNMI_HTX_MULTICAST, + SK_PNMI_HTX_UNICAST, + SK_PNMI_HTX_BURST, + SK_PNMI_HTX_PMACC, + SK_PNMI_HTX_MACC, + SK_PNMI_HTX_COL, + SK_PNMI_HTX_SINGLE_COL, + SK_PNMI_HTX_MULTI_COL, + SK_PNMI_HTX_EXCESS_COL, + SK_PNMI_HTX_LATE_COL, + SK_PNMI_HTX_DEFFERAL, + SK_PNMI_HTX_EXCESS_DEF, + SK_PNMI_HTX_UNDERRUN, + SK_PNMI_HTX_CARRIER, + SK_PNMI_HTX_UTILUNDER, + SK_PNMI_HTX_UTILOVER, + SK_PNMI_HTX_64, + SK_PNMI_HTX_127, + SK_PNMI_HTX_255, + SK_PNMI_HTX_511, + SK_PNMI_HTX_1023, + SK_PNMI_HTX_MAX, + SK_PNMI_HTX_LONGFRAMES, + SK_PNMI_HTX_SYNC, + SK_PNMI_HTX_SYNC_OCTET, + SK_PNMI_HTX_RESERVED, + + SK_PNMI_HRX, + SK_PNMI_HRX_OCTET, + SK_PNMI_HRX_OCTETHIGH = SK_PNMI_HRX_OCTET, + SK_PNMI_HRX_OCTETLOW, + SK_PNMI_HRX_BADOCTET, + SK_PNMI_HRX_BADOCTETHIGH = SK_PNMI_HRX_BADOCTET, + SK_PNMI_HRX_BADOCTETLOW, + SK_PNMI_HRX_BROADCAST, + SK_PNMI_HRX_MULTICAST, + SK_PNMI_HRX_UNICAST, + SK_PNMI_HRX_PMACC, + SK_PNMI_HRX_MACC, + SK_PNMI_HRX_PMACC_ERR, + SK_PNMI_HRX_MACC_UNKWN, + SK_PNMI_HRX_BURST, + SK_PNMI_HRX_MISSED, + SK_PNMI_HRX_FRAMING, + SK_PNMI_HRX_UNDERSIZE, + SK_PNMI_HRX_OVERFLOW, + SK_PNMI_HRX_JABBER, + SK_PNMI_HRX_CARRIER, + SK_PNMI_HRX_IRLENGTH, + SK_PNMI_HRX_SYMBOL, + SK_PNMI_HRX_SHORTS, + SK_PNMI_HRX_RUNT, + SK_PNMI_HRX_TOO_LONG, + SK_PNMI_HRX_FCS, + SK_PNMI_HRX_CEXT, + SK_PNMI_HRX_UTILUNDER, + SK_PNMI_HRX_UTILOVER, + SK_PNMI_HRX_64, + SK_PNMI_HRX_127, + SK_PNMI_HRX_255, + SK_PNMI_HRX_511, + SK_PNMI_HRX_1023, + SK_PNMI_HRX_MAX, + SK_PNMI_HRX_LONGFRAMES, + + SK_PNMI_HRX_RESERVED, + + SK_PNMI_MAX_IDX /* NOTE: Ensure SK_PNMI_CNT_NO is set to this value */ +}; + +/* + * MAC specific data + */ +typedef struct s_PnmiStatAddr { + SK_U16 Reg; /* MAC register containing the value */ + SK_BOOL GetOffset; /* TRUE: Offset managed by PNMI (call GetStatVal())*/ +} SK_PNMI_STATADDR; + + +/* + * SK_PNMI_STRUCT_DATA copy offset evaluation macros + */ +#define SK_PNMI_OFF(e) ((SK_U32)(SK_UPTR)&(((SK_PNMI_STRUCT_DATA *)0)->e)) +#define SK_PNMI_MAI_OFF(e) ((SK_U32)(SK_UPTR)&(((SK_PNMI_STRUCT_DATA *)0)->e)) +#define SK_PNMI_VPD_OFF(e) ((SK_U32)(SK_UPTR)&(((SK_PNMI_VPD *)0)->e)) +#define SK_PNMI_SEN_OFF(e) ((SK_U32)(SK_UPTR)&(((SK_PNMI_SENSOR *)0)->e)) +#define SK_PNMI_CHK_OFF(e) ((SK_U32)(SK_UPTR)&(((SK_PNMI_CHECKSUM *)0)->e)) +#define SK_PNMI_STA_OFF(e) ((SK_U32)(SK_UPTR)&(((SK_PNMI_STAT *)0)->e)) +#define SK_PNMI_CNF_OFF(e) ((SK_U32)(SK_UPTR)&(((SK_PNMI_CONF *)0)->e)) +#define SK_PNMI_RLM_OFF(e) ((SK_U32)(SK_UPTR)&(((SK_PNMI_RLMT *)0)->e)) +#define SK_PNMI_MON_OFF(e) ((SK_U32)(SK_UPTR)&(((SK_PNMI_RLMT_MONITOR *)0)->e)) +#define SK_PNMI_TRP_OFF(e) ((SK_U32)(SK_UPTR)&(((SK_PNMI_TRAP *)0)->e)) + +#define SK_PNMI_SET_STAT(b,s,o) {SK_U32 Val32; char *pVal; \ + Val32 = (s); \ + pVal = (char *)(b) + ((SK_U32)(SK_UPTR) \ + &(((SK_PNMI_STRUCT_DATA *)0)-> \ + ReturnStatus.ErrorStatus)); \ + SK_PNMI_STORE_U32(pVal, Val32); \ + Val32 = (o); \ + pVal = (char *)(b) + ((SK_U32)(SK_UPTR) \ + &(((SK_PNMI_STRUCT_DATA *)0)-> \ + ReturnStatus.ErrorOffset)); \ + SK_PNMI_STORE_U32(pVal, Val32);} + +/* + * Time macros + */ +#ifndef SK_PNMI_HUNDREDS_SEC +#if SK_TICKS_PER_SEC == 100 +#define SK_PNMI_HUNDREDS_SEC(t) (t) +#else +#define SK_PNMI_HUNDREDS_SEC(t) (((t) * 100) / (SK_TICKS_PER_SEC)) +#endif /* !SK_TICKS_PER_SEC */ +#endif /* !SK_PNMI_HUNDREDS_SEC */ + +/* + * Macros to work around alignment problems + */ +#ifndef SK_PNMI_STORE_U16 +#define SK_PNMI_STORE_U16(p,v) {*(char *)(p) = *((char *)&(v)); \ + *((char *)(p) + 1) = \ + *(((char *)&(v)) + 1);} +#endif + +#ifndef SK_PNMI_STORE_U32 +#define SK_PNMI_STORE_U32(p,v) {*(char *)(p) = *((char *)&(v)); \ + *((char *)(p) + 1) = \ + *(((char *)&(v)) + 1); \ + *((char *)(p) + 2) = \ + *(((char *)&(v)) + 2); \ + *((char *)(p) + 3) = \ + *(((char *)&(v)) + 3);} +#endif + +#ifndef SK_PNMI_STORE_U64 +#define SK_PNMI_STORE_U64(p,v) {*(char *)(p) = *((char *)&(v)); \ + *((char *)(p) + 1) = \ + *(((char *)&(v)) + 1); \ + *((char *)(p) + 2) = \ + *(((char *)&(v)) + 2); \ + *((char *)(p) + 3) = \ + *(((char *)&(v)) + 3); \ + *((char *)(p) + 4) = \ + *(((char *)&(v)) + 4); \ + *((char *)(p) + 5) = \ + *(((char *)&(v)) + 5); \ + *((char *)(p) + 6) = \ + *(((char *)&(v)) + 6); \ + *((char *)(p) + 7) = \ + *(((char *)&(v)) + 7);} +#endif + +#ifndef SK_PNMI_READ_U16 +#define SK_PNMI_READ_U16(p,v) {*((char *)&(v)) = *(char *)(p); \ + *(((char *)&(v)) + 1) = \ + *((char *)(p) + 1);} +#endif + +#ifndef SK_PNMI_READ_U32 +#define SK_PNMI_READ_U32(p,v) {*((char *)&(v)) = *(char *)(p); \ + *(((char *)&(v)) + 1) = \ + *((char *)(p) + 1); \ + *(((char *)&(v)) + 2) = \ + *((char *)(p) + 2); \ + *(((char *)&(v)) + 3) = \ + *((char *)(p) + 3);} +#endif + +#ifndef SK_PNMI_READ_U64 +#define SK_PNMI_READ_U64(p,v) {*((char *)&(v)) = *(char *)(p); \ + *(((char *)&(v)) + 1) = \ + *((char *)(p) + 1); \ + *(((char *)&(v)) + 2) = \ + *((char *)(p) + 2); \ + *(((char *)&(v)) + 3) = \ + *((char *)(p) + 3); \ + *(((char *)&(v)) + 4) = \ + *((char *)(p) + 4); \ + *(((char *)&(v)) + 5) = \ + *((char *)(p) + 5); \ + *(((char *)&(v)) + 6) = \ + *((char *)(p) + 6); \ + *(((char *)&(v)) + 7) = \ + *((char *)(p) + 7);} +#endif + +/* + * Macros for Debug + */ +#ifdef DEBUG + +#define SK_PNMI_CHECKFLAGS(vSt) {if (pAC->Pnmi.MacUpdatedFlag > 0 || \ + pAC->Pnmi.RlmtUpdatedFlag > 0 || \ + pAC->Pnmi.SirqUpdatedFlag > 0) { \ + SK_DBG_MSG(pAC, \ + SK_DBGMOD_PNMI, \ + SK_DBGCAT_CTRL, \ + ("PNMI: ERR: %s MacUFlag=%d, RlmtUFlag=%d, SirqUFlag=%d\n", \ + vSt, \ + pAC->Pnmi.MacUpdatedFlag, \ + pAC->Pnmi.RlmtUpdatedFlag, \ + pAC->Pnmi.SirqUpdatedFlag));}} + +#else /* !DEBUG */ + +#define SK_PNMI_CHECKFLAGS(vSt) /* Nothing */ + +#endif /* !DEBUG */ + +#endif /* _SKGEPNM2_H_ */ diff -urN linux-2.4.32-600/drivers/net/sk98lin/h/skgepnmi.h linux-2.4.32-600-sk98_831/drivers/net/sk98lin/h/skgepnmi.h --- linux-2.4.32-600/drivers/net/sk98lin/h/skgepnmi.h Sat Mar 20 10:08:19 2004 +++ linux-2.4.32-600-sk98_831/drivers/net/sk98lin/h/skgepnmi.h Sun Feb 26 11:13:02 2006 @@ -1,964 +1,1019 @@ -/***************************************************************************** - * - * Name: skgepnmi.h - * Project: GEnesis, PCI Gigabit Ethernet Adapter - * Purpose: Defines for Private Network Management Interface - * - ****************************************************************************/ - -/****************************************************************************** - * - * (C)Copyright 1998-2002 SysKonnect GmbH. - * (C)Copyright 2002-2003 Marvell. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * The information in this file is provided "AS IS" without warranty. - * - ******************************************************************************/ - -#ifndef _SKGEPNMI_H_ -#define _SKGEPNMI_H_ - -/* - * Include dependencies - */ -#include "h/sktypes.h" -#include "h/skerror.h" -#include "h/sktimer.h" -#include "h/ski2c.h" -#include "h/skaddr.h" -#include "h/skrlmt.h" -#include "h/skvpd.h" - -/* - * Management Database Version - */ -#define SK_PNMI_MDB_VERSION 0x00030001 /* 3.1 */ - - -/* - * Event definitions - */ -#define SK_PNMI_EVT_SIRQ_OVERFLOW 1 /* Counter overflow */ -#define SK_PNMI_EVT_SEN_WAR_LOW 2 /* Lower war thres exceeded */ -#define SK_PNMI_EVT_SEN_WAR_UPP 3 /* Upper war thres exceeded */ -#define SK_PNMI_EVT_SEN_ERR_LOW 4 /* Lower err thres exceeded */ -#define SK_PNMI_EVT_SEN_ERR_UPP 5 /* Upper err thres exceeded */ -#define SK_PNMI_EVT_CHG_EST_TIMER 6 /* Timer event for RLMT Chg */ -#define SK_PNMI_EVT_UTILIZATION_TIMER 7 /* Timer event for Utiliza. */ -#define SK_PNMI_EVT_CLEAR_COUNTER 8 /* Clear statistic counters */ -#define SK_PNMI_EVT_XMAC_RESET 9 /* XMAC will be reset */ - -#define SK_PNMI_EVT_RLMT_PORT_UP 10 /* Port came logically up */ -#define SK_PNMI_EVT_RLMT_PORT_DOWN 11 /* Port went logically down */ -#define SK_PNMI_EVT_RLMT_SEGMENTATION 13 /* Two SP root bridges found */ -#define SK_PNMI_EVT_RLMT_ACTIVE_DOWN 14 /* Port went logically down */ -#define SK_PNMI_EVT_RLMT_ACTIVE_UP 15 /* Port came logically up */ -#define SK_PNMI_EVT_RLMT_SET_NETS 16 /* 1. Parameter is number of nets - 1 = single net; 2 = dual net */ -#define SK_PNMI_EVT_VCT_RESET 17 /* VCT port reset timer event started with SET. */ - - -/* - * Return values - */ -#define SK_PNMI_ERR_OK 0 -#define SK_PNMI_ERR_GENERAL 1 -#define SK_PNMI_ERR_TOO_SHORT 2 -#define SK_PNMI_ERR_BAD_VALUE 3 -#define SK_PNMI_ERR_READ_ONLY 4 -#define SK_PNMI_ERR_UNKNOWN_OID 5 -#define SK_PNMI_ERR_UNKNOWN_INST 6 -#define SK_PNMI_ERR_UNKNOWN_NET 7 -#define SK_PNMI_ERR_NOT_SUPPORTED 10 - - -/* - * Return values of driver reset function SK_DRIVER_RESET() and - * driver event function SK_DRIVER_EVENT() - */ -#define SK_PNMI_ERR_OK 0 -#define SK_PNMI_ERR_FAIL 1 - - -/* - * Return values of driver test function SK_DRIVER_SELFTEST() - */ -#define SK_PNMI_TST_UNKNOWN (1 << 0) -#define SK_PNMI_TST_TRANCEIVER (1 << 1) -#define SK_PNMI_TST_ASIC (1 << 2) -#define SK_PNMI_TST_SENSOR (1 << 3) -#define SK_PNMI_TST_POWERMGMT (1 << 4) -#define SK_PNMI_TST_PCI (1 << 5) -#define SK_PNMI_TST_MAC (1 << 6) - - -/* - * RLMT specific definitions - */ -#define SK_PNMI_RLMT_STATUS_STANDBY 1 -#define SK_PNMI_RLMT_STATUS_ACTIVE 2 -#define SK_PNMI_RLMT_STATUS_ERROR 3 - -#define SK_PNMI_RLMT_LSTAT_PHY_DOWN 1 -#define SK_PNMI_RLMT_LSTAT_AUTONEG 2 -#define SK_PNMI_RLMT_LSTAT_LOG_DOWN 3 -#define SK_PNMI_RLMT_LSTAT_LOG_UP 4 -#define SK_PNMI_RLMT_LSTAT_INDETERMINATED 5 - -#define SK_PNMI_RLMT_MODE_CHK_LINK (SK_RLMT_CHECK_LINK) -#define SK_PNMI_RLMT_MODE_CHK_RX (SK_RLMT_CHECK_LOC_LINK) -#define SK_PNMI_RLMT_MODE_CHK_SPT (SK_RLMT_CHECK_SEG) -/* #define SK_PNMI_RLMT_MODE_CHK_EX */ - -/* - * OID definition - */ -#ifndef _NDIS_ /* Check, whether NDIS already included OIDs */ - -#define OID_GEN_XMIT_OK 0x00020101 -#define OID_GEN_RCV_OK 0x00020102 -#define OID_GEN_XMIT_ERROR 0x00020103 -#define OID_GEN_RCV_ERROR 0x00020104 -#define OID_GEN_RCV_NO_BUFFER 0x00020105 - -/* #define OID_GEN_DIRECTED_BYTES_XMIT 0x00020201 */ -#define OID_GEN_DIRECTED_FRAMES_XMIT 0x00020202 -/* #define OID_GEN_MULTICAST_BYTES_XMIT 0x00020203 */ -#define OID_GEN_MULTICAST_FRAMES_XMIT 0x00020204 -/* #define OID_GEN_BROADCAST_BYTES_XMIT 0x00020205 */ -#define OID_GEN_BROADCAST_FRAMES_XMIT 0x00020206 -/* #define OID_GEN_DIRECTED_BYTES_RCV 0x00020207 */ -#define OID_GEN_DIRECTED_FRAMES_RCV 0x00020208 -/* #define OID_GEN_MULTICAST_BYTES_RCV 0x00020209 */ -#define OID_GEN_MULTICAST_FRAMES_RCV 0x0002020A -/* #define OID_GEN_BROADCAST_BYTES_RCV 0x0002020B */ -#define OID_GEN_BROADCAST_FRAMES_RCV 0x0002020C -#define OID_GEN_RCV_CRC_ERROR 0x0002020D -#define OID_GEN_TRANSMIT_QUEUE_LENGTH 0x0002020E - -#define OID_802_3_PERMANENT_ADDRESS 0x01010101 -#define OID_802_3_CURRENT_ADDRESS 0x01010102 -/* #define OID_802_3_MULTICAST_LIST 0x01010103 */ -/* #define OID_802_3_MAXIMUM_LIST_SIZE 0x01010104 */ -/* #define OID_802_3_MAC_OPTIONS 0x01010105 */ - -#define OID_802_3_RCV_ERROR_ALIGNMENT 0x01020101 -#define OID_802_3_XMIT_ONE_COLLISION 0x01020102 -#define OID_802_3_XMIT_MORE_COLLISIONS 0x01020103 -#define OID_802_3_XMIT_DEFERRED 0x01020201 -#define OID_802_3_XMIT_MAX_COLLISIONS 0x01020202 -#define OID_802_3_RCV_OVERRUN 0x01020203 -#define OID_802_3_XMIT_UNDERRUN 0x01020204 -#define OID_802_3_XMIT_TIMES_CRS_LOST 0x01020206 -#define OID_802_3_XMIT_LATE_COLLISIONS 0x01020207 - -/* - * PnP and PM OIDs - */ -#ifdef SK_POWER_MGMT -#define OID_PNP_CAPABILITIES 0xFD010100 -#define OID_PNP_SET_POWER 0xFD010101 -#define OID_PNP_QUERY_POWER 0xFD010102 -#define OID_PNP_ADD_WAKE_UP_PATTERN 0xFD010103 -#define OID_PNP_REMOVE_WAKE_UP_PATTERN 0xFD010104 -#define OID_PNP_ENABLE_WAKE_UP 0xFD010106 -#endif /* SK_POWER_MGMT */ - -#endif /* _NDIS_ */ - -#define OID_SKGE_MDB_VERSION 0xFF010100 -#define OID_SKGE_SUPPORTED_LIST 0xFF010101 -#define OID_SKGE_VPD_FREE_BYTES 0xFF010102 -#define OID_SKGE_VPD_ENTRIES_LIST 0xFF010103 -#define OID_SKGE_VPD_ENTRIES_NUMBER 0xFF010104 -#define OID_SKGE_VPD_KEY 0xFF010105 -#define OID_SKGE_VPD_VALUE 0xFF010106 -#define OID_SKGE_VPD_ACCESS 0xFF010107 -#define OID_SKGE_VPD_ACTION 0xFF010108 - -#define OID_SKGE_PORT_NUMBER 0xFF010110 -#define OID_SKGE_DEVICE_TYPE 0xFF010111 -#define OID_SKGE_DRIVER_DESCR 0xFF010112 -#define OID_SKGE_DRIVER_VERSION 0xFF010113 -#define OID_SKGE_HW_DESCR 0xFF010114 -#define OID_SKGE_HW_VERSION 0xFF010115 -#define OID_SKGE_CHIPSET 0xFF010116 -#define OID_SKGE_ACTION 0xFF010117 -#define OID_SKGE_RESULT 0xFF010118 -#define OID_SKGE_BUS_TYPE 0xFF010119 -#define OID_SKGE_BUS_SPEED 0xFF01011A -#define OID_SKGE_BUS_WIDTH 0xFF01011B -/* 0xFF01011C unused */ -#define OID_SKGE_DIAG_ACTION 0xFF01011D -#define OID_SKGE_DIAG_RESULT 0xFF01011E -#define OID_SKGE_MTU 0xFF01011F -#define OID_SKGE_PHYS_CUR_ADDR 0xFF010120 -#define OID_SKGE_PHYS_FAC_ADDR 0xFF010121 -#define OID_SKGE_PMD 0xFF010122 -#define OID_SKGE_CONNECTOR 0xFF010123 -#define OID_SKGE_LINK_CAP 0xFF010124 -#define OID_SKGE_LINK_MODE 0xFF010125 -#define OID_SKGE_LINK_MODE_STATUS 0xFF010126 -#define OID_SKGE_LINK_STATUS 0xFF010127 -#define OID_SKGE_FLOWCTRL_CAP 0xFF010128 -#define OID_SKGE_FLOWCTRL_MODE 0xFF010129 -#define OID_SKGE_FLOWCTRL_STATUS 0xFF01012A -#define OID_SKGE_PHY_OPERATION_CAP 0xFF01012B -#define OID_SKGE_PHY_OPERATION_MODE 0xFF01012C -#define OID_SKGE_PHY_OPERATION_STATUS 0xFF01012D -#define OID_SKGE_MULTICAST_LIST 0xFF01012E -#define OID_SKGE_CURRENT_PACKET_FILTER 0xFF01012F - -#define OID_SKGE_TRAP 0xFF010130 -#define OID_SKGE_TRAP_NUMBER 0xFF010131 - -#define OID_SKGE_RLMT_MODE 0xFF010140 -#define OID_SKGE_RLMT_PORT_NUMBER 0xFF010141 -#define OID_SKGE_RLMT_PORT_ACTIVE 0xFF010142 -#define OID_SKGE_RLMT_PORT_PREFERRED 0xFF010143 -#define OID_SKGE_INTERMEDIATE_SUPPORT 0xFF010160 - -#define OID_SKGE_SPEED_CAP 0xFF010170 -#define OID_SKGE_SPEED_MODE 0xFF010171 -#define OID_SKGE_SPEED_STATUS 0xFF010172 - -#define OID_SKGE_BOARDLEVEL 0xFF010180 - -#define OID_SKGE_SENSOR_NUMBER 0xFF020100 -#define OID_SKGE_SENSOR_INDEX 0xFF020101 -#define OID_SKGE_SENSOR_DESCR 0xFF020102 -#define OID_SKGE_SENSOR_TYPE 0xFF020103 -#define OID_SKGE_SENSOR_VALUE 0xFF020104 -#define OID_SKGE_SENSOR_WAR_THRES_LOW 0xFF020105 -#define OID_SKGE_SENSOR_WAR_THRES_UPP 0xFF020106 -#define OID_SKGE_SENSOR_ERR_THRES_LOW 0xFF020107 -#define OID_SKGE_SENSOR_ERR_THRES_UPP 0xFF020108 -#define OID_SKGE_SENSOR_STATUS 0xFF020109 -#define OID_SKGE_SENSOR_WAR_CTS 0xFF02010A -#define OID_SKGE_SENSOR_ERR_CTS 0xFF02010B -#define OID_SKGE_SENSOR_WAR_TIME 0xFF02010C -#define OID_SKGE_SENSOR_ERR_TIME 0xFF02010D - -#define OID_SKGE_CHKSM_NUMBER 0xFF020110 -#define OID_SKGE_CHKSM_RX_OK_CTS 0xFF020111 -#define OID_SKGE_CHKSM_RX_UNABLE_CTS 0xFF020112 -#define OID_SKGE_CHKSM_RX_ERR_CTS 0xFF020113 -#define OID_SKGE_CHKSM_TX_OK_CTS 0xFF020114 -#define OID_SKGE_CHKSM_TX_UNABLE_CTS 0xFF020115 - -#define OID_SKGE_STAT_TX 0xFF020120 -#define OID_SKGE_STAT_TX_OCTETS 0xFF020121 -#define OID_SKGE_STAT_TX_BROADCAST 0xFF020122 -#define OID_SKGE_STAT_TX_MULTICAST 0xFF020123 -#define OID_SKGE_STAT_TX_UNICAST 0xFF020124 -#define OID_SKGE_STAT_TX_LONGFRAMES 0xFF020125 -#define OID_SKGE_STAT_TX_BURST 0xFF020126 -#define OID_SKGE_STAT_TX_PFLOWC 0xFF020127 -#define OID_SKGE_STAT_TX_FLOWC 0xFF020128 -#define OID_SKGE_STAT_TX_SINGLE_COL 0xFF020129 -#define OID_SKGE_STAT_TX_MULTI_COL 0xFF02012A -#define OID_SKGE_STAT_TX_EXCESS_COL 0xFF02012B -#define OID_SKGE_STAT_TX_LATE_COL 0xFF02012C -#define OID_SKGE_STAT_TX_DEFFERAL 0xFF02012D -#define OID_SKGE_STAT_TX_EXCESS_DEF 0xFF02012E -#define OID_SKGE_STAT_TX_UNDERRUN 0xFF02012F -#define OID_SKGE_STAT_TX_CARRIER 0xFF020130 -/* #define OID_SKGE_STAT_TX_UTIL 0xFF020131 */ -#define OID_SKGE_STAT_TX_64 0xFF020132 -#define OID_SKGE_STAT_TX_127 0xFF020133 -#define OID_SKGE_STAT_TX_255 0xFF020134 -#define OID_SKGE_STAT_TX_511 0xFF020135 -#define OID_SKGE_STAT_TX_1023 0xFF020136 -#define OID_SKGE_STAT_TX_MAX 0xFF020137 -#define OID_SKGE_STAT_TX_SYNC 0xFF020138 -#define OID_SKGE_STAT_TX_SYNC_OCTETS 0xFF020139 -#define OID_SKGE_STAT_RX 0xFF02013A -#define OID_SKGE_STAT_RX_OCTETS 0xFF02013B -#define OID_SKGE_STAT_RX_BROADCAST 0xFF02013C -#define OID_SKGE_STAT_RX_MULTICAST 0xFF02013D -#define OID_SKGE_STAT_RX_UNICAST 0xFF02013E -#define OID_SKGE_STAT_RX_PFLOWC 0xFF02013F -#define OID_SKGE_STAT_RX_FLOWC 0xFF020140 -#define OID_SKGE_STAT_RX_PFLOWC_ERR 0xFF020141 -#define OID_SKGE_STAT_RX_FLOWC_UNKWN 0xFF020142 -#define OID_SKGE_STAT_RX_BURST 0xFF020143 -#define OID_SKGE_STAT_RX_MISSED 0xFF020144 -#define OID_SKGE_STAT_RX_FRAMING 0xFF020145 -#define OID_SKGE_STAT_RX_OVERFLOW 0xFF020146 -#define OID_SKGE_STAT_RX_JABBER 0xFF020147 -#define OID_SKGE_STAT_RX_CARRIER 0xFF020148 -#define OID_SKGE_STAT_RX_IR_LENGTH 0xFF020149 -#define OID_SKGE_STAT_RX_SYMBOL 0xFF02014A -#define OID_SKGE_STAT_RX_SHORTS 0xFF02014B -#define OID_SKGE_STAT_RX_RUNT 0xFF02014C -#define OID_SKGE_STAT_RX_CEXT 0xFF02014D -#define OID_SKGE_STAT_RX_TOO_LONG 0xFF02014E -#define OID_SKGE_STAT_RX_FCS 0xFF02014F -/* #define OID_SKGE_STAT_RX_UTIL 0xFF020150 */ -#define OID_SKGE_STAT_RX_64 0xFF020151 -#define OID_SKGE_STAT_RX_127 0xFF020152 -#define OID_SKGE_STAT_RX_255 0xFF020153 -#define OID_SKGE_STAT_RX_511 0xFF020154 -#define OID_SKGE_STAT_RX_1023 0xFF020155 -#define OID_SKGE_STAT_RX_MAX 0xFF020156 -#define OID_SKGE_STAT_RX_LONGFRAMES 0xFF020157 - -#define OID_SKGE_RLMT_CHANGE_CTS 0xFF020160 -#define OID_SKGE_RLMT_CHANGE_TIME 0xFF020161 -#define OID_SKGE_RLMT_CHANGE_ESTIM 0xFF020162 -#define OID_SKGE_RLMT_CHANGE_THRES 0xFF020163 - -#define OID_SKGE_RLMT_PORT_INDEX 0xFF020164 -#define OID_SKGE_RLMT_STATUS 0xFF020165 -#define OID_SKGE_RLMT_TX_HELLO_CTS 0xFF020166 -#define OID_SKGE_RLMT_RX_HELLO_CTS 0xFF020167 -#define OID_SKGE_RLMT_TX_SP_REQ_CTS 0xFF020168 -#define OID_SKGE_RLMT_RX_SP_CTS 0xFF020169 - -#define OID_SKGE_RLMT_MONITOR_NUMBER 0xFF010150 -#define OID_SKGE_RLMT_MONITOR_INDEX 0xFF010151 -#define OID_SKGE_RLMT_MONITOR_ADDR 0xFF010152 -#define OID_SKGE_RLMT_MONITOR_ERRS 0xFF010153 -#define OID_SKGE_RLMT_MONITOR_TIMESTAMP 0xFF010154 -#define OID_SKGE_RLMT_MONITOR_ADMIN 0xFF010155 - -#define OID_SKGE_TX_SW_QUEUE_LEN 0xFF020170 -#define OID_SKGE_TX_SW_QUEUE_MAX 0xFF020171 -#define OID_SKGE_TX_RETRY 0xFF020172 -#define OID_SKGE_RX_INTR_CTS 0xFF020173 -#define OID_SKGE_TX_INTR_CTS 0xFF020174 -#define OID_SKGE_RX_NO_BUF_CTS 0xFF020175 -#define OID_SKGE_TX_NO_BUF_CTS 0xFF020176 -#define OID_SKGE_TX_USED_DESCR_NO 0xFF020177 -#define OID_SKGE_RX_DELIVERED_CTS 0xFF020178 -#define OID_SKGE_RX_OCTETS_DELIV_CTS 0xFF020179 -#define OID_SKGE_RX_HW_ERROR_CTS 0xFF02017A -#define OID_SKGE_TX_HW_ERROR_CTS 0xFF02017B -#define OID_SKGE_IN_ERRORS_CTS 0xFF02017C -#define OID_SKGE_OUT_ERROR_CTS 0xFF02017D -#define OID_SKGE_ERR_RECOVERY_CTS 0xFF02017E -#define OID_SKGE_SYSUPTIME 0xFF02017F - -#define OID_SKGE_ALL_DATA 0xFF020190 - -/* Defines for VCT. */ -#define OID_SKGE_VCT_GET 0xFF020200 -#define OID_SKGE_VCT_SET 0xFF020201 -#define OID_SKGE_VCT_STATUS 0xFF020202 - -#ifdef SK_DIAG_SUPPORT -/* Defines for driver DIAG mode. */ -#define OID_SKGE_DIAG_MODE 0xFF020204 -#endif /* SK_DIAG_SUPPORT */ - -/* New OIDs */ -#define OID_SKGE_DRIVER_RELDATE 0xFF020210 -#define OID_SKGE_DRIVER_FILENAME 0xFF020211 -#define OID_SKGE_CHIPID 0xFF020212 -#define OID_SKGE_RAMSIZE 0xFF020213 -#define OID_SKGE_VAUXAVAIL 0xFF020214 -#define OID_SKGE_PHY_TYPE 0xFF020215 -#define OID_SKGE_PHY_LP_MODE 0xFF020216 - -/* VCT struct to store a backup copy of VCT data after a port reset. */ -typedef struct s_PnmiVct { - SK_U8 VctStatus; - SK_U8 PCableLen; - SK_U32 PMdiPairLen[4]; - SK_U8 PMdiPairSts[4]; -} SK_PNMI_VCT; - - -/* VCT status values (to be given to CPA via OID_SKGE_VCT_STATUS). */ -#define SK_PNMI_VCT_NONE 0 -#define SK_PNMI_VCT_OLD_VCT_DATA 1 -#define SK_PNMI_VCT_NEW_VCT_DATA 2 -#define SK_PNMI_VCT_OLD_DSP_DATA 4 -#define SK_PNMI_VCT_NEW_DSP_DATA 8 -#define SK_PNMI_VCT_RUNNING 16 - - -/* VCT cable test status. */ -#define SK_PNMI_VCT_NORMAL_CABLE 0 -#define SK_PNMI_VCT_SHORT_CABLE 1 -#define SK_PNMI_VCT_OPEN_CABLE 2 -#define SK_PNMI_VCT_TEST_FAIL 3 -#define SK_PNMI_VCT_IMPEDANCE_MISMATCH 4 - -#define OID_SKGE_TRAP_SEN_WAR_LOW 500 -#define OID_SKGE_TRAP_SEN_WAR_UPP 501 -#define OID_SKGE_TRAP_SEN_ERR_LOW 502 -#define OID_SKGE_TRAP_SEN_ERR_UPP 503 -#define OID_SKGE_TRAP_RLMT_CHANGE_THRES 520 -#define OID_SKGE_TRAP_RLMT_CHANGE_PORT 521 -#define OID_SKGE_TRAP_RLMT_PORT_DOWN 522 -#define OID_SKGE_TRAP_RLMT_PORT_UP 523 -#define OID_SKGE_TRAP_RLMT_SEGMENTATION 524 - -#ifdef SK_DIAG_SUPPORT -/* Defines for driver DIAG mode. */ -#define SK_DIAG_ATTACHED 2 -#define SK_DIAG_RUNNING 1 -#define SK_DIAG_IDLE 0 -#endif /* SK_DIAG_SUPPORT */ - -/* - * Generic PNMI IOCTL subcommand definitions. - */ -#define SK_GET_SINGLE_VAR 1 -#define SK_SET_SINGLE_VAR 2 -#define SK_PRESET_SINGLE_VAR 3 -#define SK_GET_FULL_MIB 4 -#define SK_SET_FULL_MIB 5 -#define SK_PRESET_FULL_MIB 6 - - -/* - * Define error numbers and messages for syslog - */ -#define SK_PNMI_ERR001 (SK_ERRBASE_PNMI + 1) -#define SK_PNMI_ERR001MSG "SkPnmiGetStruct: Unknown OID" -#define SK_PNMI_ERR002 (SK_ERRBASE_PNMI + 2) -#define SK_PNMI_ERR002MSG "SkPnmiGetStruct: Cannot read VPD keys" -#define SK_PNMI_ERR003 (SK_ERRBASE_PNMI + 3) -#define SK_PNMI_ERR003MSG "OidStruct: Called with wrong OID" -#define SK_PNMI_ERR004 (SK_ERRBASE_PNMI + 4) -#define SK_PNMI_ERR004MSG "OidStruct: Called with wrong action" -#define SK_PNMI_ERR005 (SK_ERRBASE_PNMI + 5) -#define SK_PNMI_ERR005MSG "Perform: Cannot reset driver" -#define SK_PNMI_ERR006 (SK_ERRBASE_PNMI + 6) -#define SK_PNMI_ERR006MSG "Perform: Unknown OID action command" -#define SK_PNMI_ERR007 (SK_ERRBASE_PNMI + 7) -#define SK_PNMI_ERR007MSG "General: Driver description not initialized" -#define SK_PNMI_ERR008 (SK_ERRBASE_PNMI + 8) -#define SK_PNMI_ERR008MSG "Addr: Tried to get unknown OID" -#define SK_PNMI_ERR009 (SK_ERRBASE_PNMI + 9) -#define SK_PNMI_ERR009MSG "Addr: Unknown OID" -#define SK_PNMI_ERR010 (SK_ERRBASE_PNMI + 10) -#define SK_PNMI_ERR010MSG "CsumStat: Unknown OID" -#define SK_PNMI_ERR011 (SK_ERRBASE_PNMI + 11) -#define SK_PNMI_ERR011MSG "SensorStat: Sensor descr string too long" -#define SK_PNMI_ERR012 (SK_ERRBASE_PNMI + 12) -#define SK_PNMI_ERR012MSG "SensorStat: Unknown OID" -#define SK_PNMI_ERR013 (SK_ERRBASE_PNMI + 13) -#define SK_PNMI_ERR013MSG "" -#define SK_PNMI_ERR014 (SK_ERRBASE_PNMI + 14) -#define SK_PNMI_ERR014MSG "Vpd: Cannot read VPD keys" -#define SK_PNMI_ERR015 (SK_ERRBASE_PNMI + 15) -#define SK_PNMI_ERR015MSG "Vpd: Internal array for VPD keys to small" -#define SK_PNMI_ERR016 (SK_ERRBASE_PNMI + 16) -#define SK_PNMI_ERR016MSG "Vpd: Key string too long" -#define SK_PNMI_ERR017 (SK_ERRBASE_PNMI + 17) -#define SK_PNMI_ERR017MSG "Vpd: Invalid VPD status pointer" -#define SK_PNMI_ERR018 (SK_ERRBASE_PNMI + 18) -#define SK_PNMI_ERR018MSG "Vpd: VPD data not valid" -#define SK_PNMI_ERR019 (SK_ERRBASE_PNMI + 19) -#define SK_PNMI_ERR019MSG "Vpd: VPD entries list string too long" -#define SK_PNMI_ERR021 (SK_ERRBASE_PNMI + 21) -#define SK_PNMI_ERR021MSG "Vpd: VPD data string too long" -#define SK_PNMI_ERR022 (SK_ERRBASE_PNMI + 22) -#define SK_PNMI_ERR022MSG "Vpd: VPD data string too long should be errored before" -#define SK_PNMI_ERR023 (SK_ERRBASE_PNMI + 23) -#define SK_PNMI_ERR023MSG "Vpd: Unknown OID in get action" -#define SK_PNMI_ERR024 (SK_ERRBASE_PNMI + 24) -#define SK_PNMI_ERR024MSG "Vpd: Unknown OID in preset/set action" -#define SK_PNMI_ERR025 (SK_ERRBASE_PNMI + 25) -#define SK_PNMI_ERR025MSG "Vpd: Cannot write VPD after modify entry" -#define SK_PNMI_ERR026 (SK_ERRBASE_PNMI + 26) -#define SK_PNMI_ERR026MSG "Vpd: Cannot update VPD" -#define SK_PNMI_ERR027 (SK_ERRBASE_PNMI + 27) -#define SK_PNMI_ERR027MSG "Vpd: Cannot delete VPD entry" -#define SK_PNMI_ERR028 (SK_ERRBASE_PNMI + 28) -#define SK_PNMI_ERR028MSG "Vpd: Cannot update VPD after delete entry" -#define SK_PNMI_ERR029 (SK_ERRBASE_PNMI + 29) -#define SK_PNMI_ERR029MSG "General: Driver description string too long" -#define SK_PNMI_ERR030 (SK_ERRBASE_PNMI + 30) -#define SK_PNMI_ERR030MSG "General: Driver version not initialized" -#define SK_PNMI_ERR031 (SK_ERRBASE_PNMI + 31) -#define SK_PNMI_ERR031MSG "General: Driver version string too long" -#define SK_PNMI_ERR032 (SK_ERRBASE_PNMI + 32) -#define SK_PNMI_ERR032MSG "General: Cannot read VPD Name for HW descr" -#define SK_PNMI_ERR033 (SK_ERRBASE_PNMI + 33) -#define SK_PNMI_ERR033MSG "General: HW description string too long" -#define SK_PNMI_ERR034 (SK_ERRBASE_PNMI + 34) -#define SK_PNMI_ERR034MSG "General: Unknown OID" -#define SK_PNMI_ERR035 (SK_ERRBASE_PNMI + 35) -#define SK_PNMI_ERR035MSG "Rlmt: Unknown OID" -#define SK_PNMI_ERR036 (SK_ERRBASE_PNMI + 36) -#define SK_PNMI_ERR036MSG "" -#define SK_PNMI_ERR037 (SK_ERRBASE_PNMI + 37) -#define SK_PNMI_ERR037MSG "Rlmt: SK_RLMT_MODE_CHANGE event return not 0" -#define SK_PNMI_ERR038 (SK_ERRBASE_PNMI + 38) -#define SK_PNMI_ERR038MSG "Rlmt: SK_RLMT_PREFPORT_CHANGE event return not 0" -#define SK_PNMI_ERR039 (SK_ERRBASE_PNMI + 39) -#define SK_PNMI_ERR039MSG "RlmtStat: Unknown OID" -#define SK_PNMI_ERR040 (SK_ERRBASE_PNMI + 40) -#define SK_PNMI_ERR040MSG "PowerManagement: Unknown OID" -#define SK_PNMI_ERR041 (SK_ERRBASE_PNMI + 41) -#define SK_PNMI_ERR041MSG "MacPrivateConf: Unknown OID" -#define SK_PNMI_ERR042 (SK_ERRBASE_PNMI + 42) -#define SK_PNMI_ERR042MSG "MacPrivateConf: SK_HWEV_SET_ROLE returned not 0" -#define SK_PNMI_ERR043 (SK_ERRBASE_PNMI + 43) -#define SK_PNMI_ERR043MSG "MacPrivateConf: SK_HWEV_SET_LMODE returned not 0" -#define SK_PNMI_ERR044 (SK_ERRBASE_PNMI + 44) -#define SK_PNMI_ERR044MSG "MacPrivateConf: SK_HWEV_SET_FLOWMODE returned not 0" -#define SK_PNMI_ERR045 (SK_ERRBASE_PNMI + 45) -#define SK_PNMI_ERR045MSG "MacPrivateConf: SK_HWEV_SET_SPEED returned not 0" -#define SK_PNMI_ERR046 (SK_ERRBASE_PNMI + 46) -#define SK_PNMI_ERR046MSG "Monitor: Unknown OID" -#define SK_PNMI_ERR047 (SK_ERRBASE_PNMI + 47) -#define SK_PNMI_ERR047MSG "SirqUpdate: Event function returns not 0" -#define SK_PNMI_ERR048 (SK_ERRBASE_PNMI + 48) -#define SK_PNMI_ERR048MSG "RlmtUpdate: Event function returns not 0" -#define SK_PNMI_ERR049 (SK_ERRBASE_PNMI + 49) -#define SK_PNMI_ERR049MSG "SkPnmiInit: Invalid size of 'CounterOffset' struct!!" -#define SK_PNMI_ERR050 (SK_ERRBASE_PNMI + 50) -#define SK_PNMI_ERR050MSG "SkPnmiInit: Invalid size of 'StatAddr' table!!" -#define SK_PNMI_ERR051 (SK_ERRBASE_PNMI + 51) -#define SK_PNMI_ERR051MSG "SkPnmiEvent: Port switch suspicious" -#define SK_PNMI_ERR052 (SK_ERRBASE_PNMI + 52) -#define SK_PNMI_ERR052MSG "" -#define SK_PNMI_ERR053 (SK_ERRBASE_PNMI + 53) -#define SK_PNMI_ERR053MSG "General: Driver release date not initialized" -#define SK_PNMI_ERR054 (SK_ERRBASE_PNMI + 54) -#define SK_PNMI_ERR054MSG "General: Driver release date string too long" -#define SK_PNMI_ERR055 (SK_ERRBASE_PNMI + 55) -#define SK_PNMI_ERR055MSG "General: Driver file name not initialized" -#define SK_PNMI_ERR056 (SK_ERRBASE_PNMI + 56) -#define SK_PNMI_ERR056MSG "General: Driver file name string too long" - -/* - * Management counter macros called by the driver - */ -#define SK_PNMI_SET_DRIVER_DESCR(pAC,v) ((pAC)->Pnmi.pDriverDescription = \ - (char *)(v)) - -#define SK_PNMI_SET_DRIVER_VER(pAC,v) ((pAC)->Pnmi.pDriverVersion = \ - (char *)(v)) - -#define SK_PNMI_SET_DRIVER_RELDATE(pAC,v) ((pAC)->Pnmi.pDriverReleaseDate = \ - (char *)(v)) - -#define SK_PNMI_SET_DRIVER_FILENAME(pAC,v) ((pAC)->Pnmi.pDriverFileName = \ - (char *)(v)) - -#define SK_PNMI_CNT_TX_QUEUE_LEN(pAC,v,p) \ - { \ - (pAC)->Pnmi.Port[p].TxSwQueueLen = (SK_U64)(v); \ - if ((pAC)->Pnmi.Port[p].TxSwQueueLen > (pAC)->Pnmi.Port[p].TxSwQueueMax) { \ - (pAC)->Pnmi.Port[p].TxSwQueueMax = (pAC)->Pnmi.Port[p].TxSwQueueLen; \ - } \ - } -#define SK_PNMI_CNT_TX_RETRY(pAC,p) (((pAC)->Pnmi.Port[p].TxRetryCts)++) -#define SK_PNMI_CNT_RX_INTR(pAC,p) (((pAC)->Pnmi.Port[p].RxIntrCts)++) -#define SK_PNMI_CNT_TX_INTR(pAC,p) (((pAC)->Pnmi.Port[p].TxIntrCts)++) -#define SK_PNMI_CNT_NO_RX_BUF(pAC,p) (((pAC)->Pnmi.Port[p].RxNoBufCts)++) -#define SK_PNMI_CNT_NO_TX_BUF(pAC,p) (((pAC)->Pnmi.Port[p].TxNoBufCts)++) -#define SK_PNMI_CNT_USED_TX_DESCR(pAC,v,p) \ - ((pAC)->Pnmi.Port[p].TxUsedDescrNo=(SK_U64)(v)); -#define SK_PNMI_CNT_RX_OCTETS_DELIVERED(pAC,v,p) \ - { \ - ((pAC)->Pnmi.Port[p].RxDeliveredCts)++; \ - (pAC)->Pnmi.Port[p].RxOctetsDeliveredCts += (SK_U64)(v); \ - } -#define SK_PNMI_CNT_ERR_RECOVERY(pAC,p) (((pAC)->Pnmi.Port[p].ErrRecoveryCts)++); - -#define SK_PNMI_CNT_SYNC_OCTETS(pAC,p,v) \ - { \ - if ((p) < SK_MAX_MACS) { \ - ((pAC)->Pnmi.Port[p].StatSyncCts)++; \ - (pAC)->Pnmi.Port[p].StatSyncOctetsCts += (SK_U64)(v); \ - } \ - } - -#define SK_PNMI_CNT_RX_LONGFRAMES(pAC,p) \ - { \ - if ((p) < SK_MAX_MACS) { \ - ((pAC)->Pnmi.Port[p].StatRxLongFrameCts++); \ - } \ - } - -#define SK_PNMI_CNT_RX_FRAMETOOLONG(pAC,p) \ - { \ - if ((p) < SK_MAX_MACS) { \ - ((pAC)->Pnmi.Port[p].StatRxFrameTooLongCts++); \ - } \ - } - -#define SK_PNMI_CNT_RX_PMACC_ERR(pAC,p) \ - { \ - if ((p) < SK_MAX_MACS) { \ - ((pAC)->Pnmi.Port[p].StatRxPMaccErr++); \ - } \ - } - -/* - * Conversion Macros - */ -#define SK_PNMI_PORT_INST2LOG(i) ((unsigned int)(i) - 1) -#define SK_PNMI_PORT_LOG2INST(l) ((unsigned int)(l) + 1) -#define SK_PNMI_PORT_PHYS2LOG(p) ((unsigned int)(p) + 1) -#define SK_PNMI_PORT_LOG2PHYS(pAC,l) ((unsigned int)(l) - 1) -#define SK_PNMI_PORT_PHYS2INST(pAC,p) \ - (pAC->Pnmi.DualNetActiveFlag ? 2 : ((unsigned int)(p) + 2)) -#define SK_PNMI_PORT_INST2PHYS(pAC,i) ((unsigned int)(i) - 2) - -/* - * Structure definition for SkPnmiGetStruct and SkPnmiSetStruct - */ -#define SK_PNMI_VPD_KEY_SIZE 5 -#define SK_PNMI_VPD_BUFSIZE (VPD_SIZE) -#define SK_PNMI_VPD_ENTRIES (VPD_SIZE / 4) -#define SK_PNMI_VPD_DATALEN 128 /* Number of data bytes */ - -#define SK_PNMI_MULTICAST_LISTLEN 64 -#define SK_PNMI_SENSOR_ENTRIES (SK_MAX_SENSORS) -#define SK_PNMI_CHECKSUM_ENTRIES 3 -#define SK_PNMI_MAC_ENTRIES (SK_MAX_MACS + 1) -#define SK_PNMI_MONITOR_ENTRIES 20 -#define SK_PNMI_TRAP_ENTRIES 10 -#define SK_PNMI_TRAPLEN 128 -#define SK_PNMI_STRINGLEN1 80 -#define SK_PNMI_STRINGLEN2 25 -#define SK_PNMI_TRAP_QUEUE_LEN 512 - -typedef struct s_PnmiVpd { - char VpdKey[SK_PNMI_VPD_KEY_SIZE]; - char VpdValue[SK_PNMI_VPD_DATALEN]; - SK_U8 VpdAccess; - SK_U8 VpdAction; -} SK_PNMI_VPD; - -typedef struct s_PnmiSensor { - SK_U8 SensorIndex; - char SensorDescr[SK_PNMI_STRINGLEN2]; - SK_U8 SensorType; - SK_U32 SensorValue; - SK_U32 SensorWarningThresholdLow; - SK_U32 SensorWarningThresholdHigh; - SK_U32 SensorErrorThresholdLow; - SK_U32 SensorErrorThresholdHigh; - SK_U8 SensorStatus; - SK_U64 SensorWarningCts; - SK_U64 SensorErrorCts; - SK_U64 SensorWarningTimestamp; - SK_U64 SensorErrorTimestamp; -} SK_PNMI_SENSOR; - -typedef struct s_PnmiChecksum { - SK_U64 ChecksumRxOkCts; - SK_U64 ChecksumRxUnableCts; - SK_U64 ChecksumRxErrCts; - SK_U64 ChecksumTxOkCts; - SK_U64 ChecksumTxUnableCts; -} SK_PNMI_CHECKSUM; - -typedef struct s_PnmiStat { - SK_U64 StatTxOkCts; - SK_U64 StatTxOctetsOkCts; - SK_U64 StatTxBroadcastOkCts; - SK_U64 StatTxMulticastOkCts; - SK_U64 StatTxUnicastOkCts; - SK_U64 StatTxLongFramesCts; - SK_U64 StatTxBurstCts; - SK_U64 StatTxPauseMacCtrlCts; - SK_U64 StatTxMacCtrlCts; - SK_U64 StatTxSingleCollisionCts; - SK_U64 StatTxMultipleCollisionCts; - SK_U64 StatTxExcessiveCollisionCts; - SK_U64 StatTxLateCollisionCts; - SK_U64 StatTxDeferralCts; - SK_U64 StatTxExcessiveDeferralCts; - SK_U64 StatTxFifoUnderrunCts; - SK_U64 StatTxCarrierCts; - SK_U64 Dummy1; /* StatTxUtilization */ - SK_U64 StatTx64Cts; - SK_U64 StatTx127Cts; - SK_U64 StatTx255Cts; - SK_U64 StatTx511Cts; - SK_U64 StatTx1023Cts; - SK_U64 StatTxMaxCts; - SK_U64 StatTxSyncCts; - SK_U64 StatTxSyncOctetsCts; - SK_U64 StatRxOkCts; - SK_U64 StatRxOctetsOkCts; - SK_U64 StatRxBroadcastOkCts; - SK_U64 StatRxMulticastOkCts; - SK_U64 StatRxUnicastOkCts; - SK_U64 StatRxLongFramesCts; - SK_U64 StatRxPauseMacCtrlCts; - SK_U64 StatRxMacCtrlCts; - SK_U64 StatRxPauseMacCtrlErrorCts; - SK_U64 StatRxMacCtrlUnknownCts; - SK_U64 StatRxBurstCts; - SK_U64 StatRxMissedCts; - SK_U64 StatRxFramingCts; - SK_U64 StatRxFifoOverflowCts; - SK_U64 StatRxJabberCts; - SK_U64 StatRxCarrierCts; - SK_U64 StatRxIRLengthCts; - SK_U64 StatRxSymbolCts; - SK_U64 StatRxShortsCts; - SK_U64 StatRxRuntCts; - SK_U64 StatRxCextCts; - SK_U64 StatRxTooLongCts; - SK_U64 StatRxFcsCts; - SK_U64 Dummy2; /* StatRxUtilization */ - SK_U64 StatRx64Cts; - SK_U64 StatRx127Cts; - SK_U64 StatRx255Cts; - SK_U64 StatRx511Cts; - SK_U64 StatRx1023Cts; - SK_U64 StatRxMaxCts; -} SK_PNMI_STAT; - -typedef struct s_PnmiConf { - char ConfMacCurrentAddr[6]; - char ConfMacFactoryAddr[6]; - SK_U8 ConfPMD; - SK_U8 ConfConnector; - SK_U32 ConfPhyType; - SK_U32 ConfPhyMode; - SK_U8 ConfLinkCapability; - SK_U8 ConfLinkMode; - SK_U8 ConfLinkModeStatus; - SK_U8 ConfLinkStatus; - SK_U8 ConfFlowCtrlCapability; - SK_U8 ConfFlowCtrlMode; - SK_U8 ConfFlowCtrlStatus; - SK_U8 ConfPhyOperationCapability; - SK_U8 ConfPhyOperationMode; - SK_U8 ConfPhyOperationStatus; - SK_U8 ConfSpeedCapability; - SK_U8 ConfSpeedMode; - SK_U8 ConfSpeedStatus; -} SK_PNMI_CONF; - -typedef struct s_PnmiRlmt { - SK_U32 RlmtIndex; - SK_U32 RlmtStatus; - SK_U64 RlmtTxHelloCts; - SK_U64 RlmtRxHelloCts; - SK_U64 RlmtTxSpHelloReqCts; - SK_U64 RlmtRxSpHelloCts; -} SK_PNMI_RLMT; - -typedef struct s_PnmiRlmtMonitor { - SK_U32 RlmtMonitorIndex; - char RlmtMonitorAddr[6]; - SK_U64 RlmtMonitorErrorCts; - SK_U64 RlmtMonitorTimestamp; - SK_U8 RlmtMonitorAdmin; -} SK_PNMI_RLMT_MONITOR; - -typedef struct s_PnmiRequestStatus { - SK_U32 ErrorStatus; - SK_U32 ErrorOffset; -} SK_PNMI_REQUEST_STATUS; - -typedef struct s_PnmiStrucData { - SK_U32 MgmtDBVersion; - SK_PNMI_REQUEST_STATUS ReturnStatus; - SK_U32 VpdFreeBytes; - char VpdEntriesList[SK_PNMI_VPD_ENTRIES * SK_PNMI_VPD_KEY_SIZE]; - SK_U32 VpdEntriesNumber; - SK_PNMI_VPD Vpd[SK_PNMI_VPD_ENTRIES]; - SK_U32 PortNumber; - SK_U32 DeviceType; - char DriverDescr[SK_PNMI_STRINGLEN1]; - char DriverVersion[SK_PNMI_STRINGLEN2]; - char DriverReleaseDate[SK_PNMI_STRINGLEN1]; - char DriverFileName[SK_PNMI_STRINGLEN1]; - char HwDescr[SK_PNMI_STRINGLEN1]; - char HwVersion[SK_PNMI_STRINGLEN2]; - SK_U16 Chipset; - SK_U32 ChipId; - SK_U8 VauxAvail; - SK_U32 RamSize; - SK_U32 MtuSize; - SK_U32 Action; - SK_U32 TestResult; - SK_U8 BusType; - SK_U8 BusSpeed; - SK_U8 BusWidth; - SK_U8 SensorNumber; - SK_PNMI_SENSOR Sensor[SK_PNMI_SENSOR_ENTRIES]; - SK_U8 ChecksumNumber; - SK_PNMI_CHECKSUM Checksum[SK_PNMI_CHECKSUM_ENTRIES]; - SK_PNMI_STAT Stat[SK_PNMI_MAC_ENTRIES]; - SK_PNMI_CONF Conf[SK_PNMI_MAC_ENTRIES]; - SK_U8 RlmtMode; - SK_U32 RlmtPortNumber; - SK_U8 RlmtPortActive; - SK_U8 RlmtPortPreferred; - SK_U64 RlmtChangeCts; - SK_U64 RlmtChangeTime; - SK_U64 RlmtChangeEstimate; - SK_U64 RlmtChangeThreshold; - SK_PNMI_RLMT Rlmt[SK_MAX_MACS]; - SK_U32 RlmtMonitorNumber; - SK_PNMI_RLMT_MONITOR RlmtMonitor[SK_PNMI_MONITOR_ENTRIES]; - SK_U32 TrapNumber; - SK_U8 Trap[SK_PNMI_TRAP_QUEUE_LEN]; - SK_U64 TxSwQueueLen; - SK_U64 TxSwQueueMax; - SK_U64 TxRetryCts; - SK_U64 RxIntrCts; - SK_U64 TxIntrCts; - SK_U64 RxNoBufCts; - SK_U64 TxNoBufCts; - SK_U64 TxUsedDescrNo; - SK_U64 RxDeliveredCts; - SK_U64 RxOctetsDeliveredCts; - SK_U64 RxHwErrorsCts; - SK_U64 TxHwErrorsCts; - SK_U64 InErrorsCts; - SK_U64 OutErrorsCts; - SK_U64 ErrRecoveryCts; - SK_U64 SysUpTime; -} SK_PNMI_STRUCT_DATA; - -#define SK_PNMI_STRUCT_SIZE (sizeof(SK_PNMI_STRUCT_DATA)) -#define SK_PNMI_MIN_STRUCT_SIZE ((unsigned int)(SK_UPTR)\ - &(((SK_PNMI_STRUCT_DATA *)0)->VpdFreeBytes)) - /* - * ReturnStatus field - * must be located - * before VpdFreeBytes - */ - -/* - * Various definitions - */ -#define SK_PNMI_MAX_PROTOS 3 - -#define SK_PNMI_CNT_NO 66 /* Must have the value of the enum - * SK_PNMI_MAX_IDX. Define SK_PNMI_CHECK - * for check while init phase 1 - */ - -/* - * Estimate data structure - */ -typedef struct s_PnmiEstimate { - unsigned int EstValueIndex; - SK_U64 EstValue[7]; - SK_U64 Estimate; - SK_TIMER EstTimer; -} SK_PNMI_ESTIMATE; - - -/* - * VCT timer data structure - */ -typedef struct s_VctTimer { - SK_TIMER VctTimer; -} SK_PNMI_VCT_TIMER; - - -/* - * PNMI specific adapter context structure - */ -typedef struct s_PnmiPort { - SK_U64 StatSyncCts; - SK_U64 StatSyncOctetsCts; - SK_U64 StatRxLongFrameCts; - SK_U64 StatRxFrameTooLongCts; - SK_U64 StatRxPMaccErr; - SK_U64 TxSwQueueLen; - SK_U64 TxSwQueueMax; - SK_U64 TxRetryCts; - SK_U64 RxIntrCts; - SK_U64 TxIntrCts; - SK_U64 RxNoBufCts; - SK_U64 TxNoBufCts; - SK_U64 TxUsedDescrNo; - SK_U64 RxDeliveredCts; - SK_U64 RxOctetsDeliveredCts; - SK_U64 RxHwErrorsCts; - SK_U64 TxHwErrorsCts; - SK_U64 InErrorsCts; - SK_U64 OutErrorsCts; - SK_U64 ErrRecoveryCts; - SK_U64 RxShortZeroMark; - SK_U64 CounterOffset[SK_PNMI_CNT_NO]; - SK_U32 CounterHigh[SK_PNMI_CNT_NO]; - SK_BOOL ActiveFlag; - SK_U8 Align[3]; -} SK_PNMI_PORT; - - -typedef struct s_PnmiData { - SK_PNMI_PORT Port [SK_MAX_MACS]; - SK_PNMI_PORT BufPort [SK_MAX_MACS]; /* 2002-09-13 pweber */ - SK_U64 VirtualCounterOffset[SK_PNMI_CNT_NO]; - SK_U32 TestResult; - char HwVersion[10]; - SK_U16 Align01; - - char *pDriverDescription; - char *pDriverVersion; - char *pDriverReleaseDate; - char *pDriverFileName; - - int MacUpdatedFlag; - int RlmtUpdatedFlag; - int SirqUpdatedFlag; - - SK_U64 RlmtChangeCts; - SK_U64 RlmtChangeTime; - SK_PNMI_ESTIMATE RlmtChangeEstimate; - SK_U64 RlmtChangeThreshold; - - SK_U64 StartUpTime; - SK_U32 DeviceType; - char PciBusSpeed; - char PciBusWidth; - char Chipset; - char PMD; - char Connector; - SK_BOOL DualNetActiveFlag; - SK_U16 Align02; - - char TrapBuf[SK_PNMI_TRAP_QUEUE_LEN]; - unsigned int TrapBufFree; - unsigned int TrapQueueBeg; - unsigned int TrapQueueEnd; - unsigned int TrapBufPad; - unsigned int TrapUnique; - SK_U8 VctStatus[SK_MAX_MACS]; - SK_PNMI_VCT VctBackup[SK_MAX_MACS]; - SK_PNMI_VCT_TIMER VctTimeout[SK_MAX_MACS]; -#ifdef SK_DIAG_SUPPORT - SK_U32 DiagAttached; -#endif /* SK_DIAG_SUPPORT */ -} SK_PNMI; - - -/* - * Function prototypes - */ -extern int SkPnmiInit(SK_AC *pAC, SK_IOC IoC, int Level); -extern int SkPnmiGetVar(SK_AC *pAC, SK_IOC IoC, SK_U32 Id, void* pBuf, - unsigned int* pLen, SK_U32 Instance, SK_U32 NetIndex); -extern int SkPnmiPreSetVar(SK_AC *pAC, SK_IOC IoC, SK_U32 Id, - void* pBuf, unsigned int *pLen, SK_U32 Instance, SK_U32 NetIndex); -extern int SkPnmiSetVar(SK_AC *pAC, SK_IOC IoC, SK_U32 Id, void* pBuf, - unsigned int *pLen, SK_U32 Instance, SK_U32 NetIndex); -extern int SkPnmiGetStruct(SK_AC *pAC, SK_IOC IoC, void* pBuf, - unsigned int *pLen, SK_U32 NetIndex); -extern int SkPnmiPreSetStruct(SK_AC *pAC, SK_IOC IoC, void* pBuf, - unsigned int *pLen, SK_U32 NetIndex); -extern int SkPnmiSetStruct(SK_AC *pAC, SK_IOC IoC, void* pBuf, - unsigned int *pLen, SK_U32 NetIndex); -extern int SkPnmiEvent(SK_AC *pAC, SK_IOC IoC, SK_U32 Event, - SK_EVPARA Param); -extern int SkPnmiGenIoctl(SK_AC *pAC, SK_IOC IoC, void * pBuf, - unsigned int * pLen, SK_U32 NetIndex); - -#endif +/***************************************************************************** + * + * Name: skgepnmi.h + * Project: Gigabit Ethernet Adapters, PNMI-Module + * Version: $Revision: 2.11 $ + * Date: $Date: 2005/08/09 09:02:12 $ + * Purpose: Defines for Private Network Management Interface + * + ****************************************************************************/ + +/****************************************************************************** + * + * (C)Copyright 1998-2002 SysKonnect GmbH. + * (C)Copyright 2002-2003 Marvell. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * The information in this file is provided "AS IS" without warranty. + * + ******************************************************************************/ + +#ifndef _SKGEPNMI_H_ +#define _SKGEPNMI_H_ + +/* + * Include dependencies + */ +#include "h/sktypes.h" +#include "h/skerror.h" +#include "h/sktimer.h" +#include "h/sktwsi.h" +#include "h/skaddr.h" +#include "h/skrlmt.h" +#include "h/skvpd.h" + +/* + * Management Database Version + */ +#define SK_PNMI_MDB_VERSION 0x00030001 /* 3.1 */ + +/* + * Event definitions + */ +#define SK_PNMI_EVT_SIRQ_OVERFLOW 1 /* Counter overflow */ +#define SK_PNMI_EVT_SEN_WAR_LOW 2 /* Lower war thres exceeded */ +#define SK_PNMI_EVT_SEN_WAR_UPP 3 /* Upper war thres exceeded */ +#define SK_PNMI_EVT_SEN_ERR_LOW 4 /* Lower err thres exceeded */ +#define SK_PNMI_EVT_SEN_ERR_UPP 5 /* Upper err thres exceeded */ +#define SK_PNMI_EVT_CHG_EST_TIMER 6 /* Timer event for RLMT Chg */ +#define SK_PNMI_EVT_UTILIZATION_TIMER 7 /* Timer event for Utiliza. */ +#define SK_PNMI_EVT_CLEAR_COUNTER 8 /* Clear statistic counters */ +#define SK_PNMI_EVT_XMAC_RESET 9 /* XMAC will be reset */ +#define SK_PNMI_EVT_RLMT_PORT_UP 10 /* Port came logically up */ +#define SK_PNMI_EVT_RLMT_PORT_DOWN 11 /* Port went logically down */ +#define SK_PNMI_EVT_RLMT_SEGMENTATION 13 /* Two SP root bridges found */ +#define SK_PNMI_EVT_RLMT_ACTIVE_DOWN 14 /* Port went logically down */ +#define SK_PNMI_EVT_RLMT_ACTIVE_UP 15 /* Port came logically up */ +#define SK_PNMI_EVT_RLMT_SET_NETS 16 /* Number of nets (1 or 2). */ +#define SK_PNMI_EVT_VCT_RESET 17 /* VCT port reset timer event started with SET. */ + +/* + * Return values + */ +#define SK_PNMI_ERR_OK 0 +#define SK_PNMI_ERR_GENERAL 1 +#define SK_PNMI_ERR_TOO_SHORT 2 +#define SK_PNMI_ERR_BAD_VALUE 3 +#define SK_PNMI_ERR_READ_ONLY 4 +#define SK_PNMI_ERR_UNKNOWN_OID 5 +#define SK_PNMI_ERR_UNKNOWN_INST 6 +#define SK_PNMI_ERR_UNKNOWN_NET 7 +#define SK_PNMI_ERR_NOT_SUPPORTED 10 + +/* + * Return values of driver reset function SK_DRIVER_RESET() and + * driver event function SK_DRIVER_EVENT() + */ +#define SK_PNMI_ERR_OK 0 +#define SK_PNMI_ERR_FAIL 1 + +/* + * Return values of driver test function SK_DRIVER_SELFTEST() + */ +#define SK_PNMI_TST_UNKNOWN (1 << 0) +#define SK_PNMI_TST_TRANCEIVER (1 << 1) +#define SK_PNMI_TST_ASIC (1 << 2) +#define SK_PNMI_TST_SENSOR (1 << 3) +#define SK_PNMI_TST_POWERMGMT (1 << 4) +#define SK_PNMI_TST_PCI (1 << 5) +#define SK_PNMI_TST_MAC (1 << 6) + +/* + * RLMT specific definitions + */ +#define SK_PNMI_RLMT_STATUS_STANDBY 1 +#define SK_PNMI_RLMT_STATUS_ACTIVE 2 +#define SK_PNMI_RLMT_STATUS_ERROR 3 + +#define SK_PNMI_RLMT_LSTAT_PHY_DOWN 1 +#define SK_PNMI_RLMT_LSTAT_AUTONEG 2 +#define SK_PNMI_RLMT_LSTAT_LOG_DOWN 3 +#define SK_PNMI_RLMT_LSTAT_LOG_UP 4 +#define SK_PNMI_RLMT_LSTAT_INDETERMINATED 5 + +#define SK_PNMI_RLMT_MODE_CHK_LINK (SK_RLMT_CHECK_LINK) +#define SK_PNMI_RLMT_MODE_CHK_RX (SK_RLMT_CHECK_LOC_LINK) +#define SK_PNMI_RLMT_MODE_CHK_SPT (SK_RLMT_CHECK_SEG) +/* #define SK_PNMI_RLMT_MODE_CHK_EX */ + +/* + * OID definition + */ +#ifndef _NDIS_ /* Check, whether NDIS already included OIDs */ + +#define OID_GEN_XMIT_OK 0x00020101 +#define OID_GEN_RCV_OK 0x00020102 +#define OID_GEN_XMIT_ERROR 0x00020103 +#define OID_GEN_RCV_ERROR 0x00020104 +#define OID_GEN_RCV_NO_BUFFER 0x00020105 + +/* #define OID_GEN_DIRECTED_BYTES_XMIT 0x00020201 */ +#define OID_GEN_DIRECTED_FRAMES_XMIT 0x00020202 +/* #define OID_GEN_MULTICAST_BYTES_XMIT 0x00020203 */ +#define OID_GEN_MULTICAST_FRAMES_XMIT 0x00020204 +/* #define OID_GEN_BROADCAST_BYTES_XMIT 0x00020205 */ +#define OID_GEN_BROADCAST_FRAMES_XMIT 0x00020206 +/* #define OID_GEN_DIRECTED_BYTES_RCV 0x00020207 */ +#define OID_GEN_DIRECTED_FRAMES_RCV 0x00020208 +/* #define OID_GEN_MULTICAST_BYTES_RCV 0x00020209 */ +#define OID_GEN_MULTICAST_FRAMES_RCV 0x0002020A +/* #define OID_GEN_BROADCAST_BYTES_RCV 0x0002020B */ +#define OID_GEN_BROADCAST_FRAMES_RCV 0x0002020C +#define OID_GEN_RCV_CRC_ERROR 0x0002020D +#define OID_GEN_TRANSMIT_QUEUE_LENGTH 0x0002020E + +#define OID_802_3_PERMANENT_ADDRESS 0x01010101 +#define OID_802_3_CURRENT_ADDRESS 0x01010102 +/* #define OID_802_3_MULTICAST_LIST 0x01010103 */ +/* #define OID_802_3_MAXIMUM_LIST_SIZE 0x01010104 */ +/* #define OID_802_3_MAC_OPTIONS 0x01010105 */ + +#define OID_802_3_RCV_ERROR_ALIGNMENT 0x01020101 +#define OID_802_3_XMIT_ONE_COLLISION 0x01020102 +#define OID_802_3_XMIT_MORE_COLLISIONS 0x01020103 +#define OID_802_3_XMIT_DEFERRED 0x01020201 +#define OID_802_3_XMIT_MAX_COLLISIONS 0x01020202 +#define OID_802_3_RCV_OVERRUN 0x01020203 +#define OID_802_3_XMIT_UNDERRUN 0x01020204 +#define OID_802_3_XMIT_TIMES_CRS_LOST 0x01020206 +#define OID_802_3_XMIT_LATE_COLLISIONS 0x01020207 + +/* + * PnP and PM OIDs + */ +#ifdef SK_POWER_MGMT +#define OID_PNP_CAPABILITIES 0xFD010100 +#define OID_PNP_SET_POWER 0xFD010101 +#define OID_PNP_QUERY_POWER 0xFD010102 +#define OID_PNP_ADD_WAKE_UP_PATTERN 0xFD010103 +#define OID_PNP_REMOVE_WAKE_UP_PATTERN 0xFD010104 +#define OID_PNP_ENABLE_WAKE_UP 0xFD010106 +#endif /* SK_POWER_MGMT */ + +#endif /* _NDIS_ */ + +#define OID_SKGE_MDB_VERSION 0xFF010100 +#define OID_SKGE_SUPPORTED_LIST 0xFF010101 +#define OID_SKGE_VPD_FREE_BYTES 0xFF010102 +#define OID_SKGE_VPD_ENTRIES_LIST 0xFF010103 +#define OID_SKGE_VPD_ENTRIES_NUMBER 0xFF010104 +#define OID_SKGE_VPD_KEY 0xFF010105 +#define OID_SKGE_VPD_VALUE 0xFF010106 +#define OID_SKGE_VPD_ACCESS 0xFF010107 +#define OID_SKGE_VPD_ACTION 0xFF010108 + +#define OID_SKGE_PORT_NUMBER 0xFF010110 +#define OID_SKGE_DEVICE_TYPE 0xFF010111 +#define OID_SKGE_DRIVER_DESCR 0xFF010112 +#define OID_SKGE_DRIVER_VERSION 0xFF010113 +#define OID_SKGE_HW_DESCR 0xFF010114 +#define OID_SKGE_HW_VERSION 0xFF010115 +#define OID_SKGE_CHIPSET 0xFF010116 +#define OID_SKGE_ACTION 0xFF010117 +#define OID_SKGE_RESULT 0xFF010118 +#define OID_SKGE_BUS_TYPE 0xFF010119 +#define OID_SKGE_BUS_SPEED 0xFF01011A +#define OID_SKGE_BUS_WIDTH 0xFF01011B +/* 0xFF01011C unused */ +#define OID_SKGE_DIAG_ACTION 0xFF01011D +#define OID_SKGE_DIAG_RESULT 0xFF01011E +#define OID_SKGE_MTU 0xFF01011F +#define OID_SKGE_PHYS_CUR_ADDR 0xFF010120 +#define OID_SKGE_PHYS_FAC_ADDR 0xFF010121 +#define OID_SKGE_PMD 0xFF010122 +#define OID_SKGE_CONNECTOR 0xFF010123 +#define OID_SKGE_LINK_CAP 0xFF010124 +#define OID_SKGE_LINK_MODE 0xFF010125 +#define OID_SKGE_LINK_MODE_STATUS 0xFF010126 +#define OID_SKGE_LINK_STATUS 0xFF010127 +#define OID_SKGE_FLOWCTRL_CAP 0xFF010128 +#define OID_SKGE_FLOWCTRL_MODE 0xFF010129 +#define OID_SKGE_FLOWCTRL_STATUS 0xFF01012A +#define OID_SKGE_PHY_OPERATION_CAP 0xFF01012B +#define OID_SKGE_PHY_OPERATION_MODE 0xFF01012C +#define OID_SKGE_PHY_OPERATION_STATUS 0xFF01012D +#define OID_SKGE_MULTICAST_LIST 0xFF01012E +#define OID_SKGE_CURRENT_PACKET_FILTER 0xFF01012F + +#define OID_SKGE_TRAP 0xFF010130 +#define OID_SKGE_TRAP_NUMBER 0xFF010131 + +#define OID_SKGE_RLMT_MODE 0xFF010140 +#define OID_SKGE_RLMT_PORT_NUMBER 0xFF010141 +#define OID_SKGE_RLMT_PORT_ACTIVE 0xFF010142 +#define OID_SKGE_RLMT_PORT_PREFERRED 0xFF010143 + +#define OID_SKGE_RLMT_MONITOR_NUMBER 0xFF010150 +#define OID_SKGE_RLMT_MONITOR_INDEX 0xFF010151 +#define OID_SKGE_RLMT_MONITOR_ADDR 0xFF010152 +#define OID_SKGE_RLMT_MONITOR_ERRS 0xFF010153 +#define OID_SKGE_RLMT_MONITOR_TIMESTAMP 0xFF010154 +#define OID_SKGE_RLMT_MONITOR_ADMIN 0xFF010155 + +#define OID_SKGE_INTERMEDIATE_SUPPORT 0xFF010160 +#define OID_SKGE_SET_TEAM_MAC_ADDRESS 0xFF010161 +#define OID_SKGE_DEVICE_INFORMATION 0xFF010162 + +#define OID_SKGE_SPEED_CAP 0xFF010170 +#define OID_SKGE_SPEED_MODE 0xFF010171 +#define OID_SKGE_SPEED_STATUS 0xFF010172 + +#define OID_SKGE_BOARDLEVEL 0xFF010180 + +#define OID_SKGE_SENSOR_NUMBER 0xFF020100 +#define OID_SKGE_SENSOR_INDEX 0xFF020101 +#define OID_SKGE_SENSOR_DESCR 0xFF020102 +#define OID_SKGE_SENSOR_TYPE 0xFF020103 +#define OID_SKGE_SENSOR_VALUE 0xFF020104 +#define OID_SKGE_SENSOR_WAR_THRES_LOW 0xFF020105 +#define OID_SKGE_SENSOR_WAR_THRES_UPP 0xFF020106 +#define OID_SKGE_SENSOR_ERR_THRES_LOW 0xFF020107 +#define OID_SKGE_SENSOR_ERR_THRES_UPP 0xFF020108 +#define OID_SKGE_SENSOR_STATUS 0xFF020109 +#define OID_SKGE_SENSOR_WAR_CTS 0xFF02010A +#define OID_SKGE_SENSOR_ERR_CTS 0xFF02010B +#define OID_SKGE_SENSOR_WAR_TIME 0xFF02010C +#define OID_SKGE_SENSOR_ERR_TIME 0xFF02010D + +#define OID_SKGE_CHKSM_NUMBER 0xFF020110 +#define OID_SKGE_CHKSM_RX_OK_CTS 0xFF020111 +#define OID_SKGE_CHKSM_RX_UNABLE_CTS 0xFF020112 +#define OID_SKGE_CHKSM_RX_ERR_CTS 0xFF020113 +#define OID_SKGE_CHKSM_TX_OK_CTS 0xFF020114 +#define OID_SKGE_CHKSM_TX_UNABLE_CTS 0xFF020115 + +#define OID_SKGE_STAT_TX 0xFF020120 +#define OID_SKGE_STAT_TX_OCTETS 0xFF020121 +#define OID_SKGE_STAT_TX_BROADCAST 0xFF020122 +#define OID_SKGE_STAT_TX_MULTICAST 0xFF020123 +#define OID_SKGE_STAT_TX_UNICAST 0xFF020124 +#define OID_SKGE_STAT_TX_LONGFRAMES 0xFF020125 +#define OID_SKGE_STAT_TX_BURST 0xFF020126 +#define OID_SKGE_STAT_TX_PFLOWC 0xFF020127 +#define OID_SKGE_STAT_TX_FLOWC 0xFF020128 +#define OID_SKGE_STAT_TX_SINGLE_COL 0xFF020129 +#define OID_SKGE_STAT_TX_MULTI_COL 0xFF02012A +#define OID_SKGE_STAT_TX_EXCESS_COL 0xFF02012B +#define OID_SKGE_STAT_TX_LATE_COL 0xFF02012C +#define OID_SKGE_STAT_TX_DEFFERAL 0xFF02012D +#define OID_SKGE_STAT_TX_EXCESS_DEF 0xFF02012E +#define OID_SKGE_STAT_TX_UNDERRUN 0xFF02012F +#define OID_SKGE_STAT_TX_CARRIER 0xFF020130 +/* #define OID_SKGE_STAT_TX_UTIL 0xFF020131 */ +#define OID_SKGE_STAT_TX_64 0xFF020132 +#define OID_SKGE_STAT_TX_127 0xFF020133 +#define OID_SKGE_STAT_TX_255 0xFF020134 +#define OID_SKGE_STAT_TX_511 0xFF020135 +#define OID_SKGE_STAT_TX_1023 0xFF020136 +#define OID_SKGE_STAT_TX_MAX 0xFF020137 +#define OID_SKGE_STAT_TX_SYNC 0xFF020138 +#define OID_SKGE_STAT_TX_SYNC_OCTETS 0xFF020139 +#define OID_SKGE_STAT_RX 0xFF02013A +#define OID_SKGE_STAT_RX_OCTETS 0xFF02013B +#define OID_SKGE_STAT_RX_BROADCAST 0xFF02013C +#define OID_SKGE_STAT_RX_MULTICAST 0xFF02013D +#define OID_SKGE_STAT_RX_UNICAST 0xFF02013E +#define OID_SKGE_STAT_RX_PFLOWC 0xFF02013F +#define OID_SKGE_STAT_RX_FLOWC 0xFF020140 +#define OID_SKGE_STAT_RX_PFLOWC_ERR 0xFF020141 +#define OID_SKGE_STAT_RX_FLOWC_UNKWN 0xFF020142 +#define OID_SKGE_STAT_RX_BURST 0xFF020143 +#define OID_SKGE_STAT_RX_MISSED 0xFF020144 +#define OID_SKGE_STAT_RX_FRAMING 0xFF020145 +#define OID_SKGE_STAT_RX_OVERFLOW 0xFF020146 +#define OID_SKGE_STAT_RX_JABBER 0xFF020147 +#define OID_SKGE_STAT_RX_CARRIER 0xFF020148 +#define OID_SKGE_STAT_RX_IR_LENGTH 0xFF020149 +#define OID_SKGE_STAT_RX_SYMBOL 0xFF02014A +#define OID_SKGE_STAT_RX_SHORTS 0xFF02014B +#define OID_SKGE_STAT_RX_RUNT 0xFF02014C +#define OID_SKGE_STAT_RX_CEXT 0xFF02014D +#define OID_SKGE_STAT_RX_TOO_LONG 0xFF02014E +#define OID_SKGE_STAT_RX_FCS 0xFF02014F +/* #define OID_SKGE_STAT_RX_UTIL 0xFF020150 */ +#define OID_SKGE_STAT_RX_64 0xFF020151 +#define OID_SKGE_STAT_RX_127 0xFF020152 +#define OID_SKGE_STAT_RX_255 0xFF020153 +#define OID_SKGE_STAT_RX_511 0xFF020154 +#define OID_SKGE_STAT_RX_1023 0xFF020155 +#define OID_SKGE_STAT_RX_MAX 0xFF020156 +#define OID_SKGE_STAT_RX_LONGFRAMES 0xFF020157 + +#define OID_SKGE_RLMT_CHANGE_CTS 0xFF020160 +#define OID_SKGE_RLMT_CHANGE_TIME 0xFF020161 +#define OID_SKGE_RLMT_CHANGE_ESTIM 0xFF020162 +#define OID_SKGE_RLMT_CHANGE_THRES 0xFF020163 + +#define OID_SKGE_RLMT_PORT_INDEX 0xFF020164 +#define OID_SKGE_RLMT_STATUS 0xFF020165 +#define OID_SKGE_RLMT_TX_HELLO_CTS 0xFF020166 +#define OID_SKGE_RLMT_RX_HELLO_CTS 0xFF020167 +#define OID_SKGE_RLMT_TX_SP_REQ_CTS 0xFF020168 +#define OID_SKGE_RLMT_RX_SP_CTS 0xFF020169 + +#define OID_SKGE_TX_SW_QUEUE_LEN 0xFF020170 +#define OID_SKGE_TX_SW_QUEUE_MAX 0xFF020171 +#define OID_SKGE_TX_RETRY 0xFF020172 +#define OID_SKGE_RX_INTR_CTS 0xFF020173 +#define OID_SKGE_TX_INTR_CTS 0xFF020174 +#define OID_SKGE_RX_NO_BUF_CTS 0xFF020175 +#define OID_SKGE_TX_NO_BUF_CTS 0xFF020176 +#define OID_SKGE_TX_USED_DESCR_NO 0xFF020177 +#define OID_SKGE_RX_DELIVERED_CTS 0xFF020178 +#define OID_SKGE_RX_OCTETS_DELIV_CTS 0xFF020179 +#define OID_SKGE_RX_HW_ERROR_CTS 0xFF02017A +#define OID_SKGE_TX_HW_ERROR_CTS 0xFF02017B +#define OID_SKGE_IN_ERRORS_CTS 0xFF02017C +#define OID_SKGE_OUT_ERROR_CTS 0xFF02017D +#define OID_SKGE_ERR_RECOVERY_CTS 0xFF02017E +#define OID_SKGE_SYSUPTIME 0xFF02017F + +#define OID_SKGE_ALL_DATA 0xFF020190 + +/* Defines for VCT. */ +#define OID_SKGE_VCT_GET 0xFF020200 +#define OID_SKGE_VCT_SET 0xFF020201 +#define OID_SKGE_VCT_STATUS 0xFF020202 +#define OID_SKGE_VCT_CAPABILITIES 0xFF020203 + +#ifdef SK_DIAG_SUPPORT +/* Defines for driver DIAG mode. */ +#define OID_SKGE_DIAG_MODE 0xFF020204 +#endif /* SK_DIAG_SUPPORT */ + +/* New OIDs */ +#define OID_SKGE_DRIVER_RELDATE 0xFF020210 +#define OID_SKGE_DRIVER_FILENAME 0xFF020211 +#define OID_SKGE_CHIPID 0xFF020212 +#define OID_SKGE_RAMSIZE 0xFF020213 +#define OID_SKGE_VAUXAVAIL 0xFF020214 +#define OID_SKGE_PHY_TYPE 0xFF020215 +#define OID_SKGE_PHY_LP_MODE 0xFF020216 + +/* + * Added for new DualNet IM driver V2 + * these OIDs should later be in pnmi.h + */ +#define OID_SKGE_MAC_COUNT 0xFF020217 +#define OID_SKGE_DUALNET_MODE 0xFF020218 +#define OID_SKGE_SET_TAGHEADER 0xFF020219 + +#ifdef SK_ASF +/* Defines for ASF */ +#define OID_SKGE_ASF 0xFF02021a +#define OID_SKGE_ASF_STORE_CONFIG 0xFF02021b +#define OID_SKGE_ASF_ENA 0xFF02021c +#define OID_SKGE_ASF_RETRANS 0xFF02021d +#define OID_SKGE_ASF_RETRANS_INT 0xFF02021e +#define OID_SKGE_ASF_HB_ENA 0xFF02021f +#define OID_SKGE_ASF_HB_INT 0xFF020220 +#define OID_SKGE_ASF_WD_ENA 0xFF020221 +#define OID_SKGE_ASF_WD_TIME 0xFF020222 +#define OID_SKGE_ASF_IP_SOURCE 0xFF020223 +#define OID_SKGE_ASF_MAC_SOURCE 0xFF020224 +#define OID_SKGE_ASF_IP_DEST 0xFF020225 +#define OID_SKGE_ASF_MAC_DEST 0xFF020226 +#define OID_SKGE_ASF_COMMUNITY_NAME 0xFF020227 +#define OID_SKGE_ASF_RSP_ENA 0xFF020228 +#define OID_SKGE_ASF_RETRANS_COUNT_MIN 0xFF020229 +#define OID_SKGE_ASF_RETRANS_COUNT_MAX 0xFF02022a +#define OID_SKGE_ASF_RETRANS_INT_MIN 0xFF02022b +#define OID_SKGE_ASF_RETRANS_INT_MAX 0xFF02022c +#define OID_SKGE_ASF_HB_INT_MIN 0xFF02022d +#define OID_SKGE_ASF_HB_INT_MAX 0xFF02022e +#define OID_SKGE_ASF_WD_TIME_MIN 0xFF02022f +#define OID_SKGE_ASF_WD_TIME_MAX 0xFF020230 +#define OID_SKGE_ASF_HB_CAP 0xFF020231 +#define OID_SKGE_ASF_WD_TIMER_RES 0xFF020232 +#define OID_SKGE_ASF_GUID 0xFF020233 +#define OID_SKGE_ASF_KEY_OP 0xFF020234 +#define OID_SKGE_ASF_KEY_ADM 0xFF020235 +#define OID_SKGE_ASF_KEY_GEN 0xFF020236 +#define OID_SKGE_ASF_CAP 0xFF020237 +#define OID_SKGE_ASF_PAR_1 0xFF020238 +#define OID_SKGE_ASF_OVERALL_OID 0xFF020239 +#endif /* SK_ASF */ + + +// Defined for yukon2 path only +#define OID_SKGE_UPPER_MINIPORT 0xFF02023D + + +#ifdef SK_ASF +/* Defines for ASF */ +#define OID_SKGE_ASF_FWVER_OID 0xFF020240 +#define OID_SKGE_ASF_ACPI_OID 0xFF020241 +#define OID_SKGE_ASF_SMBUS_OID 0xFF020242 +#endif /* SK_ASF */ + + +/* VCT struct to store a backup copy of VCT data after a port reset. */ +typedef struct s_PnmiVct { + SK_U8 VctStatus; + SK_U8 CableLen; + SK_U32 MdiPairLen[4]; + SK_U8 MdiPairSts[4]; +} SK_PNMI_VCT; + + +/* VCT status values (to be given to CPA via OID_SKGE_VCT_STATUS). */ +#define SK_PNMI_VCT_NONE 0x00 +#define SK_PNMI_VCT_OLD_VCT_DATA 0x01 +#define SK_PNMI_VCT_NEW_VCT_DATA 0x02 +#define SK_PNMI_VCT_OLD_DSP_DATA 0x04 +#define SK_PNMI_VCT_NEW_DSP_DATA 0x08 +#define SK_PNMI_VCT_RUNNING 0x10 + + +/* VCT cable test status. */ +#define SK_PNMI_VCT_NORMAL_CABLE 0 +#define SK_PNMI_VCT_SHORT_CABLE 1 +#define SK_PNMI_VCT_OPEN_CABLE 2 +#define SK_PNMI_VCT_TEST_FAIL 3 +#define SK_PNMI_VCT_IMPEDANCE_MISMATCH 4 +#define SK_PNMI_VCT_NOT_PRESENT 5 + +/* VCT capabilities (needed for OID_SKGE_VCT_CAPABILITIES. */ +#define SK_PNMI_VCT_SUPPORTED 1 +#define SK_PNMI_VCT_NOT_SUPPORTED 0 + +#define OID_SKGE_TRAP_SEN_WAR_LOW 500 +#define OID_SKGE_TRAP_SEN_WAR_UPP 501 +#define OID_SKGE_TRAP_SEN_ERR_LOW 502 +#define OID_SKGE_TRAP_SEN_ERR_UPP 503 +#define OID_SKGE_TRAP_RLMT_CHANGE_THRES 520 +#define OID_SKGE_TRAP_RLMT_CHANGE_PORT 521 +#define OID_SKGE_TRAP_RLMT_PORT_DOWN 522 +#define OID_SKGE_TRAP_RLMT_PORT_UP 523 +#define OID_SKGE_TRAP_RLMT_SEGMENTATION 524 + +#ifdef SK_DIAG_SUPPORT +/* Defines for driver DIAG mode. */ +#define SK_DIAG_ATTACHED 2 +#define SK_DIAG_RUNNING 1 +#define SK_DIAG_IDLE 0 +#endif /* SK_DIAG_SUPPORT */ + +/* + * Generic PNMI IOCTL subcommand definitions. + */ +#define SK_GET_SINGLE_VAR 1 +#define SK_SET_SINGLE_VAR 2 +#define SK_PRESET_SINGLE_VAR 3 +#define SK_GET_FULL_MIB 4 +#define SK_SET_FULL_MIB 5 +#define SK_PRESET_FULL_MIB 6 + +/* + * Define error numbers and messages for syslog + */ +#define SK_PNMI_ERR001 (SK_ERRBASE_PNMI + 1) +#define SK_PNMI_ERR001MSG "SkPnmiGetStruct: Unknown OID" +#define SK_PNMI_ERR002 (SK_ERRBASE_PNMI + 2) +#define SK_PNMI_ERR002MSG "SkPnmiGetStruct: Cannot read VPD keys" +#define SK_PNMI_ERR003 (SK_ERRBASE_PNMI + 3) +#define SK_PNMI_ERR003MSG "OidStruct: Called with wrong OID" +#define SK_PNMI_ERR004 (SK_ERRBASE_PNMI + 4) +#define SK_PNMI_ERR004MSG "OidStruct: Called with wrong action" +#define SK_PNMI_ERR005 (SK_ERRBASE_PNMI + 5) +#define SK_PNMI_ERR005MSG "Perform: Cannot reset driver" +#define SK_PNMI_ERR006 (SK_ERRBASE_PNMI + 6) +#define SK_PNMI_ERR006MSG "Perform: Unknown OID action command" +#define SK_PNMI_ERR007 (SK_ERRBASE_PNMI + 7) +#define SK_PNMI_ERR007MSG "General: Driver description not initialized" +#define SK_PNMI_ERR008 (SK_ERRBASE_PNMI + 8) +#define SK_PNMI_ERR008MSG "Addr: Tried to get unknown OID" +#define SK_PNMI_ERR009 (SK_ERRBASE_PNMI + 9) +#define SK_PNMI_ERR009MSG "Addr: Unknown OID" +#define SK_PNMI_ERR010 (SK_ERRBASE_PNMI + 10) +#define SK_PNMI_ERR010MSG "CsumStat: Unknown OID" +#define SK_PNMI_ERR011 (SK_ERRBASE_PNMI + 11) +#define SK_PNMI_ERR011MSG "SensorStat: Sensor descr string too long" +#define SK_PNMI_ERR012 (SK_ERRBASE_PNMI + 12) +#define SK_PNMI_ERR012MSG "SensorStat: Unknown OID" +#define SK_PNMI_ERR013 (SK_ERRBASE_PNMI + 13) +#define SK_PNMI_ERR013MSG "" +#define SK_PNMI_ERR014 (SK_ERRBASE_PNMI + 14) +#define SK_PNMI_ERR014MSG "Vpd: Cannot read VPD keys" +#define SK_PNMI_ERR015 (SK_ERRBASE_PNMI + 15) +#define SK_PNMI_ERR015MSG "Vpd: Internal array for VPD keys too small" +#define SK_PNMI_ERR016 (SK_ERRBASE_PNMI + 16) +#define SK_PNMI_ERR016MSG "Vpd: Key string too long" +#define SK_PNMI_ERR017 (SK_ERRBASE_PNMI + 17) +#define SK_PNMI_ERR017MSG "Vpd: Invalid VPD status pointer" +#define SK_PNMI_ERR018 (SK_ERRBASE_PNMI + 18) +#define SK_PNMI_ERR018MSG "Vpd: VPD data not valid" +#define SK_PNMI_ERR019 (SK_ERRBASE_PNMI + 19) +#define SK_PNMI_ERR019MSG "Vpd: VPD entries list string too long" +#define SK_PNMI_ERR021 (SK_ERRBASE_PNMI + 21) +#define SK_PNMI_ERR021MSG "Vpd: VPD data string too long" +#define SK_PNMI_ERR022 (SK_ERRBASE_PNMI + 22) +#define SK_PNMI_ERR022MSG "Vpd: VPD data string too long should be errored before" +#define SK_PNMI_ERR023 (SK_ERRBASE_PNMI + 23) +#define SK_PNMI_ERR023MSG "Vpd: Unknown OID in get action" +#define SK_PNMI_ERR024 (SK_ERRBASE_PNMI + 24) +#define SK_PNMI_ERR024MSG "Vpd: Unknown OID in preset/set action" +#define SK_PNMI_ERR025 (SK_ERRBASE_PNMI + 25) +#define SK_PNMI_ERR025MSG "Vpd: Cannot write VPD after modify entry" +#define SK_PNMI_ERR026 (SK_ERRBASE_PNMI + 26) +#define SK_PNMI_ERR026MSG "Vpd: Cannot update VPD" +#define SK_PNMI_ERR027 (SK_ERRBASE_PNMI + 27) +#define SK_PNMI_ERR027MSG "Vpd: Cannot delete VPD entry" +#define SK_PNMI_ERR028 (SK_ERRBASE_PNMI + 28) +#define SK_PNMI_ERR028MSG "Vpd: Cannot update VPD after delete entry" +#define SK_PNMI_ERR029 (SK_ERRBASE_PNMI + 29) +#define SK_PNMI_ERR029MSG "General: Driver description string too long" +#define SK_PNMI_ERR030 (SK_ERRBASE_PNMI + 30) +#define SK_PNMI_ERR030MSG "General: Driver version not initialized" +#define SK_PNMI_ERR031 (SK_ERRBASE_PNMI + 31) +#define SK_PNMI_ERR031MSG "General: Driver version string too long" +#define SK_PNMI_ERR032 (SK_ERRBASE_PNMI + 32) +#define SK_PNMI_ERR032MSG "General: Cannot read VPD Name for HW descr" +#define SK_PNMI_ERR033 (SK_ERRBASE_PNMI + 33) +#define SK_PNMI_ERR033MSG "General: HW description string too long" +#define SK_PNMI_ERR034 (SK_ERRBASE_PNMI + 34) +#define SK_PNMI_ERR034MSG "General: Unknown OID" +#define SK_PNMI_ERR035 (SK_ERRBASE_PNMI + 35) +#define SK_PNMI_ERR035MSG "Rlmt: Unknown OID" +#define SK_PNMI_ERR036 (SK_ERRBASE_PNMI + 36) +#define SK_PNMI_ERR036MSG "" +#define SK_PNMI_ERR037 (SK_ERRBASE_PNMI + 37) +#define SK_PNMI_ERR037MSG "Rlmt: SK_RLMT_MODE_CHANGE event returned not 0" +#define SK_PNMI_ERR038 (SK_ERRBASE_PNMI + 38) +#define SK_PNMI_ERR038MSG "Rlmt: SK_RLMT_PREFPORT_CHANGE event returned not 0" +#define SK_PNMI_ERR039 (SK_ERRBASE_PNMI + 39) +#define SK_PNMI_ERR039MSG "RlmtStat: Unknown OID" +#define SK_PNMI_ERR040 (SK_ERRBASE_PNMI + 40) +#define SK_PNMI_ERR040MSG "PowerManagement: Unknown OID" +#define SK_PNMI_ERR041 (SK_ERRBASE_PNMI + 41) +#define SK_PNMI_ERR041MSG "MacPrivateConf: Unknown OID" +#define SK_PNMI_ERR042 (SK_ERRBASE_PNMI + 42) +#define SK_PNMI_ERR042MSG "MacPrivateConf: SK_HWEV_SET_ROLE returned not 0" +#define SK_PNMI_ERR043 (SK_ERRBASE_PNMI + 43) +#define SK_PNMI_ERR043MSG "MacPrivateConf: SK_HWEV_SET_LMODE returned not 0" +#define SK_PNMI_ERR044 (SK_ERRBASE_PNMI + 44) +#define SK_PNMI_ERR044MSG "MacPrivateConf: SK_HWEV_SET_FLOWMODE returned not 0" +#define SK_PNMI_ERR045 (SK_ERRBASE_PNMI + 45) +#define SK_PNMI_ERR045MSG "MacPrivateConf: SK_HWEV_SET_SPEED returned not 0" +#define SK_PNMI_ERR046 (SK_ERRBASE_PNMI + 46) +#define SK_PNMI_ERR046MSG "Monitor: Unknown OID" +#define SK_PNMI_ERR047 (SK_ERRBASE_PNMI + 47) +#define SK_PNMI_ERR047MSG "SirqUpdate: Event function returned not 0" +#define SK_PNMI_ERR048 (SK_ERRBASE_PNMI + 48) +#define SK_PNMI_ERR048MSG "RlmtUpdate: Event function returned not 0" +#define SK_PNMI_ERR049 (SK_ERRBASE_PNMI + 49) +#define SK_PNMI_ERR049MSG "SkPnmiInit: Invalid size of 'CounterOffset' struct!!" +#define SK_PNMI_ERR050 (SK_ERRBASE_PNMI + 50) +#define SK_PNMI_ERR050MSG "SkPnmiInit: Invalid size of 'StatAddr' table!!" +#define SK_PNMI_ERR051 (SK_ERRBASE_PNMI + 51) +#define SK_PNMI_ERR051MSG "SkPnmiEvent: Port switch suspicious" +#define SK_PNMI_ERR052 (SK_ERRBASE_PNMI + 52) +#define SK_PNMI_ERR052MSG "" +#define SK_PNMI_ERR053 (SK_ERRBASE_PNMI + 53) +#define SK_PNMI_ERR053MSG "General: Driver release date not initialized" +#define SK_PNMI_ERR054 (SK_ERRBASE_PNMI + 54) +#define SK_PNMI_ERR054MSG "General: Driver release date string too long" +#define SK_PNMI_ERR055 (SK_ERRBASE_PNMI + 55) +#define SK_PNMI_ERR055MSG "General: Driver file name not initialized" +#define SK_PNMI_ERR056 (SK_ERRBASE_PNMI + 56) +#define SK_PNMI_ERR056MSG "General: Driver file name string too long" + +/* + * Management counter macros called by the driver + */ +#define SK_PNMI_SET_DRIVER_DESCR(pAC,v) ((pAC)->Pnmi.pDriverDescription = \ + (char *)(v)) + +#define SK_PNMI_SET_DRIVER_VER(pAC,v) ((pAC)->Pnmi.pDriverVersion = \ + (char *)(v)) + +#define SK_PNMI_SET_DRIVER_RELDATE(pAC,v) ((pAC)->Pnmi.pDriverReleaseDate = \ + (char *)(v)) + +#define SK_PNMI_SET_DRIVER_FILENAME(pAC,v) ((pAC)->Pnmi.pDriverFileName = \ + (char *)(v)) + +#define SK_PNMI_CNT_TX_QUEUE_LEN(pAC,v,p) \ + { \ + (pAC)->Pnmi.Port[p].TxSwQueueLen = (SK_U64)(v); \ + if ((pAC)->Pnmi.Port[p].TxSwQueueLen > (pAC)->Pnmi.Port[p].TxSwQueueMax) { \ + (pAC)->Pnmi.Port[p].TxSwQueueMax = (pAC)->Pnmi.Port[p].TxSwQueueLen; \ + } \ + } +#define SK_PNMI_CNT_TX_RETRY(pAC,p) (((pAC)->Pnmi.Port[p].TxRetryCts)++) +#define SK_PNMI_CNT_RX_INTR(pAC,p) (((pAC)->Pnmi.Port[p].RxIntrCts)++) +#define SK_PNMI_CNT_TX_INTR(pAC,p) (((pAC)->Pnmi.Port[p].TxIntrCts)++) +#define SK_PNMI_CNT_NO_RX_BUF(pAC,p) (((pAC)->Pnmi.Port[p].RxNoBufCts)++) +#define SK_PNMI_CNT_NO_TX_BUF(pAC,p) (((pAC)->Pnmi.Port[p].TxNoBufCts)++) +#define SK_PNMI_CNT_USED_TX_DESCR(pAC,v,p) \ + ((pAC)->Pnmi.Port[p].TxUsedDescrNo=(SK_U64)(v)); +#define SK_PNMI_CNT_RX_OCTETS_DELIVERED(pAC,v,p) \ + { \ + ((pAC)->Pnmi.Port[p].RxDeliveredCts)++; \ + (pAC)->Pnmi.Port[p].RxOctetsDeliveredCts += (SK_U64)(v); \ + } +#define SK_PNMI_CNT_ERR_RECOVERY(pAC,p) (((pAC)->Pnmi.Port[p].ErrRecoveryCts)++); + +#define SK_PNMI_CNT_SYNC_OCTETS(pAC,p,v) \ + { \ + if ((p) < SK_MAX_MACS) { \ + ((pAC)->Pnmi.Port[p].StatSyncCts)++; \ + (pAC)->Pnmi.Port[p].StatSyncOctetsCts += (SK_U64)(v); \ + } \ + } + +#define SK_PNMI_CNT_RX_LONGFRAMES(pAC,p) \ + { \ + if ((p) < SK_MAX_MACS) { \ + ((pAC)->Pnmi.Port[p].StatRxLongFrameCts++); \ + } \ + } + +#define SK_PNMI_CNT_RX_FRAMETOOLONG(pAC,p) \ + { \ + if ((p) < SK_MAX_MACS) { \ + ((pAC)->Pnmi.Port[p].StatRxFrameTooLongCts++); \ + } \ + } + +#define SK_PNMI_CNT_RX_PMACC_ERR(pAC,p) \ + { \ + if ((p) < SK_MAX_MACS) { \ + ((pAC)->Pnmi.Port[p].StatRxPMaccErr++); \ + } \ + } + +/* + * Conversion Macros + */ +#define SK_PNMI_PORT_INST2LOG(i) ((unsigned int)(i) - 1) +#define SK_PNMI_PORT_LOG2INST(l) ((unsigned int)(l) + 1) +#define SK_PNMI_PORT_PHYS2LOG(p) ((unsigned int)(p) + 1) +#define SK_PNMI_PORT_LOG2PHYS(pAC,l) ((unsigned int)(l) - 1) +#define SK_PNMI_PORT_PHYS2INST(pAC,p) \ + (pAC->Pnmi.DualNetActiveFlag ? 2 : ((unsigned int)(p) + 2)) +#define SK_PNMI_PORT_INST2PHYS(pAC,i) ((unsigned int)(i) - 2) + +/* + * Structure definition for SkPnmiGetStruct and SkPnmiSetStruct + */ +#define SK_PNMI_VPD_KEY_SIZE 5 +#define SK_PNMI_VPD_BUFSIZE (VPD_SIZE) +#define SK_PNMI_VPD_ENTRIES (VPD_SIZE / 4) +#define SK_PNMI_VPD_DATALEN 128 /* Number of data bytes */ + +#define SK_PNMI_MULTICAST_LISTLEN 64 +#define SK_PNMI_SENSOR_ENTRIES (SK_MAX_SENSORS) +#define SK_PNMI_CHECKSUM_ENTRIES 3 +#define SK_PNMI_MAC_ENTRIES (SK_MAX_MACS + 1) +#define SK_PNMI_MONITOR_ENTRIES 20 +#define SK_PNMI_TRAP_ENTRIES 10 +#define SK_PNMI_TRAPLEN 128 +#define SK_PNMI_STRINGLEN1 80 +#define SK_PNMI_STRINGLEN2 25 +#define SK_PNMI_TRAP_QUEUE_LEN 512 + +typedef struct s_PnmiVpd { + char VpdKey[SK_PNMI_VPD_KEY_SIZE]; + char VpdValue[SK_PNMI_VPD_DATALEN]; + SK_U8 VpdAccess; + SK_U8 VpdAction; +} SK_PNMI_VPD; + +typedef struct s_PnmiSensor { + SK_U8 SensorIndex; + char SensorDescr[SK_PNMI_STRINGLEN2]; + SK_U8 SensorType; + SK_U32 SensorValue; + SK_U32 SensorWarningThresholdLow; + SK_U32 SensorWarningThresholdHigh; + SK_U32 SensorErrorThresholdLow; + SK_U32 SensorErrorThresholdHigh; + SK_U8 SensorStatus; + SK_U64 SensorWarningCts; + SK_U64 SensorErrorCts; + SK_U64 SensorWarningTimestamp; + SK_U64 SensorErrorTimestamp; +} SK_PNMI_SENSOR; + +typedef struct s_PnmiChecksum { + SK_U64 ChecksumRxOkCts; + SK_U64 ChecksumRxUnableCts; + SK_U64 ChecksumRxErrCts; + SK_U64 ChecksumTxOkCts; + SK_U64 ChecksumTxUnableCts; +} SK_PNMI_CHECKSUM; + +typedef struct s_PnmiStat { + SK_U64 StatTxOkCts; + SK_U64 StatTxOctetsOkCts; + SK_U64 StatTxBroadcastOkCts; + SK_U64 StatTxMulticastOkCts; + SK_U64 StatTxUnicastOkCts; + SK_U64 StatTxLongFramesCts; + SK_U64 StatTxBurstCts; + SK_U64 StatTxPauseMacCtrlCts; + SK_U64 StatTxMacCtrlCts; + SK_U64 StatTxSingleCollisionCts; + SK_U64 StatTxMultipleCollisionCts; + SK_U64 StatTxExcessiveCollisionCts; + SK_U64 StatTxLateCollisionCts; + SK_U64 StatTxDeferralCts; + SK_U64 StatTxExcessiveDeferralCts; + SK_U64 StatTxFifoUnderrunCts; + SK_U64 StatTxCarrierCts; + SK_U64 Dummy1; /* StatTxUtilization */ + SK_U64 StatTx64Cts; + SK_U64 StatTx127Cts; + SK_U64 StatTx255Cts; + SK_U64 StatTx511Cts; + SK_U64 StatTx1023Cts; + SK_U64 StatTxMaxCts; + SK_U64 StatTxSyncCts; + SK_U64 StatTxSyncOctetsCts; + SK_U64 StatRxOkCts; + SK_U64 StatRxOctetsOkCts; + SK_U64 StatRxBroadcastOkCts; + SK_U64 StatRxMulticastOkCts; + SK_U64 StatRxUnicastOkCts; + SK_U64 StatRxLongFramesCts; + SK_U64 StatRxPauseMacCtrlCts; + SK_U64 StatRxMacCtrlCts; + SK_U64 StatRxPauseMacCtrlErrorCts; + SK_U64 StatRxMacCtrlUnknownCts; + SK_U64 StatRxBurstCts; + SK_U64 StatRxMissedCts; + SK_U64 StatRxFramingCts; + SK_U64 StatRxFifoOverflowCts; + SK_U64 StatRxJabberCts; + SK_U64 StatRxCarrierCts; + SK_U64 StatRxIRLengthCts; + SK_U64 StatRxSymbolCts; + SK_U64 StatRxShortsCts; + SK_U64 StatRxRuntCts; + SK_U64 StatRxCextCts; + SK_U64 StatRxTooLongCts; + SK_U64 StatRxFcsCts; + SK_U64 Dummy2; /* StatRxUtilization */ + SK_U64 StatRx64Cts; + SK_U64 StatRx127Cts; + SK_U64 StatRx255Cts; + SK_U64 StatRx511Cts; + SK_U64 StatRx1023Cts; + SK_U64 StatRxMaxCts; +} SK_PNMI_STAT; + +typedef struct s_PnmiConf { + char ConfMacCurrentAddr[6]; + char ConfMacFactoryAddr[6]; + SK_U8 ConfPMD; + SK_U8 ConfConnector; + SK_U32 ConfPhyType; + SK_U32 ConfPhyMode; + SK_U8 ConfLinkCapability; + SK_U8 ConfLinkMode; + SK_U8 ConfLinkModeStatus; + SK_U8 ConfLinkStatus; + SK_U8 ConfFlowCtrlCapability; + SK_U8 ConfFlowCtrlMode; + SK_U8 ConfFlowCtrlStatus; + SK_U8 ConfPhyOperationCapability; + SK_U8 ConfPhyOperationMode; + SK_U8 ConfPhyOperationStatus; + SK_U8 ConfSpeedCapability; + SK_U8 ConfSpeedMode; + SK_U8 ConfSpeedStatus; +} SK_PNMI_CONF; + +typedef struct s_PnmiRlmt { + SK_U32 RlmtIndex; + SK_U32 RlmtStatus; + SK_U64 RlmtTxHelloCts; + SK_U64 RlmtRxHelloCts; + SK_U64 RlmtTxSpHelloReqCts; + SK_U64 RlmtRxSpHelloCts; +} SK_PNMI_RLMT; + +typedef struct s_PnmiRlmtMonitor { + SK_U32 RlmtMonitorIndex; + char RlmtMonitorAddr[6]; + SK_U64 RlmtMonitorErrorCts; + SK_U64 RlmtMonitorTimestamp; + SK_U8 RlmtMonitorAdmin; +} SK_PNMI_RLMT_MONITOR; + +typedef struct s_PnmiRequestStatus { + SK_U32 ErrorStatus; + SK_U32 ErrorOffset; +} SK_PNMI_REQUEST_STATUS; + +typedef struct s_PnmiStrucData { + SK_U32 MgmtDBVersion; + SK_PNMI_REQUEST_STATUS ReturnStatus; + SK_U32 VpdFreeBytes; + char VpdEntriesList[SK_PNMI_VPD_ENTRIES * SK_PNMI_VPD_KEY_SIZE]; + SK_U32 VpdEntriesNumber; + SK_PNMI_VPD Vpd[SK_PNMI_VPD_ENTRIES]; + SK_U32 PortNumber; + SK_U32 DeviceType; + char DriverDescr[SK_PNMI_STRINGLEN1]; + char DriverVersion[SK_PNMI_STRINGLEN2]; + char DriverReleaseDate[SK_PNMI_STRINGLEN1]; + char DriverFileName[SK_PNMI_STRINGLEN1]; + char HwDescr[SK_PNMI_STRINGLEN1]; + char HwVersion[SK_PNMI_STRINGLEN2]; + SK_U16 Chipset; + SK_U32 ChipId; + SK_U8 VauxAvail; + SK_U32 RamSize; + SK_U32 MtuSize; + SK_U32 Action; + SK_U32 TestResult; + SK_U8 BusType; + SK_U8 BusSpeed; + SK_U8 BusWidth; + SK_U8 SensorNumber; + SK_PNMI_SENSOR Sensor[SK_PNMI_SENSOR_ENTRIES]; + SK_U8 ChecksumNumber; + SK_PNMI_CHECKSUM Checksum[SK_PNMI_CHECKSUM_ENTRIES]; + SK_PNMI_STAT Stat[SK_PNMI_MAC_ENTRIES]; + SK_PNMI_CONF Conf[SK_PNMI_MAC_ENTRIES]; + SK_U8 RlmtMode; + SK_U32 RlmtPortNumber; + SK_U8 RlmtPortActive; + SK_U8 RlmtPortPreferred; + SK_U64 RlmtChangeCts; + SK_U64 RlmtChangeTime; + SK_U64 RlmtChangeEstimate; + SK_U64 RlmtChangeThreshold; + SK_PNMI_RLMT Rlmt[SK_MAX_MACS]; + SK_U32 RlmtMonitorNumber; + SK_PNMI_RLMT_MONITOR RlmtMonitor[SK_PNMI_MONITOR_ENTRIES]; + SK_U32 TrapNumber; + SK_U8 Trap[SK_PNMI_TRAP_QUEUE_LEN]; + SK_U64 TxSwQueueLen; + SK_U64 TxSwQueueMax; + SK_U64 TxRetryCts; + SK_U64 RxIntrCts; + SK_U64 TxIntrCts; + SK_U64 RxNoBufCts; + SK_U64 TxNoBufCts; + SK_U64 TxUsedDescrNo; + SK_U64 RxDeliveredCts; + SK_U64 RxOctetsDeliveredCts; + SK_U64 RxHwErrorsCts; + SK_U64 TxHwErrorsCts; + SK_U64 InErrorsCts; + SK_U64 OutErrorsCts; + SK_U64 ErrRecoveryCts; + SK_U64 SysUpTime; +} SK_PNMI_STRUCT_DATA; + +#define SK_PNMI_STRUCT_SIZE (sizeof(SK_PNMI_STRUCT_DATA)) + +/* The ReturnStatus field must be located before VpdFreeBytes! */ +#define SK_PNMI_MIN_STRUCT_SIZE ((unsigned int)(SK_UPTR)\ + &(((SK_PNMI_STRUCT_DATA *)0)->VpdFreeBytes)) + +/* + * Various definitions + */ +#define SK_PNMI_EVT_TIMER_CHECK 28125000L /* 28125 ms */ + +#define SK_PNMI_VCT_TIMER_CHECK 4000000L /* 4 sec. */ + +#define SK_PNMI_MAX_PROTOS 3 + +/* + * SK_PNMI_CNT_NO must have the value of the enum SK_PNMI_MAX_IDX. + * Define SK_PNMI_CHECK to check this during init level SK_INIT_IO. + */ +#define SK_PNMI_CNT_NO 66 + +/* + * Estimate data structure + */ +typedef struct s_PnmiEstimate { + unsigned int EstValueIndex; + SK_U64 EstValue[7]; + SK_U64 Estimate; + SK_TIMER EstTimer; +} SK_PNMI_ESTIMATE; + + +/* + * PNMI specific adapter context structure + */ +typedef struct s_PnmiPort { + SK_U64 StatSyncCts; + SK_U64 StatSyncOctetsCts; + SK_U64 StatRxLongFrameCts; + SK_U64 StatRxFrameTooLongCts; + SK_U64 StatRxPMaccErr; + SK_U64 TxSwQueueLen; + SK_U64 TxSwQueueMax; + SK_U64 TxRetryCts; + SK_U64 RxIntrCts; + SK_U64 TxIntrCts; + SK_U64 RxNoBufCts; + SK_U64 TxNoBufCts; + SK_U64 TxUsedDescrNo; + SK_U64 RxDeliveredCts; + SK_U64 RxOctetsDeliveredCts; + SK_U64 RxHwErrorsCts; + SK_U64 TxHwErrorsCts; + SK_U64 InErrorsCts; + SK_U64 OutErrorsCts; + SK_U64 ErrRecoveryCts; + SK_U64 RxShortZeroMark; + SK_U64 CounterOffset[SK_PNMI_CNT_NO]; + SK_U32 CounterHigh[SK_PNMI_CNT_NO]; + SK_BOOL ActiveFlag; + SK_U8 Align[3]; +} SK_PNMI_PORT; + + +typedef struct s_PnmiData { + SK_PNMI_PORT Port [SK_MAX_MACS]; + SK_PNMI_PORT BufPort [SK_MAX_MACS]; /* 2002-09-13 pweber */ + SK_U64 VirtualCounterOffset[SK_PNMI_CNT_NO]; + SK_U32 TestResult; + char HwVersion[10]; + SK_U16 Align01; + + char *pDriverDescription; + char *pDriverVersion; + char *pDriverReleaseDate; + char *pDriverFileName; + + int MacUpdatedFlag; + int RlmtUpdatedFlag; + int SirqUpdatedFlag; + + SK_U64 RlmtChangeCts; + SK_U64 RlmtChangeTime; + SK_PNMI_ESTIMATE RlmtChangeEstimate; + SK_U64 RlmtChangeThreshold; + + SK_U64 StartUpTime; + SK_U32 DeviceType; + char PciBusSpeed; + char PciBusWidth; + char Chipset; + char PMD; + char Connector; + SK_BOOL DualNetActiveFlag; + SK_U16 Align02; + + char TrapBuf[SK_PNMI_TRAP_QUEUE_LEN]; + unsigned int TrapBufFree; + unsigned int TrapQueueBeg; + unsigned int TrapQueueEnd; + unsigned int TrapBufPad; + unsigned int TrapUnique; + SK_U8 VctStatus[SK_MAX_MACS]; + SK_PNMI_VCT VctBackup[SK_MAX_MACS]; + SK_TIMER VctTimeout[SK_MAX_MACS]; +#ifdef SK_DIAG_SUPPORT + SK_U32 DiagAttached; +#endif /* SK_DIAG_SUPPORT */ + SK_BOOL VpdKeyReadError; +} SK_PNMI; + + +/* + * Function prototypes + */ +extern int SkPnmiInit(SK_AC *pAC, SK_IOC IoC, int Level); +extern int SkPnmiGetVar(SK_AC *pAC, SK_IOC IoC, SK_U32 Id, void* pBuf, + unsigned int* pLen, SK_U32 Instance, SK_U32 NetIndex); +extern int SkPnmiPreSetVar(SK_AC *pAC, SK_IOC IoC, SK_U32 Id, + void* pBuf, unsigned int *pLen, SK_U32 Instance, SK_U32 NetIndex); +extern int SkPnmiSetVar(SK_AC *pAC, SK_IOC IoC, SK_U32 Id, void* pBuf, + unsigned int *pLen, SK_U32 Instance, SK_U32 NetIndex); +extern int SkPnmiGetStruct(SK_AC *pAC, SK_IOC IoC, void* pBuf, + unsigned int *pLen, SK_U32 NetIndex); +extern int SkPnmiPreSetStruct(SK_AC *pAC, SK_IOC IoC, void* pBuf, + unsigned int *pLen, SK_U32 NetIndex); +extern int SkPnmiSetStruct(SK_AC *pAC, SK_IOC IoC, void* pBuf, + unsigned int *pLen, SK_U32 NetIndex); +extern int SkPnmiEvent(SK_AC *pAC, SK_IOC IoC, SK_U32 Event, + SK_EVPARA Param); +extern int SkPnmiGenIoctl(SK_AC *pAC, SK_IOC IoC, void * pBuf, + unsigned int * pLen, SK_U32 NetIndex); + +#endif diff -urN linux-2.4.32-600/drivers/net/sk98lin/h/skgesirq.h linux-2.4.32-600-sk98_831/drivers/net/sk98lin/h/skgesirq.h --- linux-2.4.32-600/drivers/net/sk98lin/h/skgesirq.h Sat Mar 20 10:08:19 2004 +++ linux-2.4.32-600-sk98_831/drivers/net/sk98lin/h/skgesirq.h Sun Feb 26 11:13:02 2006 @@ -2,21 +2,24 @@ * * Name: skgesirq.h * Project: Gigabit Ethernet Adapters, Common Modules - * Purpose: SK specific Gigabit Ethernet special IRQ functions + * Version: $Revision: 2.5 $ + * Date: $Date: 2005/12/14 16:11:35 $ + * Purpose: Gigabit Ethernet special IRQ functions * ******************************************************************************/ /****************************************************************************** * + * LICENSE: * (C)Copyright 1998-2002 SysKonnect. - * (C)Copyright 2002-2003 Marvell. + * (C)Copyright 2002-2005 Marvell. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. - * * The information in this file is provided "AS IS" without warranty. + * /LICENSE * ******************************************************************************/ @@ -24,9 +27,9 @@ #define _INC_SKGESIRQ_H_ /* Define return codes of SkGePortCheckUp and CheckShort */ -#define SK_HW_PS_NONE 0 /* No action needed */ -#define SK_HW_PS_RESTART 1 /* Restart needed */ -#define SK_HW_PS_LINK 2 /* Link Up actions needed */ +#define SK_HW_PS_NONE 0 /* No action needed */ +#define SK_HW_PS_RESTART 1 /* Restart needed */ +#define SK_HW_PS_LINK 2 /* Link Up actions needed */ /* * Define the Event the special IRQ/INI module can handle @@ -42,10 +45,10 @@ #define SK_HWEV_SET_SPEED 9 /* Set Link Speed by PNMI */ #define SK_HWEV_HALFDUP_CHK 10 /* Half Duplex Hangup Workaround */ -#define SK_WA_ACT_TIME (5000000UL) /* 5 sec */ -#define SK_WA_INA_TIME (100000UL) /* 100 msec */ +#define SK_WA_ACT_TIME 1000000UL /* 1000 msec (1 sec) */ +#define SK_WA_INA_TIME 100000UL /* 100 msec */ -#define SK_HALFDUP_CHK_TIME (10000UL) /* 10 msec */ +#define SK_HALFDUP_CHK_TIME 10000UL /* 10 msec */ /* * Define the error numbers and messages @@ -73,9 +76,9 @@ #define SKERR_SIRQ_E011 (SKERR_SIRQ_E010+1) #define SKERR_SIRQ_E011MSG "CHECK failure XA2" #define SKERR_SIRQ_E012 (SKERR_SIRQ_E011+1) -#define SKERR_SIRQ_E012MSG "unexpected IRQ Master error" +#define SKERR_SIRQ_E012MSG "Unexpected IRQ Master error" #define SKERR_SIRQ_E013 (SKERR_SIRQ_E012+1) -#define SKERR_SIRQ_E013MSG "unexpected IRQ Status error" +#define SKERR_SIRQ_E013MSG "Unexpected IRQ Status error" #define SKERR_SIRQ_E014 (SKERR_SIRQ_E013+1) #define SKERR_SIRQ_E014MSG "Parity error on RAM (read)" #define SKERR_SIRQ_E015 (SKERR_SIRQ_E014+1) @@ -100,10 +103,35 @@ #define SKERR_SIRQ_E024MSG "FIFO overflow error" #define SKERR_SIRQ_E025 (SKERR_SIRQ_E024+1) #define SKERR_SIRQ_E025MSG "2 Pair Downshift detected" +#define SKERR_SIRQ_E026 (SKERR_SIRQ_E025+1) +#define SKERR_SIRQ_E026MSG "Uncorrectable PCI Express error" +#define SKERR_SIRQ_E027 (SKERR_SIRQ_E026+1) +#define SKERR_SIRQ_E027MSG "PCI Bus Abort detected" +#define SKERR_SIRQ_E028 (SKERR_SIRQ_E027+1) +#define SKERR_SIRQ_E028MSG "Parity error on RAM 1 (read)" +#define SKERR_SIRQ_E029 (SKERR_SIRQ_E028+1) +#define SKERR_SIRQ_E029MSG "Parity error on RAM 1 (write)" +#define SKERR_SIRQ_E030 (SKERR_SIRQ_E029+1) +#define SKERR_SIRQ_E030MSG "Parity error on RAM 2 (read)" +#define SKERR_SIRQ_E031 (SKERR_SIRQ_E030+1) +#define SKERR_SIRQ_E031MSG "Parity error on RAM 2 (write)" +#define SKERR_SIRQ_E032 (SKERR_SIRQ_E031+1) +#define SKERR_SIRQ_E032MSG "TCP segmentation error async. queue 1" +#define SKERR_SIRQ_E033 (SKERR_SIRQ_E032+1) +#define SKERR_SIRQ_E033MSG "TCP segmentation error sync. queue 1" +#define SKERR_SIRQ_E034 (SKERR_SIRQ_E033+1) +#define SKERR_SIRQ_E034MSG "TCP segmentation error async. queue 2" +#define SKERR_SIRQ_E035 (SKERR_SIRQ_E034+1) +#define SKERR_SIRQ_E035MSG "TCP segmentation error sync. queue 2" +#define SKERR_SIRQ_E036 (SKERR_SIRQ_E035+1) +#define SKERR_SIRQ_E036MSG "CHECK failure polling unit" extern void SkGeSirqIsr(SK_AC *pAC, SK_IOC IoC, SK_U32 Istatus); extern int SkGeSirqEvent(SK_AC *pAC, SK_IOC IoC, SK_U32 Event, SK_EVPARA Para); extern void SkHWLinkUp(SK_AC *pAC, SK_IOC IoC, int Port); extern void SkHWLinkDown(SK_AC *pAC, SK_IOC IoC, int Port); +extern void SkGeYuSirqIsr(SK_AC *pAC, SK_IOC IoC, SK_U32 Istatus); +extern void SkYuk2SirqIsr(SK_AC *pAC, SK_IOC IoC, SK_U32 Istatus); #endif /* _INC_SKGESIRQ_H_ */ + diff -urN linux-2.4.32-600/drivers/net/sk98lin/h/skgetwsi.h linux-2.4.32-600-sk98_831/drivers/net/sk98lin/h/skgetwsi.h --- linux-2.4.32-600/drivers/net/sk98lin/h/skgetwsi.h Thu Jan 1 01:00:00 1970 +++ linux-2.4.32-600-sk98_831/drivers/net/sk98lin/h/skgetwsi.h Sun Feb 26 11:12:56 2006 @@ -0,0 +1,241 @@ +/****************************************************************************** + * + * Name: skgetwsi.h + * Project: Gigabit Ethernet Adapters, TWSI-Module + * Version: $Revision: 1.7 $ + * Date: $Date: 2004/12/20 14:48:51 $ + * Purpose: Special defines for TWSI + * + ******************************************************************************/ + +/****************************************************************************** + * + * (C)Copyright 1998-2002 SysKonnect. + * (C)Copyright 2002-2004 Marvell. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * The information in this file is provided "AS IS" without warranty. + * + ******************************************************************************/ + +/* + * SKGETWSI.H contains all SK-98xx specific defines for the TWSI handling + */ + +#ifndef _INC_SKGETWSI_H_ +#define _INC_SKGETWSI_H_ + +/* + * Macros to access the B2_I2C_CTRL + */ +#define SK_I2C_CTL(IoC, flag, dev, dev_size, reg, burst) \ + SK_OUT32(IoC, B2_I2C_CTRL,\ + (flag ? 0x80000000UL : 0x0L) | \ + (((SK_U32)reg << 16) & I2C_ADDR) | \ + (((SK_U32)dev << 9) & I2C_DEV_SEL) | \ + (dev_size & I2C_DEV_SIZE) | \ + ((burst << 4) & I2C_BURST_LEN)) + +#define SK_I2C_STOP(IoC) { \ + SK_U32 I2cCtrl; \ + SK_IN32(IoC, B2_I2C_CTRL, &I2cCtrl); \ + SK_OUT32(IoC, B2_I2C_CTRL, I2cCtrl | I2C_STOP); \ +} + +#define SK_I2C_GET_CTL(IoC, pI2cCtrl) SK_IN32(IoC, B2_I2C_CTRL, pI2cCtrl) + +/* + * Macros to access the TWSI SW Registers + */ +#define SK_I2C_SET_BIT(IoC, SetBits) { \ + SK_U8 OrgBits; \ + SK_IN8(IoC, B2_I2C_SW, &OrgBits); \ + SK_OUT8(IoC, B2_I2C_SW, OrgBits | (SK_U8)(SetBits)); \ +} + +#define SK_I2C_CLR_BIT(IoC, ClrBits) { \ + SK_U8 OrgBits; \ + SK_IN8(IoC, B2_I2C_SW, &OrgBits); \ + SK_OUT8(IoC, B2_I2C_SW, OrgBits & ~((SK_U8)(ClrBits))); \ +} + +#define SK_I2C_GET_SW(IoC, pI2cSw) SK_IN8(IoC, B2_I2C_SW, pI2cSw) + +/* + * define the possible sensor states + */ +#define SK_SEN_IDLE 0 /* Idle: sensor not read */ +#define SK_SEN_VALUE 1 /* Value Read cycle */ +#define SK_SEN_VALEXT 2 /* Extended Value Read cycle */ + +/* + * Conversion factor to convert read Voltage sensor to milli Volt + * Conversion factor to convert read Temperature sensor to 10th degree Celsius + */ +#define SK_LM80_VT_LSB 22 /* 22mV LSB resolution */ +#define SK_LM80_TEMP_LSB 10 /* 1 degree LSB resolution */ +#define SK_LM80_TEMPEXT_LSB 5 /* 0.5 degree LSB resolution for ext. val. */ + +/* + * formula: counter = (22500*60)/(rpm * divisor * pulses/2) + * assuming: 6500rpm, 4 pulses, divisor 1 + */ +#define SK_LM80_FAN_FAKTOR ((22500L*60)/(1*2)) + +/* + * Define sensor management data + * Maximum is reached on Genesis copper dual port and Yukon-64 + * Board specific maximum is in pAC->I2c.MaxSens + */ +#define SK_MAX_SENSORS 8 /* maximal no. of installed sensors */ +#define SK_MIN_SENSORS 5 /* minimal no. of installed sensors */ + +/* + * To watch the state machine (SM) use the timer in two ways + * instead of one as hitherto + */ +#define SK_TIMER_WATCH_SM 0 /* Watch the SM to finish in a spec. time */ +#define SK_TIMER_NEW_GAUGING 1 /* Start a new gauging when timer expires */ + +/* + * Defines for the individual thresholds + */ + +#define C_PLUS_20 120 / 100 +#define C_PLUS_15 115 / 100 +#define C_PLUS_10 110 / 100 +#define C_PLUS_5 105 / 100 +#define C_MINUS_5 95 / 100 +#define C_MINUS_10 90 / 100 +#define C_MINUS_15 85 / 100 + +/* Temperature sensor */ +#define SK_SEN_TEMP_HIGH_ERR 800 /* Temperature High Err Threshold */ +#define SK_SEN_TEMP_HIGH_WARN 700 /* Temperature High Warn Threshold */ +#define SK_SEN_TEMP_LOW_WARN 100 /* Temperature Low Warn Threshold */ +#define SK_SEN_TEMP_LOW_ERR 0 /* Temperature Low Err Threshold */ + +/* VCC which should be 5 V */ +#define SK_SEN_PCI_5V_HIGH_ERR 5588 /* Voltage PCI High Err Threshold */ +#define SK_SEN_PCI_5V_HIGH_WARN 5346 /* Voltage PCI High Warn Threshold */ +#define SK_SEN_PCI_5V_LOW_WARN 4664 /* Voltage PCI Low Warn Threshold */ +#define SK_SEN_PCI_5V_LOW_ERR 4422 /* Voltage PCI Low Err Threshold */ + +/* + * VIO may be 5 V or 3.3 V. Initialization takes two parts: + * 1. Initialize lowest lower limit and highest higher limit. + * 2. After the first value is read correct the upper or the lower limit to + * the appropriate C constant. + * + * Warning limits are +-5% of the exepected voltage. + * Error limits are +-10% of the expected voltage. + */ + +/* Bug fix AF: 16.Aug.2001: Correct the init base of LM80 sensor */ + +#define SK_SEN_PCI_IO_5V_HIGH_ERR 5566 /* + 10% V PCI-IO High Err Threshold */ +#define SK_SEN_PCI_IO_5V_HIGH_WARN 5324 /* + 5% V PCI-IO High Warn Threshold */ + /* 5000 mVolt */ +#define SK_SEN_PCI_IO_5V_LOW_WARN 4686 /* - 5% V PCI-IO Low Warn Threshold */ +#define SK_SEN_PCI_IO_5V_LOW_ERR 4444 /* - 10% V PCI-IO Low Err Threshold */ + +#define SK_SEN_PCI_IO_RANGE_LIMITER 4000 /* 4000 mV range delimiter */ + +/* correction values for the second pass */ +#define SK_SEN_PCI_IO_3V3_HIGH_ERR 3850 /* + 15% V PCI-IO High Err Threshold */ +#define SK_SEN_PCI_IO_3V3_HIGH_WARN 3674 /* + 10% V PCI-IO High Warn Threshold */ + /* 3300 mVolt */ +#define SK_SEN_PCI_IO_3V3_LOW_WARN 2926 /* - 10% V PCI-IO Low Warn Threshold */ +#define SK_SEN_PCI_IO_3V3_LOW_ERR 2772 /* - 15% V PCI-IO Low Err Threshold */ + +/* + * VDD voltage + */ +#define SK_SEN_VDD_HIGH_ERR 3630 /* Voltage ASIC High Err Threshold */ +#define SK_SEN_VDD_HIGH_WARN 3476 /* Voltage ASIC High Warn Threshold */ +#define SK_SEN_VDD_LOW_WARN 3146 /* Voltage ASIC Low Warn Threshold */ +#define SK_SEN_VDD_LOW_ERR 2970 /* Voltage ASIC Low Err Threshold */ + +/* + * PHY PLL 3V3 voltage + */ +#define SK_SEN_PLL_3V3_HIGH_ERR 3630 /* Voltage PMA High Err Threshold */ +#define SK_SEN_PLL_3V3_HIGH_WARN 3476 /* Voltage PMA High Warn Threshold */ +#define SK_SEN_PLL_3V3_LOW_WARN 3146 /* Voltage PMA Low Warn Threshold */ +#define SK_SEN_PLL_3V3_LOW_ERR 2970 /* Voltage PMA Low Err Threshold */ + +/* + * VAUX (YUKON only) + */ +#define SK_SEN_VAUX_3V3_VAL 3300 /* Voltage VAUX 3.3 Volt */ + +#define SK_SEN_VAUX_3V3_HIGH_ERR (SK_I32)(SK_SEN_VAUX_3V3_VAL * C_PLUS_10) +#define SK_SEN_VAUX_3V3_HIGH_WARN (SK_I32)(SK_SEN_VAUX_3V3_VAL * C_PLUS_5) +#define SK_SEN_VAUX_3V3_LOW_WARN (SK_I32)(SK_SEN_VAUX_3V3_VAL * C_MINUS_5) +#define SK_SEN_VAUX_3V3_LOW_ERR (SK_I32)(SK_SEN_VAUX_3V3_VAL * C_MINUS_10) + +#define SK_SEN_VAUX_RANGE_LIMITER 1000 /* 1000 mV range delimiter */ + +/* + * PHY 2V5 voltage + */ +#define SK_SEN_PHY_2V5_VAL 2500 /* Voltage PHY 2.5 Volt */ + +#define SK_SEN_PHY_2V5_HIGH_ERR (SK_I32)(SK_SEN_PHY_2V5_VAL * C_PLUS_10) +#define SK_SEN_PHY_2V5_HIGH_WARN (SK_I32)(SK_SEN_PHY_2V5_VAL * C_PLUS_5) +#define SK_SEN_PHY_2V5_LOW_WARN (SK_I32)(SK_SEN_PHY_2V5_VAL * C_MINUS_5) +#define SK_SEN_PHY_2V5_LOW_ERR (SK_I32)(SK_SEN_PHY_2V5_VAL * C_MINUS_10) + +/* + * ASIC Core 1V5 voltage (YUKON only) + */ +#define SK_SEN_CORE_1V5_VAL 1500 /* Voltage ASIC Core 1.5 Volt */ + +#define SK_SEN_CORE_1V5_HIGH_ERR (SK_I32)(SK_SEN_CORE_1V5_VAL * C_PLUS_10) +#define SK_SEN_CORE_1V5_HIGH_WARN (SK_I32)(SK_SEN_CORE_1V5_VAL * C_PLUS_5) +#define SK_SEN_CORE_1V5_LOW_WARN (SK_I32)(SK_SEN_CORE_1V5_VAL * C_MINUS_5) +#define SK_SEN_CORE_1V5_LOW_ERR (SK_I32)(SK_SEN_CORE_1V5_VAL * C_MINUS_10) + +/* + * ASIC Core 1V2 (1V3) voltage (YUKON-2 only) + */ +#define SK_SEN_CORE_1V2_VAL 1200 /* Voltage ASIC Core 1.2 Volt */ + +#define SK_SEN_CORE_1V2_HIGH_ERR (SK_I32)(SK_SEN_CORE_1V2_VAL * C_PLUS_20) +#define SK_SEN_CORE_1V2_HIGH_WARN (SK_I32)(SK_SEN_CORE_1V2_VAL * C_PLUS_15) +#define SK_SEN_CORE_1V2_LOW_WARN (SK_I32)(SK_SEN_CORE_1V2_VAL * C_MINUS_5) +#define SK_SEN_CORE_1V2_LOW_ERR (SK_I32)(SK_SEN_CORE_1V2_VAL * C_MINUS_10) + +#define SK_SEN_CORE_1V3_VAL 1300 /* Voltage ASIC Core 1.3 Volt */ + +#define SK_SEN_CORE_1V3_HIGH_ERR (SK_I32)(SK_SEN_CORE_1V3_VAL * C_PLUS_15) +#define SK_SEN_CORE_1V3_HIGH_WARN (SK_I32)(SK_SEN_CORE_1V3_VAL * C_PLUS_10) +#define SK_SEN_CORE_1V3_LOW_WARN (SK_I32)(SK_SEN_CORE_1V3_VAL * C_MINUS_5) +#define SK_SEN_CORE_1V3_LOW_ERR (SK_I32)(SK_SEN_CORE_1V3_VAL * C_MINUS_10) + +/* + * FAN 1 speed + */ +/* assuming: 6500rpm +-15%, 4 pulses, + * warning at: 80 % + * error at: 70 % + * no upper limit + */ +#define SK_SEN_FAN_HIGH_ERR 20000 /* FAN Speed High Err Threshold */ +#define SK_SEN_FAN_HIGH_WARN 20000 /* FAN Speed High Warn Threshold */ +#define SK_SEN_FAN_LOW_WARN 5200 /* FAN Speed Low Warn Threshold */ +#define SK_SEN_FAN_LOW_ERR 4550 /* FAN Speed Low Err Threshold */ + +/* + * Some Voltages need dynamic thresholds + */ +#define SK_SEN_DYN_INIT_NONE 0 /* No dynamic init of thresholds */ +#define SK_SEN_DYN_INIT_PCI_IO 10 /* Init PCI-IO with new thresholds */ +#define SK_SEN_DYN_INIT_VAUX 11 /* Init VAUX with new thresholds */ + +extern int SkLm80ReadSensor(SK_AC *pAC, SK_IOC IoC, SK_SENSOR *pSen); +#endif /* n_INC_SKGETWSI_H */ + diff -urN linux-2.4.32-600/drivers/net/sk98lin/h/ski2c.h linux-2.4.32-600-sk98_831/drivers/net/sk98lin/h/ski2c.h --- linux-2.4.32-600/drivers/net/sk98lin/h/ski2c.h Sat Mar 20 10:08:19 2004 +++ linux-2.4.32-600-sk98_831/drivers/net/sk98lin/h/ski2c.h Thu Jan 1 01:00:00 1970 @@ -1,175 +0,0 @@ -/****************************************************************************** - * - * Name: ski2c.h - * Project: Gigabit Ethernet Adapters, TWSI-Module - * Purpose: Defines to access Voltage and Temperature Sensor - * - ******************************************************************************/ - -/****************************************************************************** - * - * (C)Copyright 1998-2002 SysKonnect. - * (C)Copyright 2002-2003 Marvell. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * The information in this file is provided "AS IS" without warranty. - * - ******************************************************************************/ - -/* - * SKI2C.H contains all I2C specific defines - */ - -#ifndef _SKI2C_H_ -#define _SKI2C_H_ - -typedef struct s_Sensor SK_SENSOR; - -#include "h/skgei2c.h" - -/* - * Define the I2C events. - */ -#define SK_I2CEV_IRQ 1 /* IRQ happened Event */ -#define SK_I2CEV_TIM 2 /* Timeout event */ -#define SK_I2CEV_CLEAR 3 /* Clear MIB Values */ - -/* - * Define READ and WRITE Constants. - */ -#define I2C_READ 0 -#define I2C_WRITE 1 -#define I2C_BURST 1 -#define I2C_SINGLE 0 - -#define SKERR_I2C_E001 (SK_ERRBASE_I2C+0) -#define SKERR_I2C_E001MSG "Sensor index unknown" -#define SKERR_I2C_E002 (SKERR_I2C_E001+1) -#define SKERR_I2C_E002MSG "TWSI: transfer does not complete" -#define SKERR_I2C_E003 (SKERR_I2C_E002+1) -#define SKERR_I2C_E003MSG "LM80: NAK on device send" -#define SKERR_I2C_E004 (SKERR_I2C_E003+1) -#define SKERR_I2C_E004MSG "LM80: NAK on register send" -#define SKERR_I2C_E005 (SKERR_I2C_E004+1) -#define SKERR_I2C_E005MSG "LM80: NAK on device (2) send" -#define SKERR_I2C_E006 (SKERR_I2C_E005+1) -#define SKERR_I2C_E006MSG "Unknown event" -#define SKERR_I2C_E007 (SKERR_I2C_E006+1) -#define SKERR_I2C_E007MSG "LM80 read out of state" -#define SKERR_I2C_E008 (SKERR_I2C_E007+1) -#define SKERR_I2C_E008MSG "Unexpected sensor read completed" -#define SKERR_I2C_E009 (SKERR_I2C_E008+1) -#define SKERR_I2C_E009MSG "WARNING: temperature sensor out of range" -#define SKERR_I2C_E010 (SKERR_I2C_E009+1) -#define SKERR_I2C_E010MSG "WARNING: voltage sensor out of range" -#define SKERR_I2C_E011 (SKERR_I2C_E010+1) -#define SKERR_I2C_E011MSG "ERROR: temperature sensor out of range" -#define SKERR_I2C_E012 (SKERR_I2C_E011+1) -#define SKERR_I2C_E012MSG "ERROR: voltage sensor out of range" -#define SKERR_I2C_E013 (SKERR_I2C_E012+1) -#define SKERR_I2C_E013MSG "ERROR: couldn't init sensor" -#define SKERR_I2C_E014 (SKERR_I2C_E013+1) -#define SKERR_I2C_E014MSG "WARNING: fan sensor out of range" -#define SKERR_I2C_E015 (SKERR_I2C_E014+1) -#define SKERR_I2C_E015MSG "ERROR: fan sensor out of range" -#define SKERR_I2C_E016 (SKERR_I2C_E015+1) -#define SKERR_I2C_E016MSG "TWSI: active transfer does not complete" - -/* - * Define Timeout values - */ -#define SK_I2C_TIM_LONG 2000000L /* 2 seconds */ -#define SK_I2C_TIM_SHORT 100000L /* 100 milliseconds */ -#define SK_I2C_TIM_WATCH 1000000L /* 1 second */ - -/* - * Define trap and error log hold times - */ -#ifndef SK_SEN_ERR_TR_HOLD -#define SK_SEN_ERR_TR_HOLD (4*SK_TICKS_PER_SEC) -#endif -#ifndef SK_SEN_ERR_LOG_HOLD -#define SK_SEN_ERR_LOG_HOLD (60*SK_TICKS_PER_SEC) -#endif -#ifndef SK_SEN_WARN_TR_HOLD -#define SK_SEN_WARN_TR_HOLD (15*SK_TICKS_PER_SEC) -#endif -#ifndef SK_SEN_WARN_LOG_HOLD -#define SK_SEN_WARN_LOG_HOLD (15*60*SK_TICKS_PER_SEC) -#endif - -/* - * Defines for SenType - */ -#define SK_SEN_UNKNOWN 0 -#define SK_SEN_TEMP 1 -#define SK_SEN_VOLT 2 -#define SK_SEN_FAN 3 - -/* - * Define for the SenErrorFlag - */ -#define SK_SEN_ERR_NOT_PRESENT 0 /* Error Flag: Sensor not present */ -#define SK_SEN_ERR_OK 1 /* Error Flag: O.K. */ -#define SK_SEN_ERR_WARN 2 /* Error Flag: Warning */ -#define SK_SEN_ERR_ERR 3 /* Error Flag: Error */ -#define SK_SEN_ERR_FAULTY 4 /* Error Flag: Faulty */ - -/* - * Define the Sensor struct - */ -struct s_Sensor { - char *SenDesc; /* Description */ - int SenType; /* Voltage or Temperature */ - SK_I32 SenValue; /* Current value of the sensor */ - SK_I32 SenThreErrHigh; /* High error Threshhold of this sensor */ - SK_I32 SenThreWarnHigh; /* High warning Threshhold of this sensor */ - SK_I32 SenThreErrLow; /* Lower error Threshold of the sensor */ - SK_I32 SenThreWarnLow; /* Lower warning Threshold of the sensor */ - int SenErrFlag; /* Sensor indicated an error */ - SK_BOOL SenInit; /* Is sensor initialized ? */ - SK_U64 SenErrCts; /* Error trap counter */ - SK_U64 SenWarnCts; /* Warning trap counter */ - SK_U64 SenBegErrTS; /* Begin error timestamp */ - SK_U64 SenBegWarnTS; /* Begin warning timestamp */ - SK_U64 SenLastErrTrapTS; /* Last error trap timestamp */ - SK_U64 SenLastErrLogTS; /* Last error log timestamp */ - SK_U64 SenLastWarnTrapTS; /* Last warning trap timestamp */ - SK_U64 SenLastWarnLogTS; /* Last warning log timestamp */ - int SenState; /* Sensor State (see HW specific include) */ - int (*SenRead)(SK_AC *pAC, SK_IOC IoC, struct s_Sensor *pSen); - /* Sensors read function */ - SK_U16 SenReg; /* Register Address for this sensor */ - SK_U8 SenDev; /* Device Selection for this sensor */ -}; - -typedef struct s_I2c { - SK_SENSOR SenTable[SK_MAX_SENSORS]; /* Sensor Table */ - int CurrSens; /* Which sensor is currently queried */ - int MaxSens; /* Max. number of sensors */ - int TimerMode; /* Use the timer also to watch the state machine */ - int InitLevel; /* Initialized Level */ -#ifndef SK_DIAG - int DummyReads; /* Number of non-checked dummy reads */ - SK_TIMER SenTimer; /* Sensors timer */ -#endif /* !SK_DIAG */ -} SK_I2C; - -extern int SkI2cInit(SK_AC *pAC, SK_IOC IoC, int Level); -extern int SkI2cWrite(SK_AC *pAC, SK_IOC IoC, SK_U32 Data, int Dev, int Size, - int Reg, int Burst); -extern int SkI2cReadSensor(SK_AC *pAC, SK_IOC IoC, SK_SENSOR *pSen); -#ifdef SK_DIAG -extern SK_U32 SkI2cRead(SK_AC *pAC, SK_IOC IoC, int Dev, int Size, int Reg, - int Burst); -#else /* !SK_DIAG */ -extern int SkI2cEvent(SK_AC *pAC, SK_IOC IoC, SK_U32 Event, SK_EVPARA Para); -extern void SkI2cWaitIrq(SK_AC *pAC, SK_IOC IoC); -extern void SkI2cIsr(SK_AC *pAC, SK_IOC IoC); -#endif /* !SK_DIAG */ -#endif /* n_SKI2C_H */ - diff -urN linux-2.4.32-600/drivers/net/sk98lin/h/skqueue.h linux-2.4.32-600-sk98_831/drivers/net/sk98lin/h/skqueue.h --- linux-2.4.32-600/drivers/net/sk98lin/h/skqueue.h Sat Mar 20 10:08:19 2004 +++ linux-2.4.32-600-sk98_831/drivers/net/sk98lin/h/skqueue.h Sun Feb 26 11:12:56 2006 @@ -2,6 +2,8 @@ * * Name: skqueue.h * Project: Gigabit Ethernet Adapters, Event Scheduler Module + * Version: $Revision: 2.3 $ + * Date: $Date: 2004/05/14 13:39:15 $ * Purpose: Defines for the Event queue * ******************************************************************************/ @@ -20,6 +22,10 @@ * ******************************************************************************/ +/* + * SKQUEUE.H contains all defines and types for the event queue + */ + #ifndef _SKQUEUE_H_ #define _SKQUEUE_H_ @@ -39,6 +45,9 @@ #define SKGE_RSF 11 /* RSF Aggregation Event Class */ #define SKGE_MARKER 12 /* MARKER Aggregation Event Class */ #define SKGE_FD 13 /* FD Distributor Event Class */ +#ifdef SK_ASF +#define SKGE_ASF 14 /* ASF Event Class */ +#endif /* * define event queue as circular buffer @@ -84,5 +93,11 @@ #define SKERR_Q_E001MSG "Event queue overflow" #define SKERR_Q_E002 (SKERR_Q_E001+1) #define SKERR_Q_E002MSG "Undefined event class" +#define SKERR_Q_E003 (SKERR_Q_E001+2) +#define SKERR_Q_E003MSG "Event queued in Init Level 0" +#define SKERR_Q_E004 (SKERR_Q_E001+3) +#define SKERR_Q_E004MSG "Error Reported from Event Fuction (Queue Blocked)" +#define SKERR_Q_E005 (SKERR_Q_E001+4) +#define SKERR_Q_E005MSG "Event scheduler called in Init Level 0 or 1" #endif /* _SKQUEUE_H_ */ diff -urN linux-2.4.32-600/drivers/net/sk98lin/h/skrlmt.h linux-2.4.32-600-sk98_831/drivers/net/sk98lin/h/skrlmt.h --- linux-2.4.32-600/drivers/net/sk98lin/h/skrlmt.h Sat Mar 20 10:08:19 2004 +++ linux-2.4.32-600-sk98_831/drivers/net/sk98lin/h/skrlmt.h Sun Feb 26 11:12:56 2006 @@ -2,6 +2,8 @@ * * Name: skrlmt.h * Project: GEnesis, PCI Gigabit Ethernet Adapter + * Version: $Revision: 2.1 $ + * Date: $Date: 2003/10/27 14:16:09 $ * Purpose: Header file for Redundant Link ManagemenT. * ******************************************************************************/ diff -urN linux-2.4.32-600/drivers/net/sk98lin/h/sktimer.h linux-2.4.32-600-sk98_831/drivers/net/sk98lin/h/sktimer.h --- linux-2.4.32-600/drivers/net/sk98lin/h/sktimer.h Sat Mar 20 10:08:19 2004 +++ linux-2.4.32-600-sk98_831/drivers/net/sk98lin/h/sktimer.h Sun Feb 26 11:12:56 2006 @@ -2,6 +2,8 @@ * * Name: sktimer.h * Project: Gigabit Ethernet Adapters, Event Scheduler Module + * Version: $Revision: 2.1 $ + * Date: $Date: 2003/10/27 14:16:09 $ * Purpose: Defines for the timer functions * ******************************************************************************/ diff -urN linux-2.4.32-600/drivers/net/sk98lin/h/sktwsi.h linux-2.4.32-600-sk98_831/drivers/net/sk98lin/h/sktwsi.h --- linux-2.4.32-600/drivers/net/sk98lin/h/sktwsi.h Thu Jan 1 01:00:00 1970 +++ linux-2.4.32-600-sk98_831/drivers/net/sk98lin/h/sktwsi.h Sun Feb 26 11:12:56 2006 @@ -0,0 +1,177 @@ +/****************************************************************************** + * + * Name: sktwsi.h + * Project: Gigabit Ethernet Adapters, TWSI-Module + * Version: $Revision: 1.1 $ + * Date: $Date: 2003/12/19 14:02:56 $ + * Purpose: Defines to access Voltage and Temperature Sensor + * + ******************************************************************************/ + +/****************************************************************************** + * + * (C)Copyright 1998-2002 SysKonnect. + * (C)Copyright 2002-2003 Marvell. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * The information in this file is provided "AS IS" without warranty. + * + ******************************************************************************/ + +/* + * SKTWSI.H contains all TWSI specific defines + */ + +#ifndef _SKTWSI_H_ +#define _SKTWSI_H_ + +typedef struct s_Sensor SK_SENSOR; + +#include "h/skgetwsi.h" + +/* + * Define the TWSI events. + */ +#define SK_I2CEV_IRQ 1 /* IRQ happened Event */ +#define SK_I2CEV_TIM 2 /* Timeout event */ +#define SK_I2CEV_CLEAR 3 /* Clear MIB Values */ + +/* + * Define READ and WRITE Constants. + */ +#define I2C_READ 0 +#define I2C_WRITE 1 +#define I2C_BURST 1 +#define I2C_SINGLE 0 + +#define SKERR_I2C_E001 (SK_ERRBASE_I2C+0) +#define SKERR_I2C_E001MSG "Sensor index unknown" +#define SKERR_I2C_E002 (SKERR_I2C_E001+1) +#define SKERR_I2C_E002MSG "TWSI: transfer does not complete" +#define SKERR_I2C_E003 (SKERR_I2C_E002+1) +#define SKERR_I2C_E003MSG "LM80: NAK on device send" +#define SKERR_I2C_E004 (SKERR_I2C_E003+1) +#define SKERR_I2C_E004MSG "LM80: NAK on register send" +#define SKERR_I2C_E005 (SKERR_I2C_E004+1) +#define SKERR_I2C_E005MSG "LM80: NAK on device (2) send" +#define SKERR_I2C_E006 (SKERR_I2C_E005+1) +#define SKERR_I2C_E006MSG "Unknown event" +#define SKERR_I2C_E007 (SKERR_I2C_E006+1) +#define SKERR_I2C_E007MSG "LM80 read out of state" +#define SKERR_I2C_E008 (SKERR_I2C_E007+1) +#define SKERR_I2C_E008MSG "Unexpected sensor read completed" +#define SKERR_I2C_E009 (SKERR_I2C_E008+1) +#define SKERR_I2C_E009MSG "WARNING: temperature sensor out of range" +#define SKERR_I2C_E010 (SKERR_I2C_E009+1) +#define SKERR_I2C_E010MSG "WARNING: voltage sensor out of range" +#define SKERR_I2C_E011 (SKERR_I2C_E010+1) +#define SKERR_I2C_E011MSG "ERROR: temperature sensor out of range" +#define SKERR_I2C_E012 (SKERR_I2C_E011+1) +#define SKERR_I2C_E012MSG "ERROR: voltage sensor out of range" +#define SKERR_I2C_E013 (SKERR_I2C_E012+1) +#define SKERR_I2C_E013MSG "ERROR: couldn't init sensor" +#define SKERR_I2C_E014 (SKERR_I2C_E013+1) +#define SKERR_I2C_E014MSG "WARNING: fan sensor out of range" +#define SKERR_I2C_E015 (SKERR_I2C_E014+1) +#define SKERR_I2C_E015MSG "ERROR: fan sensor out of range" +#define SKERR_I2C_E016 (SKERR_I2C_E015+1) +#define SKERR_I2C_E016MSG "TWSI: active transfer does not complete" + +/* + * Define Timeout values + */ +#define SK_I2C_TIM_LONG 2000000L /* 2 seconds */ +#define SK_I2C_TIM_SHORT 100000L /* 100 milliseconds */ +#define SK_I2C_TIM_WATCH 1000000L /* 1 second */ + +/* + * Define trap and error log hold times + */ +#ifndef SK_SEN_ERR_TR_HOLD +#define SK_SEN_ERR_TR_HOLD (4*SK_TICKS_PER_SEC) +#endif +#ifndef SK_SEN_ERR_LOG_HOLD +#define SK_SEN_ERR_LOG_HOLD (60*SK_TICKS_PER_SEC) +#endif +#ifndef SK_SEN_WARN_TR_HOLD +#define SK_SEN_WARN_TR_HOLD (15*SK_TICKS_PER_SEC) +#endif +#ifndef SK_SEN_WARN_LOG_HOLD +#define SK_SEN_WARN_LOG_HOLD (15*60*SK_TICKS_PER_SEC) +#endif + +/* + * Defines for SenType + */ +#define SK_SEN_UNKNOWN 0 +#define SK_SEN_TEMP 1 +#define SK_SEN_VOLT 2 +#define SK_SEN_FAN 3 + +/* + * Define for the SenErrorFlag + */ +#define SK_SEN_ERR_NOT_PRESENT 0 /* Error Flag: Sensor not present */ +#define SK_SEN_ERR_OK 1 /* Error Flag: O.K. */ +#define SK_SEN_ERR_WARN 2 /* Error Flag: Warning */ +#define SK_SEN_ERR_ERR 3 /* Error Flag: Error */ +#define SK_SEN_ERR_FAULTY 4 /* Error Flag: Faulty */ + +/* + * Define the Sensor struct + */ +struct s_Sensor { + char *SenDesc; /* Description */ + int SenType; /* Voltage or Temperature */ + SK_I32 SenValue; /* Current value of the sensor */ + SK_I32 SenThreErrHigh; /* High error Threshhold of this sensor */ + SK_I32 SenThreWarnHigh; /* High warning Threshhold of this sensor */ + SK_I32 SenThreErrLow; /* Lower error Threshold of the sensor */ + SK_I32 SenThreWarnLow; /* Lower warning Threshold of the sensor */ + int SenErrFlag; /* Sensor indicated an error */ + SK_BOOL SenInit; /* Is sensor initialized ? */ + SK_U64 SenErrCts; /* Error trap counter */ + SK_U64 SenWarnCts; /* Warning trap counter */ + SK_U64 SenBegErrTS; /* Begin error timestamp */ + SK_U64 SenBegWarnTS; /* Begin warning timestamp */ + SK_U64 SenLastErrTrapTS; /* Last error trap timestamp */ + SK_U64 SenLastErrLogTS; /* Last error log timestamp */ + SK_U64 SenLastWarnTrapTS; /* Last warning trap timestamp */ + SK_U64 SenLastWarnLogTS; /* Last warning log timestamp */ + int SenState; /* Sensor State (see HW specific include) */ + int (*SenRead)(SK_AC *pAC, SK_IOC IoC, struct s_Sensor *pSen); + /* Sensors read function */ + SK_U16 SenReg; /* Register Address for this sensor */ + SK_U8 SenDev; /* Device Selection for this sensor */ +}; + +typedef struct s_I2c { + SK_SENSOR SenTable[SK_MAX_SENSORS]; /* Sensor Table */ + int CurrSens; /* Which sensor is currently queried */ + int MaxSens; /* Max. number of sensors */ + int TimerMode; /* Use the timer also to watch the state machine */ + int InitLevel; /* Initialized Level */ +#ifndef SK_DIAG + int DummyReads; /* Number of non-checked dummy reads */ + SK_TIMER SenTimer; /* Sensors timer */ +#endif /* !SK_DIAG */ +} SK_I2C; + +extern int SkI2cInit(SK_AC *pAC, SK_IOC IoC, int Level); +extern int SkI2cWrite(SK_AC *pAC, SK_IOC IoC, SK_U32 Data, int Dev, int Size, + int Reg, int Burst); +extern int SkI2cReadSensor(SK_AC *pAC, SK_IOC IoC, SK_SENSOR *pSen); +#ifdef SK_DIAG +extern SK_U32 SkI2cRead(SK_AC *pAC, SK_IOC IoC, int Dev, int Size, int Reg, + int Burst); +#else /* !SK_DIAG */ +extern int SkI2cEvent(SK_AC *pAC, SK_IOC IoC, SK_U32 Event, SK_EVPARA Para); +extern void SkI2cWaitIrq(SK_AC *pAC, SK_IOC IoC); +extern void SkI2cIsr(SK_AC *pAC, SK_IOC IoC); +#endif /* !SK_DIAG */ +#endif /* n_SKTWSI_H */ + diff -urN linux-2.4.32-600/drivers/net/sk98lin/h/sktypes.h linux-2.4.32-600-sk98_831/drivers/net/sk98lin/h/sktypes.h --- linux-2.4.32-600/drivers/net/sk98lin/h/sktypes.h Sat Mar 20 10:08:19 2004 +++ linux-2.4.32-600-sk98_831/drivers/net/sk98lin/h/sktypes.h Sun Feb 26 11:12:56 2006 @@ -2,6 +2,8 @@ * * Name: sktypes.h * Project: GEnesis, PCI Gigabit Ethernet Adapter + * Version: $Revision: 1.2.2.1 $ + * Date: $Date: 2005/04/11 09:00:53 $ * Purpose: Define data types for Linux * ******************************************************************************/ @@ -9,7 +11,7 @@ /****************************************************************************** * * (C)Copyright 1998-2002 SysKonnect GmbH. - * (C)Copyright 2002-2003 Marvell. + * (C)Copyright 2002-2005 Marvell. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -20,48 +22,28 @@ * ******************************************************************************/ -/****************************************************************************** - * - * Description: - * - * In this file, all data types that are needed by the common modules - * are mapped to Linux data types. - * - * - * Include File Hierarchy: - * - * - ******************************************************************************/ - #ifndef __INC_SKTYPES_H #define __INC_SKTYPES_H - -/* defines *******************************************************************/ - -/* - * Data types with a specific size. 'I' = signed, 'U' = unsigned. - */ -#define SK_I8 s8 -#define SK_U8 u8 -#define SK_I16 s16 -#define SK_U16 u16 -#define SK_I32 s32 -#define SK_U32 u32 -#define SK_I64 s64 -#define SK_U64 u64 - -#define SK_UPTR ulong /* casting pointer <-> integral */ - -/* -* Boolean type. -*/ -#define SK_BOOL SK_U8 -#define SK_FALSE 0 -#define SK_TRUE (!SK_FALSE) - -/* typedefs *******************************************************************/ - -/* function prototypes ********************************************************/ +#define SK_I8 s8 /* 8 bits (1 byte) signed */ +#define SK_U8 u8 /* 8 bits (1 byte) unsigned */ +#define SK_I16 s16 /* 16 bits (2 bytes) signed */ +#define SK_U16 u16 /* 16 bits (2 bytes) unsigned */ +#define SK_I32 s32 /* 32 bits (4 bytes) signed */ +#define SK_U32 u32 /* 32 bits (4 bytes) unsigned */ +#define SK_I64 s64 /* 64 bits (8 bytes) signed */ +#define SK_U64 u64 /* 64 bits (8 bytes) unsigned */ + +#define SK_UPTR ulong /* casting pointer <-> integral */ + +#define SK_BOOL SK_U8 +#define SK_FALSE 0 +#define SK_TRUE (!SK_FALSE) #endif /* __INC_SKTYPES_H */ + +/******************************************************************************* + * + * End of file + * + ******************************************************************************/ diff -urN linux-2.4.32-600/drivers/net/sk98lin/h/skversion.h linux-2.4.32-600-sk98_831/drivers/net/sk98lin/h/skversion.h --- linux-2.4.32-600/drivers/net/sk98lin/h/skversion.h Sat Mar 20 10:08:19 2004 +++ linux-2.4.32-600-sk98_831/drivers/net/sk98lin/h/skversion.h Sun Feb 26 11:13:02 2006 @@ -1,15 +1,17 @@ /****************************************************************************** * - * Name: version.h + * Name: skversion.h * Project: GEnesis, PCI Gigabit Ethernet Adapter - * Purpose: SK specific Error log support + * Version: $Revision: 1.3.2.1 $ + * Date: $Date: 2005/04/11 09:00:53 $ + * Purpose: specific version strings and numbers * ******************************************************************************/ /****************************************************************************** * * (C)Copyright 1998-2002 SysKonnect GmbH. - * (C)Copyright 2002-2003 Marvell. + * (C)Copyright 2002-2005 Marvell. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -20,17 +22,15 @@ * ******************************************************************************/ -#ifdef lint -static const char SysKonnectFileId[] = "@(#) (C) SysKonnect GmbH."; -static const char SysKonnectBuildNumber[] = - "@(#)SK-BUILD: 6.22 PL: 01"; -#endif /* !defined(lint) */ - -#define BOOT_STRING "sk98lin: Network Device Driver v6.22\n" \ - "(C)Copyright 1999-2004 Marvell(R)." - -#define VER_STRING "6.22" -#define DRIVER_FILE_NAME "sk98lin" -#define DRIVER_REL_DATE "Jan-30-2004" - +#define BOOT_STRING "sk98lin: Network Device Driver v8.31.2.3\n" \ + "(C)Copyright 1999-2006 Marvell(R)." +#define VER_STRING "8.31.2.3" +#define PATCHLEVEL "02" +#define DRIVER_FILE_NAME "sk98lin" +#define DRIVER_REL_DATE "Jan-18-2006" +/******************************************************************************* + * + * End of file + * + ******************************************************************************/ diff -urN linux-2.4.32-600/drivers/net/sk98lin/h/skvpd.h linux-2.4.32-600-sk98_831/drivers/net/sk98lin/h/skvpd.h --- linux-2.4.32-600/drivers/net/sk98lin/h/skvpd.h Sat Mar 20 10:08:19 2004 +++ linux-2.4.32-600-sk98_831/drivers/net/sk98lin/h/skvpd.h Sun Feb 26 11:12:56 2006 @@ -1,20 +1,22 @@ /****************************************************************************** * * Name: skvpd.h - * Project: GEnesis, PCI Gigabit Ethernet Adapter + * Project: Gigabit Ethernet Adapters, VPD-Module + * Version: $Revision: 2.6 $ + * Date: $Date: 2004/11/09 15:18:00 $ * Purpose: Defines and Macros for VPD handling * ******************************************************************************/ /****************************************************************************** * - * (C)Copyright 1998-2003 SysKonnect GmbH. + * (C)Copyright 1998-2002 SysKonnect. + * (C)Copyright 2002-2004 Marvell. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. - * * The information in this file is provided "AS IS" without warranty. * ******************************************************************************/ @@ -29,7 +31,7 @@ /* * Define Resource Type Identifiers and VPD keywords */ -#define RES_ID 0x82 /* Resource Type ID String (Product Name) */ +#define RES_ID 0x82 /* Resource Type ID String (Product Name) */ #define RES_VPD_R 0x90 /* start of VPD read only area */ #define RES_VPD_W 0x91 /* start of VPD read/write area */ #define RES_END 0x78 /* Resource Type End Tag */ @@ -38,14 +40,16 @@ #define VPD_NAME "Name" /* Product Name, VPD name of RES_ID */ #endif /* VPD_NAME */ #define VPD_PN "PN" /* Adapter Part Number */ -#define VPD_EC "EC" /* Adapter Engineering Level */ +#define VPD_EC "EC" /* Adapter Engineering Level */ #define VPD_MN "MN" /* Manufacture ID */ #define VPD_SN "SN" /* Serial Number */ #define VPD_CP "CP" /* Extended Capability */ #define VPD_RV "RV" /* Checksum and Reserved */ -#define VPD_YA "YA" /* Asset Tag Identifier */ +#define VPD_YA "YA" /* Asset Tag Identifier */ #define VPD_VL "VL" /* First Error Log Message (SK specific) */ #define VPD_VF "VF" /* Second Error Log Message (SK specific) */ +#define VPD_VB "VB" /* Boot Agent ROM Configuration (SK specific) */ +#define VPD_VE "VE" /* EFI UNDI Configuration (SK specific) */ #define VPD_RW "RW" /* Remaining Read / Write Area */ /* 'type' values for vpd_setup_para() */ @@ -53,7 +57,7 @@ #define VPD_RW_KEY 2 /* RW keys are "Yx", "Vx", and "RW" */ /* 'op' values for vpd_setup_para() */ -#define ADD_KEY 1 /* add the key at the pos "RV" or "RW" */ +#define ADD_KEY 1 /* add the key at the pos "RV" or "RW" */ #define OWR_KEY 2 /* overwrite key if already exists */ /* @@ -62,18 +66,18 @@ #define VPD_DEV_ID_GENESIS 0x4300 -#define VPD_SIZE_YUKON 256 -#define VPD_SIZE_GENESIS 512 -#define VPD_SIZE 512 +#define VPD_SIZE_YUKON 256 +#define VPD_SIZE_GENESIS 512 +#define VPD_SIZE 512 #define VPD_READ 0x0000 #define VPD_WRITE 0x8000 #define VPD_STOP(pAC,IoC) VPD_OUT16(pAC,IoC,PCI_VPD_ADR_REG,VPD_WRITE) -#define VPD_GET_RES_LEN(p) ((unsigned int) \ - (* (SK_U8 *)&(p)[1]) |\ - ((* (SK_U8 *)&(p)[2]) << 8)) -#define VPD_GET_VPD_LEN(p) ((unsigned int)(* (SK_U8 *)&(p)[2])) +#define VPD_GET_RES_LEN(p) ((unsigned int)\ + (*(SK_U8 *)&(p)[1]) |\ + ((*(SK_U8 *)&(p)[2]) << 8)) +#define VPD_GET_VPD_LEN(p) ((unsigned int)(*(SK_U8 *)&(p)[2])) #define VPD_GET_VAL(p) ((char *)&(p)[3]) #define VPD_MAX_LEN 50 @@ -124,7 +128,7 @@ /* * System specific VPD macros */ -#ifndef SKDIAG +#ifndef SK_DIAG #ifndef VPD_DO_IO #define VPD_OUT8(pAC,IoC,Addr,Val) (void)SkPciWriteCfgByte(pAC,Addr,Val) #define VPD_OUT16(pAC,IoC,Addr,Val) (void)SkPciWriteCfgWord(pAC,Addr,Val) @@ -133,61 +137,61 @@ #define VPD_IN16(pAC,IoC,Addr,pVal) (void)SkPciReadCfgWord(pAC,Addr,pVal) #define VPD_IN32(pAC,IoC,Addr,pVal) (void)SkPciReadCfgDWord(pAC,Addr,pVal) #else /* VPD_DO_IO */ -#define VPD_OUT8(pAC,IoC,Addr,Val) SK_OUT8(IoC,PCI_C(Addr),Val) -#define VPD_OUT16(pAC,IoC,Addr,Val) SK_OUT16(IoC,PCI_C(Addr),Val) -#define VPD_OUT32(pAC,IoC,Addr,Val) SK_OUT32(IoC,PCI_C(Addr),Val) -#define VPD_IN8(pAC,IoC,Addr,pVal) SK_IN8(IoC,PCI_C(Addr),pVal) -#define VPD_IN16(pAC,IoC,Addr,pVal) SK_IN16(IoC,PCI_C(Addr),pVal) -#define VPD_IN32(pAC,IoC,Addr,pVal) SK_IN32(IoC,PCI_C(Addr),pVal) +#define VPD_OUT8(pAC,IoC,Addr,Val) SK_OUT8(IoC,PCI_C(pAC,Addr),Val) +#define VPD_OUT16(pAC,IoC,Addr,Val) SK_OUT16(IoC,PCI_C(pAC,Addr),Val) +#define VPD_OUT32(pAC,IoC,Addr,Val) SK_OUT32(IoC,PCI_C(pAC,Addr),Val) +#define VPD_IN8(pAC,IoC,Addr,pVal) SK_IN8(IoC,PCI_C(pAC,Addr),pVal) +#define VPD_IN16(pAC,IoC,Addr,pVal) SK_IN16(IoC,PCI_C(pAC,Addr),pVal) +#define VPD_IN32(pAC,IoC,Addr,pVal) SK_IN32(IoC,PCI_C(pAC,Addr),pVal) #endif /* VPD_DO_IO */ -#else /* SKDIAG */ +#else /* SK_DIAG */ #define VPD_OUT8(pAC,Ioc,Addr,Val) { \ if ((pAC)->DgT.DgUseCfgCycle) \ SkPciWriteCfgByte(pAC,Addr,Val); \ else \ - SK_OUT8(pAC,PCI_C(Addr),Val); \ + SK_OUT8(pAC,PCI_C(pAC,Addr),Val); \ } #define VPD_OUT16(pAC,Ioc,Addr,Val) { \ if ((pAC)->DgT.DgUseCfgCycle) \ SkPciWriteCfgWord(pAC,Addr,Val); \ else \ - SK_OUT16(pAC,PCI_C(Addr),Val); \ + SK_OUT16(pAC,PCI_C(pAC,Addr),Val); \ } #define VPD_OUT32(pAC,Ioc,Addr,Val) { \ if ((pAC)->DgT.DgUseCfgCycle) \ SkPciWriteCfgDWord(pAC,Addr,Val); \ else \ - SK_OUT32(pAC,PCI_C(Addr),Val); \ + SK_OUT32(pAC,PCI_C(pAC,Addr),Val); \ } #define VPD_IN8(pAC,Ioc,Addr,pVal) { \ - if ((pAC)->DgT.DgUseCfgCycle) \ + if ((pAC)->DgT.DgUseCfgCycle) \ SkPciReadCfgByte(pAC,Addr,pVal); \ else \ - SK_IN8(pAC,PCI_C(Addr),pVal); \ + SK_IN8(pAC,PCI_C(pAC,Addr),pVal); \ } #define VPD_IN16(pAC,Ioc,Addr,pVal) { \ - if ((pAC)->DgT.DgUseCfgCycle) \ + if ((pAC)->DgT.DgUseCfgCycle) \ SkPciReadCfgWord(pAC,Addr,pVal); \ else \ - SK_IN16(pAC,PCI_C(Addr),pVal); \ + SK_IN16(pAC,PCI_C(pAC,Addr),pVal); \ } #define VPD_IN32(pAC,Ioc,Addr,pVal) { \ if ((pAC)->DgT.DgUseCfgCycle) \ SkPciReadCfgDWord(pAC,Addr,pVal); \ else \ - SK_IN32(pAC,PCI_C(Addr),pVal); \ + SK_IN32(pAC,PCI_C(pAC,Addr),pVal); \ } -#endif /* nSKDIAG */ +#endif /* SK_DIAG */ /* function prototypes ********************************************************/ #ifndef SK_KR_PROTO -#ifdef SKDIAG +#ifdef SK_DIAG extern SK_U32 VpdReadDWord( SK_AC *pAC, SK_IOC IoC, int addr); -#endif /* SKDIAG */ +#endif /* SK_DIAG */ extern int VpdSetupPara( SK_AC *pAC, @@ -238,7 +242,12 @@ SK_IOC IoC, char *msg); -#ifdef SKDIAG +int VpdInit( + SK_AC *pAC, + SK_IOC IoC); + +#if defined(SK_DIAG) || defined(SK_ASF) + extern int VpdReadBlock( SK_AC *pAC, SK_IOC IoC, @@ -252,7 +261,9 @@ char *buf, int addr, int len); -#endif /* SKDIAG */ + +#endif /* SK_DIAG || SK_ASF */ + #else /* SK_KR_PROTO */ extern SK_U32 VpdReadDWord(); extern int VpdSetupPara(); @@ -267,3 +278,4 @@ #endif /* SK_KR_PROTO */ #endif /* __INC_SKVPD_H_ */ + diff -urN linux-2.4.32-600/drivers/net/sk98lin/h/sky2le.h linux-2.4.32-600-sk98_831/drivers/net/sk98lin/h/sky2le.h --- linux-2.4.32-600/drivers/net/sk98lin/h/sky2le.h Thu Jan 1 01:00:00 1970 +++ linux-2.4.32-600-sk98_831/drivers/net/sk98lin/h/sky2le.h Sun Feb 26 11:13:02 2006 @@ -0,0 +1,893 @@ +/****************************************************************************** + * + * Name: sky2le.h + * Project: Gigabit Ethernet Adapters, Common Modules + * Version: $Revision: 1.10 $ + * Date: $Date: 2005/12/14 16:11:35 $ + * Purpose: Common list element definitions and access macros. + * + ******************************************************************************/ + +/****************************************************************************** + * + * LICENSE: + * (C)Copyright 2003-2004 Marvell + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * The information in this file is provided "AS IS" without warranty. + * /LICENSE + * + ******************************************************************************/ + +#ifndef __INC_SKY2LE_H +#define __INC_SKY2LE_H + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/* defines ********************************************************************/ + +#define MIN_LEN_OF_LE_TAB 128 +#define MAX_LEN_OF_LE_TAB 4096 +#ifdef USE_POLLING_UNIT +#define NUM_LE_POLLING_UNIT 2 +#endif +#define MAX_FRAG_OVERHEAD 10 + +/* Macro for aligning a given value */ +#define SK_ALIGN_SIZE(Value, Alignment, AlignedVal) { \ + (AlignedVal) = (((Value) + (Alignment) - 1) & (~((Alignment) - 1)));\ +} + +/****************************************************************************** + * + * LE2DWord() - Converts the given Little Endian value to machine order value + * + * Description: + * This function converts the Little Endian value received as an argument to + * the machine order value. + * + * Returns: + * The converted value + * + */ + +#ifdef SK_LITTLE_ENDIAN + +#ifndef SK_USE_REV_DESC +#define LE2DWord(value) (value) +#else /* SK_USE_REV_DESC */ +#define LE2DWord(value) \ + ((((value)<<24L) & 0xff000000L) + \ + (((value)<< 8L) & 0x00ff0000L) + \ + (((value)>> 8L) & 0x0000ff00L) + \ + (((value)>>24L) & 0x000000ffL)) +#endif /* SK_USE_REV_DESC */ + +#else /* !SK_LITTLE_ENDIAN */ + +#ifndef SK_USE_REV_DESC +#define LE2DWord(value) \ + ((((value)<<24L) & 0xff000000L) + \ + (((value)<< 8L) & 0x00ff0000L) + \ + (((value)>> 8L) & 0x0000ff00L) + \ + (((value)>>24L) & 0x000000ffL)) +#else /* SK_USE_REV_DESC */ +#define LE2DWord(value) (value) +#endif /* SK_USE_REV_DESC */ + +#endif /* !SK_LITTLE_ENDIAN */ + +/****************************************************************************** + * + * DWord2LE() - Converts the given value to a Little Endian value + * + * Description: + * This function converts the value received as an argument to a Little Endian + * value on Big Endian machines. If the machine running the code is Little + * Endian, then no conversion is done. + * + * Returns: + * The converted value + * + */ + +#ifdef SK_LITTLE_ENDIAN + +#ifndef SK_USE_REV_DESC +#define DWord2LE(value) (value) +#else /* SK_USE_REV_DESC */ +#define DWord2LE(value) \ + ((((value)<<24L) & 0xff000000L) + \ + (((value)<< 8L) & 0x00ff0000L) + \ + (((value)>> 8L) & 0x0000ff00L) + \ + (((value)>>24L) & 0x000000ffL)) +#endif /* SK_USE_REV_DESC */ + +#else /* !SK_LITTLE_ENDIAN */ + +#ifndef SK_USE_REV_DESC +#define DWord2LE(value) \ + ((((value)<<24L) & 0xff000000L) + \ + (((value)<< 8L) & 0x00ff0000L) + \ + (((value)>> 8L) & 0x0000ff00L) + \ + (((value)>>24L) & 0x000000ffL)) +#else /* SK_USE_REV_DESC */ +#define DWord2LE(value) (value) +#endif /* SK_USE_REV_DESC */ +#endif /* !SK_LITTLE_ENDIAN */ + +/****************************************************************************** + * + * LE2Word() - Converts the given Little Endian value to machine order value + * + * Description: + * This function converts the Little Endian value received as an argument to + * the machine order value. + * + * Returns: + * The converted value + * + */ + +#ifdef SK_LITTLE_ENDIAN +#ifndef SK_USE_REV_DESC +#define LE2Word(value) (value) +#else /* SK_USE_REV_DESC */ +#define LE2Word(value) \ + ((((value)<< 8L) & 0xff00) + \ + (((value)>> 8L) & 0x00ff)) +#endif /* SK_USE_REV_DESC */ + +#else /* !SK_LITTLE_ENDIAN */ +#ifndef SK_USE_REV_DESC +#define LE2Word(value) \ + ((((value)<< 8L) & 0xff00) + \ + (((value)>> 8L) & 0x00ff)) +#else /* SK_USE_REV_DESC */ +#define LE2Word(value) (value) +#endif /* SK_USE_REV_DESC */ +#endif /* !SK_LITTLE_ENDIAN */ + +/****************************************************************************** + * + * Word2LE() - Converts the given value to a Little Endian value + * + * Description: + * This function converts the value received as an argument to a Little Endian + * value on Big Endian machines. If the machine running the code is Little + * Endian, then no conversion is done. + * + * Returns: + * The converted value + * + */ + +#ifdef SK_LITTLE_ENDIAN +#ifndef SK_USE_REV_DESC +#define Word2LE(value) (value) +#else /* SK_USE_REV_DESC */ +#define Word2LE(value) \ + ((((value)<< 8L) & 0xff00) + \ + (((value)>> 8L) & 0x00ff)) +#endif /* SK_USE_REV_DESC */ + +#else /* !SK_LITTLE_ENDIAN */ +#ifndef SK_USE_REV_DESC +#define Word2LE(value) \ + ((((value)<< 8L) & 0xff00) + \ + (((value)>> 8L) & 0x00ff)) +#else /* SK_USE_REV_DESC */ +#define Word2LE(value) (value) +#endif /* SK_USE_REV_DESC */ +#endif /* !SK_LITTLE_ENDIAN */ + +/****************************************************************************** + * + * Transmit list element macros + * + */ + +#define TXLE_SET_ADDR(pLE, Addr) \ + ((pLE)->Tx.TxUn.BufAddr = DWord2LE(Addr)) +#define TXLE_SET_LSLEN(pLE, Len) \ + ((pLE)->Tx.TxUn.LargeSend.Length = Word2LE(Len)) +#define TXLE_SET_STACS(pLE, Start) \ + ((pLE)->Tx.TxUn.ChkSum.TxTcpSp = Word2LE(Start)) +#define TXLE_SET_WRICS(pLE, Write) \ + ((pLE)->Tx.TxUn.ChkSum.TxTcpWp = Word2LE(Write)) +#define TXLE_SET_INICS(pLE, Ini) ((pLE)->Tx.Send.InitCsum = Word2LE(Ini)) +#define TXLE_SET_LEN(pLE, Len) ((pLE)->Tx.Send.BufLen = Word2LE(Len)) +#define TXLE_SET_VLAN(pLE, Vlan) ((pLE)->Tx.Send.VlanTag = Word2LE(Vlan)) +#define TXLE_SET_LCKCS(pLE, Lock) ((pLE)->Tx.ControlFlags = (Lock)) +#define TXLE_SET_CTRL(pLE, Ctrl) ((pLE)->Tx.ControlFlags = (Ctrl)) +#define TXLE_SET_OPC(pLE, Opc) ((pLE)->Tx.Opcode = (Opc)) + +#define TXLE_GET_ADDR(pLE) LE2DWord((pLE)->Tx.TxUn.BufAddr) +#define TXLE_GET_LSLEN(pLE) LE2Word((pLE)->Tx.TxUn.LargeSend.Length) +#define TXLE_GET_STACS(pLE) LE2Word((pLE)->Tx.TxUn.ChkSum.TxTcpSp) +#define TXLE_GET_WRICS(pLE) LE2Word((pLE)->Tx.TxUn.ChkSum.TxTcpWp) +#define TXLE_GET_INICS(pLE) LE2Word((pLE)->Tx.Send.InitCsum) +#define TXLE_GET_LEN(pLE) LE2Word((pLE)->Tx.Send.BufLen) +#define TXLE_GET_VLAN(pLE) LE2Word((pLE)->Tx.Send.VlanTag) +#define TXLE_GET_LCKCS(pLE) ((pLE)->Tx.ControlFlags) +#define TXLE_GET_CTRL(pLE) ((pLE)->Tx.ControlFlags) +#define TXLE_GET_OPC(pLE) ((pLE)->Tx.Opcode) + +/****************************************************************************** + * + * Receive list element macros + * + */ + +#define RXLE_SET_ADDR(pLE, Addr) \ + ((pLE)->Rx.RxUn.BufAddr = (SK_U32) DWord2LE(Addr)) +#define RXLE_SET_STACS2(pLE, Offs) \ + ((pLE)->Rx.RxUn.ChkSum.RxTcpSp2 = Word2LE(Offs)) +#define RXLE_SET_STACS1(pLE, Offs) \ + ((pLE)->Rx.RxUn.ChkSum.RxTcpSp1 = Word2LE(Offs)) +#define RXLE_SET_LEN(pLE, Len) ((pLE)->Rx.BufferLength = Word2LE(Len)) +#define RXLE_SET_CTRL(pLE, Ctrl) ((pLE)->Rx.ControlFlags = (Ctrl)) +#define RXLE_SET_OPC(pLE, Opc) ((pLE)->Rx.Opcode = (Opc)) + +#define RXLE_GET_ADDR(pLE) LE2DWord((pLE)->Rx.RxUn.BufAddr) +#define RXLE_GET_STACS2(pLE) LE2Word((pLE)->Rx.RxUn.ChkSum.RxTcpSp2) +#define RXLE_GET_STACS1(pLE) LE2Word((pLE)->Rx.RxUn.ChkSum.RxTcpSp1) +#define RXLE_GET_LEN(pLE) LE2Word((pLE)->Rx.BufferLength) +#define RXLE_GET_CTRL(pLE) ((pLE)->Rx.ControlFlags) +#define RXLE_GET_OPC(pLE) ((pLE)->Rx.Opcode) + +/****************************************************************************** + * + * Status list element macros + * + */ + +#define STLE_SET_OPC(pLE, Opc) ((pLE)->St.Opcode = (Opc)) + +#define STLE_GET_FRSTATUS(pLE) LE2DWord((pLE)->St.StUn.StRxStatWord) +#define STLE_GET_TIST(pLE) LE2DWord((pLE)->St.StUn.StRxTimeStamp) +#define STLE_GET_TCP1(pLE) LE2Word((pLE)->St.StUn.StRxTCPCSum.RxTCPSum1) +#define STLE_GET_TCP2(pLE) LE2Word((pLE)->St.StUn.StRxTCPCSum.RxTCPSum2) +#define STLE_GET_LEN(pLE) LE2Word((pLE)->St.Stat.BufLen) +#define STLE_GET_VLAN(pLE) LE2Word((pLE)->St.Stat.VlanTag) +#define STLE_GET_LINK(pLE) ((pLE)->St.Link) +#define STLE_GET_OPC(pLE) ((pLE)->St.Opcode) +#define STLE_GET_DONE_IDX(pLE,LowVal,HighVal) { \ + (LowVal) = LE2DWord((pLE)->St.StUn.StTxStatLow); \ + (HighVal) = LE2Word((pLE)->St.Stat.StTxStatHi); \ +} + +#define STLE_GET_RSS(pLE) LE2DWord((pLE)->St.StUn.StRxRssValue) +#define STLE_GET_IPBIT(pLE) ((pLE)->St.Stat.Rss.FlagField & RSS_IP_FLAG) +#define STLE_GET_TCPBIT(pLE) ((pLE)->St.Stat.Rss.FlagField & RSS_TCP_FLAG) + + +/* I always take both values as a paramter to avoid typos */ +#define STLE_GET_DONE_IDX_TXA1(LowVal,HighVal) \ + (((LowVal) & STLE_TXA1_MSKL) >> STLE_TXA1_SHIFTL) +#define STLE_GET_DONE_IDX_TXS1(LowVal,HighVal) \ + ((LowVal & STLE_TXS1_MSKL) >> STLE_TXS1_SHIFTL) +#define STLE_GET_DONE_IDX_TXA2(LowVal,HighVal) \ + (((LowVal & STLE_TXA2_MSKL) >> STLE_TXA2_SHIFTL) + \ + ((HighVal & STLE_TXA2_MSKH) << STLE_TXA2_SHIFTH)) +#define STLE_GET_DONE_IDX_TXS2(LowVal,HighVal) \ + ((HighVal & STLE_TXS2_MSKH) >> STLE_TXS2_SHIFTH) + + +#define SK_Y2_RXSTAT_CHECK_PKT(Len, RxStat, IsOk) { \ + (IsOk) = (((RxStat) & GMR_FS_RX_OK) != 0) && \ + (((RxStat) & GMR_FS_ANY_ERR) == 0); \ + \ + if ((IsOk) && ((SK_U16)(((RxStat) & GMR_FS_LEN_MSK) >> \ + GMR_FS_LEN_SHIFT) != (Len))) { \ + /* length in MAC status differs from length in LE */\ + (IsOk) = SK_FALSE; \ + } \ +} + + +/****************************************************************************** + * + * Polling unit list element macros + * + * NOTE: the Idx must be <= 0xfff and PU_PUTIDX_VALID makes them valid + * + */ + +#ifdef USE_POLLING_UNIT + +#define POLE_SET_OPC(pLE, Opc) ((pLE)->Sa.Opcode = (Opc)) +#define POLE_SET_LINK(pLE, Port) ((pLE)->Sa.Link = (Port)) +#define POLE_SET_RXIDX(pLE, Idx) ((pLE)->Sa.RxIdxVld = Word2LE(Idx)) +#define POLE_SET_TXAIDX(pLE, Idx) ((pLE)->Sa.TxAIdxVld = Word2LE(Idx)) +#define POLE_SET_TXSIDX(pLE, Idx) ((pLE)->Sa.TxSIdxVld = Word2LE(Idx)) + +#define POLE_GET_OPC(pLE) ((pLE)->Sa.Opcode) +#define POLE_GET_LINK(pLE) ((pLE)->Sa.Link) +#define POLE_GET_RXIDX(pLE) LE2Word((pLE)->Sa.RxIdxVld) +#define POLE_GET_TXAIDX(pLE) LE2Word((pLE)->Sa.TxAIdxVld) +#define POLE_GET_TXSIDX(pLE) LE2Word((pLE)->Sa.TxSIdxVld) + +#endif /* USE_POLLING_UNIT */ + +/****************************************************************************** + * + * Debug macros for list elements + * + */ + +#ifdef DEBUG + +#define SK_DBG_DUMP_RX_LE(pLE) { \ + SK_U8 Opcode; \ + SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT, \ + ("=== RX_LIST_ELEMENT @addr: %p cont: %02x %02x %02x %02x %02x %02x %02x %02x\n", \ + pLE, ((SK_U8 *) pLE)[0], ((SK_U8 *) pLE)[1], ((SK_U8 *) pLE)[2],\ + ((SK_U8 *) pLE)[3], ((SK_U8 *) pLE)[4], ((SK_U8 *) pLE)[5], \ + ((SK_U8 *) pLE)[6], ((SK_U8 *) pLE)[7])); \ + SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT, \ + ("\t (16bit) %04x %04x %04x %04x\n", \ + ((SK_U16 *) pLE)[0], ((SK_U16 *) pLE)[1], ((SK_U16 *) pLE)[2], \ + ((SK_U16 *) pLE)[3])); \ + SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT, \ + ("\t (32bit) %08x %08x\n", \ + ((SK_U32 *) pLE)[0], ((SK_U32 *) pLE)[1])); \ + Opcode = RXLE_GET_OPC(pLE); \ + SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT, \ + ("\tOwn belongs to %s\n", ((Opcode & HW_OWNER) == HW_OWNER) ? \ + "Hardware" : "Software")); \ + SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT, \ + ("\tOpc: 0x%x ",Opcode)); \ + switch (Opcode & (~HW_OWNER)) { \ + case OP_BUFFER: \ + SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT, \ + ("\tOP_BUFFER\n")); \ + break; \ + case OP_PACKET: \ + SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT, \ + ("\tOP_PACKET\n")); \ + break; \ + case OP_ADDR64: \ + SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT, \ + ("\tOP_ADDR64\n")); \ + break; \ + case OP_TCPSTART: \ + SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT, \ + ("\tOP_TCPPAR\n")); \ + break; \ + case SW_OWNER: \ + SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT, \ + ("\tunused LE\n")); \ + break; \ + default: \ + SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT, \ + ("\tunknown Opcode!!!\n")); \ + break; \ + } \ + if ((Opcode & OP_BUFFER) == OP_BUFFER) { \ + SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT, \ + ("\tControl: 0x%x\n", RXLE_GET_CTRL(pLE))); \ + SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT, \ + ("\tBufLen: 0x%x\n", RXLE_GET_LEN(pLE))); \ + SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT, \ + ("\tLowAddr: 0x%x\n", RXLE_GET_ADDR(pLE))); \ + } \ + if ((Opcode & OP_ADDR64) == OP_ADDR64) { \ + SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT, \ + ("\tHighAddr: 0x%x\n", RXLE_GET_ADDR(pLE))); \ + } \ + if ((Opcode & OP_TCPSTART) == OP_TCPSTART) { \ + SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT, \ + ("\tTCP Sum Start 1 : 0x%x\n", RXLE_GET_STACS1(pLE))); \ + SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT, \ + ("\tTCP Sum Start 2 : 0x%x\n", RXLE_GET_STACS2(pLE))); \ + } \ + SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT, \ + ("=====================\n")); \ +} + +#define SK_DBG_DUMP_TX_LE(pLE) { \ + SK_U8 Opcode; \ + SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT, \ + ("=== TX_LIST_ELEMENT @addr: %p cont: %02x %02x %02x %02x %02x %02x %02x %02x\n", \ + pLE, ((SK_U8 *) pLE)[0], ((SK_U8 *) pLE)[1], ((SK_U8 *) pLE)[2],\ + ((SK_U8 *) pLE)[3], ((SK_U8 *) pLE)[4], ((SK_U8 *) pLE)[5], \ + ((SK_U8 *) pLE)[6], ((SK_U8 *) pLE)[7])); \ + SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT, \ + ("\t (16bit) %04x %04x %04x %04x\n", \ + ((SK_U16 *) pLE)[0], ((SK_U16 *) pLE)[1], ((SK_U16 *) pLE)[2], \ + ((SK_U16 *) pLE)[3])); \ + SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT, \ + ("\t (32bit) %08x %08x\n", \ + ((SK_U32 *) pLE)[0], ((SK_U32 *) pLE)[1])); \ + Opcode = TXLE_GET_OPC(pLE); \ + SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT, \ + ("\tOwn belongs to %s\n", ((Opcode & HW_OWNER) == HW_OWNER) ? \ + "Hardware" : "Software")); \ + SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT, \ + ("\tOpc: 0x%x ",Opcode)); \ + switch (Opcode & (~HW_OWNER)) { \ + case OP_TCPCHKSUM: \ + SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT, \ + ("\tOP_TCPCHKSUM\n")); \ + break; \ + case OP_TCPIS: \ + SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT, \ + ("\tOP_TCPIS\n")); \ + break; \ + case OP_TCPLCK: \ + SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT, \ + ("\tOP_TCPLCK\n")); \ + break; \ + case OP_TCPLW: \ + SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT, \ + ("\tOP_TCPLW\n")); \ + break; \ + case OP_TCPLSW: \ + SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT, \ + ("\tOP_TCPLSW\n")); \ + break; \ + case OP_TCPLISW: \ + SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT, \ + ("\tOP_TCPLISW\n")); \ + break; \ + case OP_ADDR64: \ + SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT, \ + ("\tOP_ADDR64\n")); \ + break; \ + case OP_VLAN: \ + SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT, \ + ("\tOP_VLAN\n")); \ + break; \ + case OP_ADDR64VLAN: \ + SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT, \ + ("\tOP_ADDR64VLAN\n")); \ + break; \ + case OP_LRGLEN: \ + SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT, \ + ("\tOP_LRGLEN\n")); \ + break; \ + case OP_LRGLENVLAN: \ + SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT, \ + ("\tOP_LRGLENVLAN\n")); \ + break; \ + case OP_BUFFER: \ + SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT, \ + ("\tOP_BUFFER\n")); \ + break; \ + case OP_PACKET: \ + SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT, \ + ("\tOP_PACKET\n")); \ + break; \ + case OP_LARGESEND: \ + SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT, \ + ("\tOP_LARGESEND\n")); \ + break; \ + case SW_OWNER: \ + SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT, \ + ("\tunused LE\n")); \ + break; \ + default: \ + SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT, \ + ("\tunknown Opcode!!!\n")); \ + break; \ + } \ + if ((Opcode & OP_BUFFER) == OP_BUFFER) { \ + SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT, \ + ("\tControl: 0x%x\n", TXLE_GET_CTRL(pLE))); \ + SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT, \ + ("\tBufLen: 0x%x\n", TXLE_GET_LEN(pLE))); \ + SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT, \ + ("\tLowAddr: 0x%x\n", TXLE_GET_ADDR(pLE))); \ + } \ + if ((Opcode & OP_ADDR64) == OP_ADDR64) { \ + SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT, \ + ("\tHighAddr: 0x%x\n", TXLE_GET_ADDR(pLE))); \ + } \ + if ((Opcode & OP_VLAN) == OP_VLAN) { \ + SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT, \ + ("\tVLAN Id: 0x%x\n", TXLE_GET_VLAN(pLE))); \ + } \ + if ((Opcode & OP_LRGLEN) == OP_LRGLEN) { \ + SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT, \ + ("\tLarge send length: 0x%x\n", TXLE_GET_LSLEN(pLE))); \ + } \ + if ((Opcode &(~HW_OWNER)) <= OP_ADDR64) { \ + if ((Opcode & OP_TCPWRITE) == OP_TCPWRITE) { \ + SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT, \ + ("\tTCP Sum Write: 0x%x\n", TXLE_GET_WRICS(pLE))); \ + } \ + if ((Opcode & OP_TCPSTART) == OP_TCPSTART) { \ + SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT, \ + ("\tTCP Sum Start: 0x%x\n", TXLE_GET_STACS(pLE))); \ + } \ + if ((Opcode & OP_TCPINIT) == OP_TCPINIT) { \ + SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT, \ + ("\tTCP Sum Init: 0x%x\n", TXLE_GET_INICS(pLE))); \ + } \ + if ((Opcode & OP_TCPLCK) == OP_TCPLCK) { \ + SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT, \ + ("\tTCP Sum Lock: 0x%x\n", TXLE_GET_LCKCS(pLE))); \ + } \ + } \ + SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT, \ + ("=====================\n")); \ +} + +#define SK_DBG_DUMP_ST_LE(pLE) { \ + SK_U8 Opcode; \ + SK_U16 HighVal; \ + SK_U32 LowVal; \ + SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT, \ + ("=== ST_LIST_ELEMENT @addr: %p contains: %02x %02x %02x %02x %02x %02x %02x %02x\n",\ + pLE, ((SK_U8 *) pLE)[0], ((SK_U8 *) pLE)[1], ((SK_U8 *) pLE)[2],\ + ((SK_U8 *) pLE)[3], ((SK_U8 *) pLE)[4], ((SK_U8 *) pLE)[5], \ + ((SK_U8 *) pLE)[6], ((SK_U8 *) pLE)[7])); \ + SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT, \ + ("\t (16bit) %04x %04x %04x %04x\n", \ + ((SK_U16 *) pLE)[0], ((SK_U16 *) pLE)[1], ((SK_U16 *) pLE)[2], \ + ((SK_U16 *) pLE)[3])); \ + SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT, \ + ("\t (32bit) %08x %08x\n", \ + ((SK_U32 *) pLE)[0], ((SK_U32 *) pLE)[1])); \ + Opcode = STLE_GET_OPC(pLE); \ + SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT, \ + ("\tOwn belongs to %s\n", ((Opcode & HW_OWNER) == SW_OWNER) ? \ + "Hardware" : "Software")); \ + SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT, \ + ("\tOpc: 0x%x", Opcode)); \ + Opcode &= (~HW_OWNER); \ + switch (Opcode) { \ + case OP_RXSTAT: \ + SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT, \ + ("\tOP_RXSTAT\n")); \ + break; \ + case OP_RXTIMESTAMP: \ + SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT, \ + ("\tOP_RXTIMESTAMP\n")); \ + break; \ + case OP_RXVLAN: \ + SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT, \ + ("\tOP_RXVLAN\n")); \ + break; \ + case OP_RXCHKS: \ + SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT, \ + ("\tOP_RXCHKS\n")); \ + break; \ + case OP_RXCHKSVLAN: \ + SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT, \ + ("\tOP_RXCHKSVLAN\n")); \ + break; \ + case OP_RXTIMEVLAN: \ + SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT, \ + ("\tOP_RXTIMEVLAN\n")); \ + break; \ + case OP_RSS_HASH: \ + SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT, \ + ("\tOP_RSS_HASH\n")); \ + break; \ + case OP_TXINDEXLE: \ + SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT, \ + ("\tOP_TXINDEXLE\n")); \ + break; \ + case HW_OWNER: \ + SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT, \ + ("\tunused LE\n")); \ + break; \ + default: \ + SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT, \ + ("\tunknown status list element!!!\n")); \ + break; \ + } \ + SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT, \ + ("\tPort: %c\n", 'A' + STLE_GET_LINK(pLE))); \ + if (Opcode == OP_RXSTAT) { \ + SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT, \ + ("\tFrameLen: 0x%x\n", STLE_GET_LEN(pLE))); \ + SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT, \ + ("\tFrameStat: 0x%x\n", STLE_GET_FRSTATUS(pLE))); \ + } \ + if ((Opcode & OP_RXVLAN) == OP_RXVLAN) { \ + SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT, \ + ("\tVLAN Id: 0x%x\n", STLE_GET_VLAN(pLE))); \ + } \ + if ((Opcode & OP_RXTIMESTAMP) == OP_RXTIMESTAMP) { \ + SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT, \ + ("\tTimestamp: 0x%x\n", STLE_GET_TIST(pLE))); \ + } \ + if ((Opcode & OP_RXCHKS) == OP_RXCHKS) { \ + SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT, \ + ("\tTCP: 0x%x 0x%x\n", STLE_GET_TCP1(pLE), \ + STLE_GET_TCP2(pLE))); \ + } \ + if (Opcode == OP_TXINDEXLE) { \ + STLE_GET_DONE_IDX(pLE, LowVal, HighVal); \ + SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT, \ + ("\tTx Index TxA1: 0x%x\n", \ + STLE_GET_DONE_IDX_TXA1(LowVal,HighVal))); \ + SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT, \ + ("\tTx Index TxS1: 0x%x\n", \ + STLE_GET_DONE_IDX_TXS1(LowVal,HighVal))); \ + SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT, \ + ("\tTx Index TxA2: 0x%x\n", \ + STLE_GET_DONE_IDX_TXA2(LowVal,HighVal))); \ + SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT, \ + ("\tTx Index TxS2: 0x%x\n", \ + STLE_GET_DONE_IDX_TXS2(LowVal,HighVal))); \ + } \ + SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT, \ + ("=====================\n")); \ +} + +#ifdef USE_POLLING_UNIT +#define SK_DBG_DUMP_PO_LE(pLE) { \ + SK_U8 Opcode; \ + SK_U16 Idx; \ + SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT, \ + ("=== PO_LIST_ELEMENT @addr: %p cont: %02x %02x %02x %02x %02x %02x %02x %02x\n", \ + pLE, ((SK_U8 *) pLE)[0], ((SK_U8 *) pLE)[1], ((SK_U8 *) pLE)[2],\ + ((SK_U8 *) pLE)[3], ((SK_U8 *) pLE)[4], ((SK_U8 *) pLE)[5], \ + ((SK_U8 *) pLE)[6], ((SK_U8 *) pLE)[7])); \ + SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT, \ + ("\t (16bit) %04x %04x %04x %04x\n", \ + ((SK_U16 *) pLE)[0], ((SK_U16 *) pLE)[1], ((SK_U16 *) pLE)[2], \ + ((SK_U16 *) pLE)[3])); \ + SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT, \ + ("\t (32bit) %08x %08x\n", \ + ((SK_U32 *) pLE)[0], ((SK_U32 *) pLE)[1])); \ + Opcode = POLE_GET_OPC(pLE); \ + SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT, \ + ("\tOwn belongs to %s\n", ((Opcode & HW_OWNER) == HW_OWNER) ? \ + "Hardware" : "Software")); \ + SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT, \ + ("\tOpc: 0x%x ",Opcode)); \ + if ((Opcode & ~HW_OWNER) == OP_PUTIDX) { \ + SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT, \ + ("\tOP_PUTIDX\n")); \ + } \ + else { \ + SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT, \ + ("\tunknown Opcode!!!\n")); \ + } \ + SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT, \ + ("\tPort %c\n", 'A' + POLE_GET_LINK(pLE))); \ + Idx = POLE_GET_TXAIDX(pLE); \ + SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT, \ + ("\tTxA Index is 0x%X and %svalid\n", Idx, \ + (Idx & PU_PUTIDX_VALID) ? "" : "not ")); \ + Idx = POLE_GET_TXSIDX(pLE); \ + SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT, \ + ("\tTxS Index is 0x%X and %svalid\n", Idx, \ + (Idx & PU_PUTIDX_VALID) ? "" : "not ")); \ + Idx = POLE_GET_RXIDX(pLE); \ + SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT, \ + ("\tRx Index is 0x%X and %svalid\n", Idx, \ + (Idx & PU_PUTIDX_VALID) ? "" : "not ")); \ + SK_DBG_MSG(pAc, SK_DBGMOD_HWM, SK_DBGCAT_INIT, \ + ("=====================\n")); \ +} +#endif /* USE_POLLING_UNIT */ + +#else /* !DEBUG */ + +#define SK_DBG_DUMP_RX_LE(pLE) +#define SK_DBG_DUMP_TX_LE(pLE) +#define SK_DBG_DUMP_ST_LE(pLE) +#define SK_DBG_DUMP_PO_LE(pLE) + +#endif /* !DEBUG */ + +/****************************************************************************** + * + * Macros for listelement tables + * + * + */ + +#define LE_SIZE sizeof(SK_HWLE) +#define LE_TAB_SIZE(NumElements) ((NumElements) * LE_SIZE) + +/* Number of unused list elements in table + * this macro always returns the number of free listelements - 1 + * this way we want to guarantee that always one LE remains unused + */ +#define NUM_FREE_LE_IN_TABLE(pTable) \ + ( ((pTable)->Put >= (pTable)->Done) ? \ + (NUM_LE_IN_TABLE(pTable) - (pTable)->Put + (pTable)->Done - 1) :\ + ((pTable)->Done - (pTable)->Put - 1) ) + +/* total number of list elements in table */ +#define NUM_LE_IN_TABLE(pTable) ((pTable)->Num) + +/* get next unused Rx list element */ +#define GET_RX_LE(pLE, pTable) { \ + pLE = &(pTable)->pLETab[(pTable)->Put]; \ + (pTable)->Put = ((pTable)->Put + 1) & (NUM_LE_IN_TABLE(pTable) - 1);\ +} + +/* get next unused Tx list element */ +#define GET_TX_LE(pLE, pTable) GET_RX_LE(pLE, pTable) + +/* get next status list element expected to be finished by hw */ +#define GET_ST_LE(pLE, pTable) { \ + pLE = &(pTable)->pLETab[(pTable)->Done]; \ + (pTable)->Done = ((pTable)->Done +1) & (NUM_LE_IN_TABLE(pTable) - 1);\ +} + +#ifdef USE_POLLING_UNIT +/* get next polling unit list element for port */ +#define GET_PO_LE(pLE, pTable, Port) { \ + pLE = &(pTable)->pLETab[(Port)]; \ +} +#endif /* USE_POLLING_UNIT */ + +#define GET_PUT_IDX(pTable) ((pTable)->Put) + +#define UPDATE_HWPUT_IDX(pTable) {(pTable)->HwPut = (pTable)->Put; } + +/* + * get own bit of next status LE + * if the result is != 0 there has been at least one status LE finished + */ +#define OWN_OF_FIRST_LE(pTable) \ + (STLE_GET_OPC(&(pTable)->pLETab[(pTable)->Done]) & HW_OWNER) + +#define SET_DONE_INDEX(pTable, Idx) (pTable)->Done = (Idx); + +#define GET_DONE_INDEX(pTable) ((pTable)->Done) + +#ifdef SAFE_BUT_SLOW + +/* check own bit of LE before current done idx */ +#define CHECK_STLE_OVERFLOW(pTable, IsOk) { \ + unsigned i; \ + if ((i = (pTable)->Done) == 0) { \ + i = NUM_LE_IN_TABLE(pTable); \ + } \ + else { \ + i = i - 1; \ + } \ + if (STLE_GET_OPC(&(pTable)->pLETab[i]) == HW_OWNER) { \ + (IsOk) = SK_TRUE; \ + } \ + else { \ + (IsOk) = SK_FALSE; \ + } \ + } + + +/* + * for Yukon-2 the hardware is not polling the list elements, so it + * is not necessary to change the own-bit of Rx or Tx LEs before + * reusing them + * but it might make debugging easier if one simply can see whether + * a LE has been worked on + */ + +#define CLEAR_LE_OWN(pTable, Idx) \ + STLE_SET_OPC(&(pTable)->pLETab[(Idx)], SW_OWNER) + +/* + * clear all own bits starting from old done index up to the LE before + * the new done index + */ +#define CLEAR_LE_OWN_FROM_DONE_TO(pTable, To) { \ + int i; \ + i = (pTable)->Done; \ + while (i != To) { \ + CLEAR_LE_OWN(pTable, i); \ + i = (i + 1) & (NUM_LE_IN_TABLE(pTable) - 1); \ + } \ + } + +#else /* !SAFE_BUT_SLOW */ + +#define CHECK_STLE_OVERFLOW(pTable, IsOk) +#define CLEAR_LE_OWN(pTable, Idx) +#define CLEAR_LE_OWN_FROM_DONE_TO(pTable, To) + +#endif /* !SAFE_BUT_SLOW */ + + +/* typedefs *******************************************************************/ + +typedef struct s_LetRxTx { + SK_U16 VlanId; /* VLAN Id given down last time */ + SK_U16 TcpWp; /* TCP Checksum Write Position */ + SK_U16 TcpSp1; /* TCP Checksum Calculation Start Position 1 */ + SK_U16 TcpSp2; /* TCP Checksum Calculation Start Position 2 */ + SK_U16 MssValue; /* Maximum Segment Size */ + SK_U16 Reserved1; /* reserved word for furture extensions */ + SK_U16 Reserved2; /* reserved word for furture extensions */ + SK_U16 Reserved3; /* reserved word for furture extensions */ +} SK_LET_RX_TX; + +typedef struct s_LetStat { + SK_U32 RxTimeStamp; /* Receive Timestamp */ + SK_U32 RssHashValue; /* RSS Hash Value */ + SK_BOOL RssIsIp; /* RSS Hash Value: IP packet detected */ + SK_BOOL RssIsTcp; /* RSS Hash Value: IP+TCP packet detected */ + SK_U16 VlanId; /* VLAN Id given received by Status BMU */ + SK_U16 TcpSum1; /* TCP checksum 1 (status BMU) */ + SK_U16 TcpSum2; /* TCP checksum 2 (status BMU) */ +} SK_LET_STAT; + +typedef union s_LetBmuSpec { + SK_LET_RX_TX RxTx; /* Rx/Tx BMU specific variables */ + SK_LET_STAT Stat; /* Status BMU specific variables */ +} SK_LET_BMU_S; + +typedef struct s_le_table { + /* all LE's between Done and HWPut are owned by the hardware */ + /* all LE's between Put and Done can be used from Software */ + /* all LE's between HWPut and Put are currently processed in DriverSend */ + unsigned Done; /* done index - consumed from HW and available */ + unsigned Put; /* put index - to be given to hardware */ + unsigned HwPut; /* put index actually given to hardware */ + unsigned Num; /* total number of list elements */ + SK_HWLE *pLETab; /* virtual address of list element table */ + SK_U32 pPhyLETABLow; /* physical address of list element table */ + SK_U32 pPhyLETABHigh; /* physical address of list element table */ + /* values to remember in order to save some LEs */ + SK_U32 BufHighAddr; /* high addr given down last time */ + SK_LET_BMU_S Bmu; /* contains BMU specific information */ + SK_U32 private; /* driver private variable free usable */ + SK_U16 TcpInitCsum; /* Init. Checksum */ +} SK_LE_TABLE; + +/* function prototypes ********************************************************/ + +#ifndef SK_KR_PROTO + +/* + * public functions in sky2le.c + */ +extern void SkGeY2SetPutIndex( + SK_AC *pAC, + SK_IOC IoC, + SK_U32 StartAddrPrefetchUnit, + SK_LE_TABLE *pLETab); + +extern void SkGeY2InitPrefetchUnit( + SK_AC *pAC, + SK_IOC IoC, + unsigned int Queue, + SK_LE_TABLE *pLETab); + +extern void SkGeY2InitStatBmu( + SK_AC *pAC, + SK_IOC IoC, + SK_LE_TABLE *pLETab); + +extern void SkGeY2InitPollUnit( + SK_AC *pAC, + SK_IOC IoC, + SK_LE_TABLE *pLETab); + +extern void SkGeY2InitSingleLETable( + SK_AC *pAC, + SK_LE_TABLE *pLETab, + unsigned int NumLE, + void *pVMem, + SK_U32 PMemLowAddr, + SK_U32 PMemHighAddr); + +#else /* SK_KR_PROTO */ +extern void SkGeY2SetPutIndex(); +extern void SkGeY2InitPrefetchUnit(); +extern void SkGeY2InitStatBmu(); +extern void SkGeY2InitPollUnit(); +extern void SkGeY2InitSingleLETable(); +#endif /* SK_KR_PROTO */ + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* __INC_SKY2LE_H */ + diff -urN linux-2.4.32-600/drivers/net/sk98lin/h/xmac_ii.h linux-2.4.32-600-sk98_831/drivers/net/sk98lin/h/xmac_ii.h --- linux-2.4.32-600/drivers/net/sk98lin/h/xmac_ii.h Sat Mar 20 10:08:19 2004 +++ linux-2.4.32-600-sk98_831/drivers/net/sk98lin/h/xmac_ii.h Sun Feb 26 11:13:02 2006 @@ -2,21 +2,24 @@ * * Name: xmac_ii.h * Project: Gigabit Ethernet Adapters, Common Modules + * Version: $Revision: 2.14 $ + * Date: $Date: 2005/12/14 16:11:35 $ * Purpose: Defines and Macros for Gigabit Ethernet Controller * ******************************************************************************/ /****************************************************************************** * + * LICENSE: * (C)Copyright 1998-2002 SysKonnect. - * (C)Copyright 2002-2003 Marvell. + * (C)Copyright 2002-2005 Marvell. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. - * * The information in this file is provided "AS IS" without warranty. + * /LICENSE * ******************************************************************************/ @@ -369,18 +372,18 @@ /* Bit 16..6: reserved */ #define XM_SC_SNP_RXC (1<<5) /* Bit 5: (sc) Snap Rx Counters */ #define XM_SC_SNP_TXC (1<<4) /* Bit 4: (sc) Snap Tx Counters */ -#define XM_SC_CP_RXC (1<<3) /* Bit 3: Copy Rx Counters Continuously */ +#define XM_SC_CP_RXC (1<<3) /* Bit 3: Copy Rx Counters Continuously */ #define XM_SC_CP_TXC (1<<2) /* Bit 2: Copy Tx Counters Continuously */ #define XM_SC_CLR_RXC (1<<1) /* Bit 1: (sc) Clear Rx Counters */ -#define XM_SC_CLR_TXC (1<<0) /* Bit 0: (sc) Clear Tx Counters */ +#define XM_SC_CLR_TXC (1<<0) /* Bit 0: (sc) Clear Tx Counters */ /* XM_RX_CNT_EV 32 bit r/o Rx Counter Event Register */ /* XM_RX_EV_MSK 32 bit r/w Rx Counter Event Mask */ -#define XMR_MAX_SZ_OV (1UL<<31) /* Bit 31: 1024-MaxSize Rx Cnt Ov*/ -#define XMR_1023B_OV (1L<<30) /* Bit 30: 512-1023Byte Rx Cnt Ov*/ -#define XMR_511B_OV (1L<<29) /* Bit 29: 256-511 Byte Rx Cnt Ov*/ -#define XMR_255B_OV (1L<<28) /* Bit 28: 128-255 Byte Rx Cnt Ov*/ +#define XMR_MAX_SZ_OV (1UL<<31) /* Bit 31: 1024-MaxSize Rx Cnt Ov */ +#define XMR_1023B_OV (1L<<30) /* Bit 30: 512-1023Byte Rx Cnt Ov */ +#define XMR_511B_OV (1L<<29) /* Bit 29: 256-511 Byte Rx Cnt Ov */ +#define XMR_255B_OV (1L<<28) /* Bit 28: 128-255 Byte Rx Cnt Ov */ #define XMR_127B_OV (1L<<27) /* Bit 27: 65-127 Byte Rx Cnt Ov */ #define XMR_64B_OV (1L<<26) /* Bit 26: 64 Byte Rx Cnt Ov */ #define XMR_UTIL_OV (1L<<25) /* Bit 25: Rx Util Cnt Overflow */ @@ -388,9 +391,9 @@ #define XMR_CEX_ERR_OV (1L<<23) /* Bit 23: CEXT Err Cnt Ov */ /* Bit 22: reserved */ #define XMR_FCS_ERR_OV (1L<<21) /* Bit 21: Rx FCS Error Cnt Ov */ -#define XMR_LNG_ERR_OV (1L<<20) /* Bit 20: Rx too Long Err Cnt Ov*/ +#define XMR_LNG_ERR_OV (1L<<20) /* Bit 20: Rx too Long Err Cnt Ov */ #define XMR_RUNT_OV (1L<<19) /* Bit 19: Runt Event Cnt Ov */ -#define XMR_SHT_ERR_OV (1L<<18) /* Bit 18: Rx Short Ev Err Cnt Ov*/ +#define XMR_SHT_ERR_OV (1L<<18) /* Bit 18: Rx Short Ev Err Cnt Ov */ #define XMR_SYM_ERR_OV (1L<<17) /* Bit 17: Rx Sym Err Cnt Ov */ /* Bit 16: reserved */ #define XMR_CAR_ERR_OV (1L<<15) /* Bit 15: Rx Carr Ev Err Cnt Ov */ @@ -399,57 +402,57 @@ #define XMR_FRA_ERR_OV (1L<<12) /* Bit 12: Rx Framing Err Cnt Ov */ #define XMR_FMISS_OV (1L<<11) /* Bit 11: Rx Missed Ev Cnt Ov */ #define XMR_BURST (1L<<10) /* Bit 10: Rx Burst Event Cnt Ov */ -#define XMR_INV_MOC (1L<<9) /* Bit 9: Rx with inv. MAC OC Ov*/ +#define XMR_INV_MOC (1L<<9) /* Bit 9: Rx with inv. MAC OC Ov */ #define XMR_INV_MP (1L<<8) /* Bit 8: Rx inv Pause Frame Ov */ #define XMR_MCTRL_OV (1L<<7) /* Bit 7: Rx MAC Ctrl-F Cnt Ov */ -#define XMR_MPAUSE_OV (1L<<6) /* Bit 6: Rx Pause MAC Ctrl-F Ov*/ -#define XMR_UC_OK_OV (1L<<5) /* Bit 5: Rx Unicast Frame CntOv*/ +#define XMR_MPAUSE_OV (1L<<6) /* Bit 6: Rx Pause MAC Ctrl-F Ov */ +#define XMR_UC_OK_OV (1L<<5) /* Bit 5: Rx Unicast Frame Cnt Ov */ #define XMR_MC_OK_OV (1L<<4) /* Bit 4: Rx Multicast Cnt Ov */ #define XMR_BC_OK_OV (1L<<3) /* Bit 3: Rx Broadcast Cnt Ov */ -#define XMR_OK_LO_OV (1L<<2) /* Bit 2: Octets Rx OK Low CntOv*/ -#define XMR_OK_HI_OV (1L<<1) /* Bit 1: Octets Rx OK Hi Cnt Ov*/ -#define XMR_OK_OV (1L<<0) /* Bit 0: Frames Received Ok Ov */ +#define XMR_OK_LO_OV (1L<<2) /* Bit 2: Octets Rx OK Low Cnt Ov */ +#define XMR_OK_HI_OV (1L<<1) /* Bit 1: Octets Rx OK High Cnt Ov */ +#define XMR_OK_OV (1L<<0) /* Bit 0: Frames Received OK Ov */ #define XMR_DEF_MSK (XMR_OK_LO_OV | XMR_OK_HI_OV) /* XM_TX_CNT_EV 32 bit r/o Tx Counter Event Register */ /* XM_TX_EV_MSK 32 bit r/w Tx Counter Event Mask */ /* Bit 31..26: reserved */ -#define XMT_MAX_SZ_OV (1L<<25) /* Bit 25: 1024-MaxSize Tx Cnt Ov*/ -#define XMT_1023B_OV (1L<<24) /* Bit 24: 512-1023Byte Tx Cnt Ov*/ -#define XMT_511B_OV (1L<<23) /* Bit 23: 256-511 Byte Tx Cnt Ov*/ -#define XMT_255B_OV (1L<<22) /* Bit 22: 128-255 Byte Tx Cnt Ov*/ +#define XMT_MAX_SZ_OV (1L<<25) /* Bit 25: 1024-MaxSize Tx Cnt Ov */ +#define XMT_1023B_OV (1L<<24) /* Bit 24: 512-1023Byte Tx Cnt Ov */ +#define XMT_511B_OV (1L<<23) /* Bit 23: 256-511 Byte Tx Cnt Ov */ +#define XMT_255B_OV (1L<<22) /* Bit 22: 128-255 Byte Tx Cnt Ov */ #define XMT_127B_OV (1L<<21) /* Bit 21: 65-127 Byte Tx Cnt Ov */ #define XMT_64B_OV (1L<<20) /* Bit 20: 64 Byte Tx Cnt Ov */ #define XMT_UTIL_OV (1L<<19) /* Bit 19: Tx Util Cnt Overflow */ #define XMT_UTIL_UR (1L<<18) /* Bit 18: Tx Util Cnt Underrun */ -#define XMT_CS_ERR_OV (1L<<17) /* Bit 17: Tx Carr Sen Err Cnt Ov*/ +#define XMT_CS_ERR_OV (1L<<17) /* Bit 17: Tx Carr Sen Err Cnt Ov */ #define XMT_FIFO_UR_OV (1L<<16) /* Bit 16: Tx FIFO Ur Ev Cnt Ov */ #define XMT_EX_DEF_OV (1L<<15) /* Bit 15: Tx Ex Deferall Cnt Ov */ #define XMT_DEF (1L<<14) /* Bit 14: Tx Deferred Cnt Ov */ #define XMT_LAT_COL_OV (1L<<13) /* Bit 13: Tx Late Col Cnt Ov */ -#define XMT_ABO_COL_OV (1L<<12) /* Bit 12: Tx abo dueto Ex Col Ov*/ +#define XMT_ABO_COL_OV (1L<<12) /* Bit 12: Tx abo dueto Ex Col Ov */ #define XMT_MUL_COL_OV (1L<<11) /* Bit 11: Tx Mult Col Cnt Ov */ #define XMT_SNG_COL (1L<<10) /* Bit 10: Tx Single Col Cnt Ov */ -#define XMT_MCTRL_OV (1L<<9) /* Bit 9: Tx MAC Ctrl Counter Ov*/ -#define XMT_MPAUSE (1L<<8) /* Bit 8: Tx Pause MAC Ctrl-F Ov*/ +#define XMT_MCTRL_OV (1L<<9) /* Bit 9: Tx MAC Ctrl Counter Ov */ +#define XMT_MPAUSE (1L<<8) /* Bit 8: Tx Pause MAC Ctrl-F Ov */ #define XMT_BURST (1L<<7) /* Bit 7: Tx Burst Event Cnt Ov */ #define XMT_LONG (1L<<6) /* Bit 6: Tx Long Frame Cnt Ov */ #define XMT_UC_OK_OV (1L<<5) /* Bit 5: Tx Unicast Cnt Ov */ #define XMT_MC_OK_OV (1L<<4) /* Bit 4: Tx Multicast Cnt Ov */ #define XMT_BC_OK_OV (1L<<3) /* Bit 3: Tx Broadcast Cnt Ov */ -#define XMT_OK_LO_OV (1L<<2) /* Bit 2: Octets Tx OK Low CntOv*/ -#define XMT_OK_HI_OV (1L<<1) /* Bit 1: Octets Tx OK Hi Cnt Ov*/ -#define XMT_OK_OV (1L<<0) /* Bit 0: Frames Tx Ok Ov */ +#define XMT_OK_LO_OV (1L<<2) /* Bit 2: Octets Tx OK Low Cnt Ov */ +#define XMT_OK_HI_OV (1L<<1) /* Bit 1: Octets Tx OK High Cnt Ov */ +#define XMT_OK_OV (1L<<0) /* Bit 0: Frames Tx OK Ov */ #define XMT_DEF_MSK (XMT_OK_LO_OV | XMT_OK_HI_OV) /* * Receive Frame Status Encoding */ -#define XMR_FS_LEN (0x3fffUL<<18) /* Bit 31..18: Rx Frame Length */ -#define XMR_FS_2L_VLAN (1L<<17) /* Bit 17: tagged wh 2Lev VLAN ID*/ -#define XMR_FS_1L_VLAN (1L<<16) /* Bit 16: tagged wh 1Lev VLAN ID*/ +#define XMR_FS_LEN_MSK (0x3fffUL<<18) /* Bit 31..18: Rx Frame Length */ +#define XMR_FS_2L_VLAN (1L<<17) /* Bit 17: Tagged wh 2Lev VLAN ID */ +#define XMR_FS_1L_VLAN (1L<<16) /* Bit 16: Tagged wh 1Lev VLAN ID */ #define XMR_FS_BC (1L<<15) /* Bit 15: Broadcast Frame */ #define XMR_FS_MC (1L<<14) /* Bit 14: Multicast Frame */ #define XMR_FS_UC (1L<<13) /* Bit 13: Unicast Frame */ @@ -467,6 +470,8 @@ #define XMR_FS_ERR (1L<<1) /* Bit 1: Frame Error */ #define XMR_FS_MCTRL (1L<<0) /* Bit 0: MAC Control Packet */ +#define XMR_FS_LEN_SHIFT 18 + /* * XMR_FS_ERR will be set if * XMR_FS_FCS_ERR, XMR_FS_LNG_ERR, XMR_FS_RUNT, @@ -486,7 +491,7 @@ #define PHY_XMAC_ID0 0x02 /* 16 bit r/o PHY ID0 Register */ #define PHY_XMAC_ID1 0x03 /* 16 bit r/o PHY ID1 Register */ #define PHY_XMAC_AUNE_ADV 0x04 /* 16 bit r/w Auto-Neg. Advertisement */ -#define PHY_XMAC_AUNE_LP 0x05 /* 16 bit r/o Link Partner Abi Reg */ +#define PHY_XMAC_AUNE_LP 0x05 /* 16 bit r/o Link Partner Ability Reg */ #define PHY_XMAC_AUNE_EXP 0x06 /* 16 bit r/o Auto-Neg. Expansion Reg */ #define PHY_XMAC_NEPG 0x07 /* 16 bit r/w Next Page Register */ #define PHY_XMAC_NEPG_LP 0x08 /* 16 bit r/o Next Page Link Partner */ @@ -508,7 +513,7 @@ #define PHY_BCOM_NEPG 0x07 /* 16 bit r/w Next Page Register */ #define PHY_BCOM_NEPG_LP 0x08 /* 16 bit r/o Next Page Link Partner */ /* Broadcom-specific registers */ -#define PHY_BCOM_1000T_CTRL 0x09 /* 16 bit r/w 1000Base-T Ctrl Reg */ +#define PHY_BCOM_1000T_CTRL 0x09 /* 16 bit r/w 1000Base-T Control Reg */ #define PHY_BCOM_1000T_STAT 0x0a /* 16 bit r/o 1000Base-T Status Reg */ /* 0x0b - 0x0e: reserved */ #define PHY_BCOM_EXT_STAT 0x0f /* 16 bit r/o Extended Status Reg */ @@ -539,24 +544,32 @@ #define PHY_MARV_NEPG 0x07 /* 16 bit r/w Next Page Register */ #define PHY_MARV_NEPG_LP 0x08 /* 16 bit r/o Next Page Link Partner */ /* Marvel-specific registers */ -#define PHY_MARV_1000T_CTRL 0x09 /* 16 bit r/w 1000Base-T Ctrl Reg */ +#define PHY_MARV_1000T_CTRL 0x09 /* 16 bit r/w 1000Base-T Control Reg */ #define PHY_MARV_1000T_STAT 0x0a /* 16 bit r/o 1000Base-T Status Reg */ /* 0x0b - 0x0e: reserved */ #define PHY_MARV_EXT_STAT 0x0f /* 16 bit r/o Extended Status Reg */ -#define PHY_MARV_PHY_CTRL 0x10 /* 16 bit r/w PHY Specific Ctrl Reg */ -#define PHY_MARV_PHY_STAT 0x11 /* 16 bit r/o PHY Specific Stat Reg */ +#define PHY_MARV_PHY_CTRL 0x10 /* 16 bit r/w PHY Specific Control Reg */ +#define PHY_MARV_PHY_STAT 0x11 /* 16 bit r/o PHY Specific Status Reg */ #define PHY_MARV_INT_MASK 0x12 /* 16 bit r/w Interrupt Mask Reg */ #define PHY_MARV_INT_STAT 0x13 /* 16 bit r/o Interrupt Status Reg */ #define PHY_MARV_EXT_CTRL 0x14 /* 16 bit r/w Ext. PHY Specific Ctrl */ #define PHY_MARV_RXE_CNT 0x15 /* 16 bit r/w Receive Error Counter */ #define PHY_MARV_EXT_ADR 0x16 /* 16 bit r/w Ext. Ad. for Cable Diag. */ - /* 0x17: reserved */ +#define PHY_MARV_PORT_IRQ 0x17 /* 16 bit r/o Port 0 IRQ (88E1111 only) */ #define PHY_MARV_LED_CTRL 0x18 /* 16 bit r/w LED Control Reg */ #define PHY_MARV_LED_OVER 0x19 /* 16 bit r/w Manual LED Override Reg */ #define PHY_MARV_EXT_CTRL_2 0x1a /* 16 bit r/w Ext. PHY Specific Ctrl 2 */ #define PHY_MARV_EXT_P_STAT 0x1b /* 16 bit r/w Ext. PHY Spec. Stat Reg */ #define PHY_MARV_CABLE_DIAG 0x1c /* 16 bit r/o Cable Diagnostic Reg */ - /* 0x1d - 0x1f: reserved */ +#define PHY_MARV_PAGE_ADDR 0x1d /* 16 bit r/w Extended Page Address Reg */ +#define PHY_MARV_PAGE_DATA 0x1e /* 16 bit r/w Extended Page Data Reg */ + +/* for 10/100 Fast Ethernet PHY (88E3082 only) */ +#define PHY_MARV_FE_LED_PAR 0x16 /* 16 bit r/w LED Parallel Select Reg. */ +#define PHY_MARV_FE_LED_SER 0x17 /* 16 bit r/w LED Stream Select S. LED */ +#define PHY_MARV_FE_VCT_TX 0x1a /* 16 bit r/w VCT Reg. for TXP/N Pins */ +#define PHY_MARV_FE_VCT_RX 0x1b /* 16 bit r/o VCT Reg. for RXP/N Pins */ +#define PHY_MARV_FE_SPEC_2 0x1c /* 16 bit r/w Specific Control Reg. 2 */ /*----------------------------------------------------------------------------*/ /* @@ -572,9 +585,9 @@ #define PHY_LONE_NEPG 0x07 /* 16 bit r/w Next Page Register */ #define PHY_LONE_NEPG_LP 0x08 /* 16 bit r/o Next Page Link Partner */ /* Level One-specific registers */ -#define PHY_LONE_1000T_CTRL 0x09 /* 16 bit r/w 1000Base-T Control Reg*/ +#define PHY_LONE_1000T_CTRL 0x09 /* 16 bit r/w 1000Base-T Control Reg */ #define PHY_LONE_1000T_STAT 0x0a /* 16 bit r/o 1000Base-T Status Reg */ - /* 0x0b -0x0e: reserved */ + /* 0x0b - 0x0e: reserved */ #define PHY_LONE_EXT_STAT 0x0f /* 16 bit r/o Extended Status Reg */ #define PHY_LONE_PORT_CFG 0x10 /* 16 bit r/w Port Configuration Reg*/ #define PHY_LONE_Q_STAT 0x11 /* 16 bit r/o Quick Status Reg */ @@ -583,7 +596,7 @@ #define PHY_LONE_LED_CFG 0x14 /* 16 bit r/w LED Configuration Reg */ #define PHY_LONE_PORT_CTRL 0x15 /* 16 bit r/w Port Control Reg */ #define PHY_LONE_CIM 0x16 /* 16 bit r/o CIM Reg */ - /* 0x17 -0x1c: reserved */ + /* 0x17 - 0x1c: reserved */ /*----------------------------------------------------------------------------*/ /* @@ -601,14 +614,14 @@ /* National-specific registers */ #define PHY_NAT_1000T_CTRL 0x09 /* 16 bit r/w 1000Base-T Control Reg */ #define PHY_NAT_1000T_STAT 0x0a /* 16 bit r/o 1000Base-T Status Reg */ - /* 0x0b -0x0e: reserved */ + /* 0x0b - 0x0e: reserved */ #define PHY_NAT_EXT_STAT 0x0f /* 16 bit r/o Extended Status Register */ #define PHY_NAT_EXT_CTRL1 0x10 /* 16 bit r/o Extended Control Reg1 */ #define PHY_NAT_Q_STAT1 0x11 /* 16 bit r/o Quick Status Reg1 */ #define PHY_NAT_10B_OP 0x12 /* 16 bit r/o 10Base-T Operations Reg */ #define PHY_NAT_EXT_CTRL2 0x13 /* 16 bit r/o Extended Control Reg1 */ #define PHY_NAT_Q_STAT2 0x14 /* 16 bit r/o Quick Status Reg2 */ - /* 0x15 -0x18: reserved */ + /* 0x15 - 0x18: reserved */ #define PHY_NAT_PHY_ADDR 0x19 /* 16 bit r/o PHY Address Register */ @@ -616,7 +629,7 @@ /* * PHY bit definitions - * Bits defined as PHY_X_..., PHY_B_..., PHY_L_... or PHY_N_... are + * Bits defined as PHY_X_..., PHY_B_..., PHY_L_..., PHY_N_... or PHY_M_... are * XMAC/Broadcom/LevelOne/National/Marvell-specific. * All other are general. */ @@ -627,14 +640,14 @@ /***** PHY_LONE_CTRL 16 bit r/w PHY Control Register *****/ #define PHY_CT_RESET (1<<15) /* Bit 15: (sc) clear all PHY related regs */ #define PHY_CT_LOOP (1<<14) /* Bit 14: enable Loopback over PHY */ -#define PHY_CT_SPS_LSB (1<<13) /* Bit 13: (BC,L1) Speed select, lower bit */ +#define PHY_CT_SPS_LSB (1<<13) /* Bit 13: Speed select, lower bit */ #define PHY_CT_ANE (1<<12) /* Bit 12: Auto-Negotiation Enabled */ -#define PHY_CT_PDOWN (1<<11) /* Bit 11: (BC,L1) Power Down Mode */ -#define PHY_CT_ISOL (1<<10) /* Bit 10: (BC,L1) Isolate Mode */ -#define PHY_CT_RE_CFG (1<<9) /* Bit 9: (sc) Restart Auto-Negotiation */ +#define PHY_CT_PDOWN (1<<11) /* Bit 11: Power Down Mode */ +#define PHY_CT_ISOL (1<<10) /* Bit 10: Isolate Mode */ +#define PHY_CT_RE_CFG (1<<9) /* Bit 9: (sc) Restart Auto-Negotiation */ #define PHY_CT_DUP_MD (1<<8) /* Bit 8: Duplex Mode */ -#define PHY_CT_COL_TST (1<<7) /* Bit 7: (BC,L1) Collision Test enabled */ -#define PHY_CT_SPS_MSB (1<<6) /* Bit 6: (BC,L1) Speed select, upper bit */ +#define PHY_CT_COL_TST (1<<7) /* Bit 7: Collision Test enabled */ +#define PHY_CT_SPS_MSB (1<<6) /* Bit 6: Speed select, upper bit */ /* Bit 5..0: reserved */ #define PHY_CT_SP1000 PHY_CT_SPS_MSB /* enable speed of 1000 Mbps */ @@ -647,25 +660,25 @@ /***** PHY_MARV_STAT 16 bit r/w PHY Status Register *****/ /***** PHY_LONE_STAT 16 bit r/w PHY Status Register *****/ /* Bit 15..9: reserved */ - /* (BC/L1) 100/10 Mbps cap bits ignored*/ + /* (BC/L1) 100/10 Mbps cap bits ignored */ #define PHY_ST_EXT_ST (1<<8) /* Bit 8: Extended Status Present */ /* Bit 7: reserved */ -#define PHY_ST_PRE_SUP (1<<6) /* Bit 6: (BC/L1) preamble suppression */ +#define PHY_ST_PRE_SUP (1<<6) /* Bit 6: Preamble Suppression */ #define PHY_ST_AN_OVER (1<<5) /* Bit 5: Auto-Negotiation Over */ #define PHY_ST_REM_FLT (1<<4) /* Bit 4: Remote Fault Condition Occured */ #define PHY_ST_AN_CAP (1<<3) /* Bit 3: Auto-Negotiation Capability */ #define PHY_ST_LSYNC (1<<2) /* Bit 2: Link Synchronized */ -#define PHY_ST_JAB_DET (1<<1) /* Bit 1: (BC/L1) Jabber Detected */ +#define PHY_ST_JAB_DET (1<<1) /* Bit 1: Jabber Detected */ #define PHY_ST_EXT_REG (1<<0) /* Bit 0: Extended Register available */ -/***** PHY_XMAC_ID1 16 bit r/o PHY ID1 Register */ -/***** PHY_BCOM_ID1 16 bit r/o PHY ID1 Register */ -/***** PHY_MARV_ID1 16 bit r/o PHY ID1 Register */ -/***** PHY_LONE_ID1 16 bit r/o PHY ID1 Register */ +/***** PHY_XMAC_ID1 16 bit r/o PHY ID1 Register */ +/***** PHY_BCOM_ID1 16 bit r/o PHY ID1 Register */ +/***** PHY_MARV_ID1 16 bit r/o PHY ID1 Register */ +/***** PHY_LONE_ID1 16 bit r/o PHY ID1 Register */ #define PHY_I1_OUI_MSK (0x3f<<10) /* Bit 15..10: Organization Unique ID */ #define PHY_I1_MOD_NUM (0x3f<<4) /* Bit 9.. 4: Model Number */ -#define PHY_I1_REV_MSK 0x0f /* Bit 3.. 0: Revision Number */ +#define PHY_I1_REV_MSK 0xf /* Bit 3.. 0: Revision Number */ /* different Broadcom PHY Ids */ #define PHY_BCOM_ID1_A1 0x6041 @@ -673,11 +686,21 @@ #define PHY_BCOM_ID1_C0 0x6044 #define PHY_BCOM_ID1_C5 0x6047 +/* different Marvell PHY Ids */ +#define PHY_MARV_ID0_VAL 0x0141 /* Marvell Unique Identifier */ + +#define PHY_MARV_ID1_B0 0x0C23 /* Yukon (PHY 88E1040 Rev.C0) */ +#define PHY_MARV_ID1_B2 0x0C25 /* Yukon-Plus (PHY 88E1040 Rev.D0) */ +#define PHY_MARV_ID1_C2 0x0CC2 /* Yukon-EC (PHY 88E1111 Rev.B1) */ +#define PHY_MARV_ID1_Y2 0x0C91 /* Yukon-XL (PHY 88E1112 Rev.B0) */ +#define PHY_MARV_ID1_FE 0x0C83 /* Yukon-FE (PHY 88E3082 Rev.A1) */ +#define PHY_MARV_ID1_ECU 0x0CB0 /* Yukon-ECU (PHY 88E1149 Rev.B2?) */ + /***** PHY_XMAC_AUNE_ADV 16 bit r/w Auto-Negotiation Advertisement *****/ /***** PHY_XMAC_AUNE_LP 16 bit r/o Link Partner Ability Reg *****/ #define PHY_AN_NXT_PG (1<<15) /* Bit 15: Request Next Page */ -#define PHY_X_AN_ACK (1<<14) /* Bit 14: (ro) Acknowledge Received */ +#define PHY_X_AN_ACK (1<<14) /* Bit 14: (ro) Acknowledge Received */ #define PHY_X_AN_RFB (3<<12) /* Bit 13..12: Remote Fault Bits */ /* Bit 11.. 9: reserved */ #define PHY_X_AN_PAUSE (3<<7) /* Bit 8.. 7: Pause Bits */ @@ -825,7 +848,7 @@ #define PHY_B_PEC_BY_MLT3 (1<<8) /* Bit 8: Bypass MLT3 Encoder */ #define PHY_B_PEC_BY_RXA (1<<7) /* Bit 7: Bypass Rx Alignm. */ #define PHY_B_PEC_RES_SCR (1<<6) /* Bit 6: Reset Scrambler */ -#define PHY_B_PEC_EN_LTR (1<<5) /* Bit 5: Ena LED Traffic Mode */ +#define PHY_B_PEC_EN_LTR (1<<5) /* Bit 5: Enable LED Traffic Mode */ #define PHY_B_PEC_LED_ON (1<<4) /* Bit 4: Force LED's on */ #define PHY_B_PEC_LED_OFF (1<<3) /* Bit 3: Force LED's off */ #define PHY_B_PEC_EX_IPG (1<<2) /* Bit 2: Extend Tx IPG Mode */ @@ -979,7 +1002,7 @@ #define PHY_L_QS_DUP_MOD (1<<9) /* Bit 9: Full/Half Duplex */ #define PHY_L_QS_AN (1<<8) /* Bit 8: AutoNeg is On */ #define PHY_L_QS_AN_C (1<<7) /* Bit 7: AN is Complete */ -#define PHY_L_QS_LLE (7<<4) /* Bit 6: Line Length Estim. */ +#define PHY_L_QS_LLE (7<<4) /* Bit 6..4: Line Length Estim. */ #define PHY_L_QS_PAUSE (1<<3) /* Bit 3: LP advertised Pause */ #define PHY_L_QS_AS_PAUSE (1<<2) /* Bit 2: LP adv. asym. Pause */ #define PHY_L_QS_ISOLATE (1<<1) /* Bit 1: CIM Isolated */ @@ -1027,9 +1050,8 @@ /* Bit 9..0: not described */ /***** PHY_LONE_CIM 16 bit r/o CIM Reg *****/ -#define PHY_L_CIM_ISOL (255<<8)/* Bit 15..8: Isolate Count */ -#define PHY_L_CIM_FALSE_CAR (255<<0)/* Bit 7..0: False Carrier Count */ - +#define PHY_L_CIM_ISOL (0xff<<8) /* Bit 15..8: Isolate Count */ +#define PHY_L_CIM_FALSE_CAR 0xff /* Bit 7..0: False Carrier Count */ /* * Pause Bits (PHY_L_AN_ASP and PHY_L_AN_PC) encoding @@ -1039,7 +1061,6 @@ #define PHY_L_P_ASYM_MD (2<<10) /* Bit 11..10: asymmetric Pause Mode */ #define PHY_L_P_BOTH_MD (3<<10) /* Bit 11..10: both Pause Mode */ - /* * National-Specific */ @@ -1084,22 +1105,24 @@ */ /***** PHY_MARV_AUNE_ADV 16 bit r/w Auto-Negotiation Advertisement *****/ /***** PHY_MARV_AUNE_LP 16 bit r/w Link Part Ability Reg *****/ -#define PHY_M_AN_NXT_PG BIT_15 /* Request Next Page */ -#define PHY_M_AN_ACK BIT_14 /* (ro) Acknowledge Received */ -#define PHY_M_AN_RF BIT_13 /* Remote Fault */ - /* Bit 12: reserved */ -#define PHY_M_AN_ASP BIT_11 /* Asymmetric Pause */ -#define PHY_M_AN_PC BIT_10 /* MAC Pause implemented */ -#define PHY_M_AN_100_FD BIT_8 /* Advertise 100Base-TX Full Duplex */ -#define PHY_M_AN_100_HD BIT_7 /* Advertise 100Base-TX Half Duplex */ -#define PHY_M_AN_10_FD BIT_6 /* Advertise 10Base-TX Full Duplex */ -#define PHY_M_AN_10_HD BIT_5 /* Advertise 10Base-TX Half Duplex */ - -/* special defines for FIBER (88E1011S only) */ -#define PHY_M_AN_ASP_X BIT_8 /* Asymmetric Pause */ -#define PHY_M_AN_PC_X BIT_7 /* MAC Pause implemented */ -#define PHY_M_AN_1000X_AHD BIT_6 /* Advertise 10000Base-X Half Duplex */ -#define PHY_M_AN_1000X_AFD BIT_5 /* Advertise 10000Base-X Full Duplex */ +#define PHY_M_AN_NXT_PG BIT_15S /* Request Next Page */ +#define PHY_M_AN_ACK BIT_14S /* (ro) Acknowledge Received */ +#define PHY_M_AN_RF BIT_13S /* Remote Fault */ + /* Bit 12: reserved */ +#define PHY_M_AN_ASP BIT_11S /* Asymmetric Pause */ +#define PHY_M_AN_PC BIT_10S /* MAC Pause implemented */ +#define PHY_M_AN_100_T4 BIT_9S /* Not cap. 100Base-T4 (always 0) */ +#define PHY_M_AN_100_FD BIT_8S /* Advertise 100Base-TX Full Duplex */ +#define PHY_M_AN_100_HD BIT_7S /* Advertise 100Base-TX Half Duplex */ +#define PHY_M_AN_10_FD BIT_6S /* Advertise 10Base-TX Full Duplex */ +#define PHY_M_AN_10_HD BIT_5S /* Advertise 10Base-TX Half Duplex */ +#define PHY_M_AN_SEL_MSK (0x1f<<4) /* Bit 4.. 0: Selector Field Mask */ + +/* special defines for FIBER (88E1040S only) */ +#define PHY_M_AN_ASP_X BIT_8S /* Asymmetric Pause */ +#define PHY_M_AN_PC_X BIT_7S /* MAC Pause implemented */ +#define PHY_M_AN_1000X_AHD BIT_6S /* Advertise 10000Base-X Half Duplex */ +#define PHY_M_AN_1000X_AFD BIT_5S /* Advertise 10000Base-X Full Duplex */ /* Pause Bits (PHY_M_AN_ASP_X and PHY_M_AN_PC_X) encoding */ #define PHY_M_P_NO_PAUSE_X (0<<7) /* Bit 8.. 7: no Pause Mode */ @@ -1109,105 +1132,167 @@ /***** PHY_MARV_1000T_CTRL 16 bit r/w 1000Base-T Control Reg *****/ #define PHY_M_1000C_TEST (7<<13) /* Bit 15..13: Test Modes */ -#define PHY_M_1000C_MSE (1<<12) /* Bit 12: Manual Master/Slave Enable */ -#define PHY_M_1000C_MSC (1<<11) /* Bit 11: M/S Configuration (1=Master) */ -#define PHY_M_1000C_MPD (1<<10) /* Bit 10: Multi-Port Device */ -#define PHY_M_1000C_AFD (1<<9) /* Bit 9: Advertise Full Duplex */ -#define PHY_M_1000C_AHD (1<<8) /* Bit 8: Advertise Half Duplex */ +#define PHY_M_1000C_MSE BIT_12S /* Manual Master/Slave Enable */ +#define PHY_M_1000C_MSC BIT_11S /* M/S Configuration (1=Master) */ +#define PHY_M_1000C_MPD BIT_10S /* Multi-Port Device */ +#define PHY_M_1000C_AFD BIT_9S /* Advertise Full Duplex */ +#define PHY_M_1000C_AHD BIT_8S /* Advertise Half Duplex */ /* Bit 7..0: reserved */ /***** PHY_MARV_PHY_CTRL 16 bit r/w PHY Specific Ctrl Reg *****/ -#define PHY_M_PC_TX_FFD_MSK (3<<14) /* Bit 15..14: Tx FIFO Depth Mask */ -#define PHY_M_PC_RX_FFD_MSK (3<<12) /* Bit 13..12: Rx FIFO Depth Mask */ -#define PHY_M_PC_ASS_CRS_TX (1<<11) /* Bit 11: Assert CRS on Transmit */ -#define PHY_M_PC_FL_GOOD (1<<10) /* Bit 10: Force Link Good */ -#define PHY_M_PC_EN_DET_MSK (3<<8) /* Bit 9.. 8: Energy Detect Mask */ -#define PHY_M_PC_ENA_EXT_D (1<<7) /* Bit 7: Enable Ext. Distance (10BT) */ -#define PHY_M_PC_MDIX_MSK (3<<5) /* Bit 6.. 5: MDI/MDIX Config. Mask */ -#define PHY_M_PC_DIS_125CLK (1<<4) /* Bit 4: Disable 125 CLK */ -#define PHY_M_PC_MAC_POW_UP (1<<3) /* Bit 3: MAC Power up */ -#define PHY_M_PC_SQE_T_ENA (1<<2) /* Bit 2: SQE Test Enabled */ -#define PHY_M_PC_POL_R_DIS (1<<1) /* Bit 1: Polarity Reversal Disabled */ -#define PHY_M_PC_DIS_JABBER (1<<0) /* Bit 0: Disable Jabber */ +#define PHY_M_PC_TX_FFD_MSK (3<<14) /* Bit 15..14: Tx FIFO Depth Mask */ +#define PHY_M_PC_RX_FFD_MSK (3<<12) /* Bit 13..12: Rx FIFO Depth Mask */ +#define PHY_M_PC_ASS_CRS_TX BIT_11S /* Assert CRS on Transmit */ +#define PHY_M_PC_FL_GOOD BIT_10S /* Force Link Good */ +#define PHY_M_PC_EN_DET_MSK (3<<8) /* Bit 9.. 8: Energy Detect Mask */ +#define PHY_M_PC_ENA_EXT_D BIT_7S /* Enable Ext. Distance (10BT) */ +#define PHY_M_PC_MDIX_MSK (3<<5) /* Bit 6.. 5: MDI/MDIX Config. Mask */ +#define PHY_M_PC_DIS_125CLK BIT_4S /* Disable 125 CLK */ +#define PHY_M_PC_MAC_POW_UP BIT_3S /* MAC Power up */ +#define PHY_M_PC_SQE_T_ENA BIT_2S /* SQE Test Enabled */ +#define PHY_M_PC_POL_R_DIS BIT_1S /* Polarity Reversal Disabled */ +#define PHY_M_PC_DIS_JABBER BIT_0S /* Disable Jabber */ #define PHY_M_PC_EN_DET SHIFT8(2) /* Energy Detect (Mode 1) */ #define PHY_M_PC_EN_DET_PLUS SHIFT8(3) /* Energy Detect Plus (Mode 2) */ -#define PHY_M_PC_MDI_XMODE(x) SHIFT5(x) -#define PHY_M_PC_MAN_MDI 0 /* 00 = Manual MDI configuration */ +#define PHY_M_PC_MDI_XMODE(x) (SHIFT5(x) & PHY_M_PC_MDIX_MSK) + +#define PHY_M_PC_MAN_MDI 0 /* 00 = Manual MDI configuration */ #define PHY_M_PC_MAN_MDIX 1 /* 01 = Manual MDIX configuration */ #define PHY_M_PC_ENA_AUTO 3 /* 11 = Enable Automatic Crossover */ +/* for Yukon-2/-EC Ultra Gigabit Ethernet PHY (88E1112/88E1149 only) */ +#define PHY_M_PC_DIS_LINK_P BIT_15S /* Disable Link Pulses */ +#define PHY_M_PC_DSC_MSK (7<<12) /* Bit 14..12: Downshift Counter */ +#define PHY_M_PC_DOWN_S_ENA BIT_11S /* Downshift Enable */ + /* !!! Errata in spec. (1 = disable) */ + +#define PHY_M_PC_DSC(x) (SHIFT12(x) & PHY_M_PC_DSC_MSK) + /* 000=1x; 001=2x; 010=3x; 011=4x */ + /* 100=5x; 101=6x; 110=7x; 111=8x */ + +/* for Yukon-EC Ultra Gigabit Ethernet PHY (88E1149 only) */ + /* Bit 4: reserved */ +#define PHY_M_PC_COP_TX_DIS BIT_3S /* Copper Transmitter Disable */ +#define PHY_M_PC_POW_D_ENA BIT_2S /* Power Down Enable */ + +/* for 10/100 Fast Ethernet PHY (88E3082 only) */ +#define PHY_M_PC_ENA_DTE_DT BIT_15S /* Enable Data Terminal Equ. (DTE) Detect */ +#define PHY_M_PC_ENA_ENE_DT BIT_14S /* Enable Energy Detect (sense & pulse) */ +#define PHY_M_PC_DIS_NLP_CK BIT_13S /* Disable Normal Link Puls (NLP) Check */ +#define PHY_M_PC_ENA_LIP_NP BIT_12S /* Enable Link Partner Next Page Reg. */ +#define PHY_M_PC_DIS_NLP_GN BIT_11S /* Disable Normal Link Puls Generation */ + +#define PHY_M_PC_DIS_SCRAMB BIT_9S /* Disable Scrambler */ +#define PHY_M_PC_DIS_FEFI BIT_8S /* Disable Far End Fault Indic. (FEFI) */ + +#define PHY_M_PC_SH_TP_SEL BIT_6S /* Shielded Twisted Pair Select */ +#define PHY_M_PC_RX_FD_MSK (3<<2) /* Bit 3.. 2: Rx FIFO Depth Mask */ + /***** PHY_MARV_PHY_STAT 16 bit r/o PHY Specific Status Reg *****/ -#define PHY_M_PS_SPEED_MSK (3<<14) /* Bit 15..14: Speed Mask */ -#define PHY_M_PS_SPEED_1000 (1<<15) /* 10 = 1000 Mbps */ -#define PHY_M_PS_SPEED_100 (1<<14) /* 01 = 100 Mbps */ -#define PHY_M_PS_SPEED_10 0 /* 00 = 10 Mbps */ -#define PHY_M_PS_FULL_DUP (1<<13) /* Bit 13: Full Duplex */ -#define PHY_M_PS_PAGE_REC (1<<12) /* Bit 12: Page Received */ -#define PHY_M_PS_SPDUP_RES (1<<11) /* Bit 11: Speed & Duplex Resolved */ -#define PHY_M_PS_LINK_UP (1<<10) /* Bit 10: Link Up */ -#define PHY_M_PS_CABLE_MSK (3<<7) /* Bit 9.. 7: Cable Length Mask */ -#define PHY_M_PS_MDI_X_STAT (1<<6) /* Bit 6: MDI Crossover Stat (1=MDIX) */ -#define PHY_M_PS_DOWNS_STAT (1<<5) /* Bit 5: Downshift Status (1=downsh.) */ -#define PHY_M_PS_ENDET_STAT (1<<4) /* Bit 4: Energy Detect Status (1=act) */ -#define PHY_M_PS_TX_P_EN (1<<3) /* Bit 3: Tx Pause Enabled */ -#define PHY_M_PS_RX_P_EN (1<<2) /* Bit 2: Rx Pause Enabled */ -#define PHY_M_PS_POL_REV (1<<1) /* Bit 1: Polarity Reversed */ -#define PHY_M_PC_JABBER (1<<0) /* Bit 0: Jabber */ +#define PHY_M_PS_SPEED_MSK (3<<14) /* Bit 15..14: Speed Mask */ +#define PHY_M_PS_SPEED_1000 BIT_15S /* 10 = 1000 Mbps */ +#define PHY_M_PS_SPEED_100 BIT_14S /* 01 = 100 Mbps */ +#define PHY_M_PS_SPEED_10 0 /* 00 = 10 Mbps */ +#define PHY_M_PS_FULL_DUP BIT_13S /* Full Duplex */ +#define PHY_M_PS_PAGE_REC BIT_12S /* Page Received */ +#define PHY_M_PS_SPDUP_RES BIT_11S /* Speed & Duplex Resolved */ +#define PHY_M_PS_LINK_UP BIT_10S /* Link Up */ +#define PHY_M_PS_CABLE_MSK (7<<7) /* Bit 9.. 7: Cable Length Mask */ +#define PHY_M_PS_MDI_X_STAT BIT_6S /* MDI Crossover Stat (1=MDIX) */ +#define PHY_M_PS_DOWNS_STAT BIT_5S /* Downshift Status (1=downsh.) */ +#define PHY_M_PS_ENDET_STAT BIT_4S /* Energy Detect Status (1=act) */ +#define PHY_M_PS_TX_P_EN BIT_3S /* Tx Pause Enabled */ +#define PHY_M_PS_RX_P_EN BIT_2S /* Rx Pause Enabled */ +#define PHY_M_PS_POL_REV BIT_1S /* Polarity Reversed */ +#define PHY_M_PS_JABBER BIT_0S /* Jabber */ #define PHY_M_PS_PAUSE_MSK (PHY_M_PS_TX_P_EN | PHY_M_PS_RX_P_EN) +/* for 10/100 Fast Ethernet PHY (88E3082 only) */ +#define PHY_M_PS_DTE_DETECT BIT_15S /* Data Terminal Equipment (DTE) Detected */ +#define PHY_M_PS_RES_SPEED BIT_14S /* Resolved Speed (1=100 Mbps, 0=10 Mbps */ + /***** PHY_MARV_INT_MASK 16 bit r/w Interrupt Mask Reg *****/ /***** PHY_MARV_INT_STAT 16 bit r/o Interrupt Status Reg *****/ -#define PHY_M_IS_AN_ERROR (1<<15) /* Bit 15: Auto-Negotiation Error */ -#define PHY_M_IS_LSP_CHANGE (1<<14) /* Bit 14: Link Speed Changed */ -#define PHY_M_IS_DUP_CHANGE (1<<13) /* Bit 13: Duplex Mode Changed */ -#define PHY_M_IS_AN_PR (1<<12) /* Bit 12: Page Received */ -#define PHY_M_IS_AN_COMPL (1<<11) /* Bit 11: Auto-Negotiation Completed */ -#define PHY_M_IS_LST_CHANGE (1<<10) /* Bit 10: Link Status Changed */ -#define PHY_M_IS_SYMB_ERROR (1<<9) /* Bit 9: Symbol Error */ -#define PHY_M_IS_FALSE_CARR (1<<8) /* Bit 8: False Carrier */ -#define PHY_M_IS_FIFO_ERROR (1<<7) /* Bit 7: FIFO Overflow/Underrun Error */ -#define PHY_M_IS_MDI_CHANGE (1<<6) /* Bit 6: MDI Crossover Changed */ -#define PHY_M_IS_DOWNSH_DET (1<<5) /* Bit 5: Downshift Detected */ -#define PHY_M_IS_END_CHANGE (1<<4) /* Bit 4: Energy Detect Changed */ - /* Bit 3..2: reserved */ -#define PHY_M_IS_POL_CHANGE (1<<1) /* Bit 1: Polarity Changed */ -#define PHY_M_IS_JABBER (1<<0) /* Bit 0: Jabber */ +#define PHY_M_IS_AN_ERROR BIT_15S /* Auto-Negotiation Error */ +#define PHY_M_IS_LSP_CHANGE BIT_14S /* Link Speed Changed */ +#define PHY_M_IS_DUP_CHANGE BIT_13S /* Duplex Mode Changed */ +#define PHY_M_IS_AN_PR BIT_12S /* Page Received */ +#define PHY_M_IS_AN_COMPL BIT_11S /* Auto-Negotiation Completed */ +#define PHY_M_IS_LST_CHANGE BIT_10S /* Link Status Changed */ +#define PHY_M_IS_SYMB_ERROR BIT_9S /* Symbol Error */ +#define PHY_M_IS_FALSE_CARR BIT_8S /* False Carrier */ +#define PHY_M_IS_FIFO_ERROR BIT_7S /* FIFO Overflow/Underrun Error */ +#define PHY_M_IS_MDI_CHANGE BIT_6S /* MDI Crossover Changed */ +#define PHY_M_IS_DOWNSH_DET BIT_5S /* Downshift Detected */ +#define PHY_M_IS_END_CHANGE BIT_4S /* Energy Detect Changed */ + /* Bit 3: reserved */ +#define PHY_M_IS_DTE_CHANGE BIT_2S /* DTE Power Det. Status Changed */ + /* (88E1111 only) */ +#define PHY_M_IS_POL_CHANGE BIT_1S /* Polarity Changed */ +#define PHY_M_IS_JABBER BIT_0S /* Jabber */ #define PHY_M_DEF_MSK (PHY_M_IS_AN_ERROR | PHY_M_IS_AN_PR | \ PHY_M_IS_LST_CHANGE | PHY_M_IS_FIFO_ERROR) /***** PHY_MARV_EXT_CTRL 16 bit r/w Ext. PHY Specific Ctrl *****/ -#define PHY_M_EC_M_DSC_MSK (3<<10) /* Bit 11..10: Master downshift counter */ -#define PHY_M_EC_S_DSC_MSK (3<<8) /* Bit 9.. 8: Slave downshift counter */ +#define PHY_M_EC_ENA_BC_EXT BIT_15S /* Enable Block Carr. Ext. (88E1111 only) */ +#define PHY_M_EC_ENA_LIN_LB BIT_14S /* Enable Line Loopback (88E1111 only) */ + /* Bit 13: reserved */ +#define PHY_M_EC_DIS_LINK_P BIT_12S /* Disable Link Pulses (88E1111 only) */ +#define PHY_M_EC_M_DSC_MSK (3<<10) /* Bit 11..10: Master Downshift Counter */ + /* (88E1040 Rev.C0 only) */ +#define PHY_M_EC_S_DSC_MSK (3<<8) /* Bit 9.. 8: Slave Downshift Counter */ + /* (88E1040 Rev.C0 only) */ +#define PHY_M_EC_DSC_MSK_2 (7<<9) /* Bit 11.. 9: Downshift Counter */ + /* (88E1040 Rev.D0 and higher) */ +#define PHY_M_EC_DOWN_S_ENA BIT_8S /* Downshift Enable (88E1040 Rev.D0 and */ + /* 88E1111 !!! Errata in spec. (1=dis.) */ +#define PHY_M_EC_RX_TIM_CT BIT_7S /* RGMII Rx Timing Control*/ #define PHY_M_EC_MAC_S_MSK (7<<4) /* Bit 6.. 4: Def. MAC interface speed */ -#define PHY_M_EC_FIB_AN_ENA (1<<3) /* Bit 3: Fiber Auto-Neg. Enable */ - -#define PHY_M_EC_M_DSC(x) SHIFT10(x) /* 00=1x; 01=2x; 10=3x; 11=4x */ -#define PHY_M_EC_S_DSC(x) SHIFT8(x) /* 00=dis; 01=1x; 10=2x; 11=3x */ -#define PHY_M_EC_MAC_S(x) SHIFT4(x) /* 01X=0; 110=2.5; 111=25 (MHz) */ - +#define PHY_M_EC_FIB_AN_ENA BIT_3S /* Fiber Auto-Neg. Enable 88E1040S only) */ +#define PHY_M_EC_DTE_D_ENA BIT_2S /* DTE Detect Enable (88E1111 only) */ +#define PHY_M_EC_TX_TIM_CT BIT_1S /* RGMII Tx Timing Control */ +#define PHY_M_EC_TRANS_DIS BIT_0S /* Transmitter Disable (88E1111 only) */ + +#define PHY_M_EC_M_DSC(x) (SHIFT10(x) & PHY_M_EC_M_DSC_MSK) + /* 00=1x; 01=2x; 10=3x; 11=4x */ +#define PHY_M_EC_S_DSC(x) (SHIFT8(x) & PHY_M_EC_S_DSC_MSK) + /* 00=dis; 01=1x; 10=2x; 11=3x */ +#define PHY_M_EC_MAC_S(x) (SHIFT4(x) & PHY_M_EC_MAC_S_MSK) + /* 01X=0; 110=2.5; 111=25 (MHz) */ + +#define PHY_M_EC_DSC_2(x) (SHIFT9(x) & PHY_M_EC_DSC_MSK_2) + /* 000=1x; 001=2x; 010=3x; 011=4x */ + /* 100=5x; 101=6x; 110=7x; 111=8x */ #define MAC_TX_CLK_0_MHZ 2 #define MAC_TX_CLK_2_5_MHZ 6 #define MAC_TX_CLK_25_MHZ 7 /***** PHY_MARV_LED_CTRL 16 bit r/w LED Control Reg *****/ -#define PHY_M_LEDC_DIS_LED (1<<15) /* Bit 15: Disable LED */ -#define PHY_M_LEDC_PULS_MSK (7<<12) /* Bit 14..12: Pulse Stretch Mask */ -#define PHY_M_LEDC_F_INT (1<<11) /* Bit 11: Force Interrupt */ -#define PHY_M_LEDC_BL_R_MSK (7<<8) /* Bit 10.. 8: Blink Rate Mask */ - /* Bit 7.. 5: reserved */ -#define PHY_M_LEDC_LINK_MSK (3<<3) /* Bit 4.. 3: Link Control Mask */ -#define PHY_M_LEDC_DP_CTRL (1<<2) /* Bit 2: Duplex Control */ -#define PHY_M_LEDC_RX_CTRL (1<<1) /* Bit 1: Rx activity / Link */ -#define PHY_M_LEDC_TX_CTRL (1<<0) /* Bit 0: Tx activity / Link */ +#define PHY_M_LEDC_DIS_LED BIT_15S /* Disable LED */ +#define PHY_M_LEDC_PULS_MSK (7<<12) /* Bit 14..12: Pulse Stretch Mask */ +#define PHY_M_LEDC_F_INT BIT_11S /* Force Interrupt */ +#define PHY_M_LEDC_BL_R_MSK (7<<8) /* Bit 10.. 8: Blink Rate Mask */ +#define PHY_M_LEDC_DP_C_LSB BIT_7S /* Duplex Control (LSB, 88E1111 only) */ +#define PHY_M_LEDC_TX_C_LSB BIT_6S /* Tx Control (LSB, 88E1111 only) */ +#define PHY_M_LEDC_LK_C_MSK (7<<3) /* Bit 5.. 3: Link Control Mask */ + /* (88E1111 only) */ + /* Bit 7.. 5: reserved (88E1040 only) */ +#define PHY_M_LEDC_LINK_MSK (3<<3) /* Bit 4.. 3: Link Control Mask */ + /* (88E1040 only) */ +#define PHY_M_LEDC_DP_CTRL BIT_2S /* Duplex Control */ +#define PHY_M_LEDC_DP_C_MSB BIT_2S /* Duplex Control (MSB, 88E1111 only) */ +#define PHY_M_LEDC_RX_CTRL BIT_1S /* Rx Activity / Link */ +#define PHY_M_LEDC_TX_CTRL BIT_0S /* Tx Activity / Link */ +#define PHY_M_LEDC_TX_C_MSB BIT_0S /* Tx Control (MSB, 88E1111 only) */ -#define PHY_M_LED_PULS_DUR(x) SHIFT12(x) /* Pulse Stretch Duration */ +#define PHY_M_LED_PULS_DUR(x) (SHIFT12(x) & PHY_M_LEDC_PULS_MSK) -#define PULS_NO_STR 0 /* no pulse stretching */ -#define PULS_21MS 1 /* 21 ms to 42 ms */ +#define PULS_NO_STR 0 /* no pulse stretching */ +#define PULS_21MS 1 /* 21 ms to 42 ms */ #define PULS_42MS 2 /* 42 ms to 84 ms */ #define PULS_84MS 3 /* 84 ms to 170 ms */ #define PULS_170MS 4 /* 170 ms to 340 ms */ @@ -1215,7 +1300,7 @@ #define PULS_670MS 6 /* 670 ms to 1.3 s */ #define PULS_1300MS 7 /* 1.3 s to 2.7 s */ -#define PHY_M_LED_BLINK_RT(x) SHIFT8(x) /* Blink Rate */ +#define PHY_M_LED_BLINK_RT(x) (SHIFT8(x) & PHY_M_LEDC_BL_R_MSK) #define BLINK_42MS 0 /* 42 ms */ #define BLINK_84MS 1 /* 84 ms */ @@ -1225,6 +1310,8 @@ /* values 5 - 7: reserved */ /***** PHY_MARV_LED_OVER 16 bit r/w Manual LED Override Reg *****/ +#define PHY_M_LED_MO_SGMII(x) SHIFT14(x) /* Bit 15..14: SGMII AN Timer */ + /* Bit 13..12: reserved */ #define PHY_M_LED_MO_DUP(x) SHIFT10(x) /* Bit 11..10: Duplex */ #define PHY_M_LED_MO_10(x) SHIFT8(x) /* Bit 9.. 8: Link 10 */ #define PHY_M_LED_MO_100(x) SHIFT6(x) /* Bit 7.. 6: Link 100 */ @@ -1238,30 +1325,35 @@ #define MO_LED_ON 3 /***** PHY_MARV_EXT_CTRL_2 16 bit r/w Ext. PHY Specific Ctrl 2 *****/ - /* Bit 15.. 7: reserved */ -#define PHY_M_EC2_FI_IMPED (1<<6) /* Bit 6: Fiber Input Impedance */ -#define PHY_M_EC2_FO_IMPED (1<<5) /* Bit 5: Fiber Output Impedance */ -#define PHY_M_EC2_FO_M_CLK (1<<4) /* Bit 4: Fiber Mode Clock Enable */ -#define PHY_M_EC2_FO_BOOST (1<<3) /* Bit 3: Fiber Output Boost */ + /* Bit 15.. 7: reserved */ +#define PHY_M_EC2_FI_IMPED BIT_6S /* Fiber Input Impedance */ +#define PHY_M_EC2_FO_IMPED BIT_5S /* Fiber Output Impedance */ +#define PHY_M_EC2_FO_M_CLK BIT_4S /* Fiber Mode Clock Enable */ +#define PHY_M_EC2_FO_BOOST BIT_3S /* Fiber Output Boost */ #define PHY_M_EC2_FO_AM_MSK 7 /* Bit 2.. 0: Fiber Output Amplitude */ -/***** PHY_MARV_EXT_P_STAT 16 bit r/w Ext. PHY Specific Status *****/ -#define PHY_M_FC_AUTO_SEL (1<<15) /* Bit 15: Fiber/Copper Auto Sel. dis. */ -#define PHY_M_FC_AN_REG_ACC (1<<14) /* Bit 14: Fiber/Copper Autoneg. reg acc */ -#define PHY_M_FC_RESULUTION (1<<13) /* Bit 13: Fiber/Copper Resulution */ -#define PHY_M_SER_IF_AN_BP (1<<12) /* Bit 12: Ser IF autoneg. bypass enable */ -#define PHY_M_SER_IF_BP_ST (1<<11) /* Bit 11: Ser IF autoneg. bypass status */ -#define PHY_M_IRQ_POLARITY (1<<10) /* Bit 10: IRQ polarity */ - /* Bit 9..4: reserved */ -#define PHY_M_UNDOC1 (1<< 7) /* undocumented bit !! */ -#define PHY_M_MODE_MASK (0xf<<0)/* Bit 3..0: copy of HWCFG MODE[3:0] */ - +/***** PHY_MARV_EXT_P_STAT 16 bit r/w Ext. PHY Specific Status *****/ +#define PHY_M_FC_AUTO_SEL BIT_15S /* Fiber/Copper Auto Sel. Dis. */ +#define PHY_M_FC_AN_REG_ACC BIT_14S /* Fiber/Copper AN Reg. Access */ +#define PHY_M_FC_RESOLUTION BIT_13S /* Fiber/Copper Resolution */ +#define PHY_M_SER_IF_AN_BP BIT_12S /* Ser. IF AN Bypass Enable */ +#define PHY_M_SER_IF_BP_ST BIT_11S /* Ser. IF AN Bypass Status */ +#define PHY_M_IRQ_POLARITY BIT_10S /* IRQ polarity */ +#define PHY_M_DIS_AUT_MED BIT_9S /* Disable Aut. Medium Reg. Selection */ + /* (88E1111 only) */ + /* Bit 9.. 4: reserved (88E1040 only) */ +#define PHY_M_UNDOC1 BIT_7S /* undocumented bit !! */ +#define PHY_M_DTE_POW_STAT BIT_4S /* DTE Power Status (88E1111 only) */ +#define PHY_M_MODE_MASK 0xf /* Bit 3.. 0: copy of HWCFG MODE[3:0] */ /***** PHY_MARV_CABLE_DIAG 16 bit r/o Cable Diagnostic Reg *****/ -#define PHY_M_CABD_ENA_TEST (1<<15) /* Bit 15: Enable Test */ -#define PHY_M_CABD_STAT_MSK (3<<13) /* Bit 14..13: Status */ - /* Bit 12.. 8: reserved */ -#define PHY_M_CABD_DIST_MSK 0xff /* Bit 7.. 0: Distance */ +#define PHY_M_CABD_ENA_TEST BIT_15S /* Enable Test (Page 0) */ +#define PHY_M_CABD_DIS_WAIT BIT_15S /* Disable Waiting Period (Page 1) */ + /* (88E1111 only) */ +#define PHY_M_CABD_STAT_MSK (3<<13) /* Bit 14..13: Status Mask */ +#define PHY_M_CABD_AMPL_MSK (0x1f<<8) /* Bit 12.. 8: Amplitude Mask */ + /* (88E1111 only) */ +#define PHY_M_CABD_DIST_MSK 0xff /* Bit 7.. 0: Distance Mask */ /* values for Cable Diagnostic Status (11=fail; 00=OK; 10=open; 01=short) */ #define CABD_STAT_NORMAL 0 @@ -1269,6 +1361,79 @@ #define CABD_STAT_OPEN 2 #define CABD_STAT_FAIL 3 +/* for 10/100 Fast Ethernet PHY (88E3082 only) */ +/***** PHY_MARV_FE_LED_PAR 16 bit r/w LED Parallel Select Reg. *****/ + /* Bit 15..12: reserved (used internally) */ +#define PHY_M_FELP_LED2_MSK (0xf<<8) /* Bit 11.. 8: LED2 Mask (LINK) */ +#define PHY_M_FELP_LED1_MSK (0xf<<4) /* Bit 7.. 4: LED1 Mask (ACT) */ +#define PHY_M_FELP_LED0_MSK 0xf /* Bit 3.. 0: LED0 Mask (SPEED) */ + +#define PHY_M_FELP_LED2_CTRL(x) (SHIFT8(x) & PHY_M_FELP_LED2_MSK) +#define PHY_M_FELP_LED1_CTRL(x) (SHIFT4(x) & PHY_M_FELP_LED1_MSK) +#define PHY_M_FELP_LED0_CTRL(x) (SHIFT0(x) & PHY_M_FELP_LED0_MSK) + +#define LED_PAR_CTRL_COLX 0x00 +#define LED_PAR_CTRL_ERROR 0x01 +#define LED_PAR_CTRL_DUPLEX 0x02 +#define LED_PAR_CTRL_DP_COL 0x03 +#define LED_PAR_CTRL_SPEED 0x04 +#define LED_PAR_CTRL_LINK 0x05 +#define LED_PAR_CTRL_TX 0x06 +#define LED_PAR_CTRL_RX 0x07 +#define LED_PAR_CTRL_ACT 0x08 +#define LED_PAR_CTRL_LNK_RX 0x09 +#define LED_PAR_CTRL_LNK_AC 0x0a +#define LED_PAR_CTRL_ACT_BL 0x0b +#define LED_PAR_CTRL_TX_BL 0x0c +#define LED_PAR_CTRL_RX_BL 0x0d +#define LED_PAR_CTRL_COL_BL 0x0e +#define LED_PAR_CTRL_INACT 0x0f + +/***** PHY_MARV_FE_SPEC_2 16 bit r/w Specific Control Reg. 2 *****/ +#define PHY_M_FESC_DIS_WAIT BIT_2S /* Disable TDR Waiting Period */ +#define PHY_M_FESC_ENA_MCLK BIT_1S /* Enable MAC Rx Clock in sleep mode */ +#define PHY_M_FESC_SEL_CL_A BIT_0S /* Select Class A driver (100B-TX) */ + +/* for Yukon-2 Gigabit Ethernet PHY (88E1112 only) */ +/***** PHY_MARV_PHY_CTRL (page 1) 16 bit r/w Fiber Specific Ctrl *****/ +#define PHY_M_FIB_FORCE_LNK BIT_10S /* Force Link Good */ +#define PHY_M_FIB_SIGD_POL BIT_9S /* SIGDET Polarity */ +#define PHY_M_FIB_TX_DIS BIT_3S /* Transmitter Disable */ + +/***** PHY_MARV_PHY_CTRL (page 2) 16 bit r/w MAC Specific Ctrl *****/ +#define PHY_M_MAC_MD_MSK (7<<7) /* Bit 9.. 7: Mode Select Mask */ +#define PHY_M_MAC_GMIF_PUP BIT_3S /* GMII Power Up (88E1149 only) */ + +#define PHY_M_MAC_MD_AUTO 3 /* Auto Copper/1000Base-X */ +#define PHY_M_MAC_MD_COPPER 5 /* Copper only */ +#define PHY_M_MAC_MD_1000BX 7 /* 1000Base-X only */ +#define PHY_M_MAC_MODE_SEL(x) (SHIFT7(x) & PHY_M_MAC_MD_MSK) + +/***** PHY_MARV_PHY_CTRL (page 3) 16 bit r/w LED Control Reg. *****/ +#define PHY_M_LEDC_LOS_MSK (0xf<<12) /* Bit 15..12: LOS LED Ctrl. Mask */ +#define PHY_M_LEDC_INIT_MSK (0xf<<8) /* Bit 11.. 8: INIT LED Ctrl. Mask */ +#define PHY_M_LEDC_STA1_MSK (0xf<<4) /* Bit 7.. 4: STAT1 LED Ctrl. Mask */ +#define PHY_M_LEDC_STA0_MSK 0xf /* Bit 3.. 0: STAT0 LED Ctrl. Mask */ + +#define PHY_M_LEDC_LOS_CTRL(x) (SHIFT12(x) & PHY_M_LEDC_LOS_MSK) +#define PHY_M_LEDC_INIT_CTRL(x) (SHIFT8(x) & PHY_M_LEDC_INIT_MSK) +#define PHY_M_LEDC_STA1_CTRL(x) (SHIFT4(x) & PHY_M_LEDC_STA1_MSK) +#define PHY_M_LEDC_STA0_CTRL(x) (SHIFT0(x) & PHY_M_LEDC_STA0_MSK) + +/***** PHY_MARV_PHY_STAT (page 3) 16 bit r/w Polarity Control Reg. *****/ +#define PHY_M_POLC_LS1M_MSK (0xf<<12) /* Bit 15..12: LOS,STAT1 Mix % Mask */ +#define PHY_M_POLC_IS0M_MSK (0xf<<8) /* Bit 11.. 8: INIT,STAT0 Mix % Mask */ +#define PHY_M_POLC_LOS_MSK (0x3<<6) /* Bit 7.. 6: LOS Pol. Ctrl. Mask */ +#define PHY_M_POLC_INIT_MSK (0x3<<4) /* Bit 5.. 4: INIT Pol. Ctrl. Mask */ +#define PHY_M_POLC_STA1_MSK (0x3<<2) /* Bit 3.. 2: STAT1 Pol. Ctrl. Mask */ +#define PHY_M_POLC_STA0_MSK 0x3 /* Bit 1.. 0: STAT0 Pol. Ctrl. Mask */ + +#define PHY_M_POLC_LS1_P_MIX(x) (SHIFT12(x) & PHY_M_POLC_LS1M_MSK) +#define PHY_M_POLC_IS0_P_MIX(x) (SHIFT8(x) & PHY_M_POLC_IS0M_MSK) +#define PHY_M_POLC_LOS_CTRL(x) (SHIFT6(x) & PHY_M_POLC_LOS_MSK) +#define PHY_M_POLC_INIT_CTRL(x) (SHIFT4(x) & PHY_M_POLC_INIT_MSK) +#define PHY_M_POLC_STA1_CTRL(x) (SHIFT2(x) & PHY_M_POLC_STA1_MSK) +#define PHY_M_POLC_STA0_CTRL(x) (SHIFT0(x) & PHY_M_POLC_STA0_MSK) /* * GMAC registers @@ -1429,141 +1594,159 @@ */ /* GM_GP_STAT 16 bit r/o General Purpose Status Register */ -#define GM_GPSR_SPEED (1<<15) /* Bit 15: Port Speed (1 = 100 Mbps) */ -#define GM_GPSR_DUPLEX (1<<14) /* Bit 14: Duplex Mode (1 = Full) */ -#define GM_GPSR_FC_TX_DIS (1<<13) /* Bit 13: Tx Flow-Control Mode Disabled */ -#define GM_GPSR_LINK_UP (1<<12) /* Bit 12: Link Up Status */ -#define GM_GPSR_PAUSE (1<<11) /* Bit 11: Pause State */ -#define GM_GPSR_TX_ACTIVE (1<<10) /* Bit 10: Tx in Progress */ -#define GM_GPSR_EXC_COL (1<<9) /* Bit 9: Excessive Collisions Occured */ -#define GM_GPSR_LAT_COL (1<<8) /* Bit 8: Late Collisions Occured */ - /* Bit 7..6: reserved */ -#define GM_GPSR_PHY_ST_CH (1<<5) /* Bit 5: PHY Status Change */ -#define GM_GPSR_GIG_SPEED (1<<4) /* Bit 4: Gigabit Speed (1 = 1000 Mbps) */ -#define GM_GPSR_PART_MODE (1<<3) /* Bit 3: Partition mode */ -#define GM_GPSR_FC_RX_DIS (1<<2) /* Bit 2: Rx Flow-Control Mode Disabled */ -#define GM_GPSR_PROM_EN (1<<1) /* Bit 1: Promiscuous Mode Enabled */ - /* Bit 0: reserved */ - +#define GM_GPSR_SPEED BIT_15S /* Port Speed (1 = 100 Mbps) */ +#define GM_GPSR_DUPLEX BIT_14S /* Duplex Mode (1 = Full) */ +#define GM_GPSR_FC_TX_DIS BIT_13S /* Tx Flow-Control Mode Disabled */ +#define GM_GPSR_LINK_UP BIT_12S /* Link Up Status */ +#define GM_GPSR_PAUSE BIT_11S /* Pause State */ +#define GM_GPSR_TX_ACTIVE BIT_10S /* Tx in Progress */ +#define GM_GPSR_EXC_COL BIT_9S /* Excessive Collisions Occured */ +#define GM_GPSR_LAT_COL BIT_8S /* Late Collisions Occured */ + /* Bit 7.. 6: reserved */ +#define GM_GPSR_PHY_ST_CH BIT_5S /* PHY Status Change */ +#define GM_GPSR_GIG_SPEED BIT_4S /* Gigabit Speed (1 = 1000 Mbps) */ +#define GM_GPSR_PART_MODE BIT_3S /* Partition mode */ +#define GM_GPSR_FC_RX_DIS BIT_2S /* Rx Flow-Control Mode Disabled */ + /* Bit 2.. 0: reserved */ + /* GM_GP_CTRL 16 bit r/w General Purpose Control Register */ - /* Bit 15: reserved */ -#define GM_GPCR_PROM_ENA (1<<14) /* Bit 14: Enable Promiscuous Mode */ -#define GM_GPCR_FC_TX_DIS (1<<13) /* Bit 13: Disable Tx Flow-Control Mode */ -#define GM_GPCR_TX_ENA (1<<12) /* Bit 12: Enable Transmit */ -#define GM_GPCR_RX_ENA (1<<11) /* Bit 11: Enable Receive */ -#define GM_GPCR_BURST_ENA (1<<10) /* Bit 10: Enable Burst Mode */ -#define GM_GPCR_LOOP_ENA (1<<9) /* Bit 9: Enable MAC Loopback Mode */ -#define GM_GPCR_PART_ENA (1<<8) /* Bit 8: Enable Partition Mode */ -#define GM_GPCR_GIGS_ENA (1<<7) /* Bit 7: Gigabit Speed (1000 Mbps) */ -#define GM_GPCR_FL_PASS (1<<6) /* Bit 6: Force Link Pass */ -#define GM_GPCR_DUP_FULL (1<<5) /* Bit 5: Full Duplex Mode */ -#define GM_GPCR_FC_RX_DIS (1<<4) /* Bit 4: Disable Rx Flow-Control Mode */ -#define GM_GPCR_SPEED_100 (1<<3) /* Bit 3: Port Speed 100 Mbps */ -#define GM_GPCR_AU_DUP_DIS (1<<2) /* Bit 2: Disable Auto-Update Duplex */ -#define GM_GPCR_AU_FCT_DIS (1<<1) /* Bit 1: Disable Auto-Update Flow-C. */ -#define GM_GPCR_AU_SPD_DIS (1<<0) /* Bit 0: Disable Auto-Update Speed */ +#define GM_GPCR_RMII_PH_ENA BIT_15S /* Enable RMII for PHY (Yukon-FE only) */ +#define GM_GPCR_RMII_LB_ENA BIT_14S /* Enable RMII Loopback (Yukon-FE only) */ +#define GM_GPCR_FC_TX_DIS BIT_13S /* Disable Tx Flow-Control Mode */ +#define GM_GPCR_TX_ENA BIT_12S /* Enable Transmit */ +#define GM_GPCR_RX_ENA BIT_11S /* Enable Receive */ + /* Bit 10: reserved */ +#define GM_GPCR_LOOP_ENA BIT_9S /* Enable MAC Loopback Mode */ +#define GM_GPCR_PART_ENA BIT_8S /* Enable Partition Mode */ +#define GM_GPCR_GIGS_ENA BIT_7S /* Gigabit Speed (1000 Mbps) */ +#define GM_GPCR_FL_PASS BIT_6S /* Force Link Pass */ +#define GM_GPCR_DUP_FULL BIT_5S /* Full Duplex Mode */ +#define GM_GPCR_FC_RX_DIS BIT_4S /* Disable Rx Flow-Control Mode */ +#define GM_GPCR_SPEED_100 BIT_3S /* Port Speed 100 Mbps */ +#define GM_GPCR_AU_DUP_DIS BIT_2S /* Disable Auto-Update Duplex */ +#define GM_GPCR_AU_FCT_DIS BIT_1S /* Disable Auto-Update Flow-C. */ +#define GM_GPCR_AU_SPD_DIS BIT_0S /* Disable Auto-Update Speed */ #define GM_GPCR_SPEED_1000 (GM_GPCR_GIGS_ENA | GM_GPCR_SPEED_100) #define GM_GPCR_AU_ALL_DIS (GM_GPCR_AU_DUP_DIS | GM_GPCR_AU_FCT_DIS |\ GM_GPCR_AU_SPD_DIS) - + /* GM_TX_CTRL 16 bit r/w Transmit Control Register */ -#define GM_TXCR_FORCE_JAM (1<<15) /* Bit 15: Force Jam / Flow-Control */ -#define GM_TXCR_CRC_DIS (1<<14) /* Bit 14: Disable insertion of CRC */ -#define GM_TXCR_PAD_DIS (1<<13) /* Bit 13: Disable padding of packets */ -#define GM_TXCR_COL_THR_MSK (1<<10) /* Bit 12..10: Collision Threshold */ +#define GM_TXCR_FORCE_JAM BIT_15S /* Force Jam / Flow-Control */ +#define GM_TXCR_CRC_DIS BIT_14S /* Disable insertion of CRC */ +#define GM_TXCR_PAD_DIS BIT_13S /* Disable padding of packets */ +#define GM_TXCR_COL_THR_MSK (7<<10) /* Bit 12..10: Collision Threshold Mask */ + /* Bit 9.. 8: reserved */ +#define GM_TXCR_PAD_PAT_MSK 0xff /* Bit 7.. 0: Padding Pattern Mask */ + /* (Yukon-2 only) */ #define TX_COL_THR(x) (SHIFT10(x) & GM_TXCR_COL_THR_MSK) #define TX_COL_DEF 0x04 - + /* GM_RX_CTRL 16 bit r/w Receive Control Register */ -#define GM_RXCR_UCF_ENA (1<<15) /* Bit 15: Enable Unicast filtering */ -#define GM_RXCR_MCF_ENA (1<<14) /* Bit 14: Enable Multicast filtering */ -#define GM_RXCR_CRC_DIS (1<<13) /* Bit 13: Remove 4-byte CRC */ -#define GM_RXCR_PASS_FC (1<<12) /* Bit 12: Pass FC packets to FIFO */ - +#define GM_RXCR_UCF_ENA BIT_15S /* Enable Unicast filtering */ +#define GM_RXCR_MCF_ENA BIT_14S /* Enable Multicast filtering */ +#define GM_RXCR_CRC_DIS BIT_13S /* Remove 4-byte CRC */ +#define GM_RXCR_PASS_FC BIT_12S /* Pass FC packets to FIFO (Yukon-1 only) */ + /* Bit 11.. 0: reserved */ + /* GM_TX_PARAM 16 bit r/w Transmit Parameter Register */ -#define GM_TXPA_JAMLEN_MSK (0x03<<14) /* Bit 15..14: Jam Length */ -#define GM_TXPA_JAMIPG_MSK (0x1f<<9) /* Bit 13..9: Jam IPG */ -#define GM_TXPA_JAMDAT_MSK (0x1f<<4) /* Bit 8..4: IPG Jam to Data */ - /* Bit 3..0: reserved */ +#define GM_TXPA_JAMLEN_MSK (3<<14) /* Bit 15..14: Jam Length Mask */ +#define GM_TXPA_JAMIPG_MSK (0x1f<<9) /* Bit 13.. 9: Jam IPG Mask */ +#define GM_TXPA_JAMDAT_MSK (0x1f<<4) /* Bit 8.. 4: IPG Jam to Data Mask */ +#define GM_TXPA_BO_LIM_MSK 0x0f /* Bit 3.. 0: Backoff Limit Mask */ + /* (Yukon-2 only) */ #define TX_JAM_LEN_VAL(x) (SHIFT14(x) & GM_TXPA_JAMLEN_MSK) #define TX_JAM_IPG_VAL(x) (SHIFT9(x) & GM_TXPA_JAMIPG_MSK) #define TX_IPG_JAM_DATA(x) (SHIFT4(x) & GM_TXPA_JAMDAT_MSK) +#define TX_BACK_OFF_LIM(x) ((x) & GM_TXPA_BO_LIM_MSK) #define TX_JAM_LEN_DEF 0x03 #define TX_JAM_IPG_DEF 0x0b #define TX_IPG_JAM_DEF 0x1c +#define TX_BOF_LIM_DEF 0x04 /* GM_SERIAL_MODE 16 bit r/w Serial Mode Register */ -#define GM_SMOD_DATABL_MSK (0x1f<<11) /* Bit 15..11: Data Blinder (r/o) */ -#define GM_SMOD_LIMIT_4 (1<<10) /* Bit 10: 4 consecutive Tx trials */ -#define GM_SMOD_VLAN_ENA (1<<9) /* Bit 9: Enable VLAN (Max. Frame Len) */ -#define GM_SMOD_JUMBO_ENA (1<<8) /* Bit 8: Enable Jumbo (Max. Frame Len) */ - /* Bit 7..5: reserved */ -#define GM_SMOD_IPG_MSK 0x1f /* Bit 4..0: Inter-Packet Gap (IPG) */ - +#define GM_SMOD_DATABL_MSK (0x1f<<11) /* Bit 15..11: Data Blinder */ + /* r/o on Yukon, r/w on Yukon-EC */ +#define GM_SMOD_LIMIT_4 BIT_10S /* 4 consecutive Tx trials */ +#define GM_SMOD_VLAN_ENA BIT_9S /* Enable VLAN (Max. Frame Len) */ +#define GM_SMOD_JUMBO_ENA BIT_8S /* Enable Jumbo (Max. Frame Len) */ + /* Bit 7.. 5: reserved */ +#define GM_SMOD_IPG_MSK 0x1f /* Bit 4.. 0: Inter-Packet Gap (IPG) */ + #define DATA_BLIND_VAL(x) (SHIFT11(x) & GM_SMOD_DATABL_MSK) -#define DATA_BLIND_DEF 0x04 +#define IPG_DATA_VAL(x) ((x) & GM_SMOD_IPG_MSK) -#define IPG_DATA_VAL(x) (x & GM_SMOD_IPG_MSK) +#define DATA_BLIND_DEF 0x04 #define IPG_DATA_DEF 0x1e /* GM_SMI_CTRL 16 bit r/w SMI Control Register */ #define GM_SMI_CT_PHY_A_MSK (0x1f<<11) /* Bit 15..11: PHY Device Address */ #define GM_SMI_CT_REG_A_MSK (0x1f<<6) /* Bit 10.. 6: PHY Register Address */ -#define GM_SMI_CT_OP_RD (1<<5) /* Bit 5: OpCode Read (0=Write)*/ -#define GM_SMI_CT_RD_VAL (1<<4) /* Bit 4: Read Valid (Read completed) */ -#define GM_SMI_CT_BUSY (1<<3) /* Bit 3: Busy (Operation in progress) */ - /* Bit 2..0: reserved */ - +#define GM_SMI_CT_OP_RD BIT_5S /* OpCode Read (0=Write)*/ +#define GM_SMI_CT_RD_VAL BIT_4S /* Read Valid (Read completed) */ +#define GM_SMI_CT_BUSY BIT_3S /* Busy (Operation in progress) */ + /* Bit 2.. 0: reserved */ + #define GM_SMI_CT_PHY_AD(x) (SHIFT11(x) & GM_SMI_CT_PHY_A_MSK) #define GM_SMI_CT_REG_AD(x) (SHIFT6(x) & GM_SMI_CT_REG_A_MSK) - /* GM_PHY_ADDR 16 bit r/w GPHY Address Register */ - /* Bit 15..6: reserved */ -#define GM_PAR_MIB_CLR (1<<5) /* Bit 5: Set MIB Clear Counter Mode */ -#define GM_PAR_MIB_TST (1<<4) /* Bit 4: MIB Load Counter (Test Mode) */ - /* Bit 3..0: reserved */ - +/* GM_PHY_ADDR 16 bit r/w GPHY Address Register */ + /* Bit 15.. 6: reserved */ +#define GM_PAR_MIB_CLR BIT_5S /* Set MIB Clear Counter Mode */ +#define GM_PAR_MIB_TST BIT_4S /* MIB Load Counter (Test Mode) */ + /* Bit 3.. 0: reserved */ + /* Receive Frame Status Encoding */ -#define GMR_FS_LEN (0xffffUL<<16) /* Bit 31..16: Rx Frame Length */ +#define GMR_FS_LEN_MSK (0xffffUL<<16) /* Bit 31..16: Rx Frame Length */ /* Bit 15..14: reserved */ -#define GMR_FS_VLAN (1L<<13) /* Bit 13: VLAN Packet */ -#define GMR_FS_JABBER (1L<<12) /* Bit 12: Jabber Packet */ -#define GMR_FS_UN_SIZE (1L<<11) /* Bit 11: Undersize Packet */ -#define GMR_FS_MC (1L<<10) /* Bit 10: Multicast Packet */ -#define GMR_FS_BC (1L<<9) /* Bit 9: Broadcast Packet */ -#define GMR_FS_RX_OK (1L<<8) /* Bit 8: Receive OK (Good Packet) */ -#define GMR_FS_GOOD_FC (1L<<7) /* Bit 7: Good Flow-Control Packet */ -#define GMR_FS_BAD_FC (1L<<6) /* Bit 6: Bad Flow-Control Packet */ -#define GMR_FS_MII_ERR (1L<<5) /* Bit 5: MII Error */ -#define GMR_FS_LONG_ERR (1L<<4) /* Bit 4: Too Long Packet */ -#define GMR_FS_FRAGMENT (1L<<3) /* Bit 3: Fragment */ +#define GMR_FS_VLAN BIT_13 /* VLAN Packet */ +#define GMR_FS_JABBER BIT_12 /* Jabber Packet */ +#define GMR_FS_UN_SIZE BIT_11 /* Undersize Packet */ +#define GMR_FS_MC BIT_10 /* Multicast Packet */ +#define GMR_FS_BC BIT_9 /* Broadcast Packet */ +#define GMR_FS_RX_OK BIT_8 /* Receive OK (Good Packet) */ +#define GMR_FS_GOOD_FC BIT_7 /* Good Flow-Control Packet */ +#define GMR_FS_BAD_FC BIT_6 /* Bad Flow-Control Packet */ +#define GMR_FS_MII_ERR BIT_5 /* MII Error */ +#define GMR_FS_LONG_ERR BIT_4 /* Too Long Packet */ +#define GMR_FS_FRAGMENT BIT_3 /* Fragment */ /* Bit 2: reserved */ -#define GMR_FS_CRC_ERR (1L<<1) /* Bit 1: CRC Error */ -#define GMR_FS_RX_FF_OV (1L<<0) /* Bit 0: Rx FIFO Overflow */ +#define GMR_FS_CRC_ERR BIT_1 /* CRC Error */ +#define GMR_FS_RX_FF_OV BIT_0 /* Rx FIFO Overflow */ + +#define GMR_FS_LEN_SHIFT 16 /* * GMR_FS_ANY_ERR (analogous to XMR_FS_ANY_ERR) */ -#define GMR_FS_ANY_ERR (GMR_FS_CRC_ERR | \ - GMR_FS_LONG_ERR | \ +#ifdef SK_DIAG +#define GMR_FS_ANY_ERR ( \ + GMR_FS_RX_FF_OV | \ + GMR_FS_CRC_ERR | \ + GMR_FS_FRAGMENT | \ GMR_FS_MII_ERR | \ GMR_FS_BAD_FC | \ GMR_FS_GOOD_FC | \ GMR_FS_JABBER) - -/* Rx GMAC FIFO Flush Mask (default) */ -#define RX_FF_FL_DEF_MSK (GMR_FS_CRC_ERR | \ +#else +#define GMR_FS_ANY_ERR ( \ GMR_FS_RX_FF_OV | \ + GMR_FS_CRC_ERR | \ + GMR_FS_FRAGMENT | \ + GMR_FS_LONG_ERR | \ GMR_FS_MII_ERR | \ GMR_FS_BAD_FC | \ GMR_FS_GOOD_FC | \ GMR_FS_UN_SIZE | \ GMR_FS_JABBER) +#endif + +/* Rx GMAC FIFO Flush Mask (default) */ +#define RX_FF_FL_DEF_MSK GMR_FS_ANY_ERR /* typedefs *******************************************************************/ @@ -1575,3 +1758,4 @@ #endif /* __cplusplus */ #endif /* __INC_XMAC_H */ + diff -urN linux-2.4.32-600/drivers/net/sk98lin/skaddr.c linux-2.4.32-600-sk98_831/drivers/net/sk98lin/skaddr.c --- linux-2.4.32-600/drivers/net/sk98lin/skaddr.c Sat Mar 20 10:08:19 2004 +++ linux-2.4.32-600-sk98_831/drivers/net/sk98lin/skaddr.c Sun Feb 26 11:12:56 2006 @@ -2,6 +2,8 @@ * * Name: skaddr.c * Project: Gigabit Ethernet Adapters, ADDR-Module + * Version: $Revision: 2.8 $ + * Date: $Date: 2005/07/21 12:01:30 $ * Purpose: Manage Addresses (Multicast and Unicast) and Promiscuous Mode. * ******************************************************************************/ @@ -9,7 +11,7 @@ /****************************************************************************** * * (C)Copyright 1998-2002 SysKonnect GmbH. - * (C)Copyright 2002-2003 Marvell. + * (C)Copyright 2002-2005 Marvell. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -42,7 +44,7 @@ #if (defined(DEBUG) || ((!defined(LINT)) && (!defined(SK_SLIM)))) static const char SysKonnectFileId[] = - "@(#) $Id: skaddr.c,v 1.52 2003/06/02 13:46:15 tschilli Exp $ (C) Marvell."; + "@(#) $Id: skaddr.c,v 2.8 2005/07/21 12:01:30 tschilli Exp $ (C) Marvell."; #endif /* DEBUG ||!LINT || !SK_SLIM */ #define __SKADDR_C @@ -56,11 +58,10 @@ /* defines ********************************************************************/ - #define XMAC_POLY 0xEDB88320UL /* CRC32-Poly - XMAC: Little Endian */ #define GMAC_POLY 0x04C11DB7L /* CRC16-Poly - GMAC: Little Endian */ #define HASH_BITS 6 /* #bits in hash */ -#define SK_MC_BIT 0x01 +#define SK_MC_BIT 0x01 /* Error numbers and messages. */ @@ -77,7 +78,7 @@ /* 64-bit hash values with all bits set. */ -SK_U16 OnesHash[4] = {0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF}; +SK_U16 OnesHash[4] = {0xffff, 0xffff, 0xffff, 0xffff}; /* local variables ************************************************************/ @@ -134,13 +135,12 @@ switch (Level) { case SK_INIT_DATA: - SK_MEMSET((char *) &pAC->Addr, (SK_U8) 0, - (SK_U16) sizeof(SK_ADDR)); + SK_MEMSET((char *)&pAC->Addr, (SK_U8)0, (SK_U16)sizeof(SK_ADDR)); for (i = 0; i < SK_MAX_MACS; i++) { pAPort = &pAC->Addr.Port[i]; pAPort->PromMode = SK_PROM_MODE_NONE; - + pAPort->FirstExactMatchRlmt = SK_ADDR_FIRST_MATCH_RLMT; pAPort->FirstExactMatchDrv = SK_ADDR_FIRST_MATCH_DRV; pAPort->NextExactMatchRlmt = SK_ADDR_FIRST_MATCH_RLMT; @@ -157,7 +157,7 @@ /* pAC->Addr.InitDone = SK_INIT_DATA; */ break; - case SK_INIT_IO: + case SK_INIT_IO: #ifndef SK_NO_RLMT for (i = 0; i < SK_MAX_NETS; i++) { pAC->Addr.Net[i].ActivePort = pAC->Rlmt.Net[i].ActivePort; @@ -171,7 +171,7 @@ } } #endif /* DEBUG */ - + /* Read permanent logical MAC address from Control Register File. */ for (j = 0; j < SK_MAC_ADDR_LEN; j++) { InAddr = (SK_U8 *) &pAC->Addr.Net[0].PermanentMacAddress.a[j]; @@ -189,11 +189,11 @@ pAC->Addr.Port[pAC->Addr.Net[0].ActivePort].Exact[0] = pAC->Addr.Net[0].CurrentMacAddress; #if SK_MAX_NETS > 1 - /* Set logical MAC address for net 2 to (log | 3). */ + /* Set logical MAC address for net 2 to. */ if (!pAC->Addr.Net[1].CurrentMacAddressSet) { pAC->Addr.Net[1].PermanentMacAddress = pAC->Addr.Net[0].PermanentMacAddress; - pAC->Addr.Net[1].PermanentMacAddress.a[5] |= 3; + pAC->Addr.Net[1].PermanentMacAddress.a[5] += 1; /* Set the current logical MAC address to the permanent one. */ pAC->Addr.Net[1].CurrentMacAddress = pAC->Addr.Net[1].PermanentMacAddress; @@ -211,8 +211,8 @@ pAC->Addr.Net[i].PermanentMacAddress.a[2], pAC->Addr.Net[i].PermanentMacAddress.a[3], pAC->Addr.Net[i].PermanentMacAddress.a[4], - pAC->Addr.Net[i].PermanentMacAddress.a[5])) - + pAC->Addr.Net[i].PermanentMacAddress.a[5])); + SK_DBG_MSG(pAC, SK_DBGMOD_ADDR, SK_DBGCAT_INIT, ("Logical MAC Address (Net%d): %02X %02X %02X %02X %02X %02X\n", i, @@ -221,7 +221,7 @@ pAC->Addr.Net[i].CurrentMacAddress.a[2], pAC->Addr.Net[i].CurrentMacAddress.a[3], pAC->Addr.Net[i].CurrentMacAddress.a[4], - pAC->Addr.Net[i].CurrentMacAddress.a[5])) + pAC->Addr.Net[i].CurrentMacAddress.a[5])); } #endif /* DEBUG */ @@ -264,8 +264,8 @@ pAPort->PermanentMacAddress.a[2], pAPort->PermanentMacAddress.a[3], pAPort->PermanentMacAddress.a[4], - pAPort->PermanentMacAddress.a[5])) - + pAPort->PermanentMacAddress.a[5])); + SK_DBG_MSG(pAC, SK_DBGMOD_ADDR, SK_DBGCAT_INIT, ("SkAddrInit: Physical MAC Address: %02X %02X %02X %02X %02X %02X\n", pAPort->CurrentMacAddress.a[0], @@ -273,7 +273,7 @@ pAPort->CurrentMacAddress.a[2], pAPort->CurrentMacAddress.a[3], pAPort->CurrentMacAddress.a[4], - pAPort->CurrentMacAddress.a[5])) + pAPort->CurrentMacAddress.a[5])); #endif /* DEBUG */ } /* pAC->Addr.InitDone = SK_INIT_IO; */ @@ -297,7 +297,7 @@ } return (SK_ADDR_SUCCESS); - + } /* SkAddrInit */ #ifndef SK_SLIM @@ -331,16 +331,20 @@ int Flags) /* permanent/non-perm, sw-only */ { int ReturnCode; - + if (PortNumber >= (SK_U32) pAC->GIni.GIMacsFound) { return (SK_ADDR_ILLEGAL_PORT); } - + if (pAC->GIni.GIGenesis) { +#ifdef GENESIS ReturnCode = SkAddrXmacMcClear(pAC, IoC, PortNumber, Flags); +#endif } else { +#ifdef YUKON ReturnCode = SkAddrGmacMcClear(pAC, IoC, PortNumber, Flags); +#endif } return (ReturnCode); @@ -350,7 +354,7 @@ #endif /* !SK_SLIM */ #ifndef SK_SLIM - +#ifdef GENESIS /****************************************************************************** * * SkAddrXmacMcClear - clear the multicast table @@ -400,13 +404,13 @@ } return (SK_ADDR_SUCCESS); - -} /* SkAddrXmacMcClear */ +} /* SkAddrXmacMcClear */ +#endif /* GENESIS */ #endif /* !SK_SLIM */ #ifndef SK_SLIM - +#ifdef YUKON /****************************************************************************** * * SkAddrGmacMcClear - clear the multicast table @@ -445,38 +449,37 @@ pAC->Addr.Port[PortNumber].InexactFilter.Bytes[4], pAC->Addr.Port[PortNumber].InexactFilter.Bytes[5], pAC->Addr.Port[PortNumber].InexactFilter.Bytes[6], - pAC->Addr.Port[PortNumber].InexactFilter.Bytes[7])) + pAC->Addr.Port[PortNumber].InexactFilter.Bytes[7])); #endif /* DEBUG */ /* Clear InexactFilter */ for (i = 0; i < 8; i++) { pAC->Addr.Port[PortNumber].InexactFilter.Bytes[i] = 0; } - + if (Flags & SK_ADDR_PERMANENT) { /* permanent => RLMT */ - + /* Copy DRV bits to InexactFilter. */ for (i = 0; i < 8; i++) { pAC->Addr.Port[PortNumber].InexactFilter.Bytes[i] |= pAC->Addr.Port[PortNumber].InexactDrvFilter.Bytes[i]; - + /* Clear InexactRlmtFilter. */ pAC->Addr.Port[PortNumber].InexactRlmtFilter.Bytes[i] = 0; - - } + } } else { /* not permanent => DRV */ - + /* Copy RLMT bits to InexactFilter. */ for (i = 0; i < 8; i++) { pAC->Addr.Port[PortNumber].InexactFilter.Bytes[i] |= pAC->Addr.Port[PortNumber].InexactRlmtFilter.Bytes[i]; - + /* Clear InexactDrvFilter. */ pAC->Addr.Port[PortNumber].InexactDrvFilter.Bytes[i] = 0; } } - + #ifdef DEBUG SK_DBG_MSG(pAC, SK_DBGMOD_ADDR, SK_DBGCAT_CTRL, ("GMAC InexactFilter (cleared): %02X %02X %02X %02X %02X %02X %02X %02X\n", @@ -487,19 +490,20 @@ pAC->Addr.Port[PortNumber].InexactFilter.Bytes[4], pAC->Addr.Port[PortNumber].InexactFilter.Bytes[5], pAC->Addr.Port[PortNumber].InexactFilter.Bytes[6], - pAC->Addr.Port[PortNumber].InexactFilter.Bytes[7])) + pAC->Addr.Port[PortNumber].InexactFilter.Bytes[7])); #endif /* DEBUG */ - + if (!(Flags & SK_MC_SW_ONLY)) { (void) SkAddrGmacMcUpdate(pAC, IoC, PortNumber); } - + return (SK_ADDR_SUCCESS); } /* SkAddrGmacMcClear */ +#endif /* YUKON */ #ifndef SK_ADDR_CHEAT - +#ifdef GENESIS /****************************************************************************** * * SkXmacMcHash - hash multicast address @@ -536,8 +540,9 @@ return (Crc & ((1 << HASH_BITS) - 1)); } /* SkXmacMcHash */ +#endif /* GENESIS */ - +#ifdef YUKON /****************************************************************************** * * SkGmacMcHash - hash multicast address @@ -568,7 +573,7 @@ for (Byte = 0; Byte < 6; Byte++) { /* Get next byte. */ Data = (SK_U32) pMc[Byte]; - + /* Change bit order in byte. */ TmpData = Data; for (Bit = 0; Bit < 8; Bit++) { @@ -580,7 +585,7 @@ } TmpData >>= 1; } - + Crc ^= (Data << 24); for (Bit = 0; Bit < 8; Bit++) { if (Crc & 0x80000000) { @@ -591,11 +596,11 @@ } } } - + return (Crc & ((1 << HASH_BITS) - 1)); } /* SkGmacMcHash */ - +#endif /* YUKON */ #endif /* !SK_ADDR_CHEAT */ /****************************************************************************** @@ -630,23 +635,27 @@ int Flags) /* permanent/non-permanent */ { int ReturnCode; - + if (PortNumber >= (SK_U32) pAC->GIni.GIMacsFound) { return (SK_ADDR_ILLEGAL_PORT); } - + if (pAC->GIni.GIGenesis) { +#ifdef GENESIS ReturnCode = SkAddrXmacMcAdd(pAC, IoC, PortNumber, pMc, Flags); +#endif } else { +#ifdef YUKON ReturnCode = SkAddrGmacMcAdd(pAC, IoC, PortNumber, pMc, Flags); +#endif } return (ReturnCode); } /* SkAddrMcAdd */ - +#ifdef GENESIS /****************************************************************************** * * SkAddrXmacMcAdd - add a multicast address to a port @@ -691,7 +700,7 @@ return (SK_MC_RLMT_OVERFLOW); } #endif /* DEBUG */ - + if (pAC->Addr.Port[PortNumber].NextExactMatchRlmt > SK_ADDR_LAST_MATCH_RLMT) { return (SK_MC_RLMT_OVERFLOW); @@ -712,7 +721,7 @@ return (SK_MC_RLMT_OVERFLOW); } #endif /* DEBUG */ - + if (pAC->Addr.Port[PortNumber].NextExactMatchDrv <= SK_ADDR_LAST_MATCH_DRV) { /* Set exact match entry. */ @@ -756,8 +765,9 @@ } } /* SkAddrXmacMcAdd */ +#endif /* GENESIS */ - +#ifdef YUKON /****************************************************************************** * * SkAddrGmacMcAdd - add a multicast address to a port @@ -787,28 +797,29 @@ #ifndef SK_ADDR_CHEAT SK_U32 HashBit; #endif /* !defined(SK_ADDR_CHEAT) */ - + if (!(pMc->a[0] & SK_MC_BIT)) { /* Hashing only possible with multicast addresses */ return (SK_MC_ILLEGAL_ADDRESS); } - + #ifndef SK_ADDR_CHEAT - + /* Compute hash value of address. */ HashBit = SkGmacMcHash(&pMc->a[0]); - + if (Flags & SK_ADDR_PERMANENT) { /* permanent => RLMT */ - + /* Add bit to InexactRlmtFilter. */ pAC->Addr.Port[PortNumber].InexactRlmtFilter.Bytes[HashBit / 8] |= 1 << (HashBit % 8); - + /* Copy bit to InexactFilter. */ for (i = 0; i < 8; i++) { pAC->Addr.Port[PortNumber].InexactFilter.Bytes[i] |= pAC->Addr.Port[PortNumber].InexactRlmtFilter.Bytes[i]; } + #ifdef DEBUG SK_DBG_MSG(pAC, SK_DBGMOD_ADDR, SK_DBGCAT_CTRL, ("GMAC InexactRlmtFilter: %02X %02X %02X %02X %02X %02X %02X %02X\n", @@ -819,20 +830,21 @@ pAC->Addr.Port[PortNumber].InexactRlmtFilter.Bytes[4], pAC->Addr.Port[PortNumber].InexactRlmtFilter.Bytes[5], pAC->Addr.Port[PortNumber].InexactRlmtFilter.Bytes[6], - pAC->Addr.Port[PortNumber].InexactRlmtFilter.Bytes[7])) + pAC->Addr.Port[PortNumber].InexactRlmtFilter.Bytes[7])); #endif /* DEBUG */ } else { /* not permanent => DRV */ - + /* Add bit to InexactDrvFilter. */ pAC->Addr.Port[PortNumber].InexactDrvFilter.Bytes[HashBit / 8] |= 1 << (HashBit % 8); - + /* Copy bit to InexactFilter. */ for (i = 0; i < 8; i++) { pAC->Addr.Port[PortNumber].InexactFilter.Bytes[i] |= pAC->Addr.Port[PortNumber].InexactDrvFilter.Bytes[i]; } + #ifdef DEBUG SK_DBG_MSG(pAC, SK_DBGMOD_ADDR, SK_DBGCAT_CTRL, ("GMAC InexactDrvFilter: %02X %02X %02X %02X %02X %02X %02X %02X\n", @@ -843,22 +855,22 @@ pAC->Addr.Port[PortNumber].InexactDrvFilter.Bytes[4], pAC->Addr.Port[PortNumber].InexactDrvFilter.Bytes[5], pAC->Addr.Port[PortNumber].InexactDrvFilter.Bytes[6], - pAC->Addr.Port[PortNumber].InexactDrvFilter.Bytes[7])) + pAC->Addr.Port[PortNumber].InexactDrvFilter.Bytes[7])); #endif /* DEBUG */ } - + #else /* SK_ADDR_CHEAT */ - + /* Set all bits in InexactFilter. */ for (i = 0; i < 8; i++) { pAC->Addr.Port[PortNumber].InexactFilter.Bytes[i] = 0xFF; } #endif /* SK_ADDR_CHEAT */ - + return (SK_MC_FILTERING_INEXACT); - -} /* SkAddrGmacMcAdd */ +} /* SkAddrGmacMcAdd */ +#endif /* YUKON */ #endif /* !SK_SLIM */ /****************************************************************************** @@ -890,7 +902,8 @@ SK_IOC IoC, /* I/O context */ SK_U32 PortNumber) /* Port Number */ { - int ReturnCode; + int ReturnCode = SK_ADDR_ILLEGAL_PORT; + #if (!defined(SK_SLIM) || defined(DEBUG)) if (PortNumber >= (SK_U32) pAC->GIni.GIMacsFound) { return (SK_ADDR_ILLEGAL_PORT); @@ -946,13 +959,13 @@ SK_ADDR_PORT *pAPort; SK_DBG_MSG(pAC,SK_DBGMOD_ADDR, SK_DBGCAT_CTRL, - ("SkAddrXmacMcUpdate on Port %u.\n", PortNumber)) - + ("SkAddrXmacMcUpdate on Port %u.\n", PortNumber)); + pAPort = &pAC->Addr.Port[PortNumber]; #ifdef DEBUG SK_DBG_MSG(pAC,SK_DBGMOD_ADDR, SK_DBGCAT_CTRL, - ("Next0 on Port %d: %d\n", PortNumber, Next0[PortNumber])) + ("Next0 on Port %d: %d\n", PortNumber, Next0[PortNumber])); #endif /* DEBUG */ /* Start with 0 to also program the logical MAC address. */ @@ -964,7 +977,7 @@ /* Clear other permanent exact match addresses on XMAC */ if (pAPort->NextExactMatchRlmt <= SK_ADDR_LAST_MATCH_RLMT) { - + SkXmClrExactAddr(pAC, IoC, PortNumber, pAPort->NextExactMatchRlmt, SK_ADDR_LAST_MATCH_RLMT); } @@ -976,7 +989,7 @@ /* Clear other non-permanent exact match addresses on XMAC */ if (pAPort->NextExactMatchDrv <= SK_ADDR_LAST_MATCH_DRV) { - + SkXmClrExactAddr(pAC, IoC, PortNumber, pAPort->NextExactMatchDrv, SK_ADDR_LAST_MATCH_DRV); } @@ -986,18 +999,18 @@ } if (pAPort->PromMode & SK_PROM_MODE_ALL_MC) { - + /* Set all bits in 64-bit hash register. */ XM_OUTHASH(IoC, PortNumber, XM_HSM, &OnesHash); - + /* Enable Hashing */ SkMacHashing(pAC, IoC, (int) PortNumber, SK_TRUE); } else if (Inexact != 0) { - + /* Set 64-bit hash register to InexactFilter. */ XM_OUTHASH(IoC, PortNumber, XM_HSM, &pAPort->InexactFilter.Bytes[0]); - + /* Enable Hashing */ SkMacHashing(pAC, IoC, (int) PortNumber, SK_TRUE); } @@ -1012,7 +1025,7 @@ /* Set port's current physical MAC address. */ OutAddr = (SK_U16 *) &pAPort->CurrentMacAddress.a[0]; - + XM_OUTADDR(IoC, PortNumber, XM_SA, OutAddr); #ifdef xDEBUG @@ -1022,9 +1035,9 @@ /* Get exact match address i from port PortNumber. */ InAddr = (SK_U16 *) &InAddr8[0]; - + XM_INADDR(IoC, PortNumber, XM_EXM(i), InAddr); - + SK_DBG_MSG(pAC,SK_DBGMOD_ADDR, SK_DBGCAT_CTRL, ("SkAddrXmacMcUpdate: MC address %d on Port %u: ", "%02x %02x %02x %02x %02x %02x -- %02x %02x %02x %02x %02x %02x\n", @@ -1041,7 +1054,7 @@ pAPort->Exact[i].a[2], pAPort->Exact[i].a[3], pAPort->Exact[i].a[4], - pAPort->Exact[i].a[5])) + pAPort->Exact[i].a[5])); } #endif /* DEBUG */ @@ -1052,7 +1065,7 @@ else { return (SK_MC_FILTERING_INEXACT); } - + } /* SkAddrXmacMcUpdate */ #endif /* GENESIS */ @@ -1093,37 +1106,37 @@ SK_ADDR_PORT *pAPort; SK_DBG_MSG(pAC,SK_DBGMOD_ADDR, SK_DBGCAT_CTRL, - ("SkAddrGmacMcUpdate on Port %u.\n", PortNumber)) - + ("SkAddrGmacMcUpdate on Port %u.\n", PortNumber)); + pAPort = &pAC->Addr.Port[PortNumber]; #ifdef DEBUG SK_DBG_MSG(pAC,SK_DBGMOD_ADDR, SK_DBGCAT_CTRL, - ("Next0 on Port %d: %d\n", PortNumber, Next0[PortNumber])) + ("Next0 on Port %d: %d\n", PortNumber, Next0[PortNumber])); #endif /* DEBUG */ - + #ifndef SK_SLIM for (Inexact = 0, i = 0; i < 8; i++) { Inexact |= pAPort->InexactFilter.Bytes[i]; } - + /* Set 64-bit hash register to InexactFilter. */ GM_OUTHASH(IoC, PortNumber, GM_MC_ADDR_H1, &pAPort->InexactFilter.Bytes[0]); - - if (pAPort->PromMode & SK_PROM_MODE_ALL_MC) { - + + if (pAPort->PromMode & SK_PROM_MODE_ALL_MC) { + /* Set all bits in 64-bit hash register. */ GM_OUTHASH(IoC, PortNumber, GM_MC_ADDR_H1, &OnesHash); - + /* Enable Hashing */ SkMacHashing(pAC, IoC, (int) PortNumber, SK_TRUE); } - else { + else { /* Enable Hashing. */ SkMacHashing(pAC, IoC, (int) PortNumber, SK_TRUE); } - + if (pAPort->PromMode != SK_PROM_MODE_NONE) { (void) SkAddrGmacPromiscuousChange(pAC, IoC, PortNumber, pAPort->PromMode); } @@ -1134,19 +1147,19 @@ /* Enable Hashing */ SkMacHashing(pAC, IoC, (int) PortNumber, SK_TRUE); - + (void) SkAddrGmacPromiscuousChange(pAC, IoC, PortNumber, pAPort->PromMode); - + #endif /* SK_SLIM */ - + /* Set port's current physical MAC address. */ OutAddr = (SK_U16 *) &pAPort->CurrentMacAddress.a[0]; GM_OUTADDR(IoC, PortNumber, GM_SRC_ADDR_1L, OutAddr); - + /* Set port's current logical MAC address. */ OutAddr = (SK_U16 *) &pAPort->Exact[0].a[0]; GM_OUTADDR(IoC, PortNumber, GM_SRC_ADDR_2L, OutAddr); - + #ifdef DEBUG SK_DBG_MSG(pAC, SK_DBGMOD_ADDR, SK_DBGCAT_CTRL, ("SkAddrGmacMcUpdate: Permanent Physical MAC Address: %02X %02X %02X %02X %02X %02X\n", @@ -1155,8 +1168,8 @@ pAPort->Exact[0].a[2], pAPort->Exact[0].a[3], pAPort->Exact[0].a[4], - pAPort->Exact[0].a[5])) - + pAPort->Exact[0].a[5])); + SK_DBG_MSG(pAC, SK_DBGMOD_ADDR, SK_DBGCAT_CTRL, ("SkAddrGmacMcUpdate: Physical MAC Address: %02X %02X %02X %02X %02X %02X\n", pAPort->CurrentMacAddress.a[0], @@ -1164,9 +1177,9 @@ pAPort->CurrentMacAddress.a[2], pAPort->CurrentMacAddress.a[3], pAPort->CurrentMacAddress.a[4], - pAPort->CurrentMacAddress.a[5])) + pAPort->CurrentMacAddress.a[5])); #endif /* DEBUG */ - + #ifndef SK_SLIM /* Determine return value. */ if (Inexact == 0 && pAPort->PromMode == 0) { @@ -1178,7 +1191,7 @@ #else /* SK_SLIM */ return (SK_MC_FILTERING_INEXACT); #endif /* SK_SLIM */ - + } /* SkAddrGmacMcUpdate */ #endif /* YUKON */ @@ -1273,26 +1286,46 @@ (void) SkAddrMcUpdate(pAC, IoC, PortNumber); } else if (Flags & SK_ADDR_PHYSICAL_ADDRESS) { /* Physical MAC address. */ - if (SK_ADDR_EQUAL(pNewAddr->a, - pAC->Addr.Net[NetNumber].CurrentMacAddress.a)) { - return (SK_ADDR_DUPLICATE_ADDRESS); - } - for (i = 0; i < (SK_U32) pAC->GIni.GIMacsFound; i++) { if (!pAC->Addr.Port[i].CurrentMacAddressSet) { return (SK_ADDR_TOO_EARLY); } + } + /* + * In dual net mode it should be possible to set all MAC + * addresses independently. Therefore the equality checks + * against the locical address of the same port and the + * physical address of the other port are suppressed here. + */ +#ifndef SK_NO_RLMT + if (pAC->Rlmt.NumNets == 1) { +#endif /* SK_NO_RLMT */ if (SK_ADDR_EQUAL(pNewAddr->a, - pAC->Addr.Port[i].CurrentMacAddress.a)) { - if (i == PortNumber) { - return (SK_ADDR_SUCCESS); - } - else { - return (SK_ADDR_DUPLICATE_ADDRESS); + pAC->Addr.Net[NetNumber].CurrentMacAddress.a)) { + return (SK_ADDR_DUPLICATE_ADDRESS); + } + + for (i = 0; i < (SK_U32) pAC->GIni.GIMacsFound; i++) { + if (SK_ADDR_EQUAL(pNewAddr->a, + pAC->Addr.Port[i].CurrentMacAddress.a)) { + if (i == PortNumber) { + return (SK_ADDR_SUCCESS); + } + else { + return (SK_ADDR_DUPLICATE_ADDRESS); + } } } +#ifndef SK_NO_RLMT } + else { + if (SK_ADDR_EQUAL(pNewAddr->a, + pAC->Addr.Port[PortNumber].CurrentMacAddress.a)) { + return (SK_ADDR_SUCCESS); + } + } +#endif /* SK_NO_RLMT */ pAC->Addr.Port[PortNumber].PreviousMacAddress = pAC->Addr.Port[PortNumber].CurrentMacAddress; @@ -1323,18 +1356,32 @@ pAC->Addr.Net[NetNumber].CurrentMacAddress.a)) { return (SK_ADDR_SUCCESS); } - + for (i = 0; i < (SK_U32) pAC->GIni.GIMacsFound; i++) { if (!pAC->Addr.Port[i].CurrentMacAddressSet) { return (SK_ADDR_TOO_EARLY); } + } - if (SK_ADDR_EQUAL(pNewAddr->a, - pAC->Addr.Port[i].CurrentMacAddress.a)) { - return (SK_ADDR_DUPLICATE_ADDRESS); + /* + * In dual net mode on Yukon-2 adapters the physical address + * of port 0 and the logical address of port 1 are equal - in + * this case the equality check of the physical address leads + * to an error and is suppressed here. + */ +#ifndef SK_NO_RLMT + if (pAC->Rlmt.NumNets == 1) { +#endif /* SK_NO_RLMT */ + for (i = 0; i < (SK_U32) pAC->GIni.GIMacsFound; i++) { + if (SK_ADDR_EQUAL(pNewAddr->a, + pAC->Addr.Port[i].CurrentMacAddress.a)) { + return (SK_ADDR_DUPLICATE_ADDRESS); + } } +#ifndef SK_NO_RLMT } - +#endif /* SK_NO_RLMT */ + /* * In case that the physical and the logical MAC addresses are equal * we must also change the physical MAC address here. @@ -1343,11 +1390,11 @@ */ if (SK_ADDR_EQUAL(pAC->Addr.Port[PortNumber].CurrentMacAddress.a, pAC->Addr.Port[PortNumber].Exact[0].a)) { - + pAC->Addr.Port[PortNumber].PreviousMacAddress = pAC->Addr.Port[PortNumber].CurrentMacAddress; pAC->Addr.Port[PortNumber].CurrentMacAddress = *pNewAddr; - + #ifndef SK_NO_RLMT /* Report address change to RLMT. */ Para.Para32[0] = PortNumber; @@ -1355,7 +1402,7 @@ SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_PORT_ADDR, Para); #endif /* !SK_NO_RLMT */ } - + #ifndef SK_NO_RLMT /* Set PortNumber to number of net's active port. */ PortNumber = pAC->Rlmt.Net[NetNumber]. @@ -1371,8 +1418,8 @@ pAC->Addr.Net[NetNumber].PermanentMacAddress.a[2], pAC->Addr.Net[NetNumber].PermanentMacAddress.a[3], pAC->Addr.Net[NetNumber].PermanentMacAddress.a[4], - pAC->Addr.Net[NetNumber].PermanentMacAddress.a[5])) - + pAC->Addr.Net[NetNumber].PermanentMacAddress.a[5])); + SK_DBG_MSG(pAC,SK_DBGMOD_ADDR, SK_DBGCAT_CTRL, ("SkAddrOverride: New logical MAC Address: %02X %02X %02X %02X %02X %02X\n", pAC->Addr.Net[NetNumber].CurrentMacAddress.a[0], @@ -1380,17 +1427,16 @@ pAC->Addr.Net[NetNumber].CurrentMacAddress.a[2], pAC->Addr.Net[NetNumber].CurrentMacAddress.a[3], pAC->Addr.Net[NetNumber].CurrentMacAddress.a[4], - pAC->Addr.Net[NetNumber].CurrentMacAddress.a[5])) + pAC->Addr.Net[NetNumber].CurrentMacAddress.a[5])); #endif /* DEBUG */ - /* Write address to first exact match entry of active port. */ - (void) SkAddrMcUpdate(pAC, IoC, PortNumber); + /* Write address to first exact match entry of active port. */ + (void)SkAddrMcUpdate(pAC, IoC, PortNumber); } return (SK_ADDR_SUCCESS); - -} /* SkAddrOverride */ +} /* SkAddrOverride */ #endif /* SK_NO_MAO */ @@ -1422,7 +1468,8 @@ SK_U32 PortNumber, /* port whose promiscuous mode changes */ int NewPromMode) /* new promiscuous mode */ { - int ReturnCode; + int ReturnCode = SK_ADDR_ILLEGAL_PORT; + #if (!defined(SK_SLIM) || defined(DEBUG)) if (PortNumber >= (SK_U32) pAC->GIni.GIMacsFound) { return (SK_ADDR_ILLEGAL_PORT); @@ -1487,17 +1534,18 @@ /* Promiscuous mode! */ CurPromMode |= SK_PROM_MODE_LLC; } - + for (Inexact = 0xFF, i = 0; i < 8; i++) { Inexact &= pAC->Addr.Port[PortNumber].InexactFilter.Bytes[i]; } + if (Inexact == 0xFF) { CurPromMode |= (pAC->Addr.Port[PortNumber].PromMode & SK_PROM_MODE_ALL_MC); } else { /* Get InexactModeBit (bit XM_MD_ENA_HASH in mode register) */ XM_IN16(IoC, PortNumber, XM_MODE, &LoMode); - + InexactModeBit = (LoMode & XM_MD_ENA_HASH) != 0; /* Read 64-bit hash register from XMAC */ @@ -1520,7 +1568,7 @@ if ((NewPromMode & SK_PROM_MODE_ALL_MC) && !(CurPromMode & SK_PROM_MODE_ALL_MC)) { /* All MC. */ - + /* Set all bits in 64-bit hash register. */ XM_OUTHASH(IoC, PortNumber, XM_HSM, &OnesHash); @@ -1556,9 +1604,9 @@ /* Clear Promiscuous Mode */ SkMacPromiscMode(pAC, IoC, (int) PortNumber, SK_FALSE); } - + return (SK_ADDR_SUCCESS); - + } /* SkAddrXmacPromiscuousChange */ #endif /* GENESIS */ @@ -1605,22 +1653,25 @@ CurPromMode |= (pAC->Addr.Port[PortNumber].PromMode & SK_PROM_MODE_ALL_MC); } + /* dummy read after GM_IN16() */ + SK_IN16(IoC, B0_RAP, &ReceiveControl); + pAC->Addr.Port[PortNumber].PromMode = NewPromMode; if (NewPromMode == CurPromMode) { return (SK_ADDR_SUCCESS); } - + if ((NewPromMode & SK_PROM_MODE_ALL_MC) && !(CurPromMode & SK_PROM_MODE_ALL_MC)) { /* All MC */ - + /* Set all bits in 64-bit hash register. */ GM_OUTHASH(IoC, PortNumber, GM_MC_ADDR_H1, &OnesHash); - + /* Enable Hashing */ SkMacHashing(pAC, IoC, (int) PortNumber, SK_TRUE); } - + if ((CurPromMode & SK_PROM_MODE_ALL_MC) && !(NewPromMode & SK_PROM_MODE_ALL_MC)) { /* Norm. MC */ @@ -1634,19 +1685,19 @@ if ((NewPromMode & SK_PROM_MODE_LLC) && !(CurPromMode & SK_PROM_MODE_LLC)) { /* Prom. LLC */ - + /* Set the MAC to Promiscuous Mode. */ SkMacPromiscMode(pAC, IoC, (int) PortNumber, SK_TRUE); } else if ((CurPromMode & SK_PROM_MODE_LLC) && !(NewPromMode & SK_PROM_MODE_LLC)) { /* Norm. LLC */ - + /* Clear Promiscuous Mode. */ SkMacPromiscMode(pAC, IoC, (int) PortNumber, SK_FALSE); } return (SK_ADDR_SUCCESS); - + } /* SkAddrGmacPromiscuousChange */ #endif /* YUKON */ @@ -1718,33 +1769,33 @@ pAC->Addr.Port[ToPortNumber].InexactFilter.Bytes[i]; pAC->Addr.Port[ToPortNumber].InexactFilter.Bytes[i] = Byte; } - + i = pAC->Addr.Port[FromPortNumber].PromMode; pAC->Addr.Port[FromPortNumber].PromMode = pAC->Addr.Port[ToPortNumber].PromMode; pAC->Addr.Port[ToPortNumber].PromMode = i; - + if (pAC->GIni.GIGenesis) { DWord = pAC->Addr.Port[FromPortNumber].FirstExactMatchRlmt; pAC->Addr.Port[FromPortNumber].FirstExactMatchRlmt = pAC->Addr.Port[ToPortNumber].FirstExactMatchRlmt; pAC->Addr.Port[ToPortNumber].FirstExactMatchRlmt = DWord; - + DWord = pAC->Addr.Port[FromPortNumber].NextExactMatchRlmt; pAC->Addr.Port[FromPortNumber].NextExactMatchRlmt = pAC->Addr.Port[ToPortNumber].NextExactMatchRlmt; pAC->Addr.Port[ToPortNumber].NextExactMatchRlmt = DWord; - + DWord = pAC->Addr.Port[FromPortNumber].FirstExactMatchDrv; pAC->Addr.Port[FromPortNumber].FirstExactMatchDrv = pAC->Addr.Port[ToPortNumber].FirstExactMatchDrv; pAC->Addr.Port[ToPortNumber].FirstExactMatchDrv = DWord; - + DWord = pAC->Addr.Port[FromPortNumber].NextExactMatchDrv; pAC->Addr.Port[FromPortNumber].NextExactMatchDrv = pAC->Addr.Port[ToPortNumber].NextExactMatchDrv; pAC->Addr.Port[ToPortNumber].NextExactMatchDrv = DWord; } - + /* CAUTION: Solution works if only ports of one adapter are in use. */ for (i = 0; (SK_U32) i < pAC->Rlmt.Net[pAC->Rlmt.Port[ToPortNumber]. Net->NetNumber].NumPorts; i++) { @@ -1755,12 +1806,12 @@ /* 20001207 RA: Was "ToPortNumber;". */ } } - + (void) SkAddrMcUpdate(pAC, IoC, FromPortNumber); (void) SkAddrMcUpdate(pAC, IoC, ToPortNumber); return (SK_ADDR_SUCCESS); - + } /* SkAddrSwap */ #endif /* !SK_SLIM */ diff -urN linux-2.4.32-600/drivers/net/sk98lin/skcsum.c linux-2.4.32-600-sk98_831/drivers/net/sk98lin/skcsum.c --- linux-2.4.32-600/drivers/net/sk98lin/skcsum.c Sat Mar 20 10:08:19 2004 +++ linux-2.4.32-600-sk98_831/drivers/net/sk98lin/skcsum.c Sun Feb 26 11:12:56 2006 @@ -2,6 +2,8 @@ * * Name: skcsum.c * Project: GEnesis, PCI Gigabit Ethernet Adapter + * Version: $Revision: 2.1 $ + * Date: $Date: 2003/10/27 14:16:08 $ * Purpose: Store/verify Internet checksum in send/receive packets. * ******************************************************************************/ @@ -23,7 +25,7 @@ #ifndef lint static const char SysKonnectFileId[] = - "@(#) $Id: skcsum.c,v 1.12 2003/08/20 13:55:53 mschmid Exp $ (C) SysKonnect."; + "@(#) $Id: skcsum.c,v 2.1 2003/10/27 14:16:08 amock Exp $ (C) SysKonnect."; #endif /* !lint */ /****************************************************************************** diff -urN linux-2.4.32-600/drivers/net/sk98lin/skdim.c linux-2.4.32-600-sk98_831/drivers/net/sk98lin/skdim.c --- linux-2.4.32-600/drivers/net/sk98lin/skdim.c Sat Mar 20 10:08:19 2004 +++ linux-2.4.32-600-sk98_831/drivers/net/sk98lin/skdim.c Sun Feb 26 11:12:56 2006 @@ -1,15 +1,25 @@ /****************************************************************************** * - * Name: skdim.c - * Project: GEnesis, PCI Gigabit Ethernet Adapter - * Purpose: All functions to maintain interrupt moderation + * Name: skdim.c + * Project: GEnesis, PCI Gigabit Ethernet Adapter + * Version: $Revision: 1.5.2.2 $ + * Date: $Date: 2005/05/23 13:47:33 $ + * Purpose: All functions regardig interrupt moderation * ******************************************************************************/ /****************************************************************************** * * (C)Copyright 1998-2002 SysKonnect GmbH. - * (C)Copyright 2002-2003 Marvell. + * (C)Copyright 2002-2005 Marvell. + * + * Driver for Marvell Yukon/2 chipset and SysKonnect Gigabit Ethernet + * Server Adapters. + * + * Author: Ralph Roesler (rroesler@syskonnect.de) + * Mirko Lindner (mlindner@syskonnect.de) + * + * Address all question to: linux@syskonnect.de * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -18,709 +28,367 @@ * * The information in this file is provided "AS IS" without warranty. * - ******************************************************************************/ - -/****************************************************************************** - * - * Description: - * - * This module is intended to manage the dynamic interrupt moderation on both - * GEnesis and Yukon adapters. - * - * Include File Hierarchy: - * - * "skdrv1st.h" - * "skdrv2nd.h" - * - ******************************************************************************/ - -#ifndef lint -static const char SysKonnectFileId[] = - "@(#) $Id: skdim.c,v 1.5 2003/11/28 12:55:40 rroesler Exp $ (C) SysKonnect."; -#endif - -#define __SKADDR_C - -#ifdef __cplusplus -#error C++ is not yet supported. -extern "C" { -#endif - -/******************************************************************************* -** -** Includes -** -*******************************************************************************/ + *****************************************************************************/ -#ifndef __INC_SKDRV1ST_H #include "h/skdrv1st.h" -#endif - -#ifndef __INC_SKDRV2ND_H #include "h/skdrv2nd.h" -#endif - -#include - -/******************************************************************************* -** -** Defines -** -*******************************************************************************/ -/******************************************************************************* -** -** Typedefs -** -*******************************************************************************/ +/****************************************************************************** + * + * Local Function Prototypes + * + *****************************************************************************/ -/******************************************************************************* -** -** Local function prototypes -** -*******************************************************************************/ - -static unsigned int GetCurrentSystemLoad(SK_AC *pAC); -static SK_U64 GetIsrCalls(SK_AC *pAC); -static SK_BOOL IsIntModEnabled(SK_AC *pAC); -static void SetCurrIntCtr(SK_AC *pAC); -static void EnableIntMod(SK_AC *pAC); -static void DisableIntMod(SK_AC *pAC); -static void ResizeDimTimerDuration(SK_AC *pAC); -static void DisplaySelectedModerationType(SK_AC *pAC); -static void DisplaySelectedModerationMask(SK_AC *pAC); -static void DisplayDescrRatio(SK_AC *pAC); +static SK_U64 getIsrCalls(SK_AC *pAC); +static SK_BOOL isIntModEnabled(SK_AC *pAC); +static void setCurrIntCtr(SK_AC *pAC); +static void enableIntMod(SK_AC *pAC); +static void disableIntMod(SK_AC *pAC); -/******************************************************************************* -** -** Global variables -** -*******************************************************************************/ +#define M_DIMINFO pAC->DynIrqModInfo -/******************************************************************************* -** -** Local variables -** -*******************************************************************************/ +/****************************************************************************** + * + * Global Functions + * + *****************************************************************************/ -/******************************************************************************* -** -** Global functions -** -*******************************************************************************/ +/***************************************************************************** + * + * SkDimModerate - Moderates the IRQs depending on the current needs + * + * Description: + * Moderation of IRQs depends on the number of occurred IRQs with + * respect to the previous moderation cycle. + * + * Returns: N/A + * + */ +void SkDimModerate( +SK_AC *pAC) /* pointer to adapter control context */ +{ + SK_U64 IsrCalls = getIsrCalls(pAC); + + SK_DBG_MSG(pAC,SK_DBGMOD_DRV,SK_DBGCAT_DRV_MSG,("==> SkDimModerate\n")); + + if (M_DIMINFO.IntModTypeSelect == C_INT_MOD_DYNAMIC) { + if (isIntModEnabled(pAC)) { + if (IsrCalls < M_DIMINFO.MaxModIntsPerSecLowerLimit) { + disableIntMod(pAC); + } + } else { + if (IsrCalls > M_DIMINFO.MaxModIntsPerSecUpperLimit) { + enableIntMod(pAC); + } + } + } + setCurrIntCtr(pAC); -/******************************************************************************* -** Function : SkDimModerate -** Description : Called in every ISR to check if moderation is to be applied -** or not for the current number of interrupts -** Programmer : Ralph Roesler -** Last Modified: 22-mar-03 -** Returns : void (!) -** Notes : - -*******************************************************************************/ - -void -SkDimModerate(SK_AC *pAC) { - unsigned int CurrSysLoad = 0; /* expressed in percent */ - unsigned int LoadIncrease = 0; /* expressed in percent */ - SK_U64 ThresholdInts = 0; - SK_U64 IsrCallsPerSec = 0; + SK_DBG_MSG(pAC,SK_DBGMOD_DRV,SK_DBGCAT_DRV_MSG,("<== SkDimModerate\n")); +} -#define M_DIMINFO pAC->DynIrqModInfo +/***************************************************************************** + * + * SkDimStartModerationTimer - Starts the moderation timer + * + * Description: + * Dynamic interrupt moderation is regularly checked using the + * so-called moderation timer. This timer is started with this function. + * + * Returns: N/A + */ +void SkDimStartModerationTimer( +SK_AC *pAC) /* pointer to adapter control context */ +{ + SK_EVPARA EventParam; /* Event struct for timer event */ + + SK_DBG_MSG(pAC,SK_DBGMOD_DRV,SK_DBGCAT_DRV_MSG, + ("==> SkDimStartModerationTimer\n")); - if (!IsIntModEnabled(pAC)) { - if (M_DIMINFO.IntModTypeSelect == C_INT_MOD_DYNAMIC) { - CurrSysLoad = GetCurrentSystemLoad(pAC); - if (CurrSysLoad > 75) { - /* - ** More than 75% total system load! Enable the moderation - ** to shield the system against too many interrupts. - */ - EnableIntMod(pAC); - } else if (CurrSysLoad > M_DIMINFO.PrevSysLoad) { - LoadIncrease = (CurrSysLoad - M_DIMINFO.PrevSysLoad); - if (LoadIncrease > ((M_DIMINFO.PrevSysLoad * - C_INT_MOD_ENABLE_PERCENTAGE) / 100)) { - if (CurrSysLoad > 10) { - /* - ** More than 50% increase with respect to the - ** previous load of the system. Most likely this - ** is due to our ISR-proc... - */ - EnableIntMod(pAC); - } - } - } else { - /* - ** Neither too much system load at all nor too much increase - ** with respect to the previous system load. Hence, we can leave - ** the ISR-handling like it is without enabling moderation. - */ - } - M_DIMINFO.PrevSysLoad = CurrSysLoad; - } - } else { - if (M_DIMINFO.IntModTypeSelect == C_INT_MOD_DYNAMIC) { - ThresholdInts = ((M_DIMINFO.MaxModIntsPerSec * - C_INT_MOD_DISABLE_PERCENTAGE) / 100); - IsrCallsPerSec = GetIsrCalls(pAC); - if (IsrCallsPerSec <= ThresholdInts) { - /* - ** The number of interrupts within the last second is - ** lower than the disable_percentage of the desried - ** maxrate. Therefore we can disable the moderation. - */ - DisableIntMod(pAC); - M_DIMINFO.MaxModIntsPerSec = - (M_DIMINFO.MaxModIntsPerSecUpperLimit + - M_DIMINFO.MaxModIntsPerSecLowerLimit) / 2; - } else { - /* - ** The number of interrupts per sec is the same as expected. - ** Evalulate the descriptor-ratio. If it has changed, a resize - ** in the moderation timer might be usefull - */ - if (M_DIMINFO.AutoSizing) { - ResizeDimTimerDuration(pAC); - } - } - } - } - - /* - ** Some information to the log... - */ - if (M_DIMINFO.DisplayStats) { - DisplaySelectedModerationType(pAC); - DisplaySelectedModerationMask(pAC); - DisplayDescrRatio(pAC); - } + if (M_DIMINFO.IntModTypeSelect == C_INT_MOD_DYNAMIC) { + SK_MEMSET((char *) &EventParam, 0, sizeof(EventParam)); + EventParam.Para32[0] = SK_DRV_MODERATION_TIMER; + SkTimerStart(pAC, pAC->IoBase, + &pAC->DynIrqModInfo.ModTimer, + pAC->DynIrqModInfo.DynIrqModSampleInterval * 1000000, + SKGE_DRV, SK_DRV_TIMER, EventParam); + } - M_DIMINFO.NbrProcessedDescr = 0; - SetCurrIntCtr(pAC); + SK_DBG_MSG(pAC,SK_DBGMOD_DRV,SK_DBGCAT_DRV_MSG, + ("<== SkDimStartModerationTimer\n")); } -/******************************************************************************* -** Function : SkDimStartModerationTimer -** Description : Starts the audit-timer for the dynamic interrupt moderation -** Programmer : Ralph Roesler -** Last Modified: 22-mar-03 -** Returns : void (!) -** Notes : - -*******************************************************************************/ - -void -SkDimStartModerationTimer(SK_AC *pAC) { - SK_EVPARA EventParam; /* Event struct for timer event */ - - SK_MEMSET((char *) &EventParam, 0, sizeof(EventParam)); - EventParam.Para32[0] = SK_DRV_MODERATION_TIMER; - SkTimerStart(pAC, pAC->IoBase, &pAC->DynIrqModInfo.ModTimer, - SK_DRV_MODERATION_TIMER_LENGTH, - SKGE_DRV, SK_DRV_TIMER, EventParam); -} +/***************************************************************************** + * + * SkDimEnableModerationIfNeeded - Enables or disables any moderationtype + * + * Description: + * This function effectively initializes the IRQ moderation of a network + * adapter. Depending on the configuration, this might be either static + * or dynamic. If no moderation is configured, this function will do + * nothing. + * + * Returns: N/A + */ +void SkDimEnableModerationIfNeeded( +SK_AC *pAC) /* pointer to adapter control context */ +{ + SK_DBG_MSG(pAC,SK_DBGMOD_DRV,SK_DBGCAT_DRV_MSG, + ("==> SkDimEnableModerationIfNeeded\n")); + + if (M_DIMINFO.IntModTypeSelect != C_INT_MOD_NONE) { + if (M_DIMINFO.IntModTypeSelect == C_INT_MOD_STATIC) { + enableIntMod(pAC); + } else { /* must be C_INT_MOD_DYNAMIC */ + SkDimStartModerationTimer(pAC); + } + } -/******************************************************************************* -** Function : SkDimEnableModerationIfNeeded -** Description : Either enables or disables moderation -** Programmer : Ralph Roesler -** Last Modified: 22-mar-03 -** Returns : void (!) -** Notes : This function is called when a particular adapter is opened -** There is no Disable function, because when all interrupts -** might be disable, the moderation timer has no meaning at all -******************************************************************************/ - -void -SkDimEnableModerationIfNeeded(SK_AC *pAC) { - - if (M_DIMINFO.IntModTypeSelect == C_INT_MOD_STATIC) { - EnableIntMod(pAC); /* notification print in this function */ - } else if (M_DIMINFO.IntModTypeSelect == C_INT_MOD_DYNAMIC) { - SkDimStartModerationTimer(pAC); - if (M_DIMINFO.DisplayStats) { - printk("Dynamic moderation has been enabled\n"); - } - } else { - if (M_DIMINFO.DisplayStats) { - printk("No moderation has been enabled\n"); - } - } + SK_DBG_MSG(pAC,SK_DBGMOD_DRV,SK_DBGCAT_DRV_MSG, + ("<== SkDimEnableModerationIfNeeded\n")); } -/******************************************************************************* -** Function : SkDimDisplayModerationSettings -** Description : Displays the current settings regaring interrupt moderation -** Programmer : Ralph Roesler -** Last Modified: 22-mar-03 -** Returns : void (!) -** Notes : - -*******************************************************************************/ - -void -SkDimDisplayModerationSettings(SK_AC *pAC) { - DisplaySelectedModerationType(pAC); - DisplaySelectedModerationMask(pAC); -} +/***************************************************************************** + * + * SkDimDisableModeration - disables moderation if it is enabled + * + * Description: + * Disabling of the moderation requires that is enabled already. + * + * Returns: N/A + */ +void SkDimDisableModeration( +SK_AC *pAC, /* pointer to adapter control context */ +int CurrentModeration) /* type of current moderation */ +{ + SK_DBG_MSG(pAC,SK_DBGMOD_DRV,SK_DBGCAT_DRV_MSG, + ("==> SkDimDisableModeration\n")); + + if (M_DIMINFO.IntModTypeSelect != C_INT_MOD_NONE) { + if (CurrentModeration == C_INT_MOD_STATIC) { + disableIntMod(pAC); + } else { /* must be C_INT_MOD_DYNAMIC */ + SkTimerStop(pAC, pAC->IoBase, &M_DIMINFO.ModTimer); + disableIntMod(pAC); + } + } -/******************************************************************************* -** -** Local functions -** -*******************************************************************************/ + SK_DBG_MSG(pAC,SK_DBGMOD_DRV,SK_DBGCAT_DRV_MSG, + ("<== SkDimDisableModeration\n")); +} -/******************************************************************************* -** Function : GetCurrentSystemLoad -** Description : Retrieves the current system load of the system. This load -** is evaluated for all processors within the system. -** Programmer : Ralph Roesler -** Last Modified: 22-mar-03 -** Returns : unsigned int: load expressed in percentage -** Notes : The possible range being returned is from 0 up to 100. -** Whereas 0 means 'no load at all' and 100 'system fully loaded' -** It is impossible to determine what actually causes the system -** to be in 100%, but maybe that is due to too much interrupts. -*******************************************************************************/ - -static unsigned int -GetCurrentSystemLoad(SK_AC *pAC) { - unsigned long jif = jiffies; - unsigned int UserTime = 0; - unsigned int SystemTime = 0; - unsigned int NiceTime = 0; - unsigned int IdleTime = 0; - unsigned int TotalTime = 0; - unsigned int UsedTime = 0; - unsigned int SystemLoad = 0; - -#ifdef CONFIG_SMP - unsigned int SKNumCpus = smp_num_cpus; -#else - unsigned int SKNumCpus = 1; -#endif +/****************************************************************************** + * + * Local Functions + * + *****************************************************************************/ - unsigned int NbrCpu = 0; +/***************************************************************************** + * + * getIsrCalls - evaluate the number of IRQs handled in mod interval + * + * Description: + * Depending on the selected moderation mask, this function will return + * the number of interrupts handled in the previous moderation interval. + * This evaluated number is based on the current number of interrupts + * stored in PNMI-context and the previous stored interrupts. + * + * Returns: + * the number of IRQs handled + */ +static SK_U64 getIsrCalls( +SK_AC *pAC) /* pointer to adapter control context */ +{ + SK_U64 RxPort0IntDiff = 0, RxPort1IntDiff = 0; + SK_U64 TxPort0IntDiff = 0, TxPort1IntDiff = 0; + SK_U64 StatusPort0IntDiff = 0, StatusPort1IntDiff = 0; + + SK_DBG_MSG(pAC,SK_DBGMOD_DRV,SK_DBGCAT_DRV_MSG,("==>getIsrCalls\n")); + + if (!CHIP_ID_YUKON_2(pAC)) { + if ((M_DIMINFO.MaskIrqModeration == IRQ_MASK_TX_ONLY) || + (M_DIMINFO.MaskIrqModeration == IRQ_MASK_SP_TX)) { + if (pAC->GIni.GIMacsFound == 2) { + TxPort1IntDiff = + pAC->Pnmi.Port[1].TxIntrCts - + M_DIMINFO.PrevPort1TxIntrCts; + } + TxPort0IntDiff = pAC->Pnmi.Port[0].TxIntrCts - + M_DIMINFO.PrevPort0TxIntrCts; + } else if ((M_DIMINFO.MaskIrqModeration == IRQ_MASK_RX_ONLY) || + (M_DIMINFO.MaskIrqModeration == IRQ_MASK_SP_RX)) { + if (pAC->GIni.GIMacsFound == 2) { + RxPort1IntDiff = + pAC->Pnmi.Port[1].RxIntrCts - + M_DIMINFO.PrevPort1RxIntrCts; + } + RxPort0IntDiff = pAC->Pnmi.Port[0].RxIntrCts - + M_DIMINFO.PrevPort0RxIntrCts; + } else { + if (pAC->GIni.GIMacsFound == 2) { + RxPort1IntDiff = + pAC->Pnmi.Port[1].RxIntrCts - + M_DIMINFO.PrevPort1RxIntrCts; + TxPort1IntDiff = + pAC->Pnmi.Port[1].TxIntrCts - + M_DIMINFO.PrevPort1TxIntrCts; + } + RxPort0IntDiff = pAC->Pnmi.Port[0].RxIntrCts - + M_DIMINFO.PrevPort0RxIntrCts; + TxPort0IntDiff = pAC->Pnmi.Port[0].TxIntrCts - + M_DIMINFO.PrevPort0TxIntrCts; + } + SK_DBG_MSG(pAC,SK_DBGMOD_DRV,SK_DBGCAT_DRV_MSG, + ("==>getIsrCalls (!CHIP_ID_YUKON_2)\n")); + return (RxPort0IntDiff + RxPort1IntDiff + + TxPort0IntDiff + TxPort1IntDiff); + } - for (NbrCpu = 0; NbrCpu < SKNumCpus; NbrCpu++) { -#ifdef _LINUX_PROCESS_TIMING_H /* - ** all seconds and usec values being obtained from the - ** process_timing entries need to be adapted to jiffies - ** (in case we have a system supporting process times) + ** We have a Yukon2 compliant chipset if we come up to here + ** + if (pAC->GIni.GIMacsFound == 2) { + StatusPort1IntDiff = pAC->Pnmi.Port[1].StatusLeIntrCts - + M_DIMINFO.PrevPort1StatusIntrCts; + } + StatusPort0IntDiff = pAC->Pnmi.Port[0].StatusLeIntrCts - + M_DIMINFO.PrevPort0StatusIntrCts; */ - UserTime = UserTime + (kstat_percpu[NbrCpu].user.tv_sec * 10) - + (kstat_percpu[NbrCpu].user.tv_usec/100000); - NiceTime = NiceTime + (kstat_percpu[NbrCpu].nice.tv_sec * 10) - + (kstat_percpu[NbrCpu].nice.tv_usec/100000); - SystemTime = SystemTime + (kstat_percpu[NbrCpu].system.tv_sec * 10) - + (kstat_percpu[NbrCpu].system.tv_usec/100000); -#else - UserTime = UserTime + kstat.per_cpu_user[NbrCpu]; - NiceTime = NiceTime + kstat.per_cpu_nice[NbrCpu]; - SystemTime = SystemTime + kstat.per_cpu_system[NbrCpu]; -#endif - } - - UsedTime = UserTime + NiceTime + SystemTime; - - IdleTime = jif * SKNumCpus - UsedTime; - TotalTime = UsedTime + IdleTime; - - SystemLoad = ( 100 * (UsedTime - M_DIMINFO.PrevUsedTime) ) / - (TotalTime - M_DIMINFO.PrevTotalTime); + SK_DBG_MSG(pAC,SK_DBGMOD_DRV,SK_DBGCAT_DRV_MSG, + ("==>getIsrCalls (CHIP_ID_YUKON_2)\n")); + return (StatusPort0IntDiff + StatusPort1IntDiff); +} - if (M_DIMINFO.DisplayStats) { - printk("Current system load is: %u\n", SystemLoad); +/***************************************************************************** + * + * setCurrIntCtr - stores the current number of interrupts + * + * Description: + * Stores the current number of occurred interrupts in the adapter + * context. This is needed to evaluate the umber of interrupts within + * the moderation interval. + * + * Returns: N/A + * + */ +static void setCurrIntCtr( +SK_AC *pAC) /* pointer to adapter control context */ +{ + SK_DBG_MSG(pAC,SK_DBGMOD_DRV,SK_DBGCAT_DRV_MSG,("==>setCurrIntCtr\n")); + + if (!CHIP_ID_YUKON_2(pAC)) { + if (pAC->GIni.GIMacsFound == 2) { + M_DIMINFO.PrevPort1RxIntrCts = pAC->Pnmi.Port[1].RxIntrCts; + M_DIMINFO.PrevPort1TxIntrCts = pAC->Pnmi.Port[1].TxIntrCts; + } + M_DIMINFO.PrevPort0RxIntrCts = pAC->Pnmi.Port[0].RxIntrCts; + M_DIMINFO.PrevPort0TxIntrCts = pAC->Pnmi.Port[0].TxIntrCts; + SK_DBG_MSG(pAC,SK_DBGMOD_DRV,SK_DBGCAT_DRV_MSG, + ("<== setCurrIntCtr (!CHIP_ID_YUKON_2)\n")); + return; } - M_DIMINFO.PrevTotalTime = TotalTime; - M_DIMINFO.PrevUsedTime = UsedTime; - - return (SystemLoad); + /* + ** We have a Yukon2 compliant chipset if we come up to here + ** + if (pAC->GIni.GIMacsFound == 2) { + M_DIMINFO.PrevPort1StatusIntrCts = pAC->Pnmi.Port[1].StatusLeIntrCts; + } + M_DIMINFO.PrevPort0StatusIntrCts = pAC->Pnmi.Port[0].StatusLeIntrCts; + */ + SK_DBG_MSG(pAC,SK_DBGMOD_DRV,SK_DBGCAT_DRV_MSG, + ("<== setCurrIntCtr (CHIP_ID_YUKON_2)\n")); } -/******************************************************************************* -** Function : GetIsrCalls -** Description : Depending on the selected moderation mask, this function will -** return the number of interrupts handled in the previous time- -** frame. This evaluated number is based on the current number -** of interrupts stored in PNMI-context and the previous stored -** interrupts. -** Programmer : Ralph Roesler -** Last Modified: 23-mar-03 -** Returns : int: the number of interrupts being executed in the last -** timeframe -** Notes : It makes only sense to call this function, when dynamic -** interrupt moderation is applied -*******************************************************************************/ - -static SK_U64 -GetIsrCalls(SK_AC *pAC) { - SK_U64 RxPort0IntDiff = 0; - SK_U64 RxPort1IntDiff = 0; - SK_U64 TxPort0IntDiff = 0; - SK_U64 TxPort1IntDiff = 0; - - if (pAC->DynIrqModInfo.MaskIrqModeration == IRQ_MASK_TX_ONLY) { - if (pAC->GIni.GIMacsFound == 2) { - TxPort1IntDiff = pAC->Pnmi.Port[1].TxIntrCts - - pAC->DynIrqModInfo.PrevPort1TxIntrCts; - } - TxPort0IntDiff = pAC->Pnmi.Port[0].TxIntrCts - - pAC->DynIrqModInfo.PrevPort0TxIntrCts; - } else if (pAC->DynIrqModInfo.MaskIrqModeration == IRQ_MASK_RX_ONLY) { - if (pAC->GIni.GIMacsFound == 2) { - RxPort1IntDiff = pAC->Pnmi.Port[1].RxIntrCts - - pAC->DynIrqModInfo.PrevPort1RxIntrCts; - } - RxPort0IntDiff = pAC->Pnmi.Port[0].RxIntrCts - - pAC->DynIrqModInfo.PrevPort0RxIntrCts; - } else { - if (pAC->GIni.GIMacsFound == 2) { - RxPort1IntDiff = pAC->Pnmi.Port[1].RxIntrCts - - pAC->DynIrqModInfo.PrevPort1RxIntrCts; - TxPort1IntDiff = pAC->Pnmi.Port[1].TxIntrCts - - pAC->DynIrqModInfo.PrevPort1TxIntrCts; - } - RxPort0IntDiff = pAC->Pnmi.Port[0].RxIntrCts - - pAC->DynIrqModInfo.PrevPort0RxIntrCts; - TxPort0IntDiff = pAC->Pnmi.Port[0].TxIntrCts - - pAC->DynIrqModInfo.PrevPort0TxIntrCts; - } - - return (RxPort0IntDiff + RxPort1IntDiff + TxPort0IntDiff + TxPort1IntDiff); +/***************************************************************************** + * + * isIntModEnabled - returns the current state of interrupt moderation + * + * Description: + * This function retrieves the current value of the interrupt moderation + * command register. Its content determines whether any moderation is + * running or not. + * + * Returns: + * SK_TRUE : IRQ moderation is currently active + * SK_FALSE: No IRQ moderation is active + */ +static SK_BOOL isIntModEnabled( +SK_AC *pAC) /* pointer to adapter control context */ +{ + unsigned long CtrCmd; + + SK_DBG_MSG(pAC,SK_DBGMOD_DRV,SK_DBGCAT_DRV_MSG,("==>isIntModEnabled\n")); + + SK_IN32(pAC->IoBase, B2_IRQM_CTRL, &CtrCmd); + if ((CtrCmd & TIM_START) == TIM_START) { + SK_DBG_MSG(pAC,SK_DBGMOD_DRV,SK_DBGCAT_DRV_MSG, + ("<== isIntModEnabled (SK_TRUE)\n")); + return SK_TRUE; + } + SK_DBG_MSG(pAC,SK_DBGMOD_DRV,SK_DBGCAT_DRV_MSG, + ("<== isIntModEnabled (SK_FALSE)\n")); + return SK_FALSE; } -/******************************************************************************* -** Function : GetRxCalls -** Description : This function will return the number of times a receive inter- -** rupt was processed. This is needed to evaluate any resizing -** factor. -** Programmer : Ralph Roesler -** Last Modified: 23-mar-03 -** Returns : SK_U64: the number of RX-ints being processed -** Notes : It makes only sense to call this function, when dynamic -** interrupt moderation is applied -*******************************************************************************/ - -static SK_U64 -GetRxCalls(SK_AC *pAC) { - SK_U64 RxPort0IntDiff = 0; - SK_U64 RxPort1IntDiff = 0; - - if (pAC->GIni.GIMacsFound == 2) { - RxPort1IntDiff = pAC->Pnmi.Port[1].RxIntrCts - - pAC->DynIrqModInfo.PrevPort1RxIntrCts; - } - RxPort0IntDiff = pAC->Pnmi.Port[0].RxIntrCts - - pAC->DynIrqModInfo.PrevPort0RxIntrCts; - - return (RxPort0IntDiff + RxPort1IntDiff); -} +/***************************************************************************** + * + * enableIntMod - enables the interrupt moderation + * + * Description: + * Enabling the interrupt moderation is done by putting the desired + * moderation interval in the B2_IRQM_INI register, specifying the + * desired maks in the B2_IRQM_MSK register and finally starting the + * IRQ moderation timer using the B2_IRQM_CTRL register. + * + * Returns: N/A + * + */ +static void enableIntMod( +SK_AC *pAC) /* pointer to adapter control context */ +{ + unsigned long ModBase; + + SK_DBG_MSG(pAC,SK_DBGMOD_DRV,SK_DBGCAT_DRV_MSG,("==> enableIntMod\n")); + + if (pAC->GIni.GIChipId == CHIP_ID_GENESIS) { + ModBase = C_CLK_FREQ_GENESIS / M_DIMINFO.MaxModIntsPerSec; + } else if (pAC->GIni.GIChipId == CHIP_ID_YUKON_EC) { + ModBase = C_CLK_FREQ_YUKON_EC / M_DIMINFO.MaxModIntsPerSec; + } else { + ModBase = C_CLK_FREQ_YUKON / M_DIMINFO.MaxModIntsPerSec; + } -/******************************************************************************* -** Function : SetCurrIntCtr -** Description : Will store the current number orf occured interrupts in the -** adapter context. This is needed to evaluated the number of -** interrupts within a current timeframe. -** Programmer : Ralph Roesler -** Last Modified: 23-mar-03 -** Returns : void (!) -** Notes : - -*******************************************************************************/ - -static void -SetCurrIntCtr(SK_AC *pAC) { - if (pAC->GIni.GIMacsFound == 2) { - pAC->DynIrqModInfo.PrevPort1RxIntrCts = pAC->Pnmi.Port[1].RxIntrCts; - pAC->DynIrqModInfo.PrevPort1TxIntrCts = pAC->Pnmi.Port[1].TxIntrCts; - } - pAC->DynIrqModInfo.PrevPort0RxIntrCts = pAC->Pnmi.Port[0].RxIntrCts; - pAC->DynIrqModInfo.PrevPort0TxIntrCts = pAC->Pnmi.Port[0].TxIntrCts; -} + SK_OUT32(pAC->IoBase, B2_IRQM_INI, ModBase); + SK_OUT32(pAC->IoBase, B2_IRQM_MSK, M_DIMINFO.MaskIrqModeration); + SK_OUT32(pAC->IoBase, B2_IRQM_CTRL, TIM_START); -/******************************************************************************* -** Function : IsIntModEnabled() -** Description : Retrieves the current value of the interrupts moderation -** command register. Its content determines whether any -** moderation is running or not. -** Programmer : Ralph Roesler -** Last Modified: 23-mar-03 -** Returns : SK_TRUE : if mod timer running -** SK_FALSE : if no moderation is being performed -** Notes : - -*******************************************************************************/ - -static SK_BOOL -IsIntModEnabled(SK_AC *pAC) { - unsigned long CtrCmd; - - SK_IN32(pAC->IoBase, B2_IRQM_CTRL, &CtrCmd); - if ((CtrCmd & TIM_START) == TIM_START) { - return SK_TRUE; - } else { - return SK_FALSE; - } + SK_DBG_MSG(pAC,SK_DBGMOD_DRV,SK_DBGCAT_DRV_MSG,("<== enableIntMod\n")); } -/******************************************************************************* -** Function : EnableIntMod() -** Description : Enables the interrupt moderation using the values stored in -** in the pAC->DynIntMod data structure -** Programmer : Ralph Roesler -** Last Modified: 22-mar-03 -** Returns : - -** Notes : - -*******************************************************************************/ - -static void -EnableIntMod(SK_AC *pAC) { - unsigned long ModBase; - - if (pAC->GIni.GIChipId == CHIP_ID_GENESIS) { - ModBase = C_CLK_FREQ_GENESIS / pAC->DynIrqModInfo.MaxModIntsPerSec; - } else { - ModBase = C_CLK_FREQ_YUKON / pAC->DynIrqModInfo.MaxModIntsPerSec; - } - - SK_OUT32(pAC->IoBase, B2_IRQM_INI, ModBase); - SK_OUT32(pAC->IoBase, B2_IRQM_MSK, pAC->DynIrqModInfo.MaskIrqModeration); - SK_OUT32(pAC->IoBase, B2_IRQM_CTRL, TIM_START); - if (M_DIMINFO.DisplayStats) { - printk("Enabled interrupt moderation (%i ints/sec)\n", - M_DIMINFO.MaxModIntsPerSec); - } -} +/***************************************************************************** + * + * disableIntMod - disables the interrupt moderation + * + * Description: + * Disabling the interrupt moderation is done by stopping the + * IRQ moderation timer using the B2_IRQM_CTRL register. + * + * Returns: N/A + * + */ +static void disableIntMod( +SK_AC *pAC) /* pointer to adapter control context */ +{ + SK_DBG_MSG(pAC,SK_DBGMOD_DRV,SK_DBGCAT_DRV_MSG,("==> disableIntMod\n")); -/******************************************************************************* -** Function : DisableIntMod() -** Description : Disbles the interrupt moderation independent of what inter- -** rupts are running or not -** Programmer : Ralph Roesler -** Last Modified: 23-mar-03 -** Returns : - -** Notes : - -*******************************************************************************/ - -static void -DisableIntMod(SK_AC *pAC) { - - SK_OUT32(pAC->IoBase, B2_IRQM_CTRL, TIM_STOP); - if (M_DIMINFO.DisplayStats) { - printk("Disabled interrupt moderation\n"); - } -} + SK_OUT32(pAC->IoBase, B2_IRQM_CTRL, TIM_STOP); -/******************************************************************************* -** Function : ResizeDimTimerDuration(); -** Description : Checks the current used descriptor ratio and resizes the -** duration timer (longer/smaller) if possible. -** Programmer : Ralph Roesler -** Last Modified: 23-mar-03 -** Returns : - -** Notes : There are both maximum and minimum timer duration value. -** This function assumes that interrupt moderation is already -** enabled! -*******************************************************************************/ - -static void -ResizeDimTimerDuration(SK_AC *pAC) { - SK_BOOL IncreaseTimerDuration; - int TotalMaxNbrDescr; - int UsedDescrRatio; - int RatioDiffAbs; - int RatioDiffRel; - int NewMaxModIntsPerSec; - int ModAdjValue; - long ModBase; - - /* - ** Check first if we are allowed to perform any modification - */ - if (IsIntModEnabled(pAC)) { - if (M_DIMINFO.IntModTypeSelect != C_INT_MOD_DYNAMIC) { - return; - } else { - if (M_DIMINFO.ModJustEnabled) { - M_DIMINFO.ModJustEnabled = SK_FALSE; - return; - } - } - } - - /* - ** If we got until here, we have to evaluate the amount of the - ** descriptor ratio change... - */ - TotalMaxNbrDescr = pAC->RxDescrPerRing * GetRxCalls(pAC); - UsedDescrRatio = (M_DIMINFO.NbrProcessedDescr * 100) / TotalMaxNbrDescr; - - if (UsedDescrRatio > M_DIMINFO.PrevUsedDescrRatio) { - RatioDiffAbs = (UsedDescrRatio - M_DIMINFO.PrevUsedDescrRatio); - RatioDiffRel = (RatioDiffAbs * 100) / UsedDescrRatio; - M_DIMINFO.PrevUsedDescrRatio = UsedDescrRatio; - IncreaseTimerDuration = SK_FALSE; /* in other words: DECREASE */ - } else if (UsedDescrRatio < M_DIMINFO.PrevUsedDescrRatio) { - RatioDiffAbs = (M_DIMINFO.PrevUsedDescrRatio - UsedDescrRatio); - RatioDiffRel = (RatioDiffAbs * 100) / M_DIMINFO.PrevUsedDescrRatio; - M_DIMINFO.PrevUsedDescrRatio = UsedDescrRatio; - IncreaseTimerDuration = SK_TRUE; /* in other words: INCREASE */ - } else { - RatioDiffAbs = (M_DIMINFO.PrevUsedDescrRatio - UsedDescrRatio); - RatioDiffRel = (RatioDiffAbs * 100) / M_DIMINFO.PrevUsedDescrRatio; - M_DIMINFO.PrevUsedDescrRatio = UsedDescrRatio; - IncreaseTimerDuration = SK_TRUE; /* in other words: INCREASE */ - } - - /* - ** Now we can determine the change in percent - */ - if ((RatioDiffRel >= 0) && (RatioDiffRel <= 5) ) { - ModAdjValue = 1; /* 1% change - maybe some other value in future */ - } else if ((RatioDiffRel > 5) && (RatioDiffRel <= 10) ) { - ModAdjValue = 1; /* 1% change - maybe some other value in future */ - } else if ((RatioDiffRel > 10) && (RatioDiffRel <= 15) ) { - ModAdjValue = 1; /* 1% change - maybe some other value in future */ - } else { - ModAdjValue = 1; /* 1% change - maybe some other value in future */ - } - - if (IncreaseTimerDuration) { - NewMaxModIntsPerSec = M_DIMINFO.MaxModIntsPerSec + - (M_DIMINFO.MaxModIntsPerSec * ModAdjValue) / 100; - } else { - NewMaxModIntsPerSec = M_DIMINFO.MaxModIntsPerSec - - (M_DIMINFO.MaxModIntsPerSec * ModAdjValue) / 100; - } - - /* - ** Check if we exceed boundaries... - */ - if ( (NewMaxModIntsPerSec > M_DIMINFO.MaxModIntsPerSecUpperLimit) || - (NewMaxModIntsPerSec < M_DIMINFO.MaxModIntsPerSecLowerLimit)) { - if (M_DIMINFO.DisplayStats) { - printk("Cannot change ModTim from %i to %i ints/sec\n", - M_DIMINFO.MaxModIntsPerSec, NewMaxModIntsPerSec); - } - return; - } else { - if (M_DIMINFO.DisplayStats) { - printk("Resized ModTim from %i to %i ints/sec\n", - M_DIMINFO.MaxModIntsPerSec, NewMaxModIntsPerSec); - } - } - - M_DIMINFO.MaxModIntsPerSec = NewMaxModIntsPerSec; - - if (pAC->GIni.GIChipId == CHIP_ID_GENESIS) { - ModBase = C_CLK_FREQ_GENESIS / pAC->DynIrqModInfo.MaxModIntsPerSec; - } else { - ModBase = C_CLK_FREQ_YUKON / pAC->DynIrqModInfo.MaxModIntsPerSec; - } - - /* - ** We do not need to touch any other registers - */ - SK_OUT32(pAC->IoBase, B2_IRQM_INI, ModBase); + SK_DBG_MSG(pAC,SK_DBGMOD_DRV,SK_DBGCAT_DRV_MSG,("<== disableIntMod\n")); } /******************************************************************************* -** Function : DisplaySelectedModerationType() -** Description : Displays what type of moderation we have -** Programmer : Ralph Roesler -** Last Modified: 23-mar-03 -** Returns : void! -** Notes : - -*******************************************************************************/ - -static void -DisplaySelectedModerationType(SK_AC *pAC) { - - if (pAC->DynIrqModInfo.DisplayStats) { - if (pAC->DynIrqModInfo.IntModTypeSelect == C_INT_MOD_STATIC) { - printk("Static int moderation runs with %i INTS/sec\n", - pAC->DynIrqModInfo.MaxModIntsPerSec); - } else if (pAC->DynIrqModInfo.IntModTypeSelect == C_INT_MOD_DYNAMIC) { - if (IsIntModEnabled(pAC)) { - printk("Dynamic int moderation runs with %i INTS/sec\n", - pAC->DynIrqModInfo.MaxModIntsPerSec); - } else { - printk("Dynamic int moderation currently not applied\n"); - } - } else { - printk("No interrupt moderation selected!\n"); - } - } -} - -/******************************************************************************* -** Function : DisplaySelectedModerationMask() -** Description : Displays what interrupts are moderated -** Programmer : Ralph Roesler -** Last Modified: 23-mar-03 -** Returns : void! -** Notes : - -*******************************************************************************/ - -static void -DisplaySelectedModerationMask(SK_AC *pAC) { - - if (pAC->DynIrqModInfo.DisplayStats) { - if (pAC->DynIrqModInfo.IntModTypeSelect != C_INT_MOD_NONE) { - switch (pAC->DynIrqModInfo.MaskIrqModeration) { - case IRQ_MASK_TX_ONLY: - printk("Only Tx-interrupts are moderated\n"); - break; - case IRQ_MASK_RX_ONLY: - printk("Only Rx-interrupts are moderated\n"); - break; - case IRQ_MASK_SP_ONLY: - printk("Only special-interrupts are moderated\n"); - break; - case IRQ_MASK_TX_RX: - printk("Tx- and Rx-interrupts are moderated\n"); - break; - case IRQ_MASK_SP_RX: - printk("Special- and Rx-interrupts are moderated\n"); - break; - case IRQ_MASK_SP_TX: - printk("Special- and Tx-interrupts are moderated\n"); - break; - case IRQ_MASK_RX_TX_SP: - printk("All Rx-, Tx and special-interrupts are moderated\n"); - break; - default: - printk("Don't know what is moderated\n"); - break; - } - } else { - printk("No specific interrupts masked for moderation\n"); - } - } -} - -/******************************************************************************* -** Function : DisplayDescrRatio -** Description : Like the name states... -** Programmer : Ralph Roesler -** Last Modified: 23-mar-03 -** Returns : void! -** Notes : - -*******************************************************************************/ - -static void -DisplayDescrRatio(SK_AC *pAC) { - int TotalMaxNbrDescr = 0; - - if (pAC->DynIrqModInfo.DisplayStats) { - TotalMaxNbrDescr = pAC->RxDescrPerRing * GetRxCalls(pAC); - printk("Ratio descriptors: %i/%i\n", - M_DIMINFO.NbrProcessedDescr, TotalMaxNbrDescr); - } -} - -/******************************************************************************* -** -** End of file -** -*******************************************************************************/ + * + * End of file + * + ******************************************************************************/ diff -urN linux-2.4.32-600/drivers/net/sk98lin/skethtool.c linux-2.4.32-600-sk98_831/drivers/net/sk98lin/skethtool.c --- linux-2.4.32-600/drivers/net/sk98lin/skethtool.c Thu Jan 1 01:00:00 1970 +++ linux-2.4.32-600-sk98_831/drivers/net/sk98lin/skethtool.c Sun Feb 26 11:13:02 2006 @@ -0,0 +1,1356 @@ +/****************************************************************************** + * + * Name: skethtool.c + * Project: GEnesis, PCI Gigabit Ethernet Adapter + * Version: $Revision: 1.3.2.11 $ + * Date: $Date: 2005/10/27 12:42:34 $ + * Purpose: All functions regarding ethtool handling + * + ******************************************************************************/ + +/****************************************************************************** + * + * (C)Copyright 1998-2002 SysKonnect GmbH. + * (C)Copyright 2002-2005 Marvell. + * + * Driver for Marvell Yukon/2 chipset and SysKonnect Gigabit Ethernet + * Server Adapters. + * + * Author: Ralph Roesler (rroesler@syskonnect.de) + * Mirko Lindner (mlindner@syskonnect.de) + * + * Address all question to: linux@syskonnect.de + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * The information in this file is provided "AS IS" without warranty. + * + *****************************************************************************/ + +#include "h/skdrv1st.h" +#include "h/skdrv2nd.h" +#include "h/skversion.h" +#include +#include +#include + +/****************************************************************************** + * + * External Functions and Data + * + *****************************************************************************/ + +extern void SkDimDisableModeration(SK_AC *pAC, int CurrentModeration); +extern void SkDimEnableModerationIfNeeded(SK_AC *pAC); + +/****************************************************************************** + * + * Defines + * + *****************************************************************************/ + +#ifndef ETHT_STATSTRING_LEN +#define ETHT_STATSTRING_LEN 32 +#endif + +#define SK98LIN_STAT(m) sizeof(((SK_AC *)0)->m),offsetof(SK_AC, m) + +#define SUPP_COPPER_ALL (SUPPORTED_10baseT_Half | SUPPORTED_10baseT_Full | \ + SUPPORTED_100baseT_Half | SUPPORTED_100baseT_Full | \ + SUPPORTED_1000baseT_Half| SUPPORTED_1000baseT_Full| \ + SUPPORTED_TP) + +#define ADV_COPPER_ALL (ADVERTISED_10baseT_Half | ADVERTISED_10baseT_Full | \ + ADVERTISED_100baseT_Half | ADVERTISED_100baseT_Full | \ + ADVERTISED_1000baseT_Half| ADVERTISED_1000baseT_Full| \ + ADVERTISED_TP) + +#define SUPP_FIBRE_ALL (SUPPORTED_1000baseT_Full | \ + SUPPORTED_FIBRE | \ + SUPPORTED_Autoneg) + +#define ADV_FIBRE_ALL (ADVERTISED_1000baseT_Full | \ + ADVERTISED_FIBRE | \ + ADVERTISED_Autoneg) + +/****************************************************************************** + * + * Local Function Prototypes + * + *****************************************************************************/ + +#ifdef ETHTOOL_GSET +static void getSettings(SK_AC *pAC, int port, struct ethtool_cmd *ecmd); +#endif +#ifdef ETHTOOL_SSET +static int setSettings(SK_AC *pAC, int port, struct ethtool_cmd *ecmd); +#endif +#ifdef ETHTOOL_GPAUSEPARAM +static void getPauseParams(SK_AC *pAC, int port, struct ethtool_pauseparam *epause); +#endif +#ifdef ETHTOOL_SPAUSEPARAM +static int setPauseParams(SK_AC *pAC, int port, struct ethtool_pauseparam *epause); +#endif +#ifdef ETHTOOL_GDRVINFO +static void getDriverInfo(SK_AC *pAC, int port, struct ethtool_drvinfo *edrvinfo); +#endif +#ifdef ETHTOOL_PHYS_ID +static int startLocateNIC(SK_AC *pAC, int port, struct ethtool_value *blinkSecs); +static void toggleLeds(unsigned long ptr); +#endif +#ifdef ETHTOOL_GCOALESCE +static void getModerationParams(SK_AC *pAC, int port, struct ethtool_coalesce *ecoalesc); +#endif +#ifdef ETHTOOL_SCOALESCE +static int setModerationParams(SK_AC *pAC, int port, struct ethtool_coalesce *ecoalesc); +#endif +#ifdef ETHTOOL_GWOL +static void getWOLsettings(SK_AC *pAC, int port, struct ethtool_wolinfo *ewol); +#endif +#ifdef ETHTOOL_SWOL +static int setWOLsettings(SK_AC *pAC, int port, struct ethtool_wolinfo *ewol); +#endif + +static int getPortNumber(struct net_device *netdev, struct ifreq *ifr); + +/****************************************************************************** + * + * Local Variables + * + *****************************************************************************/ + +struct sk98lin_stats { + char stat_string[ETHT_STATSTRING_LEN]; + int sizeof_stat; + int stat_offset; +}; + +static struct sk98lin_stats sk98lin_etht_stats_port0[] = { + { "rx_packets" , SK98LIN_STAT(PnmiStruct.Stat[0].StatRxOkCts) }, + { "tx_packets" , SK98LIN_STAT(PnmiStruct.Stat[0].StatTxOkCts) }, + { "rx_bytes" , SK98LIN_STAT(PnmiStruct.Stat[0].StatRxOctetsOkCts) }, + { "tx_bytes" , SK98LIN_STAT(PnmiStruct.Stat[0].StatTxOctetsOkCts) }, + { "rx_errors" , SK98LIN_STAT(PnmiStruct.InErrorsCts) }, + { "tx_errors" , SK98LIN_STAT(PnmiStruct.Stat[0].StatTxSingleCollisionCts) }, + { "rx_dropped" , SK98LIN_STAT(PnmiStruct.RxNoBufCts) }, + { "tx_dropped" , SK98LIN_STAT(PnmiStruct.TxNoBufCts) }, + { "multicasts" , SK98LIN_STAT(PnmiStruct.Stat[0].StatRxMulticastOkCts) }, + { "collisions" , SK98LIN_STAT(PnmiStruct.Stat[0].StatTxSingleCollisionCts) }, + { "rx_length_errors" , SK98LIN_STAT(PnmiStruct.Stat[0].StatRxRuntCts) }, + { "rx_buffer_overflow_errors" , SK98LIN_STAT(PnmiStruct.Stat[0].StatRxFifoOverflowCts) }, + { "rx_crc_errors" , SK98LIN_STAT(PnmiStruct.Stat[0].StatRxFcsCts) }, + { "rx_frame_errors" , SK98LIN_STAT(PnmiStruct.Stat[0].StatRxFramingCts) }, + { "rx_too_short_errors" , SK98LIN_STAT(PnmiStruct.Stat[0].StatRxShortsCts) }, + { "rx_too_long_errors" , SK98LIN_STAT(PnmiStruct.Stat[0].StatRxTooLongCts) }, + { "rx_carrier_extension_errors", SK98LIN_STAT(PnmiStruct.Stat[0].StatRxCextCts) }, + { "rx_symbol_errors" , SK98LIN_STAT(PnmiStruct.Stat[0].StatRxSymbolCts) }, + { "rx_llc_mac_size_errors" , SK98LIN_STAT(PnmiStruct.Stat[0].StatRxIRLengthCts) }, + { "rx_carrier_errors" , SK98LIN_STAT(PnmiStruct.Stat[0].StatRxCarrierCts) }, + { "rx_jabber_errors" , SK98LIN_STAT(PnmiStruct.Stat[0].StatRxJabberCts) }, + { "rx_missed_errors" , SK98LIN_STAT(PnmiStruct.Stat[0].StatRxMissedCts) }, + { "tx_abort_collision_errors" , SK98LIN_STAT(stats.tx_aborted_errors) }, + { "tx_carrier_errors" , SK98LIN_STAT(PnmiStruct.Stat[0].StatTxCarrierCts) }, + { "tx_buffer_underrun_errors" , SK98LIN_STAT(PnmiStruct.Stat[0].StatTxFifoUnderrunCts) }, + { "tx_heartbeat_errors" , SK98LIN_STAT(PnmiStruct.Stat[0].StatTxCarrierCts) } , + { "tx_window_errors" , SK98LIN_STAT(stats.tx_window_errors) } +}; + +static struct sk98lin_stats sk98lin_etht_stats_port1[] = { + { "rx_packets" , SK98LIN_STAT(PnmiStruct.Stat[1].StatRxOkCts) }, + { "tx_packets" , SK98LIN_STAT(PnmiStruct.Stat[1].StatTxOkCts) }, + { "rx_bytes" , SK98LIN_STAT(PnmiStruct.Stat[1].StatRxOctetsOkCts) }, + { "tx_bytes" , SK98LIN_STAT(PnmiStruct.Stat[1].StatTxOctetsOkCts) }, + { "rx_errors" , SK98LIN_STAT(PnmiStruct.InErrorsCts) }, + { "tx_errors" , SK98LIN_STAT(PnmiStruct.Stat[1].StatTxSingleCollisionCts) }, + { "rx_dropped" , SK98LIN_STAT(PnmiStruct.RxNoBufCts) }, + { "tx_dropped" , SK98LIN_STAT(PnmiStruct.TxNoBufCts) }, + { "multicasts" , SK98LIN_STAT(PnmiStruct.Stat[1].StatRxMulticastOkCts) }, + { "collisions" , SK98LIN_STAT(PnmiStruct.Stat[1].StatTxSingleCollisionCts) }, + { "rx_length_errors" , SK98LIN_STAT(PnmiStruct.Stat[1].StatRxRuntCts) }, + { "rx_buffer_overflow_errors" , SK98LIN_STAT(PnmiStruct.Stat[1].StatRxFifoOverflowCts) }, + { "rx_crc_errors" , SK98LIN_STAT(PnmiStruct.Stat[1].StatRxFcsCts) }, + { "rx_frame_errors" , SK98LIN_STAT(PnmiStruct.Stat[1].StatRxFramingCts) }, + { "rx_too_short_errors" , SK98LIN_STAT(PnmiStruct.Stat[1].StatRxShortsCts) }, + { "rx_too_long_errors" , SK98LIN_STAT(PnmiStruct.Stat[1].StatRxTooLongCts) }, + { "rx_carrier_extension_errors", SK98LIN_STAT(PnmiStruct.Stat[1].StatRxCextCts) }, + { "rx_symbol_errors" , SK98LIN_STAT(PnmiStruct.Stat[1].StatRxSymbolCts) }, + { "rx_llc_mac_size_errors" , SK98LIN_STAT(PnmiStruct.Stat[1].StatRxIRLengthCts) }, + { "rx_carrier_errors" , SK98LIN_STAT(PnmiStruct.Stat[1].StatRxCarrierCts) }, + { "rx_jabber_errors" , SK98LIN_STAT(PnmiStruct.Stat[1].StatRxJabberCts) }, + { "rx_missed_errors" , SK98LIN_STAT(PnmiStruct.Stat[1].StatRxMissedCts) }, + { "tx_abort_collision_errors" , SK98LIN_STAT(stats.tx_aborted_errors) }, + { "tx_carrier_errors" , SK98LIN_STAT(PnmiStruct.Stat[1].StatTxCarrierCts) }, + { "tx_buffer_underrun_errors" , SK98LIN_STAT(PnmiStruct.Stat[1].StatTxFifoUnderrunCts) }, + { "tx_heartbeat_errors" , SK98LIN_STAT(PnmiStruct.Stat[1].StatTxCarrierCts) } , + { "tx_window_errors" , SK98LIN_STAT(stats.tx_window_errors) } +}; + +#define SK98LIN_STATS_LEN sizeof(sk98lin_etht_stats_port0) / sizeof(struct sk98lin_stats) + +static int nbrBlinkQuarterSeconds; +static int currentPortIndex; +static SK_BOOL isLocateNICrunning = SK_FALSE; +static SK_BOOL isDualNetCard = SK_FALSE; +static SK_BOOL doSwitchLEDsOn = SK_FALSE; +static SK_BOOL boardWasDown[2] = { SK_FALSE, SK_FALSE }; +static struct timer_list locateNICtimer; + +/****************************************************************************** + * + * Global Functions + * + *****************************************************************************/ + +/***************************************************************************** + * + * SkEthIoctl - IOCTL entry point for all ethtool queries + * + * Description: + * Any IOCTL request that has to deal with the ethtool command tool is + * dispatched via this function. + * + * Returns: + * ==0: everything fine, no error + * !=0: the return value is the error code of the failure + */ +int SkEthIoctl( +struct net_device *netdev, /* the pointer to netdev structure */ +struct ifreq *ifr) /* what interface the request refers to? */ +{ + DEV_NET *pNet = (DEV_NET*) netdev->priv; + SK_AC *pAC = pNet->pAC; + void *pAddr = ifr->ifr_data; + int port = getPortNumber(netdev, ifr); + SK_PNMI_STRUCT_DATA *pPnmiStruct = &pAC->PnmiStruct; + SK_U32 Size = sizeof(SK_PNMI_STRUCT_DATA); + SK_U32 cmd; + struct sk98lin_stats *sk98lin_etht_stats = + (port == 0) ? sk98lin_etht_stats_port0 : sk98lin_etht_stats_port1; + + if (get_user(cmd, (uint32_t *) pAddr)) { + return -EFAULT; + } + + switch(cmd) { +#ifdef ETHTOOL_GSET + case ETHTOOL_GSET: { + struct ethtool_cmd ecmd = { ETHTOOL_GSET }; + getSettings(pAC, port, &ecmd); + if(copy_to_user(pAddr, &ecmd, sizeof(ecmd))) { + return -EFAULT; + } + return 0; + } + break; +#endif +#ifdef ETHTOOL_SSET + case ETHTOOL_SSET: { + struct ethtool_cmd ecmd; + if(copy_from_user(&ecmd, pAddr, sizeof(ecmd))) { + return -EFAULT; + } + return setSettings(pAC, port, &ecmd); + } + break; +#endif +#ifdef ETHTOOL_GLINK + case ETHTOOL_GLINK: { + struct ethtool_value edata = { ETHTOOL_GLINK }; + edata.data = netif_carrier_ok(netdev); + if (copy_to_user(pAddr, &edata, sizeof(edata))) + return -EFAULT; + return 0; + } +#endif +#ifdef ETHTOOL_GDRVINFO + case ETHTOOL_GDRVINFO: { + struct ethtool_drvinfo drvinfo = { ETHTOOL_GDRVINFO }; + getDriverInfo(pAC, port, &drvinfo); + if(copy_to_user(pAddr, &drvinfo, sizeof(drvinfo))) { + return -EFAULT; + } + return 0; + } + break; +#endif +#ifdef ETHTOOL_GSTRINGS + case ETHTOOL_GSTRINGS: { + struct ethtool_gstrings gstrings = { ETHTOOL_GSTRINGS }; + char *strings = NULL; + int err = 0; + if(copy_from_user(&gstrings, pAddr, sizeof(gstrings))) { + return -EFAULT; + } + switch(gstrings.string_set) { +#ifdef ETHTOOL_GSTATS + case ETH_SS_STATS: { + int i; + gstrings.len = SK98LIN_STATS_LEN; + if ((strings = kmalloc(SK98LIN_STATS_LEN*ETHT_STATSTRING_LEN,GFP_KERNEL)) == NULL) { + return -ENOMEM; + } + for(i=0; i < SK98LIN_STATS_LEN; i++) { + memcpy(&strings[i * ETHT_STATSTRING_LEN], + &(sk98lin_etht_stats[i].stat_string), + ETHT_STATSTRING_LEN); + } + } + break; +#endif + default: + return -EOPNOTSUPP; + } + if(copy_to_user(pAddr, &gstrings, sizeof(gstrings))) { + err = -EFAULT; + } + pAddr = (void *) ((unsigned long int) pAddr + offsetof(struct ethtool_gstrings, data)); + if(!err && copy_to_user(pAddr, strings, gstrings.len * ETH_GSTRING_LEN)) { + err = -EFAULT; + } + kfree(strings); + return err; + } +#endif +#ifdef ETHTOOL_GSTATS + case ETHTOOL_GSTATS: { + struct { + struct ethtool_stats eth_stats; + uint64_t data[SK98LIN_STATS_LEN]; + } stats = { {ETHTOOL_GSTATS, SK98LIN_STATS_LEN} }; + int i; + + if (netif_running(pAC->dev[port])) { + SkPnmiGetStruct(pAC, pAC->IoBase, pPnmiStruct, &Size, port); + } + for(i = 0; i < SK98LIN_STATS_LEN; i++) { + if (netif_running(pAC->dev[port])) { + stats.data[i] = (sk98lin_etht_stats[i].sizeof_stat == + sizeof(uint64_t)) ? + *(uint64_t *)((char *)pAC + + sk98lin_etht_stats[i].stat_offset) : + *(uint32_t *)((char *)pAC + + sk98lin_etht_stats[i].stat_offset); + } else { + stats.data[i] = (sk98lin_etht_stats[i].sizeof_stat == + sizeof(uint64_t)) ? (uint64_t) 0 : (uint32_t) 0; + } + } + if(copy_to_user(pAddr, &stats, sizeof(stats))) { + return -EFAULT; + } + return 0; + } +#endif +#ifdef ETHTOOL_PHYS_ID + case ETHTOOL_PHYS_ID: { + struct ethtool_value blinkSecs; + if(copy_from_user(&blinkSecs, pAddr, sizeof(blinkSecs))) { + return -EFAULT; + } + return startLocateNIC(pAC, port, &blinkSecs); + } +#endif +#ifdef ETHTOOL_GPAUSEPARAM + case ETHTOOL_GPAUSEPARAM: { + struct ethtool_pauseparam epause = { ETHTOOL_GPAUSEPARAM }; + getPauseParams(pAC, port, &epause); + if(copy_to_user(pAddr, &epause, sizeof(epause))) { + return -EFAULT; + } + return 0; + } +#endif +#ifdef ETHTOOL_SPAUSEPARAM + case ETHTOOL_SPAUSEPARAM: { + struct ethtool_pauseparam epause; + if(copy_from_user(&epause, pAddr, sizeof(epause))) { + return -EFAULT; + } + return setPauseParams(pAC, port, &epause); + } +#endif +#ifdef ETHTOOL_GSG + case ETHTOOL_GSG: { + struct ethtool_value edata = { ETHTOOL_GSG }; + edata.data = (netdev->features & NETIF_F_SG) != 0; + if (copy_to_user(pAddr, &edata, sizeof(edata))) { + return -EFAULT; + } + return 0; + } +#endif +#ifdef ETHTOOL_SSG + case ETHTOOL_SSG: { + struct ethtool_value edata; + if (copy_from_user(&edata, pAddr, sizeof(edata))) { + return -EFAULT; + } + if (pAC->ChipsetType) { /* Don't handle if Genesis */ + if (edata.data) { + netdev->features |= NETIF_F_SG; + } else { + netdev->features &= ~NETIF_F_SG; + } + } + return 0; + } +#endif +#ifdef ETHTOOL_GRXCSUM + case ETHTOOL_GRXCSUM: { + struct ethtool_value edata = { ETHTOOL_GRXCSUM }; + edata.data = pAC->RxPort[port].UseRxCsum; + if (copy_to_user(pAddr, &edata, sizeof(edata))) { + return -EFAULT; + } + return 0; + } +#endif +#ifdef ETHTOOL_SRXCSUM + case ETHTOOL_SRXCSUM: { + struct ethtool_value edata; + if (copy_from_user(&edata, pAddr, sizeof(edata))) { + return -EFAULT; + } + pAC->RxPort[port].UseRxCsum = edata.data; + return 0; + } +#endif +#ifdef ETHTOOL_GTXCSUM + case ETHTOOL_GTXCSUM: { + struct ethtool_value edata = { ETHTOOL_GTXCSUM }; + edata.data = ((netdev->features & NETIF_F_IP_CSUM) != 0); + if (copy_to_user(pAddr, &edata, sizeof(edata))) { + return -EFAULT; + } + return 0; + } +#endif +#ifdef ETHTOOL_STXCSUM + case ETHTOOL_STXCSUM: { + struct ethtool_value edata; + if (copy_from_user(&edata, pAddr, sizeof(edata))) { + return -EFAULT; + } + if (pAC->ChipsetType) { /* Don't handle if Genesis */ + if (edata.data) { + netdev->features |= NETIF_F_IP_CSUM; + } else { + netdev->features &= ~NETIF_F_IP_CSUM; + } + } + return 0; + } +#endif +#ifdef ETHTOOL_NWAY_RST + case ETHTOOL_NWAY_RST: { + if(netif_running(netdev)) { + (*netdev->stop)(netdev); + (*netdev->open)(netdev); + } + return 0; + } +#endif +#ifdef NETIF_F_TSO +#ifdef ETHTOOL_GTSO + case ETHTOOL_GTSO: { + struct ethtool_value edata = { ETHTOOL_GTSO }; + edata.data = (netdev->features & NETIF_F_TSO) != 0; + if (copy_to_user(pAddr, &edata, sizeof(edata))) { + return -EFAULT; + } + return 0; + } +#endif +#ifdef ETHTOOL_STSO + case ETHTOOL_STSO: { + struct ethtool_value edata; + if (CHIP_ID_YUKON_2(pAC)) { + if (copy_from_user(&edata, pAddr, sizeof(edata))) { + return -EFAULT; + } + if (edata.data) { + netdev->features |= NETIF_F_TSO; + } else { + netdev->features &= ~NETIF_F_TSO; + } + return 0; + } + return -EOPNOTSUPP; + } +#endif +#endif +#ifdef ETHTOOL_GCOALESCE + case ETHTOOL_GCOALESCE: { + struct ethtool_coalesce ecoalesc = { ETHTOOL_GCOALESCE }; + getModerationParams(pAC, port, &ecoalesc); + if(copy_to_user(pAddr, &ecoalesc, sizeof(ecoalesc))) { + return -EFAULT; + } + return 0; + } +#endif +#ifdef ETHTOOL_SCOALESCE + case ETHTOOL_SCOALESCE: { + struct ethtool_coalesce ecoalesc; + if(copy_from_user(&ecoalesc, pAddr, sizeof(ecoalesc))) { + return -EFAULT; + } + return setModerationParams(pAC, port, &ecoalesc); + } +#endif +#ifdef ETHTOOL_GWOL + case ETHTOOL_GWOL: { + struct ethtool_wolinfo ewol = { ETHTOOL_GWOL }; + getWOLsettings(pAC, port, &ewol); + if(copy_to_user(pAddr, &ewol, sizeof(ewol))) { + return -EFAULT; + } + return 0; + } +#endif +#ifdef ETHTOOL_SWOL + case ETHTOOL_SWOL: { + struct ethtool_wolinfo ewol; + if(copy_from_user(&ewol, pAddr, sizeof(ewol))) { + return -EFAULT; + } + return setWOLsettings(pAC, port, &ewol); + } +#endif + default: + return -EOPNOTSUPP; + } +} /* SkEthIoctl() */ + +/****************************************************************************** + * + * Local Functions + * + *****************************************************************************/ + +#ifdef ETHTOOL_GSET +/***************************************************************************** + * + * getSettings - retrieves the current settings of the selected adapter + * + * Description: + * The current configuration of the selected adapter is returned. + * This configuration involves a)speed, b)duplex and c)autoneg plus + * a number of other variables. + * + * Returns: N/A + * + */ +static void getSettings( +SK_AC *pAC, /* pointer to adapter control context */ +int port, /* the port of the selected adapter */ +struct ethtool_cmd *ecmd) /* mandatory command structure for results */ +{ + SK_GEPORT *pPort = &pAC->GIni.GP[port]; + + static int DuplexAutoNegConfMap[9][3]= { + { -1 , -1 , -1 }, + { 0 , -1 , -1 }, + { SK_LMODE_HALF , DUPLEX_HALF, AUTONEG_DISABLE }, + { SK_LMODE_FULL , DUPLEX_FULL, AUTONEG_DISABLE }, + { SK_LMODE_AUTOHALF , DUPLEX_HALF, AUTONEG_ENABLE }, + { SK_LMODE_AUTOFULL , DUPLEX_FULL, AUTONEG_ENABLE }, + { SK_LMODE_AUTOBOTH , DUPLEX_FULL, AUTONEG_ENABLE }, + { SK_LMODE_AUTOSENSE , -1 , -1 }, + { SK_LMODE_INDETERMINATED, -1 , -1 } + }; + + static int SpeedConfMap[6][2] = { + { 0 , -1 }, + { SK_LSPEED_AUTO , -1 }, + { SK_LSPEED_10MBPS , SPEED_10 }, + { SK_LSPEED_100MBPS , SPEED_100 }, + { SK_LSPEED_1000MBPS , SPEED_1000 }, + { SK_LSPEED_INDETERMINATED, -1 } + }; + + static int AdvSpeedMap[6][2] = { + { 0 , -1 }, + { SK_LSPEED_AUTO , -1 }, + { SK_LSPEED_10MBPS , ADVERTISED_10baseT_Half | ADVERTISED_10baseT_Full }, + { SK_LSPEED_100MBPS , ADVERTISED_100baseT_Half | ADVERTISED_100baseT_Full }, + { SK_LSPEED_1000MBPS , ADVERTISED_1000baseT_Half | ADVERTISED_1000baseT_Full}, + { SK_LSPEED_INDETERMINATED, -1 } + }; + + ecmd->phy_address = port; + ecmd->speed = SpeedConfMap[pPort->PLinkSpeedUsed][1]; + ecmd->duplex = DuplexAutoNegConfMap[pPort->PLinkModeStatus][1]; + ecmd->autoneg = DuplexAutoNegConfMap[pPort->PLinkModeStatus][2]; + ecmd->transceiver = XCVR_INTERNAL; + + if (pAC->GIni.GICopperType) { + ecmd->port = PORT_TP; + ecmd->supported = (SUPP_COPPER_ALL|SUPPORTED_Autoneg); + if (pAC->GIni.GIGenesis) { + ecmd->supported &= ~(SUPPORTED_10baseT_Half); + ecmd->supported &= ~(SUPPORTED_10baseT_Full); + ecmd->supported &= ~(SUPPORTED_100baseT_Half); + ecmd->supported &= ~(SUPPORTED_100baseT_Full); + } else { + if (pAC->GIni.GIChipId == CHIP_ID_YUKON) { + ecmd->supported &= ~(SUPPORTED_1000baseT_Half); + } + if (pAC->GIni.GIChipId == CHIP_ID_YUKON_FE) { + ecmd->supported &= ~(SUPPORTED_1000baseT_Half); + ecmd->supported &= ~(SUPPORTED_1000baseT_Full); + } + } + if (pAC->GIni.GP[0].PLinkSpeed != SK_LSPEED_AUTO) { + ecmd->advertising = AdvSpeedMap[pPort->PLinkSpeed][1]; + if (pAC->GIni.GIChipId == CHIP_ID_YUKON) { + ecmd->advertising &= ~(SUPPORTED_1000baseT_Half); + } + } else { + ecmd->advertising = ecmd->supported; + } + if (ecmd->autoneg == AUTONEG_ENABLE) { + ecmd->advertising |= ADVERTISED_Autoneg; + } else { + ecmd->advertising = ADVERTISED_TP; + } + } else { + ecmd->port = PORT_FIBRE; + ecmd->supported = (SUPP_FIBRE_ALL); + ecmd->advertising = (ADV_FIBRE_ALL); + } +} +#endif + +#ifdef ETHTOOL_SSET +/***************************************************************************** + * + * setSettings - configures the settings of a selected adapter + * + * Description: + * Possible settings that may be altered are a)speed, b)duplex or + * c)autonegotiation. + * + * Returns: + * ==0: everything fine, no error + * !=0: the return value is the error code of the failure + */ +static int setSettings( +SK_AC *pAC, /* pointer to adapter control context */ +int port, /* the port of the selected adapter */ +struct ethtool_cmd *ecmd) /* command structure containing settings */ +{ + DEV_NET *pNet = (DEV_NET *) pAC->dev[port]->priv; + SK_U32 Instance; + char Buf[4]; + unsigned int Len = 1; + int Ret; + + if (port == 0) { + Instance = (pAC->RlmtNets == 2) ? 1 : 2; + } else { + Instance = (pAC->RlmtNets == 2) ? 2 : 3; + } + + if (((ecmd->autoneg == AUTONEG_DISABLE) || (ecmd->autoneg == AUTONEG_ENABLE)) && + ((ecmd->duplex == DUPLEX_FULL) || (ecmd->duplex == DUPLEX_HALF))) { + if (ecmd->autoneg == AUTONEG_DISABLE) { + if (ecmd->duplex == DUPLEX_FULL) { + *Buf = (char) SK_LMODE_FULL; + } else { + *Buf = (char) SK_LMODE_HALF; + } + } else { + if (ecmd->duplex == DUPLEX_FULL) { + *Buf = (char) SK_LMODE_AUTOFULL; + } else { + *Buf = (char) SK_LMODE_AUTOHALF; + } + } + + Ret = SkPnmiSetVar(pAC, pAC->IoBase, OID_SKGE_LINK_MODE, + &Buf, &Len, Instance, pNet->NetNr); + + if (Ret != SK_PNMI_ERR_OK) { + return -EINVAL; + } + } else if (ecmd->autoneg == AUTONEG_ENABLE) { + /* Set default values */ + *Buf = (char) SK_LMODE_AUTOFULL; + Ret = SkPnmiSetVar(pAC, pAC->IoBase, OID_SKGE_LINK_MODE, + &Buf, &Len, Instance, pNet->NetNr); + } + + if ((ecmd->speed == SPEED_1000) || + (ecmd->speed == SPEED_100) || + (ecmd->speed == SPEED_10)) { + if (ecmd->autoneg == AUTONEG_ENABLE) { + *Buf = (char) SK_LSPEED_AUTO; + } else if (ecmd->speed == SPEED_1000) { + *Buf = (char) SK_LSPEED_1000MBPS; + } else if (ecmd->speed == SPEED_100) { + *Buf = (char) SK_LSPEED_100MBPS; + } else { + *Buf = (char) SK_LSPEED_10MBPS; + } + + Ret = SkPnmiSetVar(pAC, pAC->IoBase, OID_SKGE_SPEED_MODE, + &Buf, &Len, Instance, pNet->NetNr); + + if (Ret != SK_PNMI_ERR_OK) { + return -EINVAL; + } + } else if (ecmd->autoneg == AUTONEG_ENABLE) { + *Buf = (char) SK_LSPEED_AUTO; + Ret = SkPnmiSetVar(pAC, pAC->IoBase, OID_SKGE_SPEED_MODE, + &Buf, &Len, Instance, pNet->NetNr); + } else { + return -EINVAL; + } + + return 0; +} +#endif + +#ifdef ETHTOOL_GPAUSEPARAM +/***************************************************************************** + * + * getPauseParams - retrieves the pause parameters + * + * Description: + * All current pause parameters of a selected adapter are placed + * in the passed ethtool_pauseparam structure and are returned. + * + * Returns: N/A + * + */ +static void getPauseParams( +SK_AC *pAC, /* pointer to adapter control context */ +int port, /* the port of the selected adapter */ +struct ethtool_pauseparam *epause) /* pause parameter struct for result */ +{ + SK_GEPORT *pPort = &pAC->GIni.GP[port]; + + epause->rx_pause = 0; + epause->tx_pause = 0; + + if (pPort->PFlowCtrlMode == SK_FLOW_MODE_LOC_SEND) { + epause->tx_pause = 1; + } + if ((pPort->PFlowCtrlMode == SK_FLOW_MODE_SYMMETRIC) || + (pPort->PFlowCtrlMode == SK_FLOW_MODE_SYM_OR_REM)) { + epause->tx_pause = 1; + epause->rx_pause = 1; + } + + if ((epause->rx_pause == 0) && (epause->tx_pause == 0)) { + epause->autoneg = SK_FALSE; + } else { + epause->autoneg = SK_TRUE; + } +} +#endif + +#ifdef ETHTOOL_SPAUSEPARAM +/***************************************************************************** + * + * setPauseParams - configures the pause parameters of an adapter + * + * Description: + * This function sets the Rx or Tx pause parameters + * + * Returns: + * ==0: everything fine, no error + * !=0: the return value is the error code of the failure + */ +static int setPauseParams( +SK_AC *pAC, /* pointer to adapter control context */ +int port, /* the port of the selected adapter */ +struct ethtool_pauseparam *epause) /* pause parameter struct with params */ +{ + SK_GEPORT *pPort = &pAC->GIni.GP[port]; + DEV_NET *pNet = (DEV_NET *) pAC->dev[port]->priv; + int PrevSpeedVal = pPort->PLinkSpeedUsed; + + SK_U32 Instance; + char Buf[4]; + int Ret; + SK_BOOL prevAutonegValue = SK_TRUE; + int prevTxPause = 0; + int prevRxPause = 0; + unsigned int Len = 1; + + if (port == 0) { + Instance = (pAC->RlmtNets == 2) ? 1 : 2; + } else { + Instance = (pAC->RlmtNets == 2) ? 2 : 3; + } + + /* + ** we have to determine the current settings to see if + ** the operator requested any modification of the flow + ** control parameters... + */ + if (pPort->PFlowCtrlMode == SK_FLOW_MODE_LOC_SEND) { + prevTxPause = 1; + } + if ((pPort->PFlowCtrlMode == SK_FLOW_MODE_SYMMETRIC) || + (pPort->PFlowCtrlMode == SK_FLOW_MODE_SYM_OR_REM)) { + prevTxPause = 1; + prevRxPause = 1; + } + + if ((prevRxPause == 0) && (prevTxPause == 0)) { + prevAutonegValue = SK_FALSE; + } + + + /* + ** perform modifications regarding the changes + ** requested by the operator + */ + if (epause->autoneg != prevAutonegValue) { + if (epause->autoneg == AUTONEG_DISABLE) { + *Buf = (char) SK_FLOW_MODE_NONE; + } else { + *Buf = (char) SK_FLOW_MODE_SYMMETRIC; + } + } else { + if(epause->rx_pause && epause->tx_pause) { + *Buf = (char) SK_FLOW_MODE_SYMMETRIC; + } else if (epause->rx_pause && !epause->tx_pause) { + *Buf = (char) SK_FLOW_MODE_SYM_OR_REM; + } else if(!epause->rx_pause && epause->tx_pause) { + *Buf = (char) SK_FLOW_MODE_LOC_SEND; + } else { + *Buf = (char) SK_FLOW_MODE_NONE; + } + } + + Ret = SkPnmiSetVar(pAC, pAC->IoBase, OID_SKGE_FLOWCTRL_MODE, + &Buf, &Len, Instance, pNet->NetNr); + + if (Ret != SK_PNMI_ERR_OK) { + SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_CTRL, + ("ethtool (sk98lin): error changing rx/tx pause (%i)\n", Ret)); + } else { + Len = 1; /* set buffer length to correct value */ + } + + /* + ** It may be that autoneg has been disabled! Therefore + ** set the speed to the previously used value... + */ + *Buf = (char) PrevSpeedVal; + + Ret = SkPnmiSetVar(pAC, pAC->IoBase, OID_SKGE_SPEED_MODE, + &Buf, &Len, Instance, pNet->NetNr); + + if (Ret != SK_PNMI_ERR_OK) { + SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_CTRL, + ("ethtool (sk98lin): error setting speed (%i)\n", Ret)); + } + return 0; +} +#endif + +#ifdef ETHTOOL_GCOALESCE +/***************************************************************************** + * + * getModerationParams - retrieves the IRQ moderation settings + * + * Description: + * All current IRQ moderation settings of a selected adapter are placed + * in the passed ethtool_coalesce structure and are returned. + * + * Returns: N/A + * + */ +static void getModerationParams( +SK_AC *pAC, /* pointer to adapter control context */ +int port, /* the port of the selected adapter */ +struct ethtool_coalesce *ecoalesc) /* IRQ moderation struct for results */ +{ + DIM_INFO *Info = &pAC->DynIrqModInfo; + SK_BOOL UseTxIrqModeration = SK_FALSE; + SK_BOOL UseRxIrqModeration = SK_FALSE; + + if (Info->IntModTypeSelect != C_INT_MOD_NONE) { + if (CHIP_ID_YUKON_2(pAC)) { + UseRxIrqModeration = SK_TRUE; + UseTxIrqModeration = SK_TRUE; + } else { + if ((Info->MaskIrqModeration == IRQ_MASK_RX_ONLY) || + (Info->MaskIrqModeration == IRQ_MASK_SP_RX) || + (Info->MaskIrqModeration == IRQ_MASK_RX_TX_SP)) { + UseRxIrqModeration = SK_TRUE; + } + if ((Info->MaskIrqModeration == IRQ_MASK_TX_ONLY) || + (Info->MaskIrqModeration == IRQ_MASK_SP_TX) || + (Info->MaskIrqModeration == IRQ_MASK_RX_TX_SP)) { + UseTxIrqModeration = SK_TRUE; + } + } + + if (UseRxIrqModeration) { + ecoalesc->rx_coalesce_usecs = 1000000 / Info->MaxModIntsPerSec; + } + if (UseTxIrqModeration) { + ecoalesc->tx_coalesce_usecs = 1000000 / Info->MaxModIntsPerSec; + } + if (Info->IntModTypeSelect == C_INT_MOD_DYNAMIC) { + ecoalesc->rate_sample_interval = Info->DynIrqModSampleInterval; + if (UseRxIrqModeration) { + ecoalesc->use_adaptive_rx_coalesce = 1; + ecoalesc->rx_coalesce_usecs_low = + 1000000 / Info->MaxModIntsPerSecLowerLimit; + ecoalesc->rx_coalesce_usecs_high = + 1000000 / Info->MaxModIntsPerSecUpperLimit; + } + if (UseTxIrqModeration) { + ecoalesc->use_adaptive_tx_coalesce = 1; + ecoalesc->tx_coalesce_usecs_low = + 1000000 / Info->MaxModIntsPerSecLowerLimit; + ecoalesc->tx_coalesce_usecs_high = + 1000000 / Info->MaxModIntsPerSecUpperLimit; + } + } + } +} +#endif + +#ifdef ETHTOOL_SCOALESCE +/***************************************************************************** + * + * setModerationParams - configures the IRQ moderation of an adapter + * + * Description: + * Depending on the desired IRQ moderation parameters, either a) static, + * b) dynamic or c) no moderation is configured. + * + * Returns: + * ==0: everything fine, no error + * !=0: the return value is the error code of the failure + * + * Notes: + * The supported timeframe for the coalesced interrupts ranges from + * 33.333us (30 IntsPerSec) down to 25us (40.000 IntsPerSec). + * Any requested value that is not in this range will abort the request! + */ +static int setModerationParams( +SK_AC *pAC, /* pointer to adapter control context */ +int port, /* the port of the selected adapter */ +struct ethtool_coalesce *ecoalesc) /* IRQ moderation struct with params */ +{ + DIM_INFO *Info = &pAC->DynIrqModInfo; + int PrevModeration = Info->IntModTypeSelect; + + Info->IntModTypeSelect = C_INT_MOD_NONE; /* initial default */ + + if ((ecoalesc->rx_coalesce_usecs) || (ecoalesc->tx_coalesce_usecs)) { + if (ecoalesc->rx_coalesce_usecs) { + if ((ecoalesc->rx_coalesce_usecs < 25) || + (ecoalesc->rx_coalesce_usecs > 33333)) { + return -EINVAL; + } + } + if (ecoalesc->tx_coalesce_usecs) { + if ((ecoalesc->tx_coalesce_usecs < 25) || + (ecoalesc->tx_coalesce_usecs > 33333)) { + return -EINVAL; + } + } + if (!CHIP_ID_YUKON_2(pAC)) { + if ((Info->MaskIrqModeration == IRQ_MASK_SP_RX) || + (Info->MaskIrqModeration == IRQ_MASK_SP_TX) || + (Info->MaskIrqModeration == IRQ_MASK_RX_TX_SP)) { + Info->MaskIrqModeration = IRQ_MASK_SP_ONLY; + } + } + Info->IntModTypeSelect = C_INT_MOD_STATIC; + if (ecoalesc->rx_coalesce_usecs) { + Info->MaxModIntsPerSec = + 1000000 / ecoalesc->rx_coalesce_usecs; + if (!CHIP_ID_YUKON_2(pAC)) { + if (Info->MaskIrqModeration == IRQ_MASK_TX_ONLY) { + Info->MaskIrqModeration = IRQ_MASK_TX_RX; + } + if (Info->MaskIrqModeration == IRQ_MASK_SP_ONLY) { + Info->MaskIrqModeration = IRQ_MASK_SP_RX; + } + if (Info->MaskIrqModeration == IRQ_MASK_SP_TX) { + Info->MaskIrqModeration = IRQ_MASK_RX_TX_SP; + } + } else { + Info->MaskIrqModeration = Y2_IRQ_MASK; + } + } + if (ecoalesc->tx_coalesce_usecs) { + Info->MaxModIntsPerSec = + 1000000 / ecoalesc->tx_coalesce_usecs; + if (!CHIP_ID_YUKON_2(pAC)) { + if (Info->MaskIrqModeration == IRQ_MASK_RX_ONLY) { + Info->MaskIrqModeration = IRQ_MASK_TX_RX; + } + if (Info->MaskIrqModeration == IRQ_MASK_SP_ONLY) { + Info->MaskIrqModeration = IRQ_MASK_SP_TX; + } + if (Info->MaskIrqModeration == IRQ_MASK_SP_RX) { + Info->MaskIrqModeration = IRQ_MASK_RX_TX_SP; + } + } else { + Info->MaskIrqModeration = Y2_IRQ_MASK; + } + } + } + if ((ecoalesc->rate_sample_interval) || + (ecoalesc->rx_coalesce_usecs_low) || + (ecoalesc->tx_coalesce_usecs_low) || + (ecoalesc->rx_coalesce_usecs_high)|| + (ecoalesc->tx_coalesce_usecs_high)) { + if (ecoalesc->rate_sample_interval) { + if ((ecoalesc->rate_sample_interval < 1) || + (ecoalesc->rate_sample_interval > 10)) { + return -EINVAL; + } + } + if (ecoalesc->rx_coalesce_usecs_low) { + if ((ecoalesc->rx_coalesce_usecs_low < 25) || + (ecoalesc->rx_coalesce_usecs_low > 33333)) { + return -EINVAL; + } + } + if (ecoalesc->rx_coalesce_usecs_high) { + if ((ecoalesc->rx_coalesce_usecs_high < 25) || + (ecoalesc->rx_coalesce_usecs_high > 33333)) { + return -EINVAL; + } + } + if (ecoalesc->tx_coalesce_usecs_low) { + if ((ecoalesc->tx_coalesce_usecs_low < 25) || + (ecoalesc->tx_coalesce_usecs_low > 33333)) { + return -EINVAL; + } + } + if (ecoalesc->tx_coalesce_usecs_high) { + if ((ecoalesc->tx_coalesce_usecs_high < 25) || + (ecoalesc->tx_coalesce_usecs_high > 33333)) { + return -EINVAL; + } + } + + Info->IntModTypeSelect = C_INT_MOD_DYNAMIC; + if (ecoalesc->rate_sample_interval) { + Info->DynIrqModSampleInterval = + ecoalesc->rate_sample_interval; + } + if (ecoalesc->rx_coalesce_usecs_low) { + Info->MaxModIntsPerSecLowerLimit = + 1000000 / ecoalesc->rx_coalesce_usecs_low; + } + if (ecoalesc->tx_coalesce_usecs_low) { + Info->MaxModIntsPerSecLowerLimit = + 1000000 / ecoalesc->tx_coalesce_usecs_low; + } + if (ecoalesc->rx_coalesce_usecs_high) { + Info->MaxModIntsPerSecUpperLimit = + 1000000 / ecoalesc->rx_coalesce_usecs_high; + } + if (ecoalesc->tx_coalesce_usecs_high) { + Info->MaxModIntsPerSecUpperLimit = + 1000000 / ecoalesc->tx_coalesce_usecs_high; + } + } + + if ((PrevModeration == C_INT_MOD_NONE) && + (Info->IntModTypeSelect != C_INT_MOD_NONE)) { + SkDimEnableModerationIfNeeded(pAC); + } + if (PrevModeration != C_INT_MOD_NONE) { + SkDimDisableModeration(pAC, PrevModeration); + if (Info->IntModTypeSelect != C_INT_MOD_NONE) { + SkDimEnableModerationIfNeeded(pAC); + } + } + + return 0; +} +#endif + +#ifdef ETHTOOL_GWOL +/***************************************************************************** + * + * getWOLsettings - retrieves the WOL settings of the selected adapter + * + * Description: + * All current WOL settings of a selected adapter are placed in the + * passed ethtool_wolinfo structure and are returned to the caller. + * + * Returns: N/A + * + */ +static void getWOLsettings( +SK_AC *pAC, /* pointer to adapter control context */ +int port, /* the port of the selected adapter */ +struct ethtool_wolinfo *ewol) /* mandatory WOL structure for results */ +{ + ewol->supported = pAC->WolInfo.SupportedWolOptions; + ewol->wolopts = pAC->WolInfo.ConfiguredWolOptions; + + return; +} +#endif + +#ifdef ETHTOOL_SWOL +/***************************************************************************** + * + * setWOLsettings - configures the WOL settings of a selected adapter + * + * Description: + * The WOL settings of a selected adapter are configured regarding + * the parameters in the passed ethtool_wolinfo structure. + * Note that currently only wake on magic packet is supported! + * + * Returns: + * ==0: everything fine, no error + * !=0: the return value is the error code of the failure + */ +static int setWOLsettings( +SK_AC *pAC, /* pointer to adapter control context */ +int port, /* the port of the selected adapter */ +struct ethtool_wolinfo *ewol) /* WOL structure containing settings */ +{ + if (((ewol->wolopts & WAKE_MAGIC) == WAKE_MAGIC) || (ewol->wolopts == 0)) { + pAC->WolInfo.ConfiguredWolOptions = ewol->wolopts; + return 0; + } + return -EFAULT; +} +#endif + +#ifdef ETHTOOL_GDRVINFO +/***************************************************************************** + * + * getDriverInfo - returns generic driver and adapter information + * + * Description: + * Generic driver information is returned via this function, such as + * the name of the driver, its version and and firmware version. + * In addition to this, the location of the selected adapter is + * returned as a bus info string (e.g. '01:05.0'). + * + * Returns: N/A + * + */ +static void getDriverInfo( +SK_AC *pAC, /* pointer to adapter control context */ +int port, /* the port of the selected adapter */ +struct ethtool_drvinfo *edrvinfo) /* mandatory info structure for results */ +{ + char versionString[32]; + + snprintf(versionString, 32, "%s (%s)", VER_STRING, PATCHLEVEL); + strncpy(edrvinfo->driver, DRIVER_FILE_NAME , 32); + strncpy(edrvinfo->version, versionString , 32); + strncpy(edrvinfo->fw_version, "N/A", 32); + strncpy(edrvinfo->bus_info, pAC->PciDev->slot_name, 32); + +#ifdef ETHTOOL_GSTATS + edrvinfo->n_stats = SK98LIN_STATS_LEN; +#endif +} +#endif + +#ifdef ETHTOOL_PHYS_ID +/***************************************************************************** + * + * startLocateNIC - start the locate NIC feature of the elected adapter + * + * Description: + * This function is used if the user want to locate a particular NIC. + * All LEDs are regularly switched on and off, so the NIC can easily + * be identified. + * + * Returns: + * ==0: everything fine, no error, locateNIC test was started + * !=0: one locateNIC test runs already + * + */ +static int startLocateNIC( +SK_AC *pAC, /* pointer to adapter control context */ +int port, /* the port of the selected adapter */ +struct ethtool_value *blinkSecs) /* how long the LEDs should blink in seconds */ +{ + struct SK_NET_DEVICE *pDev = pAC->dev[port]; + int OtherPort = (port) ? 0 : 1; + struct SK_NET_DEVICE *pOtherDev = pAC->dev[OtherPort]; + + if (isLocateNICrunning) { + return -EFAULT; + } + isLocateNICrunning = SK_TRUE; + currentPortIndex = port; + isDualNetCard = (pDev != pOtherDev) ? SK_TRUE : SK_FALSE; + + if (netif_running(pAC->dev[port])) { + boardWasDown[0] = SK_FALSE; + } else { + (*pDev->open)(pDev); + boardWasDown[0] = SK_TRUE; + } + + if (isDualNetCard) { + if (netif_running(pAC->dev[OtherPort])) { + boardWasDown[1] = SK_FALSE; + } else { + (*pOtherDev->open)(pOtherDev); + boardWasDown[1] = SK_TRUE; + } + } + + if ((blinkSecs->data < 1) || (blinkSecs->data > 30)) { + blinkSecs->data = 3; /* three seconds default */ + } + nbrBlinkQuarterSeconds = 4*blinkSecs->data; + + init_timer(&locateNICtimer); + locateNICtimer.function = toggleLeds; + locateNICtimer.data = (unsigned long) pAC; + locateNICtimer.expires = jiffies + HZ; /* initially 1sec */ + add_timer(&locateNICtimer); + + return 0; +} + +/***************************************************************************** + * + * toggleLeds - Changes the LED state of an adapter + * + * Description: + * This function changes the current state of all LEDs of an adapter so + * that it can be located by a user. If the requested time interval for + * this test has elapsed, this function cleans up everything that was + * temporarily setup during the locate NIC test. This involves of course + * also closing or opening any adapter so that the initial board state + * is recovered. + * + * Returns: N/A + * + */ +static void toggleLeds( +unsigned long ptr) /* holds the pointer to adapter control context */ +{ + SK_AC *pAC = (SK_AC *) ptr; + int port = currentPortIndex; + SK_IOC IoC = pAC->IoBase; + struct SK_NET_DEVICE *pDev = pAC->dev[port]; + int OtherPort = (port) ? 0 : 1; + struct SK_NET_DEVICE *pOtherDev = pAC->dev[OtherPort]; + + SK_U16 YukLedOn = (PHY_M_LED_MO_DUP(MO_LED_ON) | + PHY_M_LED_MO_10(MO_LED_ON) | + PHY_M_LED_MO_100(MO_LED_ON) | + PHY_M_LED_MO_1000(MO_LED_ON) | + PHY_M_LED_MO_RX(MO_LED_ON)); + SK_U16 YukLedOff = (PHY_M_LED_MO_DUP(MO_LED_OFF) | + PHY_M_LED_MO_10(MO_LED_OFF) | + PHY_M_LED_MO_100(MO_LED_OFF) | + PHY_M_LED_MO_1000(MO_LED_OFF) | + PHY_M_LED_MO_RX(MO_LED_OFF)); + + nbrBlinkQuarterSeconds--; + if (nbrBlinkQuarterSeconds <= 0) { + (*pDev->stop)(pDev); + if (isDualNetCard) { + (*pOtherDev->stop)(pOtherDev); + } + + if (!boardWasDown[0]) { + (*pDev->open)(pDev); + } + if (isDualNetCard) { + (*pOtherDev->open)(pOtherDev); + } + isDualNetCard = SK_FALSE; + isLocateNICrunning = SK_FALSE; + return; + } + + doSwitchLEDsOn = (doSwitchLEDsOn) ? SK_FALSE : SK_TRUE; + if (doSwitchLEDsOn) { + if (pAC->GIni.GIGenesis) { + SK_OUT8(IoC,MR_ADDR(port,LNK_LED_REG),(SK_U8)SK_LNK_ON); + SkGeYellowLED(pAC,IoC,LED_ON >> 1); + SkGeXmitLED(pAC,IoC,MR_ADDR(port,RX_LED_INI),SK_LED_TST); + if (pAC->GIni.GP[port].PhyType == SK_PHY_BCOM) { + SkXmPhyWrite(pAC,IoC,port,PHY_BCOM_P_EXT_CTRL,PHY_B_PEC_LED_ON); + } else if (pAC->GIni.GP[port].PhyType == SK_PHY_LONE) { + SkXmPhyWrite(pAC,IoC,port,PHY_LONE_LED_CFG,0x0800); + } else { + SkGeXmitLED(pAC,IoC,MR_ADDR(port,TX_LED_INI),SK_LED_TST); + } + } else { + SkGmPhyWrite(pAC,IoC,port,PHY_MARV_LED_CTRL,0); + SkGmPhyWrite(pAC,IoC,port,PHY_MARV_LED_OVER,YukLedOn); + } + } else { + if (pAC->GIni.GIGenesis) { + SK_OUT8(IoC,MR_ADDR(port,LNK_LED_REG),(SK_U8)SK_LNK_OFF); + SkGeYellowLED(pAC,IoC,LED_OFF >> 1); + SkGeXmitLED(pAC,IoC,MR_ADDR(port,RX_LED_INI),SK_LED_DIS); + if (pAC->GIni.GP[port].PhyType == SK_PHY_BCOM) { + SkXmPhyWrite(pAC,IoC,port,PHY_BCOM_P_EXT_CTRL,PHY_B_PEC_LED_OFF); + } else if (pAC->GIni.GP[port].PhyType == SK_PHY_LONE) { + SkXmPhyWrite(pAC,IoC,port,PHY_LONE_LED_CFG,PHY_L_LC_LEDT); + } else { + SkGeXmitLED(pAC,IoC,MR_ADDR(port,TX_LED_INI),SK_LED_DIS); + } + } else { + SkGmPhyWrite(pAC,IoC,port,PHY_MARV_LED_CTRL,0); + SkGmPhyWrite(pAC,IoC,port,PHY_MARV_LED_OVER,YukLedOff); + } + } + + locateNICtimer.function = toggleLeds; + locateNICtimer.data = (unsigned long) pAC; + locateNICtimer.expires = jiffies + (HZ/4); /* 250ms */ + add_timer(&locateNICtimer); +} +#endif + +/***************************************************************************** + * + * getPortNumber - evaluates the port number of an interface + * + * Description: + * It may be that the current interface refers to one which is located + * on a dual net adapter. Hence, this function will return the correct + * port for further use. + * + * Returns: + * the port number that corresponds to the selected adapter + * + */ +static int getPortNumber( +struct net_device *netdev, /* the pointer to netdev structure */ +struct ifreq *ifr) /* what interface the request refers to? */ +{ + DEV_NET *pNet = (DEV_NET*) netdev->priv; + SK_AC *pAC = pNet->pAC; + + if (pAC->dev[1] != pAC->dev[0]) { + if (!strcmp(pAC->dev[1]->name, ifr->ifr_name)) { + return 1; /* port index 1 */ + } + } + return 0; +} + +/******************************************************************************* + * + * End of file + * + ******************************************************************************/ diff -urN linux-2.4.32-600/drivers/net/sk98lin/skge.c linux-2.4.32-600-sk98_831/drivers/net/sk98lin/skge.c --- linux-2.4.32-600/drivers/net/sk98lin/skge.c Sun Feb 26 11:11:31 2006 +++ linux-2.4.32-600-sk98_831/drivers/net/sk98lin/skge.c Sun Feb 26 11:13:02 2006 @@ -1,32 +1,26 @@ /****************************************************************************** * - * Name: skge.c - * Project: GEnesis, PCI Gigabit Ethernet Adapter - * Version: $Revision: 1.43 $ - * Date: $Date: 2004/01/29 15:47:07 $ - * Purpose: The main driver source module + * Name: skge.c + * Project: GEnesis, PCI Gigabit Ethernet Adapter + * Version: $Revision: 1.60.2.68 $ + * Date: $Date: 2005/11/14 15:22:08 $ + * Purpose: The main driver source module * ******************************************************************************/ /****************************************************************************** * * (C)Copyright 1998-2002 SysKonnect GmbH. - * (C)Copyright 2002-2003 Marvell. + * (C)Copyright 2002-2005 Marvell. * * Driver for Marvell Yukon chipset and SysKonnect Gigabit Ethernet * Server Adapters. * - * Created 10-Feb-1999, based on Linux' acenic.c, 3c59x.c and - * SysKonnects GEnesis Solaris driver - * Author: Christoph Goos (cgoos@syskonnect.de) - * Mirko Lindner (mlindner@syskonnect.de) + * Author: Mirko Lindner (mlindner@syskonnect.de) + * Ralph Roesler (rroesler@syskonnect.de) * * Address all question to: linux@syskonnect.de * - * The technical manual for the adapters is available from SysKonnect's - * web pages: www.syskonnect.com - * Goto "Support" and search Knowledge Base for "manual". - * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or @@ -38,71 +32,33 @@ /****************************************************************************** * - * Possible compiler options (#define xxx / -Dxxx): - * - * debugging can be enable by changing SK_DEBUG_CHKMOD and - * SK_DEBUG_CHKCAT in makefile (described there). - * - ******************************************************************************/ - -/****************************************************************************** - * * Description: * - * This is the main module of the Linux GE driver. - * - * All source files except skge.c, skdrv1st.h, skdrv2nd.h and sktypes.h - * are part of SysKonnect's COMMON MODULES for the SK-98xx adapters. - * Those are used for drivers on multiple OS', so some thing may seem - * unnecessary complicated on Linux. Please do not try to 'clean up' - * them without VERY good reasons, because this will make it more - * difficult to keep the Linux driver in synchronisation with the - * other versions. - * - * Include file hierarchy: - * - * - * - * "h/skdrv1st.h" - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * those three depending on kernel version used: - * - * - * - * - * - * "h/skerror.h" - * "h/skdebug.h" - * "h/sktypes.h" - * "h/lm80.h" - * "h/xmac_ii.h" - * - * "h/skdrv2nd.h" - * "h/skqueue.h" - * "h/skgehwt.h" - * "h/sktimer.h" - * "h/ski2c.h" - * "h/skgepnmi.h" - * "h/skvpd.h" - * "h/skgehw.h" - * "h/skgeinit.h" - * "h/skaddr.h" - * "h/skgesirq.h" - * "h/skcsum.h" - * "h/skrlmt.h" + * All source files in this sk98lin directory except of the sk98lin + * Linux specific files + * + * - skdim.c + * - skethtool.c + * - skge.c + * - skproc.c + * - sky2.c + * - Makefile + * - h/skdrv1st.h + * - h/skdrv2nd.h + * - h/sktypes.h + * - h/skversion.h + * + * are part of SysKonnect's common modules for the SK-9xxx adapters. + * + * Those common module files which are not Linux specific are used to + * build drivers on different OS' (e.g. Windows, MAC OS) so that those + * drivers are based on the same set of files + * + * At a first glance, this seems to complicate things unnescessarily on + * Linux, but please do not try to 'clean up' them without VERY good + * reasons, because this will make it more difficult to keep the sk98lin + * driver for Linux in synchronisation with the other drivers running on + * other operating systems. * ******************************************************************************/ @@ -110,6 +66,7 @@ #include #include +#include #ifdef CONFIG_PROC_FS #include @@ -118,6 +75,10 @@ #include "h/skdrv1st.h" #include "h/skdrv2nd.h" +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,9) +#include +#endif + /******************************************************************************* * * Defines @@ -127,62 +88,14 @@ /* for debuging on x86 only */ /* #define BREAKPOINT() asm(" int $3"); */ -/* use the transmit hw checksum driver functionality */ -#define USE_SK_TX_CHECKSUM - -/* use the receive hw checksum driver functionality */ -#define USE_SK_RX_CHECKSUM - -/* use the scatter-gather functionality with sendfile() */ -#define SK_ZEROCOPY - -/* use of a transmit complete interrupt */ -#define USE_TX_COMPLETE - -/* - * threshold for copying small receive frames - * set to 0 to avoid copying, set to 9001 to copy all frames - */ -#define SK_COPY_THRESHOLD 50 - -/* number of adapters that can be configured via command line params */ -#define SK_MAX_CARD_PARAM 16 - - - -/* - * use those defines for a compile-in version of the driver instead - * of command line parameters - */ -// #define LINK_SPEED_A {"Auto", } -// #define LINK_SPEED_B {"Auto", } -// #define AUTO_NEG_A {"Sense", } -// #define AUTO_NEG_B {"Sense", } -// #define DUP_CAP_A {"Both", } -// #define DUP_CAP_B {"Both", } -// #define FLOW_CTRL_A {"SymOrRem", } -// #define FLOW_CTRL_B {"SymOrRem", } -// #define ROLE_A {"Auto", } -// #define ROLE_B {"Auto", } -// #define PREF_PORT {"A", } -// #define CON_TYPE {"Auto", } -// #define RLMT_MODE {"CheckLinkState", } - -#define DEV_KFREE_SKB(skb) dev_kfree_skb(skb) -#define DEV_KFREE_SKB_IRQ(skb) dev_kfree_skb_irq(skb) -#define DEV_KFREE_SKB_ANY(skb) dev_kfree_skb_any(skb) - /* Set blink mode*/ #define OEM_CONFIG_VALUE ( SK_ACT_LED_BLINK | \ SK_DUP_LED_NORMAL | \ SK_LED_LINK100_ON) - -/* Isr return value */ -#define SkIsrRetVar void -#define SkIsrRetNone NULL -#define SkIsrRetHandled NULL +#define CLEAR_AND_START_RX(Port) SK_OUT8(pAC->IoBase, RxQueueAddr[(Port)]+Q_CSR, CSR_START | CSR_IRQ_CL_F) +#define CLEAR_TX_IRQ(Port,Prio) SK_OUT8(pAC->IoBase, TxQueueAddr[(Port)][(Prio)]+Q_CSR, CSR_IRQ_CL_F) /******************************************************************************* @@ -191,12 +104,25 @@ * ******************************************************************************/ +static int __devinit sk98lin_init_device(struct pci_dev *pdev, const struct pci_device_id *ent); +static void sk98lin_remove_device(struct pci_dev *pdev); +#ifdef CONFIG_PM +static int sk98lin_suspend(struct pci_dev *pdev, u32 state); +static int sk98lin_resume(struct pci_dev *pdev); +static void SkEnableWOMagicPacket(SK_AC *pAC, SK_IOC IoC, SK_MAC_ADDR MacAddr); +#endif +#ifdef Y2_RECOVERY +static void SkGeHandleKernelTimer(unsigned long ptr); +void SkGeCheckTimer(DEV_NET *pNet); +static SK_BOOL CheckRXCounters(DEV_NET *pNet); +static void CheckRxPath(DEV_NET *pNet); +#endif static void FreeResources(struct SK_NET_DEVICE *dev); static int SkGeBoardInit(struct SK_NET_DEVICE *dev, SK_AC *pAC); static SK_BOOL BoardAllocMem(SK_AC *pAC); static void BoardFreeMem(SK_AC *pAC); static void BoardInitMem(SK_AC *pAC); -static void SetupRing(SK_AC*, void*, uintptr_t, RXD**, RXD**, RXD**, int*, SK_BOOL); +static void SetupRing(SK_AC*, void*, uintptr_t, RXD**, RXD**, RXD**, int*, int*, SK_BOOL); static SkIsrRetVar SkGeIsr(int irq, void *dev_id, struct pt_regs *ptregs); static SkIsrRetVar SkGeIsrOnePort(int irq, void *dev_id, struct pt_regs *ptregs); static int SkGeOpen(struct SK_NET_DEVICE *dev); @@ -212,24 +138,37 @@ static void FreeTxDescriptors(SK_AC*pAC, TX_PORT*); static void FillRxRing(SK_AC*, RX_PORT*); static SK_BOOL FillRxDescriptor(SK_AC*, RX_PORT*); +#ifdef CONFIG_SK98LIN_NAPI +static int SkGePoll(struct net_device *dev, int *budget); +static void ReceiveIrq(SK_AC*, RX_PORT*, SK_BOOL, int*, int); +#else static void ReceiveIrq(SK_AC*, RX_PORT*, SK_BOOL); -static void ClearAndStartRx(SK_AC*, int); -static void ClearTxIrq(SK_AC*, int, int); +#endif +#ifdef SK_POLL_CONTROLLER +static void SkGeNetPoll(struct SK_NET_DEVICE *dev); +#endif static void ClearRxRing(SK_AC*, RX_PORT*); static void ClearTxRing(SK_AC*, TX_PORT*); static int SkGeChangeMtu(struct SK_NET_DEVICE *dev, int new_mtu); static void PortReInitBmu(SK_AC*, int); static int SkGeIocMib(DEV_NET*, unsigned int, int); static int SkGeInitPCI(SK_AC *pAC); -static void StartDrvCleanupTimer(SK_AC *pAC); -static void StopDrvCleanupTimer(SK_AC *pAC); -static int XmitFrameSG(SK_AC*, TX_PORT*, struct sk_buff*); - -#ifdef SK_DIAG_SUPPORT static SK_U32 ParseDeviceNbrFromSlotName(const char *SlotName); static int SkDrvInitAdapter(SK_AC *pAC, int devNbr); static int SkDrvDeInitAdapter(SK_AC *pAC, int devNbr); -#endif +extern void SkLocalEventQueue( SK_AC *pAC, + SK_U32 Class, + SK_U32 Event, + SK_U32 Param1, + SK_U32 Param2, + SK_BOOL Flag); +extern void SkLocalEventQueue64( SK_AC *pAC, + SK_U32 Class, + SK_U32 Event, + SK_U64 Param, + SK_BOOL Flag); + +static int XmitFrameSG(SK_AC*, TX_PORT*, struct sk_buff*); /******************************************************************************* * @@ -237,9 +176,31 @@ * ******************************************************************************/ +extern SK_BOOL SkY2AllocateResources(SK_AC *pAC); +extern void SkY2FreeResources(SK_AC *pAC); +extern void SkY2AllocateRxBuffers(SK_AC *pAC,SK_IOC IoC,int Port); +extern void SkY2FreeRxBuffers(SK_AC *pAC,SK_IOC IoC,int Port); +extern void SkY2FreeTxBuffers(SK_AC *pAC,SK_IOC IoC,int Port); +extern SkIsrRetVar SkY2Isr(int irq,void *dev_id,struct pt_regs *ptregs); +extern int SkY2Xmit(struct sk_buff *skb,struct SK_NET_DEVICE *dev); +extern void SkY2PortStop(SK_AC *pAC,SK_IOC IoC,int Port,int Dir,int RstMode); +extern void SkY2PortStart(SK_AC *pAC,SK_IOC IoC,int Port); +extern int SkY2RlmtSend(SK_AC *pAC,int PortNr,struct sk_buff *pMessage); +extern void SkY2RestartStatusUnit(SK_AC *pAC); +extern void FillReceiveTableYukon2(SK_AC *pAC,SK_IOC IoC,int Port); +#ifdef CONFIG_SK98LIN_NAPI +extern int SkY2Poll(struct net_device *dev, int *budget); +#endif + +extern void SkDimEnableModerationIfNeeded(SK_AC *pAC); +extern void SkDimStartModerationTimer(SK_AC *pAC); +extern void SkDimModerate(SK_AC *pAC); + +extern int SkEthIoctl(struct net_device *netdev, struct ifreq *ifr); + #ifdef CONFIG_PROC_FS static const char SK_Root_Dir_entry[] = "sk98lin"; -static struct proc_dir_entry *pSkRootDir = NULL; +static struct proc_dir_entry *pSkRootDir; extern int sk_proc_read( char *buffer, char **buffer_location, off_t offset, @@ -248,11 +209,6 @@ void *data); #endif -extern void SkDimEnableModerationIfNeeded(SK_AC *pAC); -extern void SkDimDisplayModerationSettings(SK_AC *pAC); -extern void SkDimStartModerationTimer(SK_AC *pAC); -extern void SkDimModerate(SK_AC *pAC); - #ifdef DEBUG static void DumpMsg(struct sk_buff*, char*); static void DumpData(char*, int); @@ -262,13 +218,12 @@ /* global variables *********************************************************/ static const char *BootString = BOOT_STRING; struct SK_NET_DEVICE *SkGeRootDev = NULL; -static int probed __initdata = 0; static SK_BOOL DoPrintInterfaceChange = SK_TRUE; /* local variables **********************************************************/ static uintptr_t TxQueueAddr[SK_MAX_MACS][2] = {{0x680, 0x600},{0x780, 0x700}}; static uintptr_t RxQueueAddr[SK_MAX_MACS] = {0x400, 0x480}; - +static int sk98lin_max_boards_found = 0; #ifdef CONFIG_PROC_FS static struct proc_dir_entry *pSkRootDir; @@ -276,271 +231,413 @@ +static struct pci_device_id sk98lin_pci_tbl[] __devinitdata = { +/* { pci_vendor_id, pci_device_id, * SAMPLE ENTRY! * + PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL }, */ + { 0x10b7, 0x1700, /* 3Com (10b7), Gigabit Ethernet Adapter */ + PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL }, + { 0x10b7, 0x80eb, /* 3Com (10b7), 3Com 3C940B Gigabit LOM Ethernet Adapter */ + PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL }, + { 0x1148, 0x4300, /* SysKonnect (1148), SK-98xx Gigabit Ethernet Server Adapter */ + PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL }, + { 0x1148, 0x4320, /* SysKonnect (1148), SK-98xx V2.0 Gigabit Ethernet Adapter */ + PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL }, + { 0x1148, 0x9000, /* SysKonnect (1148), SK-9Sxx 10/100/1000Base-T Server Adapter */ + PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL }, + { 0x1148, 0x9E00, /* SysKonnect (1148), SK-9Exx 10/100/1000Base-T Adapter */ + PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL }, + { 0x1186, 0x4b00, /* D-Link (1186), Gigabit Ethernet Adapter */ + PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL }, + { 0x1186, 0x4b01, /* D-Link (1186), Gigabit Ethernet Adapter */ + PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL }, + { 0x1186, 0x4c00, /* D-Link (1186), Gigabit Ethernet Adapter */ + PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL }, + { 0x11ab, 0x4320, /* Marvell (11ab), Gigabit Ethernet Controller */ + PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL }, + { 0x11ab, 0x4340, /* Marvell (11ab), Gigabit Ethernet Controller */ + PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL }, + { 0x11ab, 0x4341, /* Marvell (11ab), Gigabit Ethernet Controller */ + PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL }, + { 0x11ab, 0x4342, /* Marvell (11ab), Gigabit Ethernet Controller */ + PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL }, + { 0x11ab, 0x4343, /* Marvell (11ab), Gigabit Ethernet Controller */ + PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL }, + { 0x11ab, 0x4344, /* Marvell (11ab), Gigabit Ethernet Controller */ + PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL }, + { 0x11ab, 0x4345, /* Marvell (11ab), Gigabit Ethernet Controller */ + PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL }, + { 0x11ab, 0x4346, /* Marvell (11ab), Gigabit Ethernet Controller */ + PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL }, + { 0x11ab, 0x4347, /* Marvell (11ab), Gigabit Ethernet Controller */ + PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL }, + { 0x11ab, 0x4350, /* Marvell (11ab), Fast Ethernet Controller */ + PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL }, + { 0x11ab, 0x4351, /* Marvell (11ab), Fast Ethernet Controller */ + PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL }, + { 0x11ab, 0x4352, /* Marvell (11ab), Fast Ethernet Controller */ + PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL }, + { 0x11ab, 0x4360, /* Marvell (11ab), Gigabit Ethernet Controller */ + PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL }, + { 0x11ab, 0x4361, /* Marvell (11ab), Gigabit Ethernet Controller */ + PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL }, + { 0x11ab, 0x4362, /* Marvell (11ab), Gigabit Ethernet Controller */ + PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL }, + { 0x11ab, 0x4363, /* Marvell (11ab), Marvell */ + PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL }, + { 0x11ab, 0x5005, /* Marvell (11ab), Belkin */ + PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL }, + { 0x1371, 0x434e, /* CNet (1371), GigaCard Network Adapter */ + PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL }, + { 0x1737, 0x1032, /* Linksys (1737), Gigabit Network Adapter */ + PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL }, + { 0x1737, 0x1064, /* Linksys (1737), Gigabit Network Adapter */ + PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL }, + { 0, } +}; + +MODULE_DEVICE_TABLE(pci, sk98lin_pci_tbl); + +static struct pci_driver sk98lin_driver = { + .name = DRIVER_FILE_NAME, + .id_table = sk98lin_pci_tbl, + .probe = sk98lin_init_device, + .remove = __devexit_p(sk98lin_remove_device), +#ifdef CONFIG_PM + .suspend = sk98lin_suspend, + .resume = sk98lin_resume +#endif +}; + + /***************************************************************************** * - * skge_probe - find all SK-98xx adapters + * sk98lin_init_device - initialize the adapter * * Description: - * This function scans the PCI bus for SK-98xx adapters. Resources for - * each adapter are allocated and the adapter is brought into Init 1 + * This function initializes the adapter. Resources for + * the adapter are allocated and the adapter is brought into Init 1 * state. * * Returns: * 0, if everything is ok * !=0, on error */ -static int __init skge_probe (void) +static int __devinit sk98lin_init_device(struct pci_dev *pdev, + const struct pci_device_id *ent) + { - int boards_found = 0; - int vendor_flag = SK_FALSE; + static SK_BOOL sk98lin_boot_string = SK_FALSE; + static SK_BOOL sk98lin_proc_entry = SK_FALSE; + static int sk98lin_boards_found = 0; SK_AC *pAC; DEV_NET *pNet = NULL; - struct pci_dev *pdev = NULL; struct SK_NET_DEVICE *dev = NULL; - SK_BOOL DeviceFound = SK_FALSE; - SK_BOOL BootStringCount = SK_FALSE; int retval; #ifdef CONFIG_PROC_FS int proc_root_initialized = 0; struct proc_dir_entry *pProcFile; #endif + int pci_using_dac; - if (probed) - return -ENODEV; - probed++; - - if (!pci_present()) { /* is PCI support present? */ - return -ENODEV; + retval = pci_enable_device(pdev); + if (retval) { + printk(KERN_ERR "Cannot enable PCI device, " + "aborting.\n"); + return retval; } - while((pdev = pci_find_class(PCI_CLASS_NETWORK_ETHERNET << 8, pdev))) { + dev = NULL; + pNet = NULL; - dev = NULL; - pNet = NULL; + /* INSERT * We have to find the power-management capabilities */ + /* Find power-management capability. */ - SK_PCI_ISCOMPLIANT(vendor_flag, pdev); - if (!vendor_flag) - continue; + pci_using_dac = 0; /* Set 32 bit DMA per default */ + /* Configure DMA attributes. */ + retval = pci_set_dma_mask(pdev, (u64) 0xffffffffffffffffULL); + if (!retval) { + pci_using_dac = 1; + } else { + retval = pci_set_dma_mask(pdev, (u64) 0xffffffff); + if (retval) { + printk(KERN_ERR "No usable DMA configuration, " + "aborting.\n"); + return retval; + } + } - /* Configure DMA attributes. */ - if (pci_set_dma_mask(pdev, (u64) 0xffffffffffffffffULL) && - pci_set_dma_mask(pdev, (u64) 0xffffffff)) - continue; + if ((dev = init_etherdev(dev, sizeof(DEV_NET))) == NULL) { + printk(KERN_ERR "Unable to allocate etherdev " + "structure!\n"); + return -ENODEV; + } - if ((dev = init_etherdev(dev, sizeof(DEV_NET))) == NULL) { - printk(KERN_ERR "Unable to allocate etherdev " - "structure!\n"); - break; - } + pNet = dev->priv; + pNet->pAC = kmalloc(sizeof(SK_AC), GFP_KERNEL); + if (pNet->pAC == NULL){ + unregister_netdev(dev); + dev->get_stats = NULL; + kfree(dev->priv); + printk(KERN_ERR "Unable to allocate adapter " + "structure!\n"); + return -ENODEV; + } - pNet = dev->priv; - pNet->pAC = kmalloc(sizeof(SK_AC), GFP_KERNEL); - if (pNet->pAC == NULL){ - unregister_netdev(dev); - dev->get_stats = NULL; - kfree(dev->priv); - printk(KERN_ERR "Unable to allocate adapter " - "structure!\n"); - break; - } - /* Print message */ - if (!BootStringCount) { - /* set display flag to TRUE so that */ - /* we only display this string ONCE */ - BootStringCount = SK_TRUE; - printk("%s\n", BootString); - } + /* Print message */ + if (!sk98lin_boot_string) { + /* set display flag to TRUE so that */ + /* we only display this string ONCE */ + sk98lin_boot_string = SK_TRUE; + printk("%s\n", BootString); + } - memset(pNet->pAC, 0, sizeof(SK_AC)); - pAC = pNet->pAC; - pAC->PciDev = pdev; - pAC->PciDevId = pdev->device; - pAC->dev[0] = dev; - pAC->dev[1] = dev; - sprintf(pAC->Name, "SysKonnect SK-98xx"); - pAC->CheckQueue = SK_FALSE; + memset(pNet->pAC, 0, sizeof(SK_AC)); + pAC = pNet->pAC; + pAC->PciDev = pdev; + pAC->PciDevId = pdev->device; + pAC->dev[0] = dev; + pAC->dev[1] = dev; + sprintf(pAC->Name, "SysKonnect SK-98xx"); + pAC->CheckQueue = SK_FALSE; + + dev->irq = pdev->irq; + retval = SkGeInitPCI(pAC); + if (retval) { + printk("SKGE: PCI setup failed: %i\n", retval); + unregister_netdev(dev); + dev->get_stats = NULL; + kfree(dev); + return -ENODEV; + } - pNet->Mtu = 1500; - pNet->Up = 0; - dev->irq = pdev->irq; - retval = SkGeInitPCI(pAC); - if (retval) { - printk("SKGE: PCI setup failed: %i\n", retval); - unregister_netdev(dev); - dev->get_stats = NULL; - kfree(dev); - continue; - } - dev->open = &SkGeOpen; - dev->stop = &SkGeClose; + dev->open = &SkGeOpen; + dev->stop = &SkGeClose; + dev->get_stats = &SkGeStats; + dev->set_multicast_list = &SkGeSetRxMode; + dev->set_mac_address = &SkGeSetMacAddr; + dev->do_ioctl = &SkGeIoctl; + dev->change_mtu = &SkGeChangeMtu; + dev->flags &= ~IFF_RUNNING; +#ifdef SK_POLL_CONTROLLER + dev->poll_controller = SkGeNetPoll; +#endif + + pAC->Index = sk98lin_boards_found; + + if (SkGeBoardInit(dev, pAC)) { + unregister_netdev(dev); + kfree(dev); + return -ENODEV; + } else { + ProductStr(pAC); + } + + if (pci_using_dac) + dev->features |= NETIF_F_HIGHDMA; + + /* shifter to later moment in time... */ + if (CHIP_ID_YUKON_2(pAC)) { + dev->hard_start_xmit = &SkY2Xmit; +#ifdef CONFIG_SK98LIN_NAPI + dev->poll = &SkY2Poll; + dev->weight = 64; +#endif + } else { dev->hard_start_xmit = &SkGeXmit; - dev->get_stats = &SkGeStats; - dev->set_multicast_list = &SkGeSetRxMode; - dev->set_mac_address = &SkGeSetMacAddr; - dev->do_ioctl = &SkGeIoctl; - dev->change_mtu = &SkGeChangeMtu; - dev->flags &= ~IFF_RUNNING; +#ifdef CONFIG_SK98LIN_NAPI + dev->poll = &SkGePoll; + dev->weight = 64; +#endif + } -#ifdef SK_ZEROCOPY +#ifdef NETIF_F_TSO +#ifdef USE_SK_TSO_FEATURE + if ((CHIP_ID_YUKON_2(pAC)) && + (pAC->GIni.GIChipId != CHIP_ID_YUKON_EC_U)) { + dev->features |= NETIF_F_TSO; + } +#endif +#endif +#ifdef CONFIG_SK98LIN_ZEROCOPY + if (pAC->GIni.GIChipId != CHIP_ID_GENESIS) + dev->features |= NETIF_F_SG; +#endif #ifdef USE_SK_TX_CHECKSUM - - if (pAC->ChipsetType) { - /* Use only if yukon hardware */ - /* SK and ZEROCOPY - fly baby... */ - dev->features |= NETIF_F_SG | NETIF_F_IP_CSUM; - } + if (pAC->GIni.GIChipId != CHIP_ID_GENESIS) + dev->features |= NETIF_F_IP_CSUM; #endif +#ifdef USE_SK_RX_CHECKSUM + pAC->RxPort[0].UseRxCsum = SK_TRUE; + if (pAC->GIni.GIMacsFound == 2 ) { + pAC->RxPort[1].UseRxCsum = SK_TRUE; + } #endif - pAC->Index = boards_found; + /* Save the hardware revision */ + pAC->HWRevision = (((pAC->GIni.GIPciHwRev >> 4) & 0x0F)*10) + + (pAC->GIni.GIPciHwRev & 0x0F); - if (SkGeBoardInit(dev, pAC)) { - unregister_netdev(dev); - kfree(dev); - continue; - } + /* Set driver globals */ + pAC->Pnmi.pDriverFileName = DRIVER_FILE_NAME; + pAC->Pnmi.pDriverReleaseDate = DRIVER_REL_DATE; + + SK_MEMSET(&(pAC->PnmiBackup), 0, sizeof(SK_PNMI_STRUCT_DATA)); + SK_MEMCPY(&(pAC->PnmiBackup), &(pAC->PnmiStruct), + sizeof(SK_PNMI_STRUCT_DATA)); - /* Print adapter specific string from vpd */ - ProductStr(pAC); - printk("%s: %s\n", dev->name, pAC->DeviceStr); + /* Save initial device name */ + strcpy(pNet->InitialDevName, dev->name); - /* Print configuration settings */ - printk(" PrefPort:%c RlmtMode:%s\n", - 'A' + pAC->Rlmt.Net[0].Port[pAC->Rlmt.Net[0].PrefPort]->PortNumber, - (pAC->RlmtMode==0) ? "Check Link State" : - ((pAC->RlmtMode==1) ? "Check Link State" : - ((pAC->RlmtMode==3) ? "Check Local Port" : - ((pAC->RlmtMode==7) ? "Check Segmentation" : - ((pAC->RlmtMode==17) ? "Dual Check Link State" :"Error"))))); + /* Set network to off */ + netif_stop_queue(dev); + netif_carrier_off(dev); - SkGeYellowLED(pAC, pAC->IoBase, 1); + /* Print adapter specific string from vpd and config settings */ + printk("%s: %s\n", pNet->InitialDevName, pAC->DeviceStr); + printk(" PrefPort:%c RlmtMode:%s\n", + 'A' + pAC->Rlmt.Net[0].Port[pAC->Rlmt.Net[0].PrefPort]->PortNumber, + (pAC->RlmtMode==0) ? "Check Link State" : + ((pAC->RlmtMode==1) ? "Check Link State" : + ((pAC->RlmtMode==3) ? "Check Local Port" : + ((pAC->RlmtMode==7) ? "Check Segmentation" : + ((pAC->RlmtMode==17) ? "Dual Check Link State" :"Error"))))); + SkGeYellowLED(pAC, pAC->IoBase, 1); - memcpy((caddr_t) &dev->dev_addr, - (caddr_t) &pAC->Addr.Net[0].CurrentMacAddress, 6); + memcpy((caddr_t) &dev->dev_addr, + (caddr_t) &pAC->Addr.Net[0].CurrentMacAddress, 6); - /* First adapter... Create proc and print message */ + /* First adapter... Create proc and print message */ #ifdef CONFIG_PROC_FS - if (!DeviceFound) { - DeviceFound = SK_TRUE; - SK_MEMCPY(&SK_Root_Dir_entry, BootString, - sizeof(SK_Root_Dir_entry) - 1); - - /*Create proc (directory)*/ - if(!proc_root_initialized) { - pSkRootDir = create_proc_entry(SK_Root_Dir_entry, - S_IFDIR | S_IWUSR | S_IRUGO | S_IXUGO, proc_net); - pSkRootDir->owner = THIS_MODULE; - proc_root_initialized = 1; - } + if (!sk98lin_proc_entry) { + sk98lin_proc_entry = SK_TRUE; + SK_MEMCPY(&SK_Root_Dir_entry, BootString, + sizeof(SK_Root_Dir_entry) - 1); + + /*Create proc (directory)*/ + if(!proc_root_initialized) { + pSkRootDir = create_proc_entry(SK_Root_Dir_entry, + S_IFDIR | S_IRUGO | S_IXUGO, proc_net); + pSkRootDir->owner = THIS_MODULE; + proc_root_initialized = 1; } + } - /* Create proc file */ - pProcFile = create_proc_entry(dev->name, - S_IFREG | S_IXUSR | S_IWGRP | S_IROTH, - pSkRootDir); + /* Create proc file */ + pProcFile = create_proc_entry(dev->name, + S_IFREG | S_IRUSR | S_IRGRP | S_IROTH, + pSkRootDir); - pProcFile->read_proc = sk_proc_read; - pProcFile->write_proc = NULL; - pProcFile->nlink = 1; - pProcFile->size = sizeof(dev->name + 1); - pProcFile->data = (void *)pProcFile; - pProcFile->owner = THIS_MODULE; + pProcFile->read_proc = sk_proc_read; + pProcFile->write_proc = NULL; + pProcFile->nlink = 1; + pProcFile->size = sizeof(dev->name + 1); + pProcFile->data = (void *)pProcFile; + pProcFile->owner = THIS_MODULE; #endif - pNet->PortNr = 0; - pNet->NetNr = 0; - - boards_found++; + pNet->PortNr = 0; + pNet->NetNr = 0; - /* More then one port found */ - if ((pAC->GIni.GIMacsFound == 2 ) && (pAC->RlmtNets == 2)) { - if ((dev = init_etherdev(NULL, sizeof(DEV_NET))) == 0) { - printk(KERN_ERR "Unable to allocate etherdev " - "structure!\n"); - break; - } + sk98lin_boards_found++; + pci_set_drvdata(pdev, dev); - pAC->dev[1] = dev; - pNet = dev->priv; - pNet->PortNr = 1; - pNet->NetNr = 1; - pNet->pAC = pAC; - pNet->Mtu = 1500; - pNet->Up = 0; - - dev->open = &SkGeOpen; - dev->stop = &SkGeClose; - dev->hard_start_xmit = &SkGeXmit; - dev->get_stats = &SkGeStats; - dev->set_multicast_list = &SkGeSetRxMode; - dev->set_mac_address = &SkGeSetMacAddr; - dev->do_ioctl = &SkGeIoctl; - dev->change_mtu = &SkGeChangeMtu; - dev->flags &= ~IFF_RUNNING; + /* More then one port found */ + if ((pAC->GIni.GIMacsFound == 2 ) && (pAC->RlmtNets == 2)) { + if ((dev = init_etherdev(NULL, sizeof(DEV_NET))) == 0) { + printk(KERN_ERR "Unable to allocate etherdev " + "structure!\n"); + return -ENODEV; + } -#ifdef SK_ZEROCOPY -#ifdef USE_SK_TX_CHECKSUM - if (pAC->ChipsetType) { - /* SG and ZEROCOPY - fly baby... */ - dev->features |= NETIF_F_SG | NETIF_F_IP_CSUM; - } + pAC->dev[1] = dev; + pNet = dev->priv; + pNet->PortNr = 1; + pNet->NetNr = 1; + pNet->pAC = pAC; + + if (CHIP_ID_YUKON_2(pAC)) { + dev->hard_start_xmit = &SkY2Xmit; +#ifdef CONFIG_SK98LIN_NAPI + dev->poll = &SkY2Poll; + dev->weight = 64; #endif + } else { + dev->hard_start_xmit = &SkGeXmit; +#ifdef CONFIG_SK98LIN_NAPI + dev->poll = &SkGePoll; + dev->weight = 64; #endif - -#ifdef CONFIG_PROC_FS - pProcFile = create_proc_entry(dev->name, - S_IFREG | S_IXUSR | S_IWGRP | S_IROTH, - pSkRootDir); - pProcFile->read_proc = sk_proc_read; - pProcFile->write_proc = NULL; - pProcFile->nlink = 1; - pProcFile->size = sizeof(dev->name + 1); - pProcFile->data = (void *)pProcFile; - pProcFile->owner = THIS_MODULE; + } + dev->open = &SkGeOpen; + dev->stop = &SkGeClose; + dev->get_stats = &SkGeStats; + dev->set_multicast_list = &SkGeSetRxMode; + dev->set_mac_address = &SkGeSetMacAddr; + dev->do_ioctl = &SkGeIoctl; + dev->change_mtu = &SkGeChangeMtu; + dev->flags &= ~IFF_RUNNING; +#ifdef SK_POLL_CONTROLLER + dev->poll_controller = SkGeNetPoll; +#endif + +#ifdef NETIF_F_TSO +#ifdef USE_SK_TSO_FEATURE + if ((CHIP_ID_YUKON_2(pAC)) && + (pAC->GIni.GIChipId != CHIP_ID_YUKON_EC_U)) { + dev->features |= NETIF_F_TSO; + } +#endif +#endif +#ifdef CONFIG_SK98LIN_ZEROCOPY + /* Don't handle if Genesis chipset */ + if (pAC->GIni.GIChipId != CHIP_ID_GENESIS) + dev->features |= NETIF_F_SG; +#endif +#ifdef USE_SK_TX_CHECKSUM + /* Don't handle if Genesis chipset */ + if (pAC->GIni.GIChipId != CHIP_ID_GENESIS) + dev->features |= NETIF_F_IP_CSUM; #endif - memcpy((caddr_t) &dev->dev_addr, - (caddr_t) &pAC->Addr.Net[1].CurrentMacAddress, 6); - - printk("%s: %s\n", dev->name, pAC->DeviceStr); - printk(" PrefPort:B RlmtMode:Dual Check Link State\n"); - } - /* Save the hardware revision */ - pAC->HWRevision = (((pAC->GIni.GIPciHwRev >> 4) & 0x0F)*10) + - (pAC->GIni.GIPciHwRev & 0x0F); + /* Save initial device name */ + strcpy(pNet->InitialDevName, dev->name); - /* Set driver globals */ - pAC->Pnmi.pDriverFileName = DRIVER_FILE_NAME; - pAC->Pnmi.pDriverReleaseDate = DRIVER_REL_DATE; + /* Set network to off */ + netif_stop_queue(dev); + netif_carrier_off(dev); - SK_MEMSET(&(pAC->PnmiBackup), 0, sizeof(SK_PNMI_STRUCT_DATA)); - SK_MEMCPY(&(pAC->PnmiBackup), &(pAC->PnmiStruct), - sizeof(SK_PNMI_STRUCT_DATA)); - /* - * This is bollocks, but we need to tell the net-init - * code that it shall go for the next device. - */ -#ifndef MODULE - dev->base_addr = 0; +#ifdef CONFIG_PROC_FS + pProcFile = create_proc_entry(dev->name, + S_IFREG | S_IRUSR | S_IRGRP | S_IROTH, + pSkRootDir); + pProcFile->read_proc = sk_proc_read; + pProcFile->write_proc = NULL; + pProcFile->nlink = 1; + pProcFile->size = sizeof(dev->name + 1); + pProcFile->data = (void *)pProcFile; + pProcFile->owner = THIS_MODULE; #endif + + memcpy((caddr_t) &dev->dev_addr, + (caddr_t) &pAC->Addr.Net[1].CurrentMacAddress, 6); + + printk("%s: %s\n", pNet->InitialDevName, pAC->DeviceStr); + printk(" PrefPort:B RlmtMode:Dual Check Link State\n"); } - /* - * If we're at this point we're going through skge_probe() for - * the first time. Return success (0) if we've initialized 1 - * or more boards. Otherwise, return failure (-ENODEV). - */ + pAC->Index = sk98lin_boards_found; + sk98lin_max_boards_found = sk98lin_boards_found; + return 0; +} - return boards_found; -} /* skge_probe */ /***************************************************************************** @@ -566,7 +663,7 @@ dev->mem_start = pci_resource_start (pdev, 0); pci_set_master(pdev); - if (pci_request_regions(pdev, pAC->Name) != 0) { + if (pci_request_regions(pdev, DRIVER_FILE_NAME) != 0) { retval = 2; goto out_disable; } @@ -603,6 +700,455 @@ return retval; } +#ifdef Y2_RECOVERY +/***************************************************************************** + * + * SkGeHandleKernelTimer - Handle the kernel timer requests + * + * Description: + * If the requested time interval for the timer has elapsed, + * this function checks the link state. + * + * Returns: N/A + * + */ +static void SkGeHandleKernelTimer( +unsigned long ptr) /* holds the pointer to adapter control context */ +{ + DEV_NET *pNet = (DEV_NET*) ptr; + SkGeCheckTimer(pNet); +} + +/***************************************************************************** + * + * sk98lin_check_timer - Resume the the card + * + * Description: + * This function checks the kernel timer + * + * Returns: N/A + * + */ +void SkGeCheckTimer( +DEV_NET *pNet) /* holds the pointer to adapter control context */ +{ + SK_AC *pAC = pNet->pAC; + SK_BOOL StartTimer = SK_TRUE; + + if (pNet->InRecover) + return; + if (pNet->TimerExpired) + return; + pNet->TimerExpired = SK_TRUE; + +#define TXPORT pAC->TxPort[pNet->PortNr][TX_PRIO_LOW] +#define RXPORT pAC->RxPort[pNet->PortNr] + + if ( (CHIP_ID_YUKON_2(pAC)) && + (netif_running(pAC->dev[pNet->PortNr]))) { + +#ifdef Y2_RX_CHECK + if (HW_FEATURE(pAC, HWF_WA_DEV_4167)) { + /* Checks the RX path */ + CheckRxPath(pNet); + } +#endif + + /* Checkthe transmitter */ + if (!(IS_Q_EMPTY(&TXPORT.TxAQ_working))) { + if (TXPORT.LastDone != TXPORT.TxALET.Done) { + TXPORT.LastDone = TXPORT.TxALET.Done; + pNet->TransmitTimeoutTimer = 0; + } else { + pNet->TransmitTimeoutTimer++; + if (pNet->TransmitTimeoutTimer >= 10) { + pNet->TransmitTimeoutTimer = 0; +#ifdef CHECK_TRANSMIT_TIMEOUT + StartTimer = SK_FALSE; + SkLocalEventQueue(pAC, SKGE_DRV, + SK_DRV_RECOVER,pNet->PortNr,-1,SK_FALSE); +#endif + } + } + } + +#ifdef CHECK_TRANSMIT_TIMEOUT +// if (!timer_pending(&pNet->KernelTimer)) { + pNet->KernelTimer.expires = jiffies + (HZ/4); /* 100ms */ + add_timer(&pNet->KernelTimer); + pNet->TimerExpired = SK_FALSE; +// } +#endif + } +} + + +/***************************************************************************** +* +* CheckRXCounters - Checks the the statistics for RX path hang +* +* Description: +* This function is called periodical by a timer. +* +* Notes: +* +* Function Parameters: +* +* Returns: +* Traffic status +* +*/ +static SK_BOOL CheckRXCounters( +DEV_NET *pNet) /* holds the pointer to adapter control context */ +{ + SK_AC *pAC = pNet->pAC; + SK_BOOL bStatus = SK_FALSE; + + /* Variable used to store the MAC RX FIFO RP, RPLev*/ + SK_U32 MACFifoRP = 0; + SK_U32 MACFifoRLev = 0; + + /* Variable used to store the PCI RX FIFO RP, RPLev*/ + SK_U32 RXFifoRP = 0; + SK_U8 RXFifoRLev = 0; + + SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_MSG, + ("==> CheckRXCounters()\n")); + + /*Check if statistic counters hangs*/ + if (pNet->LastJiffies == pAC->dev[pNet->PortNr]->last_rx) { + /* Now read the values of read pointer/level from MAC RX FIFO again */ + SK_IN32(pAC->IoBase, MR_ADDR(pNet->PortNr, RX_GMF_RP), &MACFifoRP); + SK_IN32(pAC->IoBase, MR_ADDR(pNet->PortNr, RX_GMF_RLEV), &MACFifoRLev); + + /* Now read the values of read pointer/level from RX FIFO again */ + SK_IN8(pAC->IoBase, Q_ADDR(pAC->GIni.GP[pNet->PortNr].PRxQOff, Q_RX_RP), &RXFifoRP); + SK_IN8(pAC->IoBase, Q_ADDR(pAC->GIni.GP[pNet->PortNr].PRxQOff, Q_RX_RL), &RXFifoRLev); + + /* Check if the MAC RX hang */ + if ((MACFifoRP == pNet->PreviousMACFifoRP) && + (pNet->PreviousMACFifoRP != 0) && + (MACFifoRLev >= pNet->PreviousMACFifoRLev)){ + bStatus = SK_TRUE; + } + + /* Check if the PCI RX hang */ + if ((RXFifoRP == pNet->PreviousRXFifoRP) && + (pNet->PreviousRXFifoRP != 0) && + (RXFifoRLev >= pNet->PreviousRXFifoRLev)){ + /*Set the flag to indicate that the RX FIFO hangs*/ + bStatus = SK_TRUE; + } + } + + /* Store now the values of counters for next check */ + pNet->LastJiffies = pAC->dev[pNet->PortNr]->last_rx; + + /* Store the values of read pointer/level from MAC RX FIFO for next test */ + pNet->PreviousMACFifoRP = MACFifoRP; + pNet->PreviousMACFifoRLev = MACFifoRLev; + + /* Store the values of read pointer/level from RX FIFO for next test */ + pNet->PreviousRXFifoRP = RXFifoRP; + pNet->PreviousRXFifoRLev = RXFifoRLev; + + SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_MSG, + ("<== CheckRXCounters()\n")); + + return bStatus; +} + +/***************************************************************************** +* +* CheckRxPath - Checks if the RX path +* +* Description: +* This function is called periodical by a timer. +* +* Notes: +* +* Function Parameters: +* +* Returns: +* None. +* +*/ +static void CheckRxPath( +DEV_NET *pNet) /* holds the pointer to adapter control context */ +{ + unsigned long Flags; /* for the spin locks */ + /* Initialize the pAC structure.*/ + SK_AC *pAC = pNet->pAC; + + SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_MSG, + ("==> CheckRxPath()\n")); + + /*If the statistics are not changed then could be an RX problem */ + if (CheckRXCounters(pNet)){ + /* + * First we try the simple solution by resetting the Level Timer + */ + + /* Stop Level Timer of Status BMU */ + SK_OUT8(pAC->IoBase, STAT_LEV_TIMER_CTRL, TIM_STOP); + + /* Start Level Timer of Status BMU */ + SK_OUT8(pAC->IoBase, STAT_LEV_TIMER_CTRL, TIM_START); + + if (!CheckRXCounters(pNet)) { + return; + } + + spin_lock_irqsave(&pAC->SlowPathLock, Flags); + SkLocalEventQueue(pAC, SKGE_DRV, + SK_DRV_RECOVER,pNet->PortNr,-1,SK_TRUE); + + /* Reset the fifo counters */ + pNet->PreviousMACFifoRP = 0; + pNet->PreviousMACFifoRLev = 0; + pNet->PreviousRXFifoRP = 0; + pNet->PreviousRXFifoRLev = 0; + + spin_unlock_irqrestore(&pAC->SlowPathLock, Flags); + } + + SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_MSG, + ("<== CheckRxPath()\n")); +} + + + +#endif + + +#ifdef CONFIG_PM +/***************************************************************************** + * + * sk98lin_resume - Resume the the card + * + * Description: + * This function resumes the card into the D0 state + * + * Returns: N/A + * + */ +static int sk98lin_resume( +struct pci_dev *pdev) /* the device that is to resume */ +{ + struct net_device *dev = pci_get_drvdata(pdev); + DEV_NET *pNet = (DEV_NET*) dev->priv; + SK_AC *pAC = pNet->pAC; + SK_U16 PmCtlSts; + + /* Set the power state to D0 */ + pci_set_power_state(pdev, 0); +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,9) + pci_restore_state(pdev); +#else + pci_restore_state(pdev, pAC->PciState); +#endif + + /* Set the adapter power state to D0 */ + SkPciReadCfgWord(pAC, PCI_PM_CTL_STS, &PmCtlSts); + PmCtlSts &= ~(PCI_PM_STATE_D3); /* reset all DState bits */ + PmCtlSts |= PCI_PM_STATE_D0; + SkPciWriteCfgWord(pAC, PCI_PM_CTL_STS, PmCtlSts); + + /* Reinit the adapter and start the port again */ + pAC->BoardLevel = SK_INIT_DATA; + SkDrvLeaveDiagMode(pAC); + + netif_device_attach(dev); + netif_start_queue(dev); + return 0; +} + +/***************************************************************************** + * + * sk98lin_suspend - Suspend the card + * + * Description: + * This function suspends the card into a defined state + * + * Returns: N/A + * + */ +static int sk98lin_suspend( +struct pci_dev *pdev, /* pointer to the device that is to suspend */ +u32 state) /* what power state is desired by Linux? */ +{ + struct net_device *dev = pci_get_drvdata(pdev); + DEV_NET *pNet = (DEV_NET*) dev->priv; + SK_AC *pAC = pNet->pAC; + SK_U16 PciPMControlStatus; + SK_U16 PciPMCapabilities; + SK_MAC_ADDR MacAddr; + int i; + + /* GEnesis and first yukon revs do not support power management */ + if (pAC->GIni.GIChipId == CHIP_ID_YUKON) { + if (pAC->GIni.GIChipRev == 0) { + return 0; /* power management not supported */ + } + } + + if (pAC->GIni.GIChipId == CHIP_ID_GENESIS) { + return 0; /* not supported for this chipset */ + } + + if (pAC->WolInfo.ConfiguredWolOptions == 0) { + return 0; /* WOL possible, but disabled via ethtool */ + } + + if(netif_running(dev)) { + netif_stop_queue(dev); /* stop device if running */ + } + + netif_device_detach(dev); + + /* read the PM control/status register from the PCI config space */ + SK_IN16(pAC->IoBase, PCI_C(pAC, PCI_PM_CTL_STS), &PciPMControlStatus); + + /* read the power management capabilities from the config space */ + SK_IN16(pAC->IoBase, PCI_C(pAC, PCI_PM_CAP_REG), &PciPMCapabilities); + + /* Enable WakeUp with Magic Packet - get MAC address from adapter */ + for (i = 0; i < SK_MAC_ADDR_LEN; i++) { + /* virtual address: will be used for data */ + SK_IN8(pAC->IoBase, (B2_MAC_1 + i), &MacAddr.a[i]); + } + + SkDrvEnterDiagMode(pAC); + SkEnableWOMagicPacket(pAC, pAC->IoBase, MacAddr); + + pci_enable_wake(pdev, 3, 1); + pci_enable_wake(pdev, 4, 1); /* 4 == D3 cold */ +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,9) + pci_save_state(pdev); +#else + pci_save_state(pdev, pAC->PciState); +#endif + pci_set_power_state(pdev, state); /* set the state */ + + return 0; +} + + +/****************************************************************************** + * + * SkEnableWOMagicPacket - Enable Wake on Magic Packet on the adapter + * + * Context: + * init, pageable + * the adapter should be de-initialized before calling this function + * + * Returns: + * nothing + */ + +static void SkEnableWOMagicPacket( +SK_AC *pAC, /* Adapter Control Context */ +SK_IOC IoC, /* I/O control context */ +SK_MAC_ADDR MacAddr) /* MacAddr expected in magic packet */ +{ + SK_U16 Word; + SK_U32 DWord; + int i; + int HwPortIndex; + int Port = 0; + + /* use Port 0 as long as we do not have any dual port cards which support WOL */ + HwPortIndex = 0; + DWord = 0; + + SK_OUT16(IoC, 0x0004, 0x0002); /* clear S/W Reset */ + SK_OUT16(IoC, 0x0f10, 0x0002); /* clear Link Reset */ + + /* + * PHY Configuration: + * Autonegotioation is enalbed, advertise 10 HD, 10 FD, + * 100 HD, and 100 FD. + */ + if ((pAC->GIni.GIChipId == CHIP_ID_YUKON_EC) || + (pAC->GIni.GIChipId == CHIP_ID_YUKON) || + (pAC->GIni.GIChipId == CHIP_ID_YUKON_LITE)) { + + SK_OUT16(IoC, 0x0004, 0x0800); /* enable CLK_RUN */ + SK_OUT8(IoC, 0x0007, 0xa9); /* enable VAUX */ + + /* WA code for COMA mode */ + /* Only for yukon plus based chipsets rev A3 */ + if (pAC->GIni.GIChipRev == CHIP_REV_YU_LITE_A3) { + SK_IN32(IoC, B2_GP_IO, &DWord); + DWord |= GP_DIR_9; /* set to output */ + DWord &= ~GP_IO_9; /* clear PHY reset (active high) */ + SK_OUT32(IoC, B2_GP_IO, DWord); /* clear PHY reset */ + } + + if ((pAC->GIni.GIChipId == CHIP_ID_YUKON_LITE) || + (pAC->GIni.GIChipId == CHIP_ID_YUKON)) { + SK_OUT32(IoC, 0x0f04, 0x01f04001); /* set PHY reset */ + SK_OUT32(IoC, 0x0f04, 0x01f04002); /* clear PHY reset */ + } else { + SK_OUT8(IoC, 0x0f04, 0x02); /* clear PHY reset */ + } + + SK_OUT8(IoC, 0x0f00, 0x02); /* clear MAC reset */ + SkGmPhyWrite(pAC, IoC, Port, 4, 0x01e1); /* advertise 10/100 HD/FD */ + SkGmPhyWrite(pAC, IoC, Port, 9, 0x0000); /* do not advertise 1000 HD/FD */ + SkGmPhyWrite(pAC, IoC, Port, 00, 0xB300); /* 100 MBit, disable Autoneg */ + } else if (pAC->GIni.GIChipId == CHIP_ID_YUKON_FE) { + SK_OUT8(IoC, 0x0007, 0xa9); /* enable VAUX */ + SK_OUT8(IoC, 0x0f04, 0x02); /* clear PHY reset */ + SK_OUT8(IoC, 0x0f00, 0x02); /* clear MAC reset */ + SkGmPhyWrite(pAC, IoC, Port, 16, 0x0130); /* Enable Automatic Crossover */ + SkGmPhyWrite(pAC, IoC, Port, 00, 0xB300); /* 100 MBit, disable Autoneg */ + } + + + /* + * MAC Configuration: + * Set the MAC to 100 HD and enable the auto update features + * for Speed, Flow Control and Duplex Mode. + * If autonegotiation completes successfully the + * MAC takes the link parameters from the PHY. + * If the link partner doesn't support autonegotiation + * the MAC can receive magic packets if the link partner + * uses 100 HD. + */ + SK_OUT16(IoC, 0x2804, 0x3832); + + + /* + * Set Up Magic Packet parameters + */ + for (i = 0; i < 6; i+=2) { /* set up magic packet MAC address */ + SK_IN16(IoC, 0x100 + i, &Word); + SK_OUT16(IoC, 0xf24 + i, Word); + } + + SK_OUT16(IoC, 0x0f20, 0x0208); /* enable PME on magic packet */ + /* and on wake up frame */ + + /* + * Set up PME generation + */ + /* set PME legacy mode */ + /* Only for PCI express based chipsets */ + if ((pAC->GIni.GIChipId == CHIP_ID_YUKON_EC) || + (pAC->GIni.GIChipId == CHIP_ID_YUKON_FE)) { + SkPciReadCfgDWord(pAC, 0x40, &DWord); + DWord |= 0x8000; + SkPciWriteCfgDWord(pAC, 0x40, DWord); + } + + /* clear PME status and switch adapter to DState */ + SkPciReadCfgWord(pAC, 0x4c, &Word); + Word |= 0x103; + SkPciWriteCfgWord(pAC, 0x4c, Word); +} /* SkEnableWOMagicPacket */ +#endif + /***************************************************************************** * @@ -634,7 +1180,9 @@ if (pAC->IoBase) { iounmap(pAC->IoBase); } - if (pAC->pDescrMem) { + if (CHIP_ID_YUKON_2(pAC)) { + SkY2FreeResources(pAC); + } else { BoardFreeMem(pAC); } } @@ -644,28 +1192,6 @@ MODULE_AUTHOR("Mirko Lindner "); MODULE_DESCRIPTION("SysKonnect SK-NET Gigabit Ethernet SK-98xx driver"); MODULE_LICENSE("GPL"); -MODULE_PARM(Speed_A, "1-" __MODULE_STRING(SK_MAX_CARD_PARAM) "s"); -MODULE_PARM(Speed_B, "1-" __MODULE_STRING(SK_MAX_CARD_PARAM) "s"); -MODULE_PARM(AutoNeg_A, "1-" __MODULE_STRING(SK_MAX_CARD_PARAM) "s"); -MODULE_PARM(AutoNeg_B, "1-" __MODULE_STRING(SK_MAX_CARD_PARAM) "s"); -MODULE_PARM(DupCap_A, "1-" __MODULE_STRING(SK_MAX_CARD_PARAM) "s"); -MODULE_PARM(DupCap_B, "1-" __MODULE_STRING(SK_MAX_CARD_PARAM) "s"); -MODULE_PARM(FlowCtrl_A, "1-" __MODULE_STRING(SK_MAX_CARD_PARAM) "s"); -MODULE_PARM(FlowCtrl_B, "1-" __MODULE_STRING(SK_MAX_CARD_PARAM) "s"); -MODULE_PARM(Role_A, "1-" __MODULE_STRING(SK_MAX_CARD_PARAM) "s"); -MODULE_PARM(Role_B, "1-" __MODULE_STRING(SK_MAX_CARD_PARAM) "s"); -MODULE_PARM(ConType, "1-" __MODULE_STRING(SK_MAX_CARD_PARAM) "s"); -MODULE_PARM(PrefPort, "1-" __MODULE_STRING(SK_MAX_CARD_PARAM) "s"); -MODULE_PARM(RlmtMode, "1-" __MODULE_STRING(SK_MAX_CARD_PARAM) "s"); -/* not used, just there because every driver should have them: */ -MODULE_PARM(options, "1-" __MODULE_STRING(SK_MAX_CARD_PARAM) "i"); -MODULE_PARM(debug, "i"); -/* used for interrupt moderation */ -MODULE_PARM(IntsPerSec, "1-" __MODULE_STRING(SK_MAX_CARD_PARAM) "i"); -MODULE_PARM(Moderation, "1-" __MODULE_STRING(SK_MAX_CARD_PARAM) "s"); -MODULE_PARM(Stats, "1-" __MODULE_STRING(SK_MAX_CARD_PARAM) "s"); -MODULE_PARM(ModerationMask, "1-" __MODULE_STRING(SK_MAX_CARD_PARAM) "s"); -MODULE_PARM(AutoSizing, "1-" __MODULE_STRING(SK_MAX_CARD_PARAM) "s"); #ifdef LINK_SPEED_A @@ -746,47 +1272,55 @@ static char *RlmtMode[SK_MAX_CARD_PARAM] = {"", }; #endif -static int debug = 0; /* not used */ -static int options[SK_MAX_CARD_PARAM] = {0, }; /* not used */ - static int IntsPerSec[SK_MAX_CARD_PARAM]; static char *Moderation[SK_MAX_CARD_PARAM]; static char *ModerationMask[SK_MAX_CARD_PARAM]; -static char *AutoSizing[SK_MAX_CARD_PARAM]; -static char *Stats[SK_MAX_CARD_PARAM]; - -/***************************************************************************** - * - * skge_init_module - module initialization function - * - * Description: - * Very simple, only call skge_probe and return approriate result. - * - * Returns: - * 0, if everything is ok - * !=0, on error - */ -static int __init skge_init_module(void) -{ - int cards; - SkGeRootDev = NULL; - - /* just to avoid warnings ... */ - debug = 0; - options[0] = 0; +static char *LowLatency[SK_MAX_CARD_PARAM]; - cards = skge_probe(); - if (cards == 0) { - printk("sk98lin: No adapter found.\n"); - } - return cards ? 0 : -ENODEV; -} /* skge_init_module */ +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,9) +module_param_array(Speed_A, charp, NULL, 0); +module_param_array(Speed_B, charp, NULL, 0); +module_param_array(AutoNeg_A, charp, NULL, 0); +module_param_array(AutoNeg_B, charp, NULL, 0); +module_param_array(DupCap_A, charp, NULL, 0); +module_param_array(DupCap_B, charp, NULL, 0); +module_param_array(FlowCtrl_A, charp, NULL, 0); +module_param_array(FlowCtrl_B, charp, NULL, 0); +module_param_array(Role_A, charp, NULL, 0); +module_param_array(Role_B, charp, NULL, 0); +module_param_array(ConType, charp, NULL, 0); +module_param_array(PrefPort, charp, NULL, 0); +module_param_array(RlmtMode, charp, NULL, 0); +/* used for interrupt moderation */ +module_param_array(IntsPerSec, int, NULL, 0); +module_param_array(Moderation, charp, NULL, 0); +module_param_array(ModerationMask, charp, NULL, 0); +module_param_array(LowLatency, charp, NULL, 0); +#else +MODULE_PARM(Speed_A, "1-" __MODULE_STRING(SK_MAX_CARD_PARAM) "s"); +MODULE_PARM(Speed_B, "1-" __MODULE_STRING(SK_MAX_CARD_PARAM) "s"); +MODULE_PARM(AutoNeg_A, "1-" __MODULE_STRING(SK_MAX_CARD_PARAM) "s"); +MODULE_PARM(AutoNeg_B, "1-" __MODULE_STRING(SK_MAX_CARD_PARAM) "s"); +MODULE_PARM(DupCap_A, "1-" __MODULE_STRING(SK_MAX_CARD_PARAM) "s"); +MODULE_PARM(DupCap_B, "1-" __MODULE_STRING(SK_MAX_CARD_PARAM) "s"); +MODULE_PARM(FlowCtrl_A, "1-" __MODULE_STRING(SK_MAX_CARD_PARAM) "s"); +MODULE_PARM(FlowCtrl_B, "1-" __MODULE_STRING(SK_MAX_CARD_PARAM) "s"); +MODULE_PARM(Role_A, "1-" __MODULE_STRING(SK_MAX_CARD_PARAM) "s"); +MODULE_PARM(Role_B, "1-" __MODULE_STRING(SK_MAX_CARD_PARAM) "s"); +MODULE_PARM(ConType, "1-" __MODULE_STRING(SK_MAX_CARD_PARAM) "s"); +MODULE_PARM(PrefPort, "1-" __MODULE_STRING(SK_MAX_CARD_PARAM) "s"); +MODULE_PARM(RlmtMode, "1-" __MODULE_STRING(SK_MAX_CARD_PARAM) "s"); +MODULE_PARM(IntsPerSec, "1-" __MODULE_STRING(SK_MAX_CARD_PARAM) "i"); +MODULE_PARM(Moderation, "1-" __MODULE_STRING(SK_MAX_CARD_PARAM) "s"); +MODULE_PARM(ModerationMask, "1-" __MODULE_STRING(SK_MAX_CARD_PARAM) "s"); +MODULE_PARM(LowLatency, "1-" __MODULE_STRING(SK_MAX_CARD_PARAM) "s"); +#endif /***************************************************************************** * - * skge_cleanup_module - module unload function + * sk98lin_remove_device - device deinit function * * Description: * Disable adapter if it is still running, free resources, @@ -794,73 +1328,83 @@ * * Returns: N/A */ -static void __exit skge_cleanup_module(void) + +static void sk98lin_remove_device(struct pci_dev *pdev) { DEV_NET *pNet; SK_AC *pAC; struct SK_NET_DEVICE *next; unsigned long Flags; -SK_EVPARA EvPara; +struct net_device *dev = pci_get_drvdata(pdev); + + + /* Device not available. Return. */ + if (!dev) + return; - while (SkGeRootDev) { - pNet = (DEV_NET*) SkGeRootDev->priv; - pAC = pNet->pAC; - next = pAC->Next; + pNet = (DEV_NET*) dev->priv; + pAC = pNet->pAC; + next = pAC->Next; - netif_stop_queue(SkGeRootDev); - SkGeYellowLED(pAC, pAC->IoBase, 0); + netif_stop_queue(dev); + SkGeYellowLED(pAC, pAC->IoBase, 0); - if(pAC->BoardLevel == SK_INIT_RUN) { - /* board is still alive */ - spin_lock_irqsave(&pAC->SlowPathLock, Flags); - EvPara.Para32[0] = 0; - EvPara.Para32[1] = -1; - SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_STOP, EvPara); - EvPara.Para32[0] = 1; - EvPara.Para32[1] = -1; - SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_STOP, EvPara); - SkEventDispatcher(pAC, pAC->IoBase); - /* disable interrupts */ - SK_OUT32(pAC->IoBase, B0_IMSK, 0); - SkGeDeInit(pAC, pAC->IoBase); - spin_unlock_irqrestore(&pAC->SlowPathLock, Flags); - pAC->BoardLevel = SK_INIT_DATA; - /* We do NOT check here, if IRQ was pending, of course*/ - } - - if(pAC->BoardLevel == SK_INIT_IO) { - /* board is still alive */ - SkGeDeInit(pAC, pAC->IoBase); - pAC->BoardLevel = SK_INIT_DATA; - } - - if ((pAC->GIni.GIMacsFound == 2) && pAC->RlmtNets == 2){ - unregister_netdev(pAC->dev[1]); - kfree(pAC->dev[1]); - } + if(pAC->BoardLevel == SK_INIT_RUN) { + /* board is still alive */ + spin_lock_irqsave(&pAC->SlowPathLock, Flags); + SkLocalEventQueue(pAC, SKGE_RLMT, SK_RLMT_STOP, + 0, -1, SK_FALSE); + SkLocalEventQueue(pAC, SKGE_RLMT, SK_RLMT_STOP, + 1, -1, SK_TRUE); - FreeResources(SkGeRootDev); + /* disable interrupts */ + SK_OUT32(pAC->IoBase, B0_IMSK, 0); + SkGeDeInit(pAC, pAC->IoBase); + spin_unlock_irqrestore(&pAC->SlowPathLock, Flags); + pAC->BoardLevel = SK_INIT_DATA; + /* We do NOT check here, if IRQ was pending, of course*/ + } - SkGeRootDev->get_stats = NULL; - /* - * otherwise unregister_netdev calls get_stats with - * invalid IO ... :-( - */ - unregister_netdev(SkGeRootDev); - kfree(SkGeRootDev); - kfree(pAC); - SkGeRootDev = next; + if(pAC->BoardLevel == SK_INIT_IO) { + /* board is still alive */ + SkGeDeInit(pAC, pAC->IoBase); + pAC->BoardLevel = SK_INIT_DATA; + } + + if ((pAC->GIni.GIMacsFound == 2) && pAC->RlmtNets == 2){ + unregister_netdev(pAC->dev[1]); + kfree(pAC->dev[1]); } + FreeResources(dev); + #ifdef CONFIG_PROC_FS - /* clear proc-dir */ - remove_proc_entry(pSkRootDir->name, proc_net); + /* Remove the sk98lin procfs device entries */ + if ((pAC->GIni.GIMacsFound == 2) && pAC->RlmtNets == 2){ + remove_proc_entry(pAC->dev[1]->name, pSkRootDir); + } + remove_proc_entry(pNet->InitialDevName, pSkRootDir); #endif -} /* skge_cleanup_module */ + dev->get_stats = NULL; + /* + * otherwise unregister_netdev calls get_stats with + * invalid IO ... :-( + */ + unregister_netdev(dev); + kfree(dev); + kfree(pAC); + sk98lin_max_boards_found--; + +#ifdef CONFIG_PROC_FS + /* Remove all Proc entries if last device */ + if (sk98lin_max_boards_found == 0) { + /* clear proc-dir */ + remove_proc_entry(pSkRootDir->name, proc_net); + } +#endif -module_init(skge_init_module); -module_exit(skge_cleanup_module); +} /***************************************************************************** @@ -899,7 +1443,11 @@ spin_lock_init(&pAC->TxPort[i][0].TxDesRingLock); spin_lock_init(&pAC->RxPort[i].RxDesRingLock); } + + spin_lock_init(&pAC->InitLock); /* Init lock */ spin_lock_init(&pAC->SlowPathLock); + spin_lock_init(&pAC->TxQueueLock); /* for Yukon2 chipsets */ + spin_lock_init(&pAC->SetPutIndexLock); /* for Yukon2 chipsets */ /* level 0 init common modules here */ @@ -918,15 +1466,13 @@ SkTimerInit(pAC, pAC->IoBase, SK_INIT_DATA); pAC->BoardLevel = SK_INIT_DATA; - pAC->RxBufSize = ETH_BUF_SIZE; + pAC->RxPort[0].RxBufSize = ETH_BUF_SIZE; + pAC->RxPort[1].RxBufSize = ETH_BUF_SIZE; SK_PNMI_SET_DRIVER_DESCR(pAC, DescrString); SK_PNMI_SET_DRIVER_VER(pAC, VerStr); - spin_unlock_irqrestore(&pAC->SlowPathLock, Flags); - /* level 1 init common modules here (HW init) */ - spin_lock_irqsave(&pAC->SlowPathLock, Flags); if (SkGeInit(pAC, pAC->IoBase, SK_INIT_IO) != 0) { printk("sk98lin: HWInit (1) failed.\n"); spin_unlock_irqrestore(&pAC->SlowPathLock, Flags); @@ -938,52 +1484,93 @@ SkAddrInit( pAC, pAC->IoBase, SK_INIT_IO); SkRlmtInit( pAC, pAC->IoBase, SK_INIT_IO); SkTimerInit(pAC, pAC->IoBase, SK_INIT_IO); +#ifdef Y2_RECOVERY + /* mark entries invalid */ + pAC->LastPort = 3; + pAC->LastOpc = 0xFF; +#endif /* Set chipset type support */ - pAC->ChipsetType = 0; if ((pAC->GIni.GIChipId == CHIP_ID_YUKON) || - (pAC->GIni.GIChipId == CHIP_ID_YUKON_LITE)) { - pAC->ChipsetType = 1; + (pAC->GIni.GIChipId == CHIP_ID_YUKON_LITE) || + (pAC->GIni.GIChipId == CHIP_ID_YUKON_LP)) { + pAC->ChipsetType = 1; /* Yukon chipset (descriptor logic) */ + } else if (CHIP_ID_YUKON_2(pAC)) { + pAC->ChipsetType = 2; /* Yukon2 chipset (list logic) */ + } else { + pAC->ChipsetType = 0; /* Genesis chipset (descriptor logic) */ + } + + /* wake on lan support */ + pAC->WolInfo.SupportedWolOptions = 0; +#if defined (ETHTOOL_GWOL) && defined (ETHTOOL_SWOL) + if (pAC->GIni.GIChipId != CHIP_ID_GENESIS) { + pAC->WolInfo.SupportedWolOptions = WAKE_MAGIC; + if (pAC->GIni.GIChipId == CHIP_ID_YUKON) { + if (pAC->GIni.GIChipRev == 0) { + pAC->WolInfo.SupportedWolOptions = 0; + } + } } +#endif + pAC->WolInfo.ConfiguredWolOptions = pAC->WolInfo.SupportedWolOptions; GetConfiguration(pAC); if (pAC->RlmtNets == 2) { - pAC->GIni.GIPortUsage = SK_MUL_LINK; + pAC->GIni.GP[0].PPortUsage = SK_MUL_LINK; + pAC->GIni.GP[1].PPortUsage = SK_MUL_LINK; } pAC->BoardLevel = SK_INIT_IO; spin_unlock_irqrestore(&pAC->SlowPathLock, Flags); - if (pAC->GIni.GIMacsFound == 2) { - Ret = request_irq(dev->irq, SkGeIsr, - SA_SHIRQ | SA_NET_RANDOM, pAC->Name, dev); - } else if (pAC->GIni.GIMacsFound == 1) { - Ret = request_irq(dev->irq, SkGeIsrOnePort, - SA_SHIRQ | SA_NET_RANDOM, pAC->Name, dev); - } else { - printk(KERN_WARNING "sk98lin: Illegal number of ports: %d\n", - pAC->GIni.GIMacsFound); - return -EAGAIN; + if (!CHIP_ID_YUKON_2(pAC)) { + if (pAC->GIni.GIMacsFound == 2) { + Ret = request_irq(dev->irq, SkGeIsr, SA_SHIRQ | SA_NET_RANDOM, dev->name, dev); + } else if (pAC->GIni.GIMacsFound == 1) { + Ret = request_irq(dev->irq, SkGeIsrOnePort, SA_SHIRQ | SA_NET_RANDOM, dev->name, dev); + } else { + printk(KERN_WARNING "sk98lin: Illegal number of ports: %d\n", + pAC->GIni.GIMacsFound); + return -EAGAIN; + } + } + else { + Ret = request_irq(dev->irq, SkY2Isr, SA_SHIRQ | SA_NET_RANDOM, dev->name, dev); } if (Ret) { printk(KERN_WARNING "sk98lin: Requested IRQ %d is busy.\n", - dev->irq); + dev->irq); return -EAGAIN; } pAC->AllocFlag |= SK_ALLOC_IRQ; - /* Alloc memory for this board (Mem for RxD/TxD) : */ - if(!BoardAllocMem(pAC)) { - printk("No memory for descriptor rings.\n"); - return(-EAGAIN); + /* + ** Alloc descriptor/LETable memory for this board (both RxD/TxD) + */ + if (CHIP_ID_YUKON_2(pAC)) { + if (!SkY2AllocateResources(pAC)) { + printk("No memory for Yukon2 settings\n"); + return(-EAGAIN); + } + } else { + if(!BoardAllocMem(pAC)) { + printk("No memory for descriptor rings.\n"); + return(-EAGAIN); + } } +#ifdef SK_USE_CSUM SkCsSetReceiveFlags(pAC, SKCS_PROTO_IP | SKCS_PROTO_TCP | SKCS_PROTO_UDP, &pAC->CsOfs1, &pAC->CsOfs2, 0); pAC->CsOfs = (pAC->CsOfs2 << 16) | pAC->CsOfs1; +#endif + /* + ** Function BoardInitMem() for Yukon dependent settings... + */ BoardInitMem(pAC); /* tschilling: New common function with minimum size check. */ DualNet = SK_FALSE; @@ -995,7 +1582,12 @@ pAC, pAC->ActivePort, DualNet)) { - BoardFreeMem(pAC); + if (CHIP_ID_YUKON_2(pAC)) { + SkY2FreeResources(pAC); + } else { + BoardFreeMem(pAC); + } + printk("sk98lin: SkGeInitAssignRamToQueues failed.\n"); return(-EAGAIN); } @@ -1095,16 +1687,20 @@ SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY, ("BoardFreeMem\n")); + + if (pAC->pDescrMem) { + #if (BITS_PER_LONG == 32) - AllocLength = (RX_RING_SIZE + TX_RING_SIZE) * pAC->GIni.GIMacsFound + 8; + AllocLength = (RX_RING_SIZE + TX_RING_SIZE) * pAC->GIni.GIMacsFound + 8; #else - AllocLength = (RX_RING_SIZE + TX_RING_SIZE) * pAC->GIni.GIMacsFound - + RX_RING_SIZE + 8; + AllocLength = (RX_RING_SIZE + TX_RING_SIZE) * pAC->GIni.GIMacsFound + + RX_RING_SIZE + 8; #endif - pci_free_consistent(pAC->PciDev, AllocLength, + pci_free_consistent(pAC->PciDev, AllocLength, pAC->pDescrMem, pAC->pDescrMemDMA); - pAC->pDescrMem = NULL; + pAC->pDescrMem = NULL; + } } /* BoardFreeMem */ @@ -1113,7 +1709,7 @@ * BoardInitMem - initiate the descriptor rings * * Description: - * This function sets the descriptor rings up in memory. + * This function sets the descriptor rings or LETables up in memory. * The adapter is initialized with the descriptor start addresses. * * Returns: N/A @@ -1128,34 +1724,37 @@ SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY, ("BoardInitMem\n")); - RxDescrSize = (((sizeof(RXD) - 1) / DESCR_ALIGN) + 1) * DESCR_ALIGN; - pAC->RxDescrPerRing = RX_RING_SIZE / RxDescrSize; - TxDescrSize = (((sizeof(TXD) - 1) / DESCR_ALIGN) + 1) * DESCR_ALIGN; - pAC->TxDescrPerRing = TX_RING_SIZE / RxDescrSize; + if (!pAC->GIni.GIYukon2) { + RxDescrSize = (((sizeof(RXD) - 1) / DESCR_ALIGN) + 1) * DESCR_ALIGN; + pAC->RxDescrPerRing = RX_RING_SIZE / RxDescrSize; + TxDescrSize = (((sizeof(TXD) - 1) / DESCR_ALIGN) + 1) * DESCR_ALIGN; + pAC->TxDescrPerRing = TX_RING_SIZE / RxDescrSize; - for (i=0; iGIni.GIMacsFound; i++) { - SetupRing( - pAC, - pAC->TxPort[i][0].pTxDescrRing, - pAC->TxPort[i][0].VTxDescrRing, - (RXD**)&pAC->TxPort[i][0].pTxdRingHead, - (RXD**)&pAC->TxPort[i][0].pTxdRingTail, - (RXD**)&pAC->TxPort[i][0].pTxdRingPrev, - &pAC->TxPort[i][0].TxdRingFree, - SK_TRUE); - SetupRing( - pAC, - pAC->RxPort[i].pRxDescrRing, - pAC->RxPort[i].VRxDescrRing, - &pAC->RxPort[i].pRxdRingHead, - &pAC->RxPort[i].pRxdRingTail, - &pAC->RxPort[i].pRxdRingPrev, - &pAC->RxPort[i].RxdRingFree, - SK_FALSE); + for (i=0; iGIni.GIMacsFound; i++) { + SetupRing( + pAC, + pAC->TxPort[i][0].pTxDescrRing, + pAC->TxPort[i][0].VTxDescrRing, + (RXD**)&pAC->TxPort[i][0].pTxdRingHead, + (RXD**)&pAC->TxPort[i][0].pTxdRingTail, + (RXD**)&pAC->TxPort[i][0].pTxdRingPrev, + &pAC->TxPort[i][0].TxdRingFree, + &pAC->TxPort[i][0].TxdRingPrevFree, + SK_TRUE); + SetupRing( + pAC, + pAC->RxPort[i].pRxDescrRing, + pAC->RxPort[i].VRxDescrRing, + &pAC->RxPort[i].pRxdRingHead, + &pAC->RxPort[i].pRxdRingTail, + &pAC->RxPort[i].pRxdRingPrev, + &pAC->RxPort[i].RxdRingFree, + &pAC->RxPort[i].RxdRingFree, + SK_FALSE); + } } } /* BoardInitMem */ - /***************************************************************************** * * SetupRing - create one descriptor ring @@ -1175,6 +1774,7 @@ RXD **ppRingTail, /* address where the tail should be written */ RXD **ppRingPrev, /* address where the tail should be written */ int *pRingFree, /* address where the # of free descr. goes */ +int *pRingPrevFree, /* address where the # of free descr. goes */ SK_BOOL IsTx) /* flag: is this a tx ring */ { int i; /* loop counter */ @@ -1217,11 +1817,12 @@ } pPrevDescr->pNextRxd = (RXD*) pMemArea; pPrevDescr->VNextRxd = VMemArea; - pDescr = (RXD*) pMemArea; - *ppRingHead = (RXD*) pMemArea; - *ppRingTail = *ppRingHead; - *ppRingPrev = pPrevDescr; - *pRingFree = DescrNum; + pDescr = (RXD*) pMemArea; + *ppRingHead = (RXD*) pMemArea; + *ppRingTail = *ppRingHead; + *ppRingPrev = pPrevDescr; + *pRingFree = DescrNum; + *pRingPrevFree = DescrNum; } /* SetupRing */ @@ -1293,10 +1894,28 @@ * Check and process if its our interrupt */ SK_IN32(pAC->IoBase, B0_SP_ISRC, &IntSrc); - if (IntSrc == 0) { + if ((IntSrc == 0) && (!pNet->NetConsoleMode)) { return; } +#ifdef CONFIG_SK98LIN_NAPI + if (netif_rx_schedule_prep(dev)) { + pAC->GIni.GIValIrqMask &= ~(NAPI_DRV_IRQS); + SK_OUT32(pAC->IoBase, B0_IMSK, pAC->GIni.GIValIrqMask); + __netif_rx_schedule(dev); + } + +#ifdef USE_TX_COMPLETE /* only if tx complete interrupt used */ + if (IntSrc & IS_XA1_F) { + CLEAR_TX_IRQ(0, TX_PRIO_LOW); + } + if (IntSrc & IS_XA2_F) { + CLEAR_TX_IRQ(1, TX_PRIO_LOW); + } +#endif + + +#else while (((IntSrc & IRQ_MASK) & ~SPECIAL_IRQS) != 0) { #if 0 /* software irq currently not used */ if (IntSrc & IS_IRQ_SW) { @@ -1310,6 +1929,7 @@ SK_DBGCAT_DRV_INT_SRC, ("EOF RX1 IRQ\n")); ReceiveIrq(pAC, &pAC->RxPort[0], SK_TRUE); + CLEAR_AND_START_RX(0); SK_PNMI_CNT_RX_INTR(pAC, 0); } if (IntSrc & IS_R2_F) { @@ -1317,6 +1937,7 @@ SK_DBGCAT_DRV_INT_SRC, ("EOF RX2 IRQ\n")); ReceiveIrq(pAC, &pAC->RxPort[1], SK_TRUE); + CLEAR_AND_START_RX(1); SK_PNMI_CNT_RX_INTR(pAC, 1); } #ifdef USE_TX_COMPLETE /* only if tx complete interrupt used */ @@ -1324,6 +1945,7 @@ SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_INT_SRC, ("EOF AS TX1 IRQ\n")); + CLEAR_TX_IRQ(0, TX_PRIO_LOW); SK_PNMI_CNT_TX_INTR(pAC, 0); spin_lock(&pAC->TxPort[0][TX_PRIO_LOW].TxDesRingLock); FreeTxDescriptors(pAC, &pAC->TxPort[0][TX_PRIO_LOW]); @@ -1333,6 +1955,7 @@ SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_INT_SRC, ("EOF AS TX2 IRQ\n")); + CLEAR_TX_IRQ(1, TX_PRIO_LOW); SK_PNMI_CNT_TX_INTR(pAC, 1); spin_lock(&pAC->TxPort[1][TX_PRIO_LOW].TxDesRingLock); FreeTxDescriptors(pAC, &pAC->TxPort[1][TX_PRIO_LOW]); @@ -1343,38 +1966,28 @@ SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_INT_SRC, ("EOF SY TX1 IRQ\n")); + CLEAR_TX_IRQ(0, TX_PRIO_HIGH); SK_PNMI_CNT_TX_INTR(pAC, 1); spin_lock(&pAC->TxPort[0][TX_PRIO_HIGH].TxDesRingLock); FreeTxDescriptors(pAC, 0, TX_PRIO_HIGH); spin_unlock(&pAC->TxPort[0][TX_PRIO_HIGH].TxDesRingLock); - ClearTxIrq(pAC, 0, TX_PRIO_HIGH); } if (IntSrc & IS_XS2_F) { SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_INT_SRC, ("EOF SY TX2 IRQ\n")); + CLEAR_TX_IRQ(1, TX_PRIO_HIGH); SK_PNMI_CNT_TX_INTR(pAC, 1); spin_lock(&pAC->TxPort[1][TX_PRIO_HIGH].TxDesRingLock); FreeTxDescriptors(pAC, 1, TX_PRIO_HIGH); spin_unlock(&pAC->TxPort[1][TX_PRIO_HIGH].TxDesRingLock); - ClearTxIrq(pAC, 1, TX_PRIO_HIGH); } #endif #endif - /* do all IO at once */ - if (IntSrc & IS_R1_F) - ClearAndStartRx(pAC, 0); - if (IntSrc & IS_R2_F) - ClearAndStartRx(pAC, 1); -#ifdef USE_TX_COMPLETE /* only if tx complete interrupt used */ - if (IntSrc & IS_XA1_F) - ClearTxIrq(pAC, 0, TX_PRIO_LOW); - if (IntSrc & IS_XA2_F) - ClearTxIrq(pAC, 1, TX_PRIO_LOW); -#endif SK_IN32(pAC->IoBase, B0_ISRC, &IntSrc); } /* while (IntSrc & IRQ_MASK != 0) */ +#endif IntSrc &= pAC->GIni.GIValIrqMask; if ((IntSrc & SPECIAL_IRQS) || pAC->CheckQueue) { @@ -1388,18 +2001,12 @@ SkEventDispatcher(pAC, pAC->IoBase); spin_unlock(&pAC->SlowPathLock); } - /* - * do it all again is case we cleared an interrupt that - * came in after handling the ring (OUTs may be delayed - * in hardware buffers, but are through after IN) - * - * rroesler: has been commented out and shifted to - * SkGeDrvEvent(), because it is timer - * guarded now - * + +#ifndef CONFIG_SK98LIN_NAPI + /* Handle interrupts */ ReceiveIrq(pAC, &pAC->RxPort[0], SK_TRUE); ReceiveIrq(pAC, &pAC->RxPort[1], SK_TRUE); - */ +#endif if (pAC->CheckQueue) { pAC->CheckQueue = SK_FALSE; @@ -1442,10 +2049,25 @@ * Check and process if its our interrupt */ SK_IN32(pAC->IoBase, B0_SP_ISRC, &IntSrc); - if (IntSrc == 0) { + if ((IntSrc == 0) && (!pNet->NetConsoleMode)) { return; } +#ifdef CONFIG_SK98LIN_NAPI + if (netif_rx_schedule_prep(dev)) { + CLEAR_AND_START_RX(0); + CLEAR_TX_IRQ(0, TX_PRIO_LOW); + pAC->GIni.GIValIrqMask &= ~(NAPI_DRV_IRQS); + SK_OUT32(pAC->IoBase, B0_IMSK, pAC->GIni.GIValIrqMask); + __netif_rx_schedule(dev); + } + +#ifdef USE_TX_COMPLETE /* only if tx complete interrupt used */ + if (IntSrc & IS_XA1_F) { + CLEAR_TX_IRQ(0, TX_PRIO_LOW); + } +#endif +#else while (((IntSrc & IRQ_MASK) & ~SPECIAL_IRQS) != 0) { #if 0 /* software irq currently not used */ if (IntSrc & IS_IRQ_SW) { @@ -1459,6 +2081,7 @@ SK_DBGCAT_DRV_INT_SRC, ("EOF RX1 IRQ\n")); ReceiveIrq(pAC, &pAC->RxPort[0], SK_TRUE); + CLEAR_AND_START_RX(0); SK_PNMI_CNT_RX_INTR(pAC, 0); } #ifdef USE_TX_COMPLETE /* only if tx complete interrupt used */ @@ -1466,6 +2089,7 @@ SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_INT_SRC, ("EOF AS TX1 IRQ\n")); + CLEAR_TX_IRQ(0, TX_PRIO_LOW); SK_PNMI_CNT_TX_INTR(pAC, 0); spin_lock(&pAC->TxPort[0][TX_PRIO_LOW].TxDesRingLock); FreeTxDescriptors(pAC, &pAC->TxPort[0][TX_PRIO_LOW]); @@ -1476,24 +2100,18 @@ SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_INT_SRC, ("EOF SY TX1 IRQ\n")); + CLEAR_TX_IRQ(0, TX_PRIO_HIGH); SK_PNMI_CNT_TX_INTR(pAC, 0); spin_lock(&pAC->TxPort[0][TX_PRIO_HIGH].TxDesRingLock); FreeTxDescriptors(pAC, 0, TX_PRIO_HIGH); spin_unlock(&pAC->TxPort[0][TX_PRIO_HIGH].TxDesRingLock); - ClearTxIrq(pAC, 0, TX_PRIO_HIGH); } #endif #endif - /* do all IO at once */ - if (IntSrc & IS_R1_F) - ClearAndStartRx(pAC, 0); -#ifdef USE_TX_COMPLETE /* only if tx complete interrupt used */ - if (IntSrc & IS_XA1_F) - ClearTxIrq(pAC, 0, TX_PRIO_LOW); -#endif SK_IN32(pAC->IoBase, B0_ISRC, &IntSrc); } /* while (IntSrc & IRQ_MASK != 0) */ +#endif IntSrc &= pAC->GIni.GIValIrqMask; if ((IntSrc & SPECIAL_IRQS) || pAC->CheckQueue) { @@ -1507,17 +2125,10 @@ SkEventDispatcher(pAC, pAC->IoBase); spin_unlock(&pAC->SlowPathLock); } - /* - * do it all again is case we cleared an interrupt that - * came in after handling the ring (OUTs may be delayed - * in hardware buffers, but are through after IN) - * - * rroesler: has been commented out and shifted to - * SkGeDrvEvent(), because it is timer - * guarded now - * + +#ifndef CONFIG_SK98LIN_NAPI ReceiveIrq(pAC, &pAC->RxPort[0], SK_TRUE); - */ +#endif /* IRQ is processed - Enable IRQs again*/ SK_OUT32(pAC->IoBase, B0_IMSK, pAC->GIni.GIValIrqMask); @@ -1525,7 +2136,6 @@ return; } /* SkGeIsrOnePort */ - /**************************************************************************** * * SkGeOpen - handle start of initialized adapter @@ -1543,27 +2153,23 @@ * != 0 on error */ static int SkGeOpen( -struct SK_NET_DEVICE *dev) +struct SK_NET_DEVICE *dev) /* the device that is to be opened */ { - DEV_NET *pNet; - SK_AC *pAC; - unsigned long Flags; /* for spin lock */ - int i; - SK_EVPARA EvPara; /* an event parameter union */ + DEV_NET *pNet = (DEV_NET*) dev->priv; + SK_AC *pAC = pNet->pAC; + unsigned long Flags; /* for the spin locks */ + unsigned long InitFlags; /* for the spin locks */ + int CurrMac; /* loop ctr for ports */ - pNet = (DEV_NET*) dev->priv; - pAC = pNet->pAC; - SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY, ("SkGeOpen: pAC=0x%lX:\n", (unsigned long)pAC)); + spin_lock_irqsave(&pAC->InitLock, InitFlags); -#ifdef SK_DIAG_SUPPORT if (pAC->DiagModeActive == DIAG_ACTIVE) { if (pAC->Pnmi.DiagAttached == SK_DIAG_RUNNING) { return (-1); /* still in use by diag; deny actions */ } } -#endif /* Set blink mode */ @@ -1583,6 +2189,11 @@ SkRlmtInit (pAC, pAC->IoBase, SK_INIT_IO); SkTimerInit (pAC, pAC->IoBase, SK_INIT_IO); pAC->BoardLevel = SK_INIT_IO; +#ifdef Y2_RECOVERY + /* mark entries invalid */ + pAC->LastPort = 3; + pAC->LastOpc = 0xFF; +#endif } if (pAC->BoardLevel != SK_INIT_RUN) { @@ -1600,46 +2211,63 @@ pAC->BoardLevel = SK_INIT_RUN; } - for (i=0; iGIni.GIMacsFound; i++) { - /* Enable transmit descriptor polling. */ - SkGePollTxD(pAC, pAC->IoBase, i, SK_TRUE); - FillRxRing(pAC, &pAC->RxPort[i]); + for (CurrMac=0; CurrMacGIni.GIMacsFound; CurrMac++) { + if (!CHIP_ID_YUKON_2(pAC)) { + /* Enable transmit descriptor polling. */ + SkGePollTxD(pAC, pAC->IoBase, CurrMac, SK_TRUE); + FillRxRing(pAC, &pAC->RxPort[CurrMac]); + SkMacRxTxEnable(pAC, pAC->IoBase, pNet->PortNr); + } } - SkGeYellowLED(pAC, pAC->IoBase, 1); - StartDrvCleanupTimer(pAC); + SkGeYellowLED(pAC, pAC->IoBase, 1); SkDimEnableModerationIfNeeded(pAC); - SkDimDisplayModerationSettings(pAC); - pAC->GIni.GIValIrqMask &= IRQ_MASK; - - /* enable Interrupts */ - SK_OUT32(pAC->IoBase, B0_IMSK, pAC->GIni.GIValIrqMask); - SK_OUT32(pAC->IoBase, B0_HWE_IMSK, IRQ_HWE_MASK); + if (!CHIP_ID_YUKON_2(pAC)) { + /* + ** Has been setup already at SkGeInit(SK_INIT_IO), + ** but additional masking added for Genesis & Yukon + ** chipsets -> modify it... + */ + pAC->GIni.GIValIrqMask &= IRQ_MASK; +#ifndef USE_TX_COMPLETE + pAC->GIni.GIValIrqMask &= ~(TX_COMPL_IRQS); +#endif + } spin_lock_irqsave(&pAC->SlowPathLock, Flags); if ((pAC->RlmtMode != 0) && (pAC->MaxPorts == 0)) { - EvPara.Para32[0] = pAC->RlmtNets; - EvPara.Para32[1] = -1; - SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_SET_NETS, - EvPara); - EvPara.Para32[0] = pAC->RlmtMode; - EvPara.Para32[1] = 0; - SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_MODE_CHANGE, - EvPara); + SkLocalEventQueue(pAC, SKGE_RLMT, SK_RLMT_SET_NETS, + pAC->RlmtNets, -1, SK_FALSE); + SkLocalEventQueue(pAC, SKGE_RLMT, SK_RLMT_MODE_CHANGE, + pAC->RlmtMode, 0, SK_FALSE); } - EvPara.Para32[0] = pNet->NetNr; - EvPara.Para32[1] = -1; - SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_START, EvPara); - SkEventDispatcher(pAC, pAC->IoBase); + SkLocalEventQueue(pAC, SKGE_RLMT, SK_RLMT_START, + pNet->NetNr, -1, SK_TRUE); spin_unlock_irqrestore(&pAC->SlowPathLock, Flags); - pAC->MaxPorts++; - pNet->Up = 1; +#ifdef Y2_RECOVERY + pNet->TimerExpired = SK_FALSE; + pNet->InRecover = SK_FALSE; + pNet->NetConsoleMode = SK_FALSE; + + /* Initialize the kernel timer */ + init_timer(&pNet->KernelTimer); + pNet->KernelTimer.function = SkGeHandleKernelTimer; + pNet->KernelTimer.data = (unsigned long) pNet; + pNet->KernelTimer.expires = jiffies + (HZ/4); /* initially 250ms */ + add_timer(&pNet->KernelTimer); +#endif + + /* enable Interrupts */ + SK_OUT32(pAC->IoBase, B0_IMSK, pAC->GIni.GIValIrqMask); + SK_OUT32(pAC->IoBase, B0_HWE_IMSK, IRQ_HWE_MASK); + pAC->MaxPorts++; MOD_INC_USE_COUNT; + spin_unlock_irqrestore(&pAC->InitLock, InitFlags); SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY, ("SkGeOpen suceeded\n")); @@ -1660,24 +2288,28 @@ * error code - on error */ static int SkGeClose( -struct SK_NET_DEVICE *dev) +struct SK_NET_DEVICE *dev) /* the device that is to be closed */ { - DEV_NET *pNet; - DEV_NET *newPtrNet; - SK_AC *pAC; - - unsigned long Flags; /* for spin lock */ - int i; - int PortIdx; - SK_EVPARA EvPara; - + DEV_NET *pNet = (DEV_NET*) dev->priv; + SK_AC *pAC = pNet->pAC; + DEV_NET *newPtrNet; + unsigned long Flags; /* for the spin locks */ + unsigned long InitFlags; /* for the spin locks */ + int CurrMac; /* loop ctr for the current MAC */ + int PortIdx; +#ifdef CONFIG_SK98LIN_NAPI + int WorkToDo = 1; /* min(*budget, dev->quota); */ + int WorkDone = 0; +#endif SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY, ("SkGeClose: pAC=0x%lX ", (unsigned long)pAC)); + spin_lock_irqsave(&pAC->InitLock, InitFlags); - pNet = (DEV_NET*) dev->priv; - pAC = pNet->pAC; +#ifdef Y2_RECOVERY + pNet->InRecover = SK_TRUE; + del_timer(&pNet->KernelTimer); +#endif -#ifdef SK_DIAG_SUPPORT if (pAC->DiagModeActive == DIAG_ACTIVE) { if (pAC->DiagFlowCtrl == SK_FALSE) { MOD_DEC_USE_COUNT; @@ -1697,7 +2329,6 @@ pAC->DiagFlowCtrl = SK_FALSE; } } -#endif netif_stop_queue(dev); @@ -1706,8 +2337,6 @@ else PortIdx = pNet->NetNr; - StopDrvCleanupTimer(pAC); - /* * Clear multicast table, promiscuous mode .... */ @@ -1719,46 +2348,101 @@ spin_lock_irqsave(&pAC->SlowPathLock, Flags); /* disable interrupts */ SK_OUT32(pAC->IoBase, B0_IMSK, 0); - EvPara.Para32[0] = pNet->NetNr; - EvPara.Para32[1] = -1; - SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_STOP, EvPara); - SkEventDispatcher(pAC, pAC->IoBase); + SkLocalEventQueue(pAC, SKGE_RLMT, SK_RLMT_STOP, + pNet->NetNr, -1, SK_TRUE); SK_OUT32(pAC->IoBase, B0_IMSK, 0); /* stop the hardware */ - SkGeDeInit(pAC, pAC->IoBase); - pAC->BoardLevel = SK_INIT_DATA; + + + if ((pAC->GIni.GIMacsFound == 2 ) && (pAC->RlmtNets == 1)) { + /* RLMT check link state mode */ + for (CurrMac=0; CurrMacGIni.GIMacsFound; CurrMac++) { + if (CHIP_ID_YUKON_2(pAC)) + SkY2PortStop( pAC, + pAC->IoBase, + CurrMac, + SK_STOP_ALL, + SK_HARD_RST); + else + SkGeStopPort( pAC, + pAC->IoBase, + CurrMac, + SK_STOP_ALL, + SK_HARD_RST); + } /* for */ + } else { + /* Single link or single port */ + if (CHIP_ID_YUKON_2(pAC)) + SkY2PortStop( pAC, + pAC->IoBase, + PortIdx, + SK_STOP_ALL, + SK_HARD_RST); + else + SkGeStopPort( pAC, + pAC->IoBase, + PortIdx, + SK_STOP_ALL, + SK_HARD_RST); + } spin_unlock_irqrestore(&pAC->SlowPathLock, Flags); } else { - spin_lock_irqsave(&pAC->SlowPathLock, Flags); - EvPara.Para32[0] = pNet->NetNr; - EvPara.Para32[1] = -1; - SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_STOP, EvPara); - SkPnmiEvent(pAC, pAC->IoBase, SK_PNMI_EVT_XMAC_RESET, EvPara); - SkEventDispatcher(pAC, pAC->IoBase); + SkLocalEventQueue(pAC, SKGE_RLMT, SK_RLMT_STOP, + pNet->NetNr, -1, SK_FALSE); + SkLocalEventQueue(pAC, SKGE_PNMI, SK_PNMI_EVT_XMAC_RESET, + pNet->NetNr, -1, SK_TRUE); spin_unlock_irqrestore(&pAC->SlowPathLock, Flags); /* Stop port */ spin_lock_irqsave(&pAC->TxPort[pNet->PortNr] [TX_PRIO_LOW].TxDesRingLock, Flags); - SkGeStopPort(pAC, pAC->IoBase, pNet->PortNr, - SK_STOP_ALL, SK_HARD_RST); + if (CHIP_ID_YUKON_2(pAC)) { + SkY2PortStop(pAC, pAC->IoBase, pNet->PortNr, + SK_STOP_ALL, SK_HARD_RST); + } + else { + SkGeStopPort(pAC, pAC->IoBase, pNet->PortNr, + SK_STOP_ALL, SK_HARD_RST); + } spin_unlock_irqrestore(&pAC->TxPort[pNet->PortNr] [TX_PRIO_LOW].TxDesRingLock, Flags); } if (pAC->RlmtNets == 1) { /* clear all descriptor rings */ - for (i=0; iGIni.GIMacsFound; i++) { - ReceiveIrq(pAC, &pAC->RxPort[i], SK_TRUE); - ClearRxRing(pAC, &pAC->RxPort[i]); - ClearTxRing(pAC, &pAC->TxPort[i][TX_PRIO_LOW]); + for (CurrMac=0; CurrMacGIni.GIMacsFound; CurrMac++) { + if (!CHIP_ID_YUKON_2(pAC)) { +#ifdef CONFIG_SK98LIN_NAPI + WorkToDo = 1; + ReceiveIrq(pAC,&pAC->RxPort[CurrMac], + SK_TRUE,&WorkDone,WorkToDo); +#else + ReceiveIrq(pAC,&pAC->RxPort[CurrMac],SK_TRUE); +#endif + ClearRxRing(pAC, &pAC->RxPort[CurrMac]); + ClearTxRing(pAC, &pAC->TxPort[CurrMac][TX_PRIO_LOW]); + } else { + SkY2FreeRxBuffers(pAC, pAC->IoBase, CurrMac); + SkY2FreeTxBuffers(pAC, pAC->IoBase, CurrMac); + } } } else { /* clear port descriptor rings */ - ReceiveIrq(pAC, &pAC->RxPort[pNet->PortNr], SK_TRUE); - ClearRxRing(pAC, &pAC->RxPort[pNet->PortNr]); - ClearTxRing(pAC, &pAC->TxPort[pNet->PortNr][TX_PRIO_LOW]); + if (!CHIP_ID_YUKON_2(pAC)) { +#ifdef CONFIG_SK98LIN_NAPI + WorkToDo = 1; + ReceiveIrq(pAC, &pAC->RxPort[pNet->PortNr], SK_TRUE, &WorkDone, WorkToDo); +#else + ReceiveIrq(pAC, &pAC->RxPort[pNet->PortNr], SK_TRUE); +#endif + ClearRxRing(pAC, &pAC->RxPort[pNet->PortNr]); + ClearTxRing(pAC, &pAC->TxPort[pNet->PortNr][TX_PRIO_LOW]); + } + else { + SkY2FreeRxBuffers(pAC, pAC->IoBase, pNet->PortNr); + SkY2FreeTxBuffers(pAC, pAC->IoBase, pNet->PortNr); + } } SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY, @@ -1769,9 +2453,13 @@ sizeof(SK_PNMI_STRUCT_DATA)); pAC->MaxPorts--; - pNet->Up = 0; - MOD_DEC_USE_COUNT; + +#ifdef Y2_RECOVERY + pNet->InRecover = SK_FALSE; +#endif + spin_unlock_irqrestore(&pAC->InitLock, InitFlags); + return (0); } /* SkGeClose */ @@ -1829,9 +2517,11 @@ } /* Transmitter out of resources? */ +#ifdef USE_TX_COMPLETE if (Rc <= 0) { netif_stop_queue(dev); } +#endif /* If not taken, give buffer ownership back to the * queueing layer. @@ -1843,6 +2533,115 @@ return (0); } /* SkGeXmit */ +#ifdef CONFIG_SK98LIN_NAPI +/***************************************************************************** + * + * SkGePoll - NAPI Rx polling callback for GEnesis and Yukon chipsets + * + * Description: + * Called by the Linux system in case NAPI polling is activated + * + * Returns: + * The number of work data still to be handled + */ +static int SkGePoll(struct net_device *dev, int *budget) +{ + SK_AC *pAC = ((DEV_NET*)(dev->priv))->pAC; /* pointer to adapter context */ + int WorkToDo = min(*budget, dev->quota); + int WorkDone = 0; + unsigned long Flags; + + + if (pAC->dev[0] != pAC->dev[1]) { + spin_lock(&pAC->TxPort[1][TX_PRIO_LOW].TxDesRingLock); + FreeTxDescriptors(pAC, &pAC->TxPort[1][TX_PRIO_LOW]); + spin_unlock(&pAC->TxPort[1][TX_PRIO_LOW].TxDesRingLock); + + ReceiveIrq(pAC, &pAC->RxPort[1], SK_TRUE, &WorkDone, WorkToDo); + CLEAR_AND_START_RX(1); + } + spin_lock(&pAC->TxPort[0][TX_PRIO_LOW].TxDesRingLock); + FreeTxDescriptors(pAC, &pAC->TxPort[0][TX_PRIO_LOW]); + spin_unlock(&pAC->TxPort[0][TX_PRIO_LOW].TxDesRingLock); + + ReceiveIrq(pAC, &pAC->RxPort[0], SK_TRUE, &WorkDone, WorkToDo); + CLEAR_AND_START_RX(0); + + *budget -= WorkDone; + dev->quota -= WorkDone; + + if(WorkDone < WorkToDo) { + spin_lock_irqsave(&pAC->SlowPathLock, Flags); + netif_rx_complete(dev); + pAC->GIni.GIValIrqMask |= (NAPI_DRV_IRQS); +#ifndef USE_TX_COMPLETE + pAC->GIni.GIValIrqMask &= ~(TX_COMPL_IRQS); +#endif + /* enable interrupts again */ + SK_OUT32(pAC->IoBase, B0_IMSK, pAC->GIni.GIValIrqMask); + spin_unlock_irqrestore(&pAC->SlowPathLock, Flags); + } + return (WorkDone >= WorkToDo); +} /* SkGePoll */ +#endif + +#ifdef SK_POLL_CONTROLLER +/***************************************************************************** + * + * SkGeNetPoll - Polling "interrupt" + * + * Description: + * Polling 'interrupt' - used by things like netconsole and netdump + * to send skbs without having to re-enable interrupts. + * It's not called while the interrupt routine is executing. + */ +static void SkGeNetPoll( +struct SK_NET_DEVICE *dev) +{ +DEV_NET *pNet; +SK_AC *pAC; + + pNet = (DEV_NET*) dev->priv; + pAC = pNet->pAC; + pNet->NetConsoleMode = SK_TRUE; + + if (unlikely(netdump_mode)) { + int bogus_budget = 64; + + if (CHIP_ID_YUKON_2(pAC)) { + SkY2Isr(dev->irq, dev, NULL); + if (dev->poll_list.prev) + SkY2Poll(dev, &bogus_budget); + } else { + if (pAC->GIni.GIMacsFound == 2) + SkGeIsr(dev->irq, dev, NULL); + else + SkGeIsrOnePort(dev->irq, dev, NULL); + if (dev->poll_list.prev) + SkGePoll(dev, &bogus_budget); + } + + + } else { + /* Prevent any reconfiguration while handling + the 'interrupt' */ + SK_OUT32(pAC->IoBase, B0_IMSK, 0); + + if (!CHIP_ID_YUKON_2(pAC)) { + /* Handle the GENESIS Isr */ + if (pAC->GIni.GIMacsFound == 2) + SkGeIsr(dev->irq, dev, NULL); + else + SkGeIsrOnePort(dev->irq, dev, NULL); + } else { + /* Handle the Yukon2 Isr */ + SkY2Isr(dev->irq, dev, NULL); + } + + } +} +#endif + /***************************************************************************** * @@ -1867,7 +2666,7 @@ * < 0 - on failure: other problems ( -> return failure to upper layers) */ static int XmitFrame( -SK_AC *pAC, /* pointer to adapter context */ +SK_AC *pAC, /* pointer to adapter context */ TX_PORT *pTxPort, /* pointer to struct of port to send to */ struct sk_buff *pMessage) /* pointer to send-message */ { @@ -1883,11 +2682,14 @@ spin_lock_irqsave(&pTxPort->TxDesRingLock, Flags); #ifndef USE_TX_COMPLETE - FreeTxDescriptors(pAC, pTxPort); + if ((pTxPort->TxdRingPrevFree - pTxPort->TxdRingFree) > 6) { + FreeTxDescriptors(pAC, pTxPort); + pTxPort->TxdRingPrevFree = pTxPort->TxdRingFree; + } #endif if (pTxPort->TxdRingFree == 0) { /* - ** no enough free descriptors in ring at the moment. + ** not enough free descriptors in ring at the moment. ** Maybe free'ing some old one help? */ FreeTxDescriptors(pAC, pTxPort); @@ -1915,6 +2717,7 @@ */ if (BytesSend < C_LEN_ETHERNET_MINSIZE) { if ((pMessage = skb_padto(pMessage, C_LEN_ETHERNET_MINSIZE)) == NULL) { + spin_unlock_irqrestore(&pTxPort->TxDesRingLock, Flags); return 0; } pMessage->len = C_LEN_ETHERNET_MINSIZE; @@ -1972,7 +2775,7 @@ BMU_IRQ_EOF | #endif pMessage->len; - } else { + } else { pTxd->TBControl = BMU_OWN | BMU_STF | BMU_CHECK | BMU_SW | BMU_EOF | #ifdef USE_TX_COMPLETE @@ -2308,7 +3111,7 @@ SK_U16 Length; /* data fragment length */ SK_U64 PhysAddr; /* physical address of a rx buffer */ - pMsgBlock = alloc_skb(pAC->RxBufSize, GFP_ATOMIC); + pMsgBlock = alloc_skb(pRxPort->RxBufSize, GFP_ATOMIC); if (pMsgBlock == NULL) { SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY, @@ -2322,12 +3125,12 @@ pRxd = pRxPort->pRxdRingTail; pRxPort->pRxdRingTail = pRxd->pNextRxd; pRxPort->RxdRingFree--; - Length = pAC->RxBufSize; + Length = pRxPort->RxBufSize; PhysAddr = (SK_U64) pci_map_page(pAC->PciDev, virt_to_page(pMsgBlock->data), ((unsigned long) pMsgBlock->data & ~PAGE_MASK), - pAC->RxBufSize - 2, + pRxPort->RxBufSize - 2, PCI_DMA_FROMDEVICE); pRxd->VDataLow = (SK_U32) (PhysAddr & 0xffffffff); @@ -2367,7 +3170,7 @@ pRxd = pRxPort->pRxdRingTail; pRxPort->pRxdRingTail = pRxd->pNextRxd; pRxPort->RxdRingFree--; - Length = pAC->RxBufSize; + Length = pRxPort->RxBufSize; pRxd->VDataLow = PhysLow; pRxd->VDataHigh = PhysHigh; @@ -2392,33 +3195,40 @@ * Returns: N/A */ static void ReceiveIrq( - SK_AC *pAC, /* pointer to adapter context */ - RX_PORT *pRxPort, /* pointer to receive port struct */ - SK_BOOL SlowPathLock) /* indicates if SlowPathLock is needed */ -{ -RXD *pRxd; /* pointer to receive descriptors */ -SK_U32 Control; /* control field of descriptor */ -struct sk_buff *pMsg; /* pointer to message holding frame */ -struct sk_buff *pNewMsg; /* pointer to a new message for copying frame */ -int FrameLength; /* total length of received frame */ -int IpFrameLength; -SK_MBUF *pRlmtMbuf; /* ptr to a buffer for giving a frame to rlmt */ -SK_EVPARA EvPara; /* an event parameter union */ -unsigned long Flags; /* for spin lock */ -int PortIndex = pRxPort->PortIndex; -unsigned int Offset; -unsigned int NumBytes; -unsigned int ForRlmt; -SK_BOOL IsBc; -SK_BOOL IsMc; -SK_BOOL IsBadFrame; /* Bad frame */ - -SK_U32 FrameStat; -unsigned short Csum1; -unsigned short Csum2; -unsigned short Type; -int Result; -SK_U64 PhysAddr; +#ifdef CONFIG_SK98LIN_NAPI +SK_AC *pAC, /* pointer to adapter context */ +RX_PORT *pRxPort, /* pointer to receive port struct */ +SK_BOOL SlowPathLock, /* indicates if SlowPathLock is needed */ +int *WorkDone, +int WorkToDo) +#else +SK_AC *pAC, /* pointer to adapter context */ +RX_PORT *pRxPort, /* pointer to receive port struct */ +SK_BOOL SlowPathLock) /* indicates if SlowPathLock is needed */ +#endif +{ + RXD *pRxd; /* pointer to receive descriptors */ + struct sk_buff *pMsg; /* pointer to message holding frame */ + struct sk_buff *pNewMsg; /* pointer to new message for frame copy */ + SK_MBUF *pRlmtMbuf; /* ptr to buffer for giving frame to RLMT */ + SK_EVPARA EvPara; /* an event parameter union */ + SK_U32 Control; /* control field of descriptor */ + unsigned long Flags; /* for spin lock handling */ + int PortIndex = pRxPort->PortIndex; + int FrameLength; /* total length of received frame */ + int IpFrameLength; /* IP length of the received frame */ + unsigned int Offset; + unsigned int NumBytes; + unsigned int RlmtNotifier; + SK_BOOL IsBc; /* we received a broadcast packet */ + SK_BOOL IsMc; /* we received a multicast packet */ + SK_BOOL IsBadFrame; /* the frame received is bad! */ + SK_U32 FrameStat; + unsigned short Csum1; + unsigned short Csum2; + unsigned short Type; + int Result; + SK_U64 PhysAddr; rx_start: /* do forever; exit if BMU_OWN found */ @@ -2440,6 +3250,13 @@ Control = pRxd->RBControl; +#ifdef CONFIG_SK98LIN_NAPI + if (*WorkDone >= WorkToDo) { + break; + } + (*WorkDone)++; +#endif + /* check if this descriptor is ready */ if ((Control & BMU_OWN) != 0) { /* this descriptor is not yet ready */ @@ -2448,11 +3265,10 @@ FillRxRing(pAC, pRxPort); return; } - pAC->DynIrqModInfo.NbrProcessedDescr++; /* get length of frame and check it */ FrameLength = Control & BMU_BBC; - if (FrameLength > pAC->RxBufSize) { + if (FrameLength > pRxPort->RxBufSize) { goto rx_failed; } @@ -2467,8 +3283,8 @@ FrameStat = pRxd->FrameStat; /* check for frame length mismatch */ -#define XMR_FS_LEN_SHIFT 18 -#define GMR_FS_LEN_SHIFT 16 +#define XMR_FS_LEN_SHIFT 18 +#define GMR_FS_LEN_SHIFT 16 if (pAC->GIni.GIChipId == CHIP_ID_GENESIS) { if (FrameLength != (SK_U32) (FrameStat >> XMR_FS_LEN_SHIFT)) { SK_DBG_MSG(NULL, SK_DBGMOD_DRV, @@ -2478,8 +3294,7 @@ (SK_U32) (FrameStat >> XMR_FS_LEN_SHIFT))); goto rx_failed; } - } - else { + } else { if (FrameLength != (SK_U32) (FrameStat >> GMR_FS_LEN_SHIFT)) { SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_RX_PROGRESS, @@ -2512,9 +3327,6 @@ /* DumpMsg(pMsg, "Rx"); */ if ((Control & BMU_STAT_VAL) != BMU_STAT_VAL || (IsBadFrame)) { -#if 0 - (FrameStat & (XMR_FS_ANY_ERR | XMR_FS_2L_VLAN)) != 0) { -#endif /* there is a receive error in this frame */ SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_RX_PROGRESS, @@ -2524,10 +3336,18 @@ PhysAddr = ((SK_U64) pRxd->VDataHigh) << (SK_U64)32; PhysAddr |= (SK_U64) pRxd->VDataLow; + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,5) pci_dma_sync_single(pAC->PciDev, (dma_addr_t) PhysAddr, FrameLength, PCI_DMA_FROMDEVICE); +#else + pci_dma_sync_single_for_cpu(pAC->PciDev, + (dma_addr_t) PhysAddr, + FrameLength, + PCI_DMA_FROMDEVICE); +#endif ReQueueRxBuffer(pAC, pRxPort, pMsg, pRxd->VDataHigh, pRxd->VDataLow); @@ -2547,11 +3367,18 @@ skb_put(pNewMsg, FrameLength); PhysAddr = ((SK_U64) pRxd->VDataHigh) << (SK_U64)32; PhysAddr |= (SK_U64) pRxd->VDataLow; - +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,5) pci_dma_sync_single(pAC->PciDev, (dma_addr_t) PhysAddr, FrameLength, PCI_DMA_FROMDEVICE); +#else + pci_dma_sync_single_for_device(pAC->PciDev, + (dma_addr_t) PhysAddr, + FrameLength, + PCI_DMA_FROMDEVICE); +#endif + eth_copy_and_sum(pNewMsg, pMsg->data, FrameLength, 0); ReQueueRxBuffer(pAC, pRxPort, pMsg, @@ -2559,134 +3386,88 @@ pMsg = pNewMsg; - } - else { + } else { /* * if large frame, or SKB allocation failed, pass * the SKB directly to the networking */ - PhysAddr = ((SK_U64) pRxd->VDataHigh) << (SK_U64)32; PhysAddr |= (SK_U64) pRxd->VDataLow; /* release the DMA mapping */ pci_unmap_single(pAC->PciDev, PhysAddr, - pAC->RxBufSize - 2, + pRxPort->RxBufSize - 2, PCI_DMA_FROMDEVICE); + skb_put(pMsg, FrameLength); /* set message len */ + pMsg->ip_summed = CHECKSUM_NONE; /* initial default */ - /* set length in message */ - skb_put(pMsg, FrameLength); - /* hardware checksum */ - Type = ntohs(*((short*)&pMsg->data[12])); - -#ifdef USE_SK_RX_CHECKSUM - if (Type == 0x800) { - Csum1=le16_to_cpu(pRxd->TcpSums & 0xffff); - Csum2=le16_to_cpu((pRxd->TcpSums >> 16) & 0xffff); - IpFrameLength = (int) ntohs((unsigned short) - ((unsigned short *) pMsg->data)[8]); - - /* - * Test: If frame is padded, a check is not possible! - * Frame not padded? Length difference must be 14 (0xe)! - */ - if ((FrameLength - IpFrameLength) != 0xe) { - /* Frame padded => TCP offload not possible! */ - pMsg->ip_summed = CHECKSUM_NONE; - } else { - /* Frame not padded => TCP offload! */ - if ((((Csum1 & 0xfffe) && (Csum2 & 0xfffe)) && - (pAC->GIni.GIChipId == CHIP_ID_GENESIS)) || - (pAC->ChipsetType)) { - Result = SkCsGetReceiveInfo(pAC, - &pMsg->data[14], - Csum1, Csum2, pRxPort->PortIndex); - if (Result == - SKCS_STATUS_IP_FRAGMENT || - Result == - SKCS_STATUS_IP_CSUM_OK || - Result == - SKCS_STATUS_TCP_CSUM_OK || - Result == - SKCS_STATUS_UDP_CSUM_OK) { - pMsg->ip_summed = - CHECKSUM_UNNECESSARY; - } - else if (Result == - SKCS_STATUS_TCP_CSUM_ERROR || - Result == - SKCS_STATUS_UDP_CSUM_ERROR || - Result == - SKCS_STATUS_IP_CSUM_ERROR_UDP || - Result == - SKCS_STATUS_IP_CSUM_ERROR_TCP || - Result == - SKCS_STATUS_IP_CSUM_ERROR ) { - /* HW Checksum error */ - SK_DBG_MSG(NULL, SK_DBGMOD_DRV, - SK_DBGCAT_DRV_RX_PROGRESS, - ("skge: CRC error. Frame dropped!\n")); - goto rx_failed; - } else { - pMsg->ip_summed = - CHECKSUM_NONE; - } - }/* checksumControl calculation valid */ - } /* Frame length check */ - } /* IP frame */ -#else - pMsg->ip_summed = CHECKSUM_NONE; -#endif + if (pRxPort->UseRxCsum) { + Type = ntohs(*((short*)&pMsg->data[12])); + if (Type == 0x800) { + IpFrameLength = (int) ntohs((unsigned short) + ((unsigned short *) pMsg->data)[8]); + if ((FrameLength - IpFrameLength) == 0xe) { + Csum1=le16_to_cpu(pRxd->TcpSums & 0xffff); + Csum2=le16_to_cpu((pRxd->TcpSums >> 16) & 0xffff); + if ((((Csum1 & 0xfffe) && (Csum2 & 0xfffe)) && + (pAC->GIni.GIChipId == CHIP_ID_GENESIS)) || + (pAC->ChipsetType)) { + Result = SkCsGetReceiveInfo(pAC, &pMsg->data[14], + Csum1, Csum2, PortIndex); + if ((Result == SKCS_STATUS_IP_FRAGMENT) || + (Result == SKCS_STATUS_IP_CSUM_OK) || + (Result == SKCS_STATUS_TCP_CSUM_OK) || + (Result == SKCS_STATUS_UDP_CSUM_OK)) { + pMsg->ip_summed = CHECKSUM_UNNECESSARY; + } else if ((Result == SKCS_STATUS_TCP_CSUM_ERROR) || + (Result == SKCS_STATUS_UDP_CSUM_ERROR) || + (Result == SKCS_STATUS_IP_CSUM_ERROR_UDP) || + (Result == SKCS_STATUS_IP_CSUM_ERROR_TCP) || + (Result == SKCS_STATUS_IP_CSUM_ERROR)) { + /* HW Checksum error */ + SK_DBG_MSG(NULL, SK_DBGMOD_DRV, + SK_DBGCAT_DRV_RX_PROGRESS, + ("skge: CRC error. Frame dropped!\n")); + goto rx_failed; + } else { + pMsg->ip_summed = CHECKSUM_NONE; + } + }/* checksumControl calculation valid */ + } /* Frame length check */ + } /* IP frame */ + } /* pRxPort->UseRxCsum */ } /* frame > SK_COPY_TRESHOLD */ SK_DBG_MSG(NULL, SK_DBGMOD_DRV, 1,("V")); - ForRlmt = SK_RLMT_RX_PROTOCOL; -#if 0 - IsBc = (FrameStat & XMR_FS_BC)==XMR_FS_BC; -#endif + RlmtNotifier = SK_RLMT_RX_PROTOCOL; SK_RLMT_PRE_LOOKAHEAD(pAC, PortIndex, FrameLength, - IsBc, &Offset, &NumBytes); - if (NumBytes != 0) { -#if 0 - IsMc = (FrameStat & XMR_FS_MC)==XMR_FS_MC; -#endif - SK_RLMT_LOOKAHEAD(pAC, PortIndex, - &pMsg->data[Offset], - IsBc, IsMc, &ForRlmt); + IsBc, &Offset, &NumBytes); + if (NumBytes != 0) { + SK_RLMT_LOOKAHEAD(pAC,PortIndex,&pMsg->data[Offset], + IsBc,IsMc,&RlmtNotifier); } - if (ForRlmt == SK_RLMT_RX_PROTOCOL) { - SK_DBG_MSG(NULL, SK_DBGMOD_DRV, 1,("W")); + if (RlmtNotifier == SK_RLMT_RX_PROTOCOL) { + SK_DBG_MSG(NULL, SK_DBGMOD_DRV, 1,("W")); /* send up only frames from active port */ - if ((PortIndex == pAC->ActivePort) || - (pAC->RlmtNets == 2)) { - /* frame for upper layer */ + if ((PortIndex == pAC->ActivePort)||(pAC->RlmtNets == 2)) { SK_DBG_MSG(NULL, SK_DBGMOD_DRV, 1,("U")); #ifdef xDEBUG DumpMsg(pMsg, "Rx"); #endif - SK_PNMI_CNT_RX_OCTETS_DELIVERED(pAC, - FrameLength, pRxPort->PortIndex); - - pMsg->dev = pAC->dev[pRxPort->PortIndex]; - pMsg->protocol = eth_type_trans(pMsg, - pAC->dev[pRxPort->PortIndex]); - netif_rx(pMsg); - pAC->dev[pRxPort->PortIndex]->last_rx = jiffies; - } - else { - /* drop frame */ + SK_PNMI_CNT_RX_OCTETS_DELIVERED(pAC,FrameLength,PortIndex); + pMsg->dev = pAC->dev[PortIndex]; + pMsg->protocol = eth_type_trans(pMsg,pAC->dev[PortIndex]); + netif_rx(pMsg); /* frame for upper layer */ + pAC->dev[PortIndex]->last_rx = jiffies; + } else { SK_DBG_MSG(NULL, SK_DBGMOD_DRV, - SK_DBGCAT_DRV_RX_PROGRESS, - ("D")); - DEV_KFREE_SKB(pMsg); + SK_DBGCAT_DRV_RX_PROGRESS,("D")); + DEV_KFREE_SKB(pMsg); /* drop frame */ } - - } /* if not for rlmt */ - else { - /* packet for rlmt */ + } else { /* packet for RLMT stack */ SK_DBG_MSG(NULL, SK_DBGMOD_DRV, - SK_DBGCAT_DRV_RX_PROGRESS, ("R")); + SK_DBGCAT_DRV_RX_PROGRESS,("R")); pRlmtMbuf = SkDrvAllocRlmtMbuf(pAC, pAC->IoBase, FrameLength); if (pRlmtMbuf != NULL) { @@ -2714,32 +3495,22 @@ } SK_DBG_MSG(NULL, SK_DBGMOD_DRV, - SK_DBGCAT_DRV_RX_PROGRESS, - ("Q")); + SK_DBGCAT_DRV_RX_PROGRESS,("Q")); } - if ((pAC->dev[pRxPort->PortIndex]->flags & - (IFF_PROMISC | IFF_ALLMULTI)) != 0 || - (ForRlmt & SK_RLMT_RX_PROTOCOL) == - SK_RLMT_RX_PROTOCOL) { - pMsg->dev = pAC->dev[pRxPort->PortIndex]; - pMsg->protocol = eth_type_trans(pMsg, - pAC->dev[pRxPort->PortIndex]); + if ((pAC->dev[PortIndex]->flags & (IFF_PROMISC | IFF_ALLMULTI)) || + (RlmtNotifier & SK_RLMT_RX_PROTOCOL)) { + pMsg->dev = pAC->dev[PortIndex]; + pMsg->protocol = eth_type_trans(pMsg,pAC->dev[PortIndex]); netif_rx(pMsg); - pAC->dev[pRxPort->PortIndex]->last_rx = jiffies; - } - else { + pAC->dev[PortIndex]->last_rx = jiffies; + } else { DEV_KFREE_SKB(pMsg); } - - } /* if packet for rlmt */ + } /* if packet for RLMT stack */ } /* for ... scanning the RXD ring */ /* RXD ring is empty -> fill and restart */ FillRxRing(pAC, pRxPort); - /* do not start if called from Close */ - if (pAC->BoardLevel > SK_INIT_DATA) { - ClearAndStartRx(pAC, PortIndex); - } return; rx_failed: @@ -2753,7 +3524,7 @@ PhysAddr |= (SK_U64) pRxd->VDataLow; pci_unmap_page(pAC->PciDev, PhysAddr, - pAC->RxBufSize - 2, + pRxPort->RxBufSize - 2, PCI_DMA_FROMDEVICE); DEV_KFREE_SKB_IRQ(pRxd->pMBuf); pRxd->pMBuf = NULL; @@ -2763,49 +3534,6 @@ } /* ReceiveIrq */ - -/***************************************************************************** - * - * ClearAndStartRx - give a start receive command to BMU, clear IRQ - * - * Description: - * This function sends a start command and a clear interrupt - * command for one receive queue to the BMU. - * - * Returns: N/A - * none - */ -static void ClearAndStartRx( -SK_AC *pAC, /* pointer to the adapter context */ -int PortIndex) /* index of the receive port (XMAC) */ -{ - SK_OUT8(pAC->IoBase, - RxQueueAddr[PortIndex]+Q_CSR, - CSR_START | CSR_IRQ_CL_F); -} /* ClearAndStartRx */ - - -/***************************************************************************** - * - * ClearTxIrq - give a clear transmit IRQ command to BMU - * - * Description: - * This function sends a clear tx IRQ command for one - * transmit queue to the BMU. - * - * Returns: N/A - */ -static void ClearTxIrq( -SK_AC *pAC, /* pointer to the adapter context */ -int PortIndex, /* index of the transmit port (XMAC) */ -int Prio) /* priority or normal queue */ -{ - SK_OUT8(pAC->IoBase, - TxQueueAddr[PortIndex][Prio]+Q_CSR, - CSR_IRQ_CL_F); -} /* ClearTxIrq */ - - /***************************************************************************** * * ClearRxRing - remove all buffers from the receive ring @@ -2836,7 +3564,7 @@ PhysAddr |= (SK_U64) pRxd->VDataLow; pci_unmap_page(pAC->PciDev, PhysAddr, - pAC->RxBufSize - 2, + pRxPort->RxBufSize - 2, PCI_DMA_FROMDEVICE); DEV_KFREE_SKB(pRxd->pMBuf); pRxd->pMBuf = NULL; @@ -2896,29 +3624,30 @@ DEV_NET *pNet = (DEV_NET*) dev->priv; SK_AC *pAC = pNet->pAC; +int Ret; struct sockaddr *addr = p; unsigned long Flags; SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY, ("SkGeSetMacAddr starts now...\n")); - if(netif_running(dev)) - return -EBUSY; memcpy(dev->dev_addr, addr->sa_data,dev->addr_len); spin_lock_irqsave(&pAC->SlowPathLock, Flags); if (pAC->RlmtNets == 2) - SkAddrOverride(pAC, pAC->IoBase, pNet->NetNr, + Ret = SkAddrOverride(pAC, pAC->IoBase, pNet->NetNr, (SK_MAC_ADDR*)dev->dev_addr, SK_ADDR_VIRTUAL_ADDRESS); else - SkAddrOverride(pAC, pAC->IoBase, pAC->ActivePort, + Ret = SkAddrOverride(pAC, pAC->IoBase, pAC->ActivePort, (SK_MAC_ADDR*)dev->dev_addr, SK_ADDR_VIRTUAL_ADDRESS); - - spin_unlock_irqrestore(&pAC->SlowPathLock, Flags); + + if (Ret != SK_ADDR_OVERRIDE_SUCCESS) + return -EBUSY; + return 0; } /* SkGeSetMacAddr */ @@ -3000,6 +3729,45 @@ /***************************************************************************** * + * SkSetMtuBufferSize - set the MTU buffer to another value + * + * Description: + * This function sets the new buffers and is called whenever the MTU + * size is changed + * + * Returns: + * N/A + */ + +static void SkSetMtuBufferSize( +SK_AC *pAC, /* pointer to adapter context */ +int PortNr, /* Port number */ +int Mtu) /* pointer to tx prt struct */ +{ + pAC->RxPort[PortNr].RxBufSize = Mtu + 32; + + /* RxBufSize must be a multiple of 8 */ + while (pAC->RxPort[PortNr].RxBufSize % 8) { + pAC->RxPort[PortNr].RxBufSize = + pAC->RxPort[PortNr].RxBufSize + 1; + } + + if (Mtu > 1500) { + pAC->GIni.GP[PortNr].PPortUsage = SK_JUMBO_LINK; + } else { + if ((pAC->GIni.GIMacsFound == 2 ) && (pAC->RlmtNets == 2)) { + pAC->GIni.GP[PortNr].PPortUsage = SK_MUL_LINK; + } else { + pAC->GIni.GP[PortNr].PPortUsage = SK_RED_LINK; + } + } + + return; +} + + +/***************************************************************************** + * * SkGeChangeMtu - set the MTU to another value * * Description: @@ -3013,12 +3781,13 @@ */ static int SkGeChangeMtu(struct SK_NET_DEVICE *dev, int NewMtu) { -DEV_NET *pNet; -DEV_NET *pOtherNet; -SK_AC *pAC; -unsigned long Flags; -int i; -SK_EVPARA EvPara; +DEV_NET *pNet; +SK_AC *pAC; +unsigned long Flags; +#ifdef CONFIG_SK98LIN_NAPI +int WorkToDo = 1; // min(*budget, dev->quota); +int WorkDone = 0; +#endif SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY, ("SkGeChangeMtu starts now...\n")); @@ -3026,15 +3795,18 @@ pNet = (DEV_NET*) dev->priv; pAC = pNet->pAC; + /* MTU size outside the spec */ if ((NewMtu < 68) || (NewMtu > SK_JUMBO_MTU)) { return -EINVAL; } - if(pAC->BoardLevel != SK_INIT_RUN) { + /* MTU > 1500 on yukon ulra not allowed */ + if ((pAC->GIni.GIChipId == CHIP_ID_YUKON_EC_U) + && (NewMtu > 1500)){ return -EINVAL; } -#ifdef SK_DIAG_SUPPORT + /* Diag access active */ if (pAC->DiagModeActive == DIAG_ACTIVE) { if (pAC->DiagFlowCtrl == SK_FALSE) { return -1; /* still in use, deny any actions of MTU */ @@ -3042,201 +3814,74 @@ pAC->DiagFlowCtrl = SK_FALSE; } } -#endif - - pNet->Mtu = NewMtu; - pOtherNet = (DEV_NET*)pAC->dev[1 - pNet->NetNr]->priv; - if ((pOtherNet->Mtu>1500) && (NewMtu<=1500) && (pOtherNet->Up==1)) { - return(0); - } - pAC->RxBufSize = NewMtu + 32; dev->mtu = NewMtu; + SkSetMtuBufferSize(pAC, pNet->PortNr, NewMtu); - SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY, - ("New MTU: %d\n", NewMtu)); + if(!netif_running(dev)) { + /* Preset MTU size if device not ready/running */ + return 0; + } - /* - ** Prevent any reconfiguration while changing the MTU - ** by disabling any interrupts - */ + /* Prevent any reconfiguration while changing the MTU + by disabling any interrupts */ SK_OUT32(pAC->IoBase, B0_IMSK, 0); spin_lock_irqsave(&pAC->SlowPathLock, Flags); - /* - ** Notify RLMT that any ports are to be stopped - */ - EvPara.Para32[0] = 0; - EvPara.Para32[1] = -1; - if ((pAC->GIni.GIMacsFound == 2 ) && (pAC->RlmtNets == 2)) { - SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_STOP, EvPara); - EvPara.Para32[0] = 1; - SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_STOP, EvPara); - } else { - SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_STOP, EvPara); - } - - /* - ** After calling the SkEventDispatcher(), RLMT is aware about - ** the stopped ports -> configuration can take place! - */ - SkEventDispatcher(pAC, pAC->IoBase); - - for (i=0; iGIni.GIMacsFound; i++) { - spin_lock_irqsave( - &pAC->TxPort[i][TX_PRIO_LOW].TxDesRingLock, Flags); - netif_stop_queue(pAC->dev[i]); + /* Notify RLMT that the port has to be stopped */ + netif_stop_queue(dev); + SkLocalEventQueue(pAC, SKGE_RLMT, SK_RLMT_STOP, + pNet->PortNr, -1, SK_TRUE); + spin_lock(&pAC->TxPort[pNet->PortNr][TX_PRIO_LOW].TxDesRingLock); - } - /* - ** Depending on the desired MTU size change, a different number of - ** RX buffers need to be allocated - */ - if (NewMtu > 1500) { - /* - ** Use less rx buffers - */ - for (i=0; iGIni.GIMacsFound; i++) { - if ((pAC->GIni.GIMacsFound == 2 ) && (pAC->RlmtNets == 2)) { - pAC->RxPort[i].RxFillLimit = pAC->RxDescrPerRing - - (pAC->RxDescrPerRing / 4); - } else { - if (i == pAC->ActivePort) { - pAC->RxPort[i].RxFillLimit = pAC->RxDescrPerRing - - (pAC->RxDescrPerRing / 4); - } else { - pAC->RxPort[i].RxFillLimit = pAC->RxDescrPerRing - - (pAC->RxDescrPerRing / 10); - } - } - } + /* Change RxFillLimit to 1 */ + if ((pAC->GIni.GIMacsFound == 2 ) && (pAC->RlmtNets == 2)) { + pAC->RxPort[pNet->PortNr].RxFillLimit = 1; } else { - /* - ** Use the normal amount of rx buffers - */ - for (i=0; iGIni.GIMacsFound; i++) { - if ((pAC->GIni.GIMacsFound == 2 ) && (pAC->RlmtNets == 2)) { - pAC->RxPort[i].RxFillLimit = 1; - } else { - if (i == pAC->ActivePort) { - pAC->RxPort[i].RxFillLimit = 1; - } else { - pAC->RxPort[i].RxFillLimit = pAC->RxDescrPerRing - - (pAC->RxDescrPerRing / 4); - } - } - } + pAC->RxPort[1 - pNet->PortNr].RxFillLimit = 1; + pAC->RxPort[pNet->PortNr].RxFillLimit = pAC->RxDescrPerRing - + (pAC->RxDescrPerRing / 4); } - - SkGeDeInit(pAC, pAC->IoBase); - /* - ** enable/disable hardware support for long frames - */ - if (NewMtu > 1500) { -// pAC->JumboActivated = SK_TRUE; /* is never set back !!! */ - pAC->GIni.GIPortUsage = SK_JUMBO_LINK; + /* clear and reinit the rx rings here, because of new MTU size */ + if (CHIP_ID_YUKON_2(pAC)) { + SkY2PortStop(pAC, pAC->IoBase, pNet->PortNr, SK_STOP_ALL, SK_SOFT_RST); + SkY2AllocateRxBuffers(pAC, pAC->IoBase, pNet->PortNr); + SkY2PortStart(pAC, pAC->IoBase, pNet->PortNr); } else { - if ((pAC->GIni.GIMacsFound == 2 ) && (pAC->RlmtNets == 2)) { - pAC->GIni.GIPortUsage = SK_MUL_LINK; - } else { - pAC->GIni.GIPortUsage = SK_RED_LINK; - } - } +// SkGeStopPort(pAC, pAC->IoBase, pNet->PortNr, SK_STOP_ALL, SK_SOFT_RST); +#ifdef CONFIG_SK98LIN_NAPI + WorkToDo = 1; + ReceiveIrq(pAC, &pAC->RxPort[pNet->PortNr], SK_TRUE, &WorkDone, WorkToDo); +#else + ReceiveIrq(pAC, &pAC->RxPort[pNet->PortNr], SK_TRUE); +#endif + ClearRxRing(pAC, &pAC->RxPort[pNet->PortNr]); + FillRxRing(pAC, &pAC->RxPort[pNet->PortNr]); - SkGeInit( pAC, pAC->IoBase, SK_INIT_IO); - SkI2cInit( pAC, pAC->IoBase, SK_INIT_IO); - SkEventInit(pAC, pAC->IoBase, SK_INIT_IO); - SkPnmiInit( pAC, pAC->IoBase, SK_INIT_IO); - SkAddrInit( pAC, pAC->IoBase, SK_INIT_IO); - SkRlmtInit( pAC, pAC->IoBase, SK_INIT_IO); - SkTimerInit(pAC, pAC->IoBase, SK_INIT_IO); - - /* - ** tschilling: - ** Speed and others are set back to default in level 1 init! - */ - GetConfiguration(pAC); - - SkGeInit( pAC, pAC->IoBase, SK_INIT_RUN); - SkI2cInit( pAC, pAC->IoBase, SK_INIT_RUN); - SkEventInit(pAC, pAC->IoBase, SK_INIT_RUN); - SkPnmiInit( pAC, pAC->IoBase, SK_INIT_RUN); - SkAddrInit( pAC, pAC->IoBase, SK_INIT_RUN); - SkRlmtInit( pAC, pAC->IoBase, SK_INIT_RUN); - SkTimerInit(pAC, pAC->IoBase, SK_INIT_RUN); + /* Enable transmit descriptor polling */ + SkGePollTxD(pAC, pAC->IoBase, pNet->PortNr, SK_TRUE); + FillRxRing(pAC, &pAC->RxPort[pNet->PortNr]); + } - /* - ** clear and reinit the rx rings here - */ - for (i=0; iGIni.GIMacsFound; i++) { - ReceiveIrq(pAC, &pAC->RxPort[i], SK_TRUE); - ClearRxRing(pAC, &pAC->RxPort[i]); - FillRxRing(pAC, &pAC->RxPort[i]); + netif_start_queue(pAC->dev[pNet->PortNr]); - /* - ** Enable transmit descriptor polling - */ - SkGePollTxD(pAC, pAC->IoBase, i, SK_TRUE); - FillRxRing(pAC, &pAC->RxPort[i]); - }; + spin_unlock(&pAC->TxPort[pNet->PortNr][TX_PRIO_LOW].TxDesRingLock); - SkGeYellowLED(pAC, pAC->IoBase, 1); - SkDimEnableModerationIfNeeded(pAC); - SkDimDisplayModerationSettings(pAC); - netif_start_queue(pAC->dev[pNet->PortNr]); - for (i=pAC->GIni.GIMacsFound-1; i>=0; i--) { - spin_unlock(&pAC->TxPort[i][TX_PRIO_LOW].TxDesRingLock); - } + /* Notify RLMT about the changing and restarting one (or more) ports */ + SkLocalEventQueue(pAC, SKGE_RLMT, SK_RLMT_START, + pNet->PortNr, -1, SK_TRUE); - /* - ** Enable Interrupts again - */ + /* Enable Interrupts again */ SK_OUT32(pAC->IoBase, B0_IMSK, pAC->GIni.GIValIrqMask); SK_OUT32(pAC->IoBase, B0_HWE_IMSK, IRQ_HWE_MASK); - SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_START, EvPara); - SkEventDispatcher(pAC, pAC->IoBase); - - /* - ** Notify RLMT about the changing and restarting one (or more) ports - */ - if ((pAC->GIni.GIMacsFound == 2 ) && (pAC->RlmtNets == 2)) { - EvPara.Para32[0] = pAC->RlmtNets; - EvPara.Para32[1] = -1; - SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_SET_NETS, EvPara); - EvPara.Para32[0] = pNet->PortNr; - EvPara.Para32[1] = -1; - SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_START, EvPara); - - if (pOtherNet->Up) { - EvPara.Para32[0] = pOtherNet->PortNr; - SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_START, EvPara); - } - } else { - SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_START, EvPara); - } - - SkEventDispatcher(pAC, pAC->IoBase); spin_unlock_irqrestore(&pAC->SlowPathLock, Flags); - - /* - ** While testing this driver with latest kernel 2.5 (2.5.70), it - ** seems as if upper layers have a problem to handle a successful - ** return value of '0'. If such a zero is returned, the complete - ** system hangs for several minutes (!), which is in acceptable. - ** - ** Currently it is not clear, what the exact reason for this problem - ** is. The implemented workaround for 2.5 is to return the desired - ** new MTU size if all needed changes for the new MTU size where - ** performed. In kernels 2.2 and 2.4, a zero value is returned, - ** which indicates the successful change of the mtu-size. - */ return 0; -} /* SkGeChangeMtu */ +} /***************************************************************************** @@ -3252,75 +3897,67 @@ */ static struct net_device_stats *SkGeStats(struct SK_NET_DEVICE *dev) { -DEV_NET *pNet = (DEV_NET*) dev->priv; -SK_AC *pAC = pNet->pAC; -SK_PNMI_STRUCT_DATA *pPnmiStruct; /* structure for all Pnmi-Data */ -SK_PNMI_STAT *pPnmiStat; /* pointer to virtual XMAC stat. data */ -SK_PNMI_CONF *pPnmiConf; /* pointer to virtual link config. */ -unsigned int Size; /* size of pnmi struct */ -unsigned long Flags; /* for spin lock */ - - SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY, - ("SkGeStats starts now...\n")); - pPnmiStruct = &pAC->PnmiStruct; + DEV_NET *pNet = (DEV_NET*) dev->priv; + SK_AC *pAC = pNet->pAC; + unsigned long LateCollisions, ExcessiveCollisions, RxTooLong; + unsigned long Flags; /* for spin lock */ + SK_U32 MaxNumOidEntries, Oid, Len; + char Buf[8]; + struct { + SK_U32 Oid; + unsigned long *pVar; + } Vars[] = { + { OID_SKGE_STAT_TX_LATE_COL, &LateCollisions }, + { OID_SKGE_STAT_TX_EXCESS_COL, &ExcessiveCollisions }, + { OID_SKGE_STAT_RX_TOO_LONG, &RxTooLong }, + { OID_SKGE_STAT_RX, &pAC->stats.rx_packets }, + { OID_SKGE_STAT_TX, &pAC->stats.tx_packets }, + { OID_SKGE_STAT_RX_OCTETS, &pAC->stats.rx_bytes }, + { OID_SKGE_STAT_TX_OCTETS, &pAC->stats.tx_bytes }, + { OID_SKGE_RX_NO_BUF_CTS, &pAC->stats.rx_dropped }, + { OID_SKGE_TX_NO_BUF_CTS, &pAC->stats.tx_dropped }, + { OID_SKGE_STAT_RX_MULTICAST, &pAC->stats.multicast }, + { OID_SKGE_STAT_RX_RUNT, &pAC->stats.rx_length_errors }, + { OID_SKGE_STAT_RX_FCS, &pAC->stats.rx_crc_errors }, + { OID_SKGE_STAT_RX_FRAMING, &pAC->stats.rx_frame_errors }, + { OID_SKGE_STAT_RX_OVERFLOW, &pAC->stats.rx_over_errors }, + { OID_SKGE_STAT_RX_MISSED, &pAC->stats.rx_missed_errors }, + { OID_SKGE_STAT_TX_CARRIER, &pAC->stats.tx_carrier_errors }, + { OID_SKGE_STAT_TX_UNDERRUN, &pAC->stats.tx_fifo_errors }, + }; + + if ((pAC->DiagModeActive == DIAG_NOTACTIVE) && + (pAC->BoardLevel == SK_INIT_RUN)) { + memset(&pAC->stats, 0x00, sizeof(pAC->stats)); /* clean first */ + spin_lock_irqsave(&pAC->SlowPathLock, Flags); -#ifdef SK_DIAG_SUPPORT - if ((pAC->DiagModeActive == DIAG_NOTACTIVE) && - (pAC->BoardLevel == SK_INIT_RUN)) { -#endif - SK_MEMSET(pPnmiStruct, 0, sizeof(SK_PNMI_STRUCT_DATA)); - spin_lock_irqsave(&pAC->SlowPathLock, Flags); - Size = SK_PNMI_STRUCT_SIZE; - SkPnmiGetStruct(pAC, pAC->IoBase, pPnmiStruct, &Size, pNet->NetNr); - spin_unlock_irqrestore(&pAC->SlowPathLock, Flags); -#ifdef SK_DIAG_SUPPORT - } -#endif + MaxNumOidEntries = sizeof(Vars) / sizeof(Vars[0]); + for (Oid = 0; Oid < MaxNumOidEntries; Oid++) { + if (SkPnmiGetVar(pAC,pAC->IoBase, Vars[Oid].Oid, + &Buf, &Len, 1, pNet->NetNr) != SK_PNMI_ERR_OK) { + memset(Buf, 0x00, sizeof(Buf)); + } + *Vars[Oid].pVar = (unsigned long) (*((SK_U64 *) Buf)); + } + spin_unlock_irqrestore(&pAC->SlowPathLock, Flags); - pPnmiStat = &pPnmiStruct->Stat[0]; - pPnmiConf = &pPnmiStruct->Conf[0]; + pAC->stats.collisions = LateCollisions + ExcessiveCollisions; + pAC->stats.tx_errors = pAC->stats.tx_carrier_errors + + pAC->stats.tx_fifo_errors; + pAC->stats.rx_errors = pAC->stats.rx_length_errors + + pAC->stats.rx_crc_errors + + pAC->stats.rx_frame_errors + + pAC->stats.rx_over_errors + + pAC->stats.rx_missed_errors; - pAC->stats.rx_packets = (SK_U32) pPnmiStruct->RxDeliveredCts & 0xFFFFFFFF; - pAC->stats.tx_packets = (SK_U32) pPnmiStat->StatTxOkCts & 0xFFFFFFFF; - pAC->stats.rx_bytes = (SK_U32) pPnmiStruct->RxOctetsDeliveredCts; - pAC->stats.tx_bytes = (SK_U32) pPnmiStat->StatTxOctetsOkCts; - - if (pNet->Mtu <= 1500) { - pAC->stats.rx_errors = (SK_U32) pPnmiStruct->InErrorsCts & 0xFFFFFFFF; - } else { - pAC->stats.rx_errors = (SK_U32) ((pPnmiStruct->InErrorsCts - - pPnmiStat->StatRxTooLongCts) & 0xFFFFFFFF); + if (dev->mtu > 1500) { + pAC->stats.rx_errors = pAC->stats.rx_errors - RxTooLong; + } } - - if (pAC->GIni.GP[0].PhyType == SK_PHY_XMAC && pAC->HWRevision < 12) - pAC->stats.rx_errors = pAC->stats.rx_errors - pPnmiStat->StatRxShortsCts; - - pAC->stats.tx_errors = (SK_U32) pPnmiStat->StatTxSingleCollisionCts & 0xFFFFFFFF; - pAC->stats.rx_dropped = (SK_U32) pPnmiStruct->RxNoBufCts & 0xFFFFFFFF; - pAC->stats.tx_dropped = (SK_U32) pPnmiStruct->TxNoBufCts & 0xFFFFFFFF; - pAC->stats.multicast = (SK_U32) pPnmiStat->StatRxMulticastOkCts & 0xFFFFFFFF; - pAC->stats.collisions = (SK_U32) pPnmiStat->StatTxSingleCollisionCts & 0xFFFFFFFF; - - /* detailed rx_errors: */ - pAC->stats.rx_length_errors = (SK_U32) pPnmiStat->StatRxRuntCts & 0xFFFFFFFF; - pAC->stats.rx_over_errors = (SK_U32) pPnmiStat->StatRxFifoOverflowCts & 0xFFFFFFFF; - pAC->stats.rx_crc_errors = (SK_U32) pPnmiStat->StatRxFcsCts & 0xFFFFFFFF; - pAC->stats.rx_frame_errors = (SK_U32) pPnmiStat->StatRxFramingCts & 0xFFFFFFFF; - pAC->stats.rx_fifo_errors = (SK_U32) pPnmiStat->StatRxFifoOverflowCts & 0xFFFFFFFF; - pAC->stats.rx_missed_errors = (SK_U32) pPnmiStat->StatRxMissedCts & 0xFFFFFFFF; - - /* detailed tx_errors */ - pAC->stats.tx_aborted_errors = (SK_U32) 0; - pAC->stats.tx_carrier_errors = (SK_U32) pPnmiStat->StatTxCarrierCts & 0xFFFFFFFF; - pAC->stats.tx_fifo_errors = (SK_U32) pPnmiStat->StatTxFifoUnderrunCts & 0xFFFFFFFF; - pAC->stats.tx_heartbeat_errors = (SK_U32) pPnmiStat->StatTxCarrierCts & 0xFFFFFFFF; - pAC->stats.tx_window_errors = (SK_U32) 0; - return(&pAC->stats); } /* SkGeStats */ - /***************************************************************************** * * SkGeIoctl - IO-control function @@ -3334,32 +3971,35 @@ * 0, if everything is ok * !=0, on error */ -static int SkGeIoctl(struct SK_NET_DEVICE *dev, struct ifreq *rq, int cmd) -{ -DEV_NET *pNet; -SK_AC *pAC; -void *pMemBuf; -struct pci_dev *pdev = NULL; -SK_GE_IOCTL Ioctl; -unsigned int Err = 0; -int Size = 0; -int Ret = 0; -unsigned int Length = 0; -int HeaderLength = sizeof(SK_U32) + sizeof(SK_U32); +static int SkGeIoctl( +struct SK_NET_DEVICE *dev, /* the device the IOCTL is to be performed on */ +struct ifreq *rq, /* additional request structure containing data */ +int cmd) /* requested IOCTL command number */ +{ + DEV_NET *pNet = (DEV_NET*) dev->priv; + SK_AC *pAC = pNet->pAC; + struct pci_dev *pdev = NULL; + void *pMemBuf; + SK_GE_IOCTL Ioctl; + unsigned long Flags; /* for spin lock */ + unsigned int Err = 0; + unsigned int Length = 0; + int HeaderLength = sizeof(SK_U32) + sizeof(SK_U32); + int Size = 0; + int Ret = 0; SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY, ("SkGeIoctl starts now...\n")); - pNet = (DEV_NET*) dev->priv; - pAC = pNet->pAC; - if(copy_from_user(&Ioctl, rq->ifr_data, sizeof(SK_GE_IOCTL))) { return -EFAULT; } switch(cmd) { - case SK_IOCTL_SETMIB: - case SK_IOCTL_PRESETMIB: + case SIOCETHTOOL: + return SkEthIoctl(dev, rq); + case SK_IOCTL_SETMIB: /* FALL THRU */ + case SK_IOCTL_PRESETMIB: /* FALL THRU (if capable!) */ if (!capable(CAP_NET_ADMIN)) return -EPERM; case SK_IOCTL_GETMIB: if(copy_from_user(&pAC->PnmiStruct, Ioctl.pData, @@ -3386,6 +4026,7 @@ if (NULL == (pMemBuf = kmalloc(Length, GFP_KERNEL))) { return -ENOMEM; } + spin_lock_irqsave(&pAC->SlowPathLock, Flags); if(copy_from_user(pMemBuf, Ioctl.pData, Length)) { Err = -EFAULT; goto fault_gen; @@ -3404,10 +4045,10 @@ goto fault_gen; } fault_gen: + spin_unlock_irqrestore(&pAC->SlowPathLock, Flags); kfree(pMemBuf); /* cleanup everything */ break; -#ifdef SK_DIAG_SUPPORT - case SK_IOCTL_DIAG: + case SK_IOCTL_DIAG: if (!capable(CAP_NET_ADMIN)) return -EPERM; if (Ioctl.Len < (sizeof(pAC->PnmiStruct) + HeaderLength)) { Length = Ioctl.Len; @@ -3444,7 +4085,6 @@ fault_diag: kfree(pMemBuf); /* cleanup everything */ break; -#endif default: Err = -EOPNOTSUPP; } @@ -3476,12 +4116,12 @@ unsigned int Size, /* length of ioctl data */ int mode) /* flag for set/preset */ { -unsigned long Flags; /* for spin lock */ -SK_AC *pAC; + SK_AC *pAC = pNet->pAC; + unsigned long Flags; /* for spin lock */ SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY, ("SkGeIocMib starts now...\n")); - pAC = pNet->pAC; + /* access MIB */ spin_lock_irqsave(&pAC->SlowPathLock, Flags); switch(mode) { @@ -3524,17 +4164,18 @@ SK_I32 Port; /* preferred port */ SK_BOOL AutoSet; SK_BOOL DupSet; -int LinkSpeed = SK_LSPEED_AUTO; /* Link speed */ -int AutoNeg = 1; /* autoneg off (0) or on (1) */ -int DuplexCap = 0; /* 0=both,1=full,2=half */ -int FlowCtrl = SK_FLOW_MODE_SYM_OR_REM; /* FlowControl */ -int MSMode = SK_MS_MODE_AUTO; /* master/slave mode */ - -SK_BOOL IsConTypeDefined = SK_TRUE; -SK_BOOL IsLinkSpeedDefined = SK_TRUE; -SK_BOOL IsFlowCtrlDefined = SK_TRUE; -SK_BOOL IsRoleDefined = SK_TRUE; -SK_BOOL IsModeDefined = SK_TRUE; +int LinkSpeed = SK_LSPEED_AUTO; /* Link speed */ +int AutoNeg = 1; /* autoneg off (0) or on (1) */ +int DuplexCap = 0; /* 0=both,1=full,2=half */ +int FlowCtrl = SK_FLOW_MODE_SYM_OR_REM; /* FlowControl */ +int MSMode = SK_MS_MODE_AUTO; /* master/slave mode */ +int IrqModMaskOffset = 6; /* all ints moderated=default */ + +SK_BOOL IsConTypeDefined = SK_TRUE; +SK_BOOL IsLinkSpeedDefined = SK_TRUE; +SK_BOOL IsFlowCtrlDefined = SK_TRUE; +SK_BOOL IsRoleDefined = SK_TRUE; +SK_BOOL IsModeDefined = SK_TRUE; /* * The two parameters AutoNeg. and DuplexCap. map to one configuration * parameter. The mapping is described by this table: @@ -3552,6 +4193,15 @@ {SK_LMODE_AUTOBOTH , SK_LMODE_AUTOFULL , SK_LMODE_AUTOHALF }, {SK_LMODE_AUTOSENSE, SK_LMODE_AUTOSENSE, SK_LMODE_AUTOSENSE} }; +SK_U32 IrqModMask[7][2] = + { { IRQ_MASK_RX_ONLY , Y2_DRIVER_IRQS }, + { IRQ_MASK_TX_ONLY , Y2_DRIVER_IRQS }, + { IRQ_MASK_SP_ONLY , Y2_SPECIAL_IRQS }, + { IRQ_MASK_SP_RX , Y2_IRQ_MASK }, + { IRQ_MASK_TX_RX , Y2_DRIVER_IRQS }, + { IRQ_MASK_SP_TX , Y2_IRQ_MASK }, + { IRQ_MASK_RX_TX_SP, Y2_IRQ_MASK } }; + #define DC_BOTH 0 #define DC_FULL 1 #define DC_HALF 2 @@ -3591,7 +4241,7 @@ ** ** This ConType parameter is used for all ports of the adapter! */ - if ( (ConType != NULL) && + if ( (ConType != NULL) && (pAC->Index < SK_MAX_CARD_PARAM) && (ConType[pAC->Index] != NULL) ) { @@ -3617,40 +4267,40 @@ M_CurrPort.PMSMode = SK_MS_MODE_AUTO; M_CurrPort.PLinkSpeed = SK_LSPEED_AUTO; } - } else if (strcmp(ConType[pAC->Index],"100FD")==0) { + } else if (strcmp(ConType[pAC->Index],"100FD")==0) { for (Port = 0; Port < SK_MAX_MACS; Port++) { M_CurrPort.PLinkModeConf = Capabilities[AN_OFF][DC_FULL]; M_CurrPort.PFlowCtrlMode = SK_FLOW_MODE_NONE; M_CurrPort.PMSMode = SK_MS_MODE_AUTO; M_CurrPort.PLinkSpeed = SK_LSPEED_100MBPS; } - } else if (strcmp(ConType[pAC->Index],"100HD")==0) { + } else if (strcmp(ConType[pAC->Index],"100HD")==0) { for (Port = 0; Port < SK_MAX_MACS; Port++) { M_CurrPort.PLinkModeConf = Capabilities[AN_OFF][DC_HALF]; M_CurrPort.PFlowCtrlMode = SK_FLOW_MODE_NONE; M_CurrPort.PMSMode = SK_MS_MODE_AUTO; M_CurrPort.PLinkSpeed = SK_LSPEED_100MBPS; } - } else if (strcmp(ConType[pAC->Index],"10FD")==0) { + } else if (strcmp(ConType[pAC->Index],"10FD")==0) { for (Port = 0; Port < SK_MAX_MACS; Port++) { M_CurrPort.PLinkModeConf = Capabilities[AN_OFF][DC_FULL]; M_CurrPort.PFlowCtrlMode = SK_FLOW_MODE_NONE; M_CurrPort.PMSMode = SK_MS_MODE_AUTO; M_CurrPort.PLinkSpeed = SK_LSPEED_10MBPS; } - } else if (strcmp(ConType[pAC->Index],"10HD")==0) { + } else if (strcmp(ConType[pAC->Index],"10HD")==0) { for (Port = 0; Port < SK_MAX_MACS; Port++) { M_CurrPort.PLinkModeConf = Capabilities[AN_OFF][DC_HALF]; M_CurrPort.PFlowCtrlMode = SK_FLOW_MODE_NONE; M_CurrPort.PMSMode = SK_MS_MODE_AUTO; M_CurrPort.PLinkSpeed = SK_LSPEED_10MBPS; } - } else { + } else { printk("sk98lin: Illegal value \"%s\" for ConType\n", ConType[pAC->Index]); IsConTypeDefined = SK_FALSE; /* Wrong ConType defined */ } - } else { + } else { IsConTypeDefined = SK_FALSE; /* No ConType defined */ } @@ -3669,14 +4319,30 @@ } else if (strcmp(Speed_A[pAC->Index],"100")==0) { LinkSpeed = SK_LSPEED_100MBPS; } else if (strcmp(Speed_A[pAC->Index],"1000")==0) { - LinkSpeed = SK_LSPEED_1000MBPS; + if ((pAC->PciDev->vendor == 0x11ab ) && + (pAC->PciDev->device == 0x4350)) { + LinkSpeed = SK_LSPEED_100MBPS; + printk("sk98lin: Illegal value \"%s\" for Speed_A.\n" + "Gigabit speed not possible with this chip revision!", + Speed_A[pAC->Index]); + } else { + LinkSpeed = SK_LSPEED_1000MBPS; + } } else { printk("sk98lin: Illegal value \"%s\" for Speed_A\n", Speed_A[pAC->Index]); IsLinkSpeedDefined = SK_FALSE; } } else { - IsLinkSpeedDefined = SK_FALSE; + if ((pAC->PciDev->vendor == 0x11ab ) && + (pAC->PciDev->device == 0x4350)) { + /* Gigabit speed not supported + * Swith to speed 100 + */ + LinkSpeed = SK_LSPEED_100MBPS; + } else { + IsLinkSpeedDefined = SK_FALSE; + } } /* @@ -3771,9 +4437,6 @@ } if (!AutoSet && DupSet) { - printk("sk98lin: Port A: Duplex setting not" - " possible in\n default AutoNegotiation mode" - " (Sense).\n Using AutoNegotiation On\n"); AutoNeg = AN_ON; } @@ -3801,7 +4464,7 @@ FlowCtrl = SK_FLOW_MODE_NONE; } else { printk("sk98lin: Illegal value \"%s\" for FlowCtrl_A\n", - FlowCtrl_A[pAC->Index]); + FlowCtrl_A[pAC->Index]); IsFlowCtrlDefined = SK_FALSE; } } else { @@ -3893,7 +4556,7 @@ ** Decide whether to set new config value if somethig valid has ** been received. */ - if (IsLinkSpeedDefined) { + if (IsLinkSpeedDefined) { pAC->GIni.GP[1].PLinkSpeed = LinkSpeed; } @@ -3969,9 +4632,6 @@ } if (!AutoSet && DupSet) { - printk("sk98lin: Port B: Duplex setting not" - " possible in\n default AutoNegotiation mode" - " (Sense).\n Using AutoNegotiation On\n"); AutoNeg = AN_ON; } @@ -4084,11 +4744,15 @@ } pAC->RlmtNets = 1; + pAC->RlmtMode = 0; if (RlmtMode != NULL && pAC->IndexIndex] != NULL) { if (strcmp(RlmtMode[pAC->Index], "") == 0) { - pAC->RlmtMode = 0; + if (pAC->GIni.GIMacsFound == 2) { + pAC->RlmtMode = SK_RLMT_CHECK_LINK; + pAC->RlmtNets = 2; + } } else if (strcmp(RlmtMode[pAC->Index], "CheckLinkState") == 0) { pAC->RlmtMode = SK_RLMT_CHECK_LINK; } else if (strcmp(RlmtMode[pAC->Index], "CheckLocalPort") == 0) { @@ -4109,12 +4773,37 @@ pAC->RlmtMode = 0; } } else { - pAC->RlmtMode = 0; + if (pAC->GIni.GIMacsFound == 2) { + pAC->RlmtMode = SK_RLMT_CHECK_LINK; + pAC->RlmtNets = 2; + } } - + +#ifdef SK_YUKON2 + /* + ** use dualnet config per default + * + pAC->RlmtMode = SK_RLMT_CHECK_LINK; + pAC->RlmtNets = 2; + */ +#endif + + + /* + ** Check the LowLatance parameters + */ + pAC->LowLatency = SK_FALSE; + if (LowLatency[pAC->Index] != NULL) { + if (strcmp(LowLatency[pAC->Index], "On") == 0) { + pAC->LowLatency = SK_TRUE; + } + } + + /* ** Check the interrupt moderation parameters */ + pAC->DynIrqModInfo.IntModTypeSelect = C_INT_MOD_NONE; if (Moderation[pAC->Index] != NULL) { if (strcmp(Moderation[pAC->Index], "") == 0) { pAC->DynIrqModInfo.IntModTypeSelect = C_INT_MOD_NONE; @@ -4128,70 +4817,49 @@ printk("sk98lin: Illegal value \"%s\" for Moderation.\n" " Disable interrupt moderation.\n", Moderation[pAC->Index]); - pAC->DynIrqModInfo.IntModTypeSelect = C_INT_MOD_NONE; - } - } else { - pAC->DynIrqModInfo.IntModTypeSelect = C_INT_MOD_NONE; - } - - if (Stats[pAC->Index] != NULL) { - if (strcmp(Stats[pAC->Index], "Yes") == 0) { - pAC->DynIrqModInfo.DisplayStats = SK_TRUE; - } else { - pAC->DynIrqModInfo.DisplayStats = SK_FALSE; } } else { - pAC->DynIrqModInfo.DisplayStats = SK_FALSE; +/* Set interrupt moderation if wished */ +#ifdef CONFIG_SK98LIN_STATINT + pAC->DynIrqModInfo.IntModTypeSelect = C_INT_MOD_STATIC; +#endif } if (ModerationMask[pAC->Index] != NULL) { if (strcmp(ModerationMask[pAC->Index], "Rx") == 0) { - pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_RX_ONLY; + IrqModMaskOffset = 0; } else if (strcmp(ModerationMask[pAC->Index], "Tx") == 0) { - pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_TX_ONLY; + IrqModMaskOffset = 1; } else if (strcmp(ModerationMask[pAC->Index], "Sp") == 0) { - pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_SP_ONLY; + IrqModMaskOffset = 2; } else if (strcmp(ModerationMask[pAC->Index], "RxSp") == 0) { - pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_SP_RX; + IrqModMaskOffset = 3; } else if (strcmp(ModerationMask[pAC->Index], "SpRx") == 0) { - pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_SP_RX; + IrqModMaskOffset = 3; } else if (strcmp(ModerationMask[pAC->Index], "RxTx") == 0) { - pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_TX_RX; + IrqModMaskOffset = 4; } else if (strcmp(ModerationMask[pAC->Index], "TxRx") == 0) { - pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_TX_RX; + IrqModMaskOffset = 4; } else if (strcmp(ModerationMask[pAC->Index], "TxSp") == 0) { - pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_SP_TX; + IrqModMaskOffset = 5; } else if (strcmp(ModerationMask[pAC->Index], "SpTx") == 0) { - pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_SP_TX; - } else if (strcmp(ModerationMask[pAC->Index], "RxTxSp") == 0) { - pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_RX_TX_SP; - } else if (strcmp(ModerationMask[pAC->Index], "RxSpTx") == 0) { - pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_RX_TX_SP; - } else if (strcmp(ModerationMask[pAC->Index], "TxRxSp") == 0) { - pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_RX_TX_SP; - } else if (strcmp(ModerationMask[pAC->Index], "TxSpRx") == 0) { - pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_RX_TX_SP; - } else if (strcmp(ModerationMask[pAC->Index], "SpTxRx") == 0) { - pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_RX_TX_SP; - } else if (strcmp(ModerationMask[pAC->Index], "SpRxTx") == 0) { - pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_RX_TX_SP; - } else { /* some rubbish */ - pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_RX_ONLY; - } - } else { /* operator has stated nothing */ - pAC->DynIrqModInfo.MaskIrqModeration = IRQ_MASK_TX_RX; - } - - if (AutoSizing[pAC->Index] != NULL) { - if (strcmp(AutoSizing[pAC->Index], "On") == 0) { - pAC->DynIrqModInfo.AutoSizing = SK_FALSE; - } else { - pAC->DynIrqModInfo.AutoSizing = SK_FALSE; + IrqModMaskOffset = 5; + } else { /* some rubbish stated */ + // IrqModMaskOffset = 6; ->has been initialized + // already at the begin of this function... } - } else { /* operator has stated nothing */ - pAC->DynIrqModInfo.AutoSizing = SK_FALSE; + } + if (!CHIP_ID_YUKON_2(pAC)) { + pAC->DynIrqModInfo.MaskIrqModeration = IrqModMask[IrqModMaskOffset][0]; + } else { + pAC->DynIrqModInfo.MaskIrqModeration = IrqModMask[IrqModMaskOffset][1]; } + if (!CHIP_ID_YUKON_2(pAC)) { + pAC->DynIrqModInfo.MaxModIntsPerSec = C_INTS_PER_SEC_DEFAULT; + } else { + pAC->DynIrqModInfo.MaxModIntsPerSec = C_Y2_INTS_PER_SEC_DEFAULT; + } if (IntsPerSec[pAC->Index] != 0) { if ((IntsPerSec[pAC->Index]< C_INT_MOD_IPS_LOWER_RANGE) || (IntsPerSec[pAC->Index] > C_INT_MOD_IPS_UPPER_RANGE)) { @@ -4200,28 +4868,25 @@ IntsPerSec[pAC->Index], C_INT_MOD_IPS_LOWER_RANGE, C_INT_MOD_IPS_UPPER_RANGE, - C_INTS_PER_SEC_DEFAULT); - pAC->DynIrqModInfo.MaxModIntsPerSec = C_INTS_PER_SEC_DEFAULT; + pAC->DynIrqModInfo.MaxModIntsPerSec); } else { pAC->DynIrqModInfo.MaxModIntsPerSec = IntsPerSec[pAC->Index]; } - } else { - pAC->DynIrqModInfo.MaxModIntsPerSec = C_INTS_PER_SEC_DEFAULT; - } + } /* ** Evaluate upper and lower moderation threshold */ pAC->DynIrqModInfo.MaxModIntsPerSecUpperLimit = pAC->DynIrqModInfo.MaxModIntsPerSec + - (pAC->DynIrqModInfo.MaxModIntsPerSec / 2); + (pAC->DynIrqModInfo.MaxModIntsPerSec / 5); pAC->DynIrqModInfo.MaxModIntsPerSecLowerLimit = pAC->DynIrqModInfo.MaxModIntsPerSec - - (pAC->DynIrqModInfo.MaxModIntsPerSec / 2); - - pAC->DynIrqModInfo.PrevTimeVal = jiffies; /* initial value */ + (pAC->DynIrqModInfo.MaxModIntsPerSec / 5); + pAC->DynIrqModInfo.DynIrqModSampleInterval = + SK_DRV_MODERATION_TIMER_LENGTH; } /* GetConfiguration */ @@ -4236,65 +4901,21 @@ * * Returns: N/A */ -static void ProductStr( -SK_AC *pAC /* pointer to adapter context */ -) -{ -int StrLen = 80; /* length of the string, defined in SK_AC */ -char Keyword[] = VPD_NAME; /* vpd productname identifier */ -int ReturnCode; /* return code from vpd_read */ -unsigned long Flags; +static void ProductStr(SK_AC *pAC) +{ + char Default[] = "Generic Marvell Yukon chipset Ethernet device"; + char Key[] = VPD_NAME; /* VPD productname key */ + int StrLen = 80; /* stringlen */ + unsigned long Flags; spin_lock_irqsave(&pAC->SlowPathLock, Flags); - ReturnCode = VpdRead(pAC, pAC->IoBase, Keyword, pAC->DeviceStr, - &StrLen); - spin_unlock_irqrestore(&pAC->SlowPathLock, Flags); - if (ReturnCode != 0) { - /* there was an error reading the vpd data */ + if (VpdRead(pAC, pAC->IoBase, Key, pAC->DeviceStr, &StrLen)) { SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ERROR, - ("Error reading VPD data: %d\n", ReturnCode)); - pAC->DeviceStr[0] = '\0'; - } -} /* ProductStr */ - -/***************************************************************************** - * - * StartDrvCleanupTimer - Start timer to check for descriptors which - * might be placed in descriptor ring, but - * havent been handled up to now - * - * Description: - * This function requests a HW-timer fo the Yukon card. The actions to - * perform when this timer expires, are located in the SkDrvEvent(). - * - * Returns: N/A - */ -static void -StartDrvCleanupTimer(SK_AC *pAC) { - SK_EVPARA EventParam; /* Event struct for timer event */ - - SK_MEMSET((char *) &EventParam, 0, sizeof(EventParam)); - EventParam.Para32[0] = SK_DRV_RX_CLEANUP_TIMER; - SkTimerStart(pAC, pAC->IoBase, &pAC->DrvCleanupTimer, - SK_DRV_RX_CLEANUP_TIMER_LENGTH, - SKGE_DRV, SK_DRV_TIMER, EventParam); -} - -/***************************************************************************** - * - * StopDrvCleanupTimer - Stop timer to check for descriptors - * - * Description: - * This function requests a HW-timer fo the Yukon card. The actions to - * perform when this timer expires, are located in the SkDrvEvent(). - * - * Returns: N/A - */ -static void -StopDrvCleanupTimer(SK_AC *pAC) { - SkTimerStop(pAC, pAC->IoBase, &pAC->DrvCleanupTimer); - SK_MEMSET((char *) &pAC->DrvCleanupTimer, 0, sizeof(SK_TIMER)); -} + ("Error reading VPD data: %d\n", ReturnCode)); + strcpy(pAC->DeviceStr, Default); + } + spin_unlock_irqrestore(&pAC->SlowPathLock, Flags); +} /* ProductStr */ /****************************************************************************/ /* functions for common modules *********************************************/ @@ -4384,7 +5005,9 @@ SK_U64 SkOsGetTime(SK_AC *pAC) { SK_U64 PrivateJiffies; + SkOsGetTimeCurrent(pAC, &PrivateJiffies); + return PrivateJiffies; } /* SkOsGetTime */ @@ -4539,29 +5162,27 @@ * */ int SkDrvEvent( -SK_AC *pAC, /* pointer to adapter context */ -SK_IOC IoC, /* io-context */ -SK_U32 Event, /* event-id */ -SK_EVPARA Param) /* event-parameter */ -{ -SK_MBUF *pRlmtMbuf; /* pointer to a rlmt-mbuf structure */ -struct sk_buff *pMsg; /* pointer to a message block */ -int FromPort; /* the port from which we switch away */ -int ToPort; /* the port we switch to */ -SK_EVPARA NewPara; /* parameter for further events */ -int Stat; -unsigned long Flags; -SK_BOOL DualNet; +SK_AC *pAC, /* pointer to adapter context */ +SK_IOC IoC, /* IO control context */ +SK_U32 Event, /* event-id */ +SK_EVPARA Param) /* event-parameter */ +{ + SK_MBUF *pRlmtMbuf; /* pointer to a rlmt-mbuf structure */ + struct sk_buff *pMsg; /* pointer to a message block */ + SK_BOOL DualNet; + SK_U32 Reason; + unsigned long Flags; + unsigned long InitFlags; + int FromPort; /* the port from which we switch away */ + int ToPort; /* the port we switch to */ + int Stat; + DEV_NET *pNet = NULL; +#ifdef CONFIG_SK98LIN_NAPI + int WorkToDo = 1; /* min(*budget, dev->quota); */ + int WorkDone = 0; +#endif switch (Event) { - case SK_DRV_ADAP_FAIL: - SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_EVENT, - ("ADAPTER FAIL EVENT\n")); - printk("%s: Adapter failed.\n", pAC->dev[0]->name); - /* disable interrupts */ - SK_OUT32(pAC->IoBase, B0_IMSK, 0); - /* cgoos */ - break; case SK_DRV_PORT_FAIL: FromPort = Param.Para32[0]; SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_EVENT, @@ -4571,222 +5192,296 @@ } else { printk("%s: Port B failed.\n", pAC->dev[1]->name); } - /* cgoos */ break; - case SK_DRV_PORT_RESET: /* SK_U32 PortIdx */ - /* action list 4 */ + case SK_DRV_PORT_RESET: FromPort = Param.Para32[0]; SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_EVENT, ("PORT RESET EVENT, Port: %d ", FromPort)); - NewPara.Para64 = FromPort; - SkPnmiEvent(pAC, IoC, SK_PNMI_EVT_XMAC_RESET, NewPara); + SkLocalEventQueue64(pAC, SKGE_PNMI, SK_PNMI_EVT_XMAC_RESET, + FromPort, SK_FALSE); spin_lock_irqsave( &pAC->TxPort[FromPort][TX_PRIO_LOW].TxDesRingLock, Flags); - - SkGeStopPort(pAC, IoC, FromPort, SK_STOP_ALL, SK_HARD_RST); + if (CHIP_ID_YUKON_2(pAC)) { + SkY2PortStop(pAC, IoC, FromPort, SK_STOP_ALL, SK_HARD_RST); + } else { + SkGeStopPort(pAC, IoC, FromPort, SK_STOP_ALL, SK_HARD_RST); + } pAC->dev[Param.Para32[0]]->flags &= ~IFF_RUNNING; spin_unlock_irqrestore( &pAC->TxPort[FromPort][TX_PRIO_LOW].TxDesRingLock, Flags); - /* clear rx ring from received frames */ - ReceiveIrq(pAC, &pAC->RxPort[FromPort], SK_FALSE); - - ClearTxRing(pAC, &pAC->TxPort[FromPort][TX_PRIO_LOW]); + if (!CHIP_ID_YUKON_2(pAC)) { +#ifdef CONFIG_SK98LIN_NAPI + WorkToDo = 1; + ReceiveIrq(pAC, &pAC->RxPort[FromPort], SK_FALSE, &WorkDone, WorkToDo); +#else + ReceiveIrq(pAC, &pAC->RxPort[FromPort], SK_FALSE); +#endif + ClearTxRing(pAC, &pAC->TxPort[FromPort][TX_PRIO_LOW]); + } spin_lock_irqsave( &pAC->TxPort[FromPort][TX_PRIO_LOW].TxDesRingLock, Flags); - - /* tschilling: Handling of return value inserted. */ - if (SkGeInitPort(pAC, IoC, FromPort)) { - if (FromPort == 0) { - printk("%s: SkGeInitPort A failed.\n", pAC->dev[0]->name); + +#ifdef USE_TIST_FOR_RESET + if (pAC->GIni.GIYukon2) { +#ifdef Y2_RECOVERY + /* for Yukon II we want to have tist enabled all the time */ + if (!SK_ADAPTER_WAITING_FOR_TIST(pAC)) { + Y2_ENABLE_TIST(pAC->IoBase); + } +#else + /* make sure that we do not accept any status LEs from now on */ + if (SK_ADAPTER_WAITING_FOR_TIST(pAC)) { +#endif + /* port already waiting for tist */ + SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DUMP, + ("Port %c is now waiting for specific Tist\n", + 'A' + FromPort)); + SK_SET_WAIT_BIT_FOR_PORT( + pAC, + SK_PSTATE_WAITING_FOR_SPECIFIC_TIST, + FromPort); + /* get current timestamp */ + Y2_GET_TIST_LOW_VAL(pAC->IoBase, &pAC->MinTistLo); + pAC->MinTistHi = pAC->GIni.GITimeStampCnt; +#ifndef Y2_RECOVERY } else { - printk("%s: SkGeInitPort B failed.\n", pAC->dev[1]->name); + /* nobody is waiting yet */ + SK_SET_WAIT_BIT_FOR_PORT( + pAC, + SK_PSTATE_WAITING_FOR_ANY_TIST, + FromPort); + SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DUMP, + ("Port %c is now waiting for any Tist (0x%X)\n", + 'A' + FromPort, pAC->AdapterResetState)); + /* start tist */ + Y2_ENABLE_TIST(pAC-IoBase); + } +#endif + } +#endif + +#ifdef Y2_LE_CHECK + /* mark entries invalid */ + pAC->LastPort = 3; + pAC->LastOpc = 0xFF; +#endif + if (CHIP_ID_YUKON_2(pAC)) { + SkY2PortStart(pAC, IoC, FromPort); + } else { + /* tschilling: Handling of return value inserted. */ + if (SkGeInitPort(pAC, IoC, FromPort)) { + if (FromPort == 0) { + printk("%s: SkGeInitPort A failed.\n", pAC->dev[0]->name); + } else { + printk("%s: SkGeInitPort B failed.\n", pAC->dev[1]->name); + } } + SkAddrMcUpdate(pAC,IoC, FromPort); + PortReInitBmu(pAC, FromPort); + SkGePollTxD(pAC, IoC, FromPort, SK_TRUE); + CLEAR_AND_START_RX(FromPort); } - SkAddrMcUpdate(pAC,IoC, FromPort); - PortReInitBmu(pAC, FromPort); - SkGePollTxD(pAC, IoC, FromPort, SK_TRUE); - ClearAndStartRx(pAC, FromPort); spin_unlock_irqrestore( &pAC->TxPort[FromPort][TX_PRIO_LOW].TxDesRingLock, Flags); break; - case SK_DRV_NET_UP: /* SK_U32 PortIdx */ - /* action list 5 */ + case SK_DRV_NET_UP: + spin_lock_irqsave(&pAC->InitLock, InitFlags); FromPort = Param.Para32[0]; SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_EVENT, - ("NET UP EVENT, Port: %d ", Param.Para32[0])); - /* Mac update */ - SkAddrMcUpdate(pAC,IoC, FromPort); - + ("NET UP EVENT, Port: %d ", FromPort)); + SkAddrMcUpdate(pAC,IoC, FromPort); /* Mac update */ if (DoPrintInterfaceChange) { - printk("%s: network connection up using" - " port %c\n", pAC->dev[Param.Para32[0]]->name, 'A'+Param.Para32[0]); + printk("%s: network connection up using port %c\n", + pAC->dev[FromPort]->name, 'A'+FromPort); - /* tschilling: Values changed according to LinkSpeedUsed. */ - Stat = pAC->GIni.GP[FromPort].PLinkSpeedUsed; - if (Stat == SK_LSPEED_STAT_10MBPS) { - printk(" speed: 10\n"); - } else if (Stat == SK_LSPEED_STAT_100MBPS) { - printk(" speed: 100\n"); - } else if (Stat == SK_LSPEED_STAT_1000MBPS) { - printk(" speed: 1000\n"); - } else { - printk(" speed: unknown\n"); - } + /* tschilling: Values changed according to LinkSpeedUsed. */ + Stat = pAC->GIni.GP[FromPort].PLinkSpeedUsed; + if (Stat == SK_LSPEED_STAT_10MBPS) { + printk(" speed: 10\n"); + } else if (Stat == SK_LSPEED_STAT_100MBPS) { + printk(" speed: 100\n"); + } else if (Stat == SK_LSPEED_STAT_1000MBPS) { + printk(" speed: 1000\n"); + } else { + printk(" speed: unknown\n"); + } + Stat = pAC->GIni.GP[FromPort].PLinkModeStatus; + if ((Stat == SK_LMODE_STAT_AUTOHALF) || + (Stat == SK_LMODE_STAT_AUTOFULL)) { + printk(" autonegotiation: yes\n"); + } else { + printk(" autonegotiation: no\n"); + } - Stat = pAC->GIni.GP[FromPort].PLinkModeStatus; - if (Stat == SK_LMODE_STAT_AUTOHALF || - Stat == SK_LMODE_STAT_AUTOFULL) { - printk(" autonegotiation: yes\n"); - } - else { - printk(" autonegotiation: no\n"); - } - if (Stat == SK_LMODE_STAT_AUTOHALF || - Stat == SK_LMODE_STAT_HALF) { - printk(" duplex mode: half\n"); - } - else { - printk(" duplex mode: full\n"); - } - Stat = pAC->GIni.GP[FromPort].PFlowCtrlStatus; - if (Stat == SK_FLOW_STAT_REM_SEND ) { - printk(" flowctrl: remote send\n"); - } - else if (Stat == SK_FLOW_STAT_LOC_SEND ){ - printk(" flowctrl: local send\n"); - } - else if (Stat == SK_FLOW_STAT_SYMMETRIC ){ - printk(" flowctrl: symmetric\n"); - } - else { - printk(" flowctrl: none\n"); - } - - /* tschilling: Check against CopperType now. */ - if ((pAC->GIni.GICopperType == SK_TRUE) && - (pAC->GIni.GP[FromPort].PLinkSpeedUsed == - SK_LSPEED_STAT_1000MBPS)) { - Stat = pAC->GIni.GP[FromPort].PMSStatus; - if (Stat == SK_MS_STAT_MASTER ) { - printk(" role: master\n"); + if ((Stat == SK_LMODE_STAT_AUTOHALF) || + (Stat == SK_LMODE_STAT_HALF)) { + printk(" duplex mode: half\n"); + } else { + printk(" duplex mode: full\n"); } - else if (Stat == SK_MS_STAT_SLAVE ) { - printk(" role: slave\n"); + + Stat = pAC->GIni.GP[FromPort].PFlowCtrlStatus; + if (Stat == SK_FLOW_STAT_REM_SEND ) { + printk(" flowctrl: remote send\n"); + } else if (Stat == SK_FLOW_STAT_LOC_SEND ) { + printk(" flowctrl: local send\n"); + } else if (Stat == SK_FLOW_STAT_SYMMETRIC ) { + printk(" flowctrl: symmetric\n"); + } else { + printk(" flowctrl: none\n"); } - else { - printk(" role: ???\n"); + + /* tschilling: Check against CopperType now. */ + if ((pAC->GIni.GICopperType == SK_TRUE) && + (pAC->GIni.GP[FromPort].PLinkSpeedUsed == + SK_LSPEED_STAT_1000MBPS)) { + Stat = pAC->GIni.GP[FromPort].PMSStatus; + if (Stat == SK_MS_STAT_MASTER ) { + printk(" role: master\n"); + } else if (Stat == SK_MS_STAT_SLAVE ) { + printk(" role: slave\n"); + } else { + printk(" role: ???\n"); + } } - } - /* - Display dim (dynamic interrupt moderation) - informations - */ - if (pAC->DynIrqModInfo.IntModTypeSelect == C_INT_MOD_STATIC) - printk(" irq moderation: static (%d ints/sec)\n", + /* Display interrupt moderation informations */ + if (pAC->DynIrqModInfo.IntModTypeSelect == C_INT_MOD_STATIC) { + printk(" irq moderation: static (%d ints/sec)\n", pAC->DynIrqModInfo.MaxModIntsPerSec); - else if (pAC->DynIrqModInfo.IntModTypeSelect == C_INT_MOD_DYNAMIC) - printk(" irq moderation: dynamic (%d ints/sec)\n", + } else if (pAC->DynIrqModInfo.IntModTypeSelect == C_INT_MOD_DYNAMIC) { + printk(" irq moderation: dynamic (%d ints/sec)\n", pAC->DynIrqModInfo.MaxModIntsPerSec); - else - printk(" irq moderation: disabled\n"); + } else { + printk(" irq moderation: disabled\n"); + } + +#ifdef NETIF_F_TSO + if (CHIP_ID_YUKON_2(pAC)) { + if (pAC->dev[FromPort]->features & NETIF_F_TSO) { + printk(" tcp offload: enabled\n"); + } else { + printk(" tcp offload: disabled\n"); + } + } +#endif + if (pAC->dev[FromPort]->features & NETIF_F_SG) { + printk(" scatter-gather: enabled\n"); + } else { + printk(" scatter-gather: disabled\n"); + } -#ifdef SK_ZEROCOPY - if (pAC->ChipsetType) -#ifdef USE_SK_TX_CHECKSUM - printk(" scatter-gather: enabled\n"); -#else - printk(" tx-checksum: disabled\n"); -#endif - else - printk(" scatter-gather: disabled\n"); -#else - printk(" scatter-gather: disabled\n"); -#endif + if (pAC->dev[FromPort]->features & NETIF_F_IP_CSUM) { + printk(" tx-checksum: enabled\n"); + } else { + printk(" tx-checksum: disabled\n"); + } -#ifndef USE_SK_RX_CHECKSUM - printk(" rx-checksum: disabled\n"); + if (pAC->RxPort[FromPort].UseRxCsum) { + printk(" rx-checksum: enabled\n"); + } else { + printk(" rx-checksum: disabled\n"); + } +#ifdef CONFIG_SK98LIN_NAPI + printk(" rx-polling: enabled\n"); #endif - + if (pAC->LowLatency) { + printk(" low latency: enabled\n"); + } } else { - DoPrintInterfaceChange = SK_TRUE; - } + DoPrintInterfaceChange = SK_TRUE; + } - if ((Param.Para32[0] != pAC->ActivePort) && - (pAC->RlmtNets == 1)) { - NewPara.Para32[0] = pAC->ActivePort; - NewPara.Para32[1] = Param.Para32[0]; - SkEventQueue(pAC, SKGE_DRV, SK_DRV_SWITCH_INTERN, - NewPara); + if ((FromPort != pAC->ActivePort)&&(pAC->RlmtNets == 1)) { + SkLocalEventQueue(pAC, SKGE_DRV, SK_DRV_SWITCH_INTERN, + pAC->ActivePort, FromPort, SK_FALSE); } /* Inform the world that link protocol is up. */ - pAC->dev[Param.Para32[0]]->flags |= IFF_RUNNING; - + netif_wake_queue(pAC->dev[FromPort]); + netif_carrier_on(pAC->dev[FromPort]); + pAC->dev[FromPort]->flags |= IFF_RUNNING; + spin_unlock_irqrestore(&pAC->InitLock, InitFlags); break; - case SK_DRV_NET_DOWN: /* SK_U32 Reason */ - /* action list 7 */ + case SK_DRV_NET_DOWN: + Reason = Param.Para32[0]; + FromPort = Param.Para32[1]; SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_EVENT, ("NET DOWN EVENT ")); + + /* Stop queue and carrier */ + netif_stop_queue(pAC->dev[FromPort]); + netif_carrier_off(pAC->dev[FromPort]); + + /* Print link change */ if (DoPrintInterfaceChange) { - printk("%s: network connection down\n", - pAC->dev[Param.Para32[1]]->name); + if (pAC->dev[FromPort]->flags & IFF_RUNNING) { + printk("%s: network connection down\n", + pAC->dev[FromPort]->name); + } } else { DoPrintInterfaceChange = SK_TRUE; } - pAC->dev[Param.Para32[1]]->flags &= ~IFF_RUNNING; + pAC->dev[FromPort]->flags &= ~IFF_RUNNING; break; - case SK_DRV_SWITCH_HARD: /* SK_U32 FromPortIdx SK_U32 ToPortIdx */ - SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_EVENT, - ("PORT SWITCH HARD ")); - case SK_DRV_SWITCH_SOFT: /* SK_U32 FromPortIdx SK_U32 ToPortIdx */ - /* action list 6 */ - printk("%s: switching to port %c\n", pAC->dev[0]->name, - 'A'+Param.Para32[1]); - case SK_DRV_SWITCH_INTERN: /* SK_U32 FromPortIdx SK_U32 ToPortIdx */ + case SK_DRV_SWITCH_HARD: /* FALL THRU */ + case SK_DRV_SWITCH_SOFT: /* FALL THRU */ + case SK_DRV_SWITCH_INTERN: FromPort = Param.Para32[0]; - ToPort = Param.Para32[1]; + ToPort = Param.Para32[1]; + printk("%s: switching from port %c to port %c\n", + pAC->dev[0]->name, 'A'+FromPort, 'A'+ToPort); SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_EVENT, ("PORT SWITCH EVENT, From: %d To: %d (Pref %d) ", FromPort, ToPort, pAC->Rlmt.Net[0].PrefPort)); - NewPara.Para64 = FromPort; - SkPnmiEvent(pAC, IoC, SK_PNMI_EVT_XMAC_RESET, NewPara); - NewPara.Para64 = ToPort; - SkPnmiEvent(pAC, IoC, SK_PNMI_EVT_XMAC_RESET, NewPara); + SkLocalEventQueue64(pAC, SKGE_PNMI, SK_PNMI_EVT_XMAC_RESET, + FromPort, SK_FALSE); + SkLocalEventQueue64(pAC, SKGE_PNMI, SK_PNMI_EVT_XMAC_RESET, + ToPort, SK_FALSE); spin_lock_irqsave( &pAC->TxPort[FromPort][TX_PRIO_LOW].TxDesRingLock, Flags); - spin_lock_irqsave( - &pAC->TxPort[ToPort][TX_PRIO_LOW].TxDesRingLock, Flags); - SkGeStopPort(pAC, IoC, FromPort, SK_STOP_ALL, SK_SOFT_RST); - SkGeStopPort(pAC, IoC, ToPort, SK_STOP_ALL, SK_SOFT_RST); - spin_unlock_irqrestore( - &pAC->TxPort[ToPort][TX_PRIO_LOW].TxDesRingLock, Flags); + spin_lock(&pAC->TxPort[ToPort][TX_PRIO_LOW].TxDesRingLock); + if (CHIP_ID_YUKON_2(pAC)) { + SkY2PortStop(pAC, IoC, FromPort, SK_STOP_ALL, SK_SOFT_RST); + SkY2PortStop(pAC, IoC, ToPort, SK_STOP_ALL, SK_SOFT_RST); + } + else { + SkGeStopPort(pAC, IoC, FromPort, SK_STOP_ALL, SK_SOFT_RST); + SkGeStopPort(pAC, IoC, ToPort, SK_STOP_ALL, SK_SOFT_RST); + } + spin_unlock(&pAC->TxPort[ToPort][TX_PRIO_LOW].TxDesRingLock); spin_unlock_irqrestore( &pAC->TxPort[FromPort][TX_PRIO_LOW].TxDesRingLock, Flags); - ReceiveIrq(pAC, &pAC->RxPort[FromPort], SK_FALSE); /* clears rx ring */ - ReceiveIrq(pAC, &pAC->RxPort[ToPort], SK_FALSE); /* clears rx ring */ - ClearTxRing(pAC, &pAC->TxPort[FromPort][TX_PRIO_LOW]); - ClearTxRing(pAC, &pAC->TxPort[ToPort][TX_PRIO_LOW]); + if (!CHIP_ID_YUKON_2(pAC)) { +#ifdef CONFIG_SK98LIN_NAPI + WorkToDo = 1; + ReceiveIrq(pAC, &pAC->RxPort[FromPort], SK_FALSE, &WorkDone, WorkToDo); + ReceiveIrq(pAC, &pAC->RxPort[ToPort], SK_FALSE, &WorkDone, WorkToDo); +#else + ReceiveIrq(pAC, &pAC->RxPort[FromPort], SK_FALSE); /* clears rx ring */ + ReceiveIrq(pAC, &pAC->RxPort[ToPort], SK_FALSE); /* clears rx ring */ +#endif + ClearTxRing(pAC, &pAC->TxPort[FromPort][TX_PRIO_LOW]); + ClearTxRing(pAC, &pAC->TxPort[ToPort][TX_PRIO_LOW]); + } + spin_lock_irqsave( &pAC->TxPort[FromPort][TX_PRIO_LOW].TxDesRingLock, Flags); - spin_lock_irqsave( - &pAC->TxPort[ToPort][TX_PRIO_LOW].TxDesRingLock, Flags); + spin_lock(&pAC->TxPort[ToPort][TX_PRIO_LOW].TxDesRingLock); pAC->ActivePort = ToPort; -#if 0 - SetQueueSizes(pAC); -#else + /* tschilling: New common function with minimum size check. */ DualNet = SK_FALSE; if (pAC->RlmtNets == 2) { @@ -4797,85 +5492,325 @@ pAC, pAC->ActivePort, DualNet)) { - spin_unlock_irqrestore( - &pAC->TxPort[ToPort][TX_PRIO_LOW].TxDesRingLock, Flags); + spin_unlock(&pAC->TxPort[ToPort][TX_PRIO_LOW].TxDesRingLock); spin_unlock_irqrestore( &pAC->TxPort[FromPort][TX_PRIO_LOW].TxDesRingLock, Flags); printk("SkGeInitAssignRamToQueues failed.\n"); break; } -#endif - /* tschilling: Handling of return values inserted. */ - if (SkGeInitPort(pAC, IoC, FromPort) || - SkGeInitPort(pAC, IoC, ToPort)) { - printk("%s: SkGeInitPort failed.\n", pAC->dev[0]->name); + + if (!CHIP_ID_YUKON_2(pAC)) { + /* tschilling: Handling of return values inserted. */ + if (SkGeInitPort(pAC, IoC, FromPort) || + SkGeInitPort(pAC, IoC, ToPort)) { + printk("%s: SkGeInitPort failed.\n", pAC->dev[0]->name); + } } - if (Event == SK_DRV_SWITCH_SOFT) { - SkMacRxTxEnable(pAC, IoC, FromPort); + if (!CHIP_ID_YUKON_2(pAC)) { + if (Event == SK_DRV_SWITCH_SOFT) { + SkMacRxTxEnable(pAC, IoC, FromPort); + } + SkMacRxTxEnable(pAC, IoC, ToPort); } - SkMacRxTxEnable(pAC, IoC, ToPort); + SkAddrSwap(pAC, IoC, FromPort, ToPort); SkAddrMcUpdate(pAC, IoC, FromPort); SkAddrMcUpdate(pAC, IoC, ToPort); - PortReInitBmu(pAC, FromPort); - PortReInitBmu(pAC, ToPort); - SkGePollTxD(pAC, IoC, FromPort, SK_TRUE); - SkGePollTxD(pAC, IoC, ToPort, SK_TRUE); - ClearAndStartRx(pAC, FromPort); - ClearAndStartRx(pAC, ToPort); - spin_unlock_irqrestore( - &pAC->TxPort[ToPort][TX_PRIO_LOW].TxDesRingLock, Flags); + +#ifdef USE_TIST_FOR_RESET + if (pAC->GIni.GIYukon2) { + /* make sure that we do not accept any status LEs from now on */ + SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DUMP, + ("both Ports now waiting for specific Tist\n")); + SK_SET_WAIT_BIT_FOR_PORT( + pAC, + SK_PSTATE_WAITING_FOR_ANY_TIST, + 0); + SK_SET_WAIT_BIT_FOR_PORT( + pAC, + SK_PSTATE_WAITING_FOR_ANY_TIST, + 1); + + /* start tist */ + Y2_ENABLE_TIST(pAC->IoBase); + } +#endif + if (!CHIP_ID_YUKON_2(pAC)) { + PortReInitBmu(pAC, FromPort); + PortReInitBmu(pAC, ToPort); + SkGePollTxD(pAC, IoC, FromPort, SK_TRUE); + SkGePollTxD(pAC, IoC, ToPort, SK_TRUE); + CLEAR_AND_START_RX(FromPort); + CLEAR_AND_START_RX(ToPort); + } else { + SkY2PortStart(pAC, IoC, FromPort); + SkY2PortStart(pAC, IoC, ToPort); +#ifdef SK_YUKON2 + /* in yukon-II always port 0 has to be started first */ + // SkY2PortStart(pAC, IoC, 0); + // SkY2PortStart(pAC, IoC, 1); +#endif + } + spin_unlock(&pAC->TxPort[ToPort][TX_PRIO_LOW].TxDesRingLock); spin_unlock_irqrestore( &pAC->TxPort[FromPort][TX_PRIO_LOW].TxDesRingLock, Flags); break; case SK_DRV_RLMT_SEND: /* SK_MBUF *pMb */ - SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_EVENT, - ("RLS ")); + SK_DBG_MSG(NULL,SK_DBGMOD_DRV,SK_DBGCAT_DRV_EVENT,("RLS ")); pRlmtMbuf = (SK_MBUF*) Param.pParaPtr; pMsg = (struct sk_buff*) pRlmtMbuf->pOs; skb_put(pMsg, pRlmtMbuf->Length); - if (XmitFrame(pAC, &pAC->TxPort[pRlmtMbuf->PortIdx][TX_PRIO_LOW], - pMsg) < 0) - - DEV_KFREE_SKB_ANY(pMsg); + if (!CHIP_ID_YUKON_2(pAC)) { + if (XmitFrame(pAC, &pAC->TxPort[pRlmtMbuf->PortIdx][TX_PRIO_LOW], + pMsg) < 0) { + DEV_KFREE_SKB_ANY(pMsg); + } + } else { + if (SkY2RlmtSend(pAC, pRlmtMbuf->PortIdx, pMsg) < 0) { + DEV_KFREE_SKB_ANY(pMsg); + } + } break; case SK_DRV_TIMER: if (Param.Para32[0] == SK_DRV_MODERATION_TIMER) { - /* - ** expiration of the moderation timer implies that - ** dynamic moderation is to be applied - */ + /* check what IRQs are to be moderated */ SkDimStartModerationTimer(pAC); SkDimModerate(pAC); - if (pAC->DynIrqModInfo.DisplayStats) { - SkDimDisplayModerationSettings(pAC); - } - } else if (Param.Para32[0] == SK_DRV_RX_CLEANUP_TIMER) { - /* - ** check if we need to check for descriptors which - ** haven't been handled the last millisecs - */ - StartDrvCleanupTimer(pAC); - if (pAC->GIni.GIMacsFound == 2) { - ReceiveIrq(pAC, &pAC->RxPort[1], SK_FALSE); - } - ReceiveIrq(pAC, &pAC->RxPort[0], SK_FALSE); } else { printk("Expiration of unknown timer\n"); } break; + case SK_DRV_ADAP_FAIL: +#if (!defined (Y2_RECOVERY) && !defined (Y2_LE_CHECK)) + SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_EVENT, + ("ADAPTER FAIL EVENT\n")); + printk("%s: Adapter failed.\n", pAC->dev[0]->name); + SK_OUT32(pAC->IoBase, B0_IMSK, 0); /* disable interrupts */ + break; +#endif + +#if (defined (Y2_RECOVERY) || defined (Y2_LE_CHECK)) + case SK_DRV_RECOVER: + spin_lock_irqsave(&pAC->InitLock, InitFlags); + pNet = (DEV_NET *) pAC->dev[Param.Para32[0]]->priv; + + /* Recover already in progress */ + if (pNet->InRecover) { + break; + } + + netif_stop_queue(pAC->dev[Param.Para32[0]]); /* stop device if running */ + pNet->InRecover = SK_TRUE; + + FromPort = Param.Para32[0]; + SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_EVENT, + ("PORT RESET EVENT, Port: %d ", FromPort)); + + /* Disable interrupts */ + SK_OUT32(pAC->IoBase, B0_IMSK, 0); + SK_OUT32(pAC->IoBase, B0_HWE_IMSK, 0); + + SkLocalEventQueue64(pAC, SKGE_PNMI, SK_PNMI_EVT_XMAC_RESET, + FromPort, SK_FALSE); + spin_lock_irqsave( + &pAC->TxPort[FromPort][TX_PRIO_LOW].TxDesRingLock, + Flags); + if (CHIP_ID_YUKON_2(pAC)) { + SkY2PortStop(pAC, IoC, FromPort, SK_STOP_ALL, SK_SOFT_RST); + } else { + SkGeStopPort(pAC, IoC, FromPort, SK_STOP_ALL, SK_SOFT_RST); + } + pAC->dev[Param.Para32[0]]->flags &= ~IFF_RUNNING; + spin_unlock_irqrestore( + &pAC->TxPort[FromPort][TX_PRIO_LOW].TxDesRingLock, + Flags); + + if (!CHIP_ID_YUKON_2(pAC)) { +#ifdef CONFIG_SK98LIN_NAPI + WorkToDo = 1; + ReceiveIrq(pAC, &pAC->RxPort[FromPort], SK_FALSE, &WorkDone, WorkToDo); +#else + ReceiveIrq(pAC, &pAC->RxPort[FromPort], SK_FALSE); +#endif + ClearTxRing(pAC, &pAC->TxPort[FromPort][TX_PRIO_LOW]); + } + spin_lock_irqsave( + &pAC->TxPort[FromPort][TX_PRIO_LOW].TxDesRingLock, + Flags); + +#ifdef USE_TIST_FOR_RESET + if (pAC->GIni.GIYukon2) { +#if 0 + /* make sure that we do not accept any status LEs from now on */ + Y2_ENABLE_TIST(pAC->IoBase); + + /* get current timestamp */ + Y2_GET_TIST_LOW_VAL(pAC->IoBase, &pAC->MinTistLo); + pAC->MinTistHi = pAC->GIni.GITimeStampCnt; + + SK_SET_WAIT_BIT_FOR_PORT( + pAC, + SK_PSTATE_WAITING_FOR_SPECIFIC_TIST, + FromPort); +#endif + SK_SET_WAIT_BIT_FOR_PORT( + pAC, + SK_PSTATE_WAITING_FOR_ANY_TIST, + FromPort); + + /* start tist */ + Y2_ENABLE_TIST(pAC->IoBase); + } +#endif + + /* Restart Receive BMU on Yukon-2 */ + if (HW_FEATURE(pAC, HWF_WA_DEV_4167)) { + SkYuk2RestartRxBmu(pAC, IoC, FromPort); + } + +#ifdef Y2_LE_CHECK + /* mark entries invalid */ + pAC->LastPort = 3; + pAC->LastOpc = 0xFF; +#endif + +#endif + /* Restart ports but do not initialize PHY. */ + if (CHIP_ID_YUKON_2(pAC)) { + SkY2PortStart(pAC, IoC, FromPort); + } else { + /* tschilling: Handling of return value inserted. */ + if (SkGeInitPort(pAC, IoC, FromPort)) { + if (FromPort == 0) { + printk("%s: SkGeInitPort A failed.\n", pAC->dev[0]->name); + } else { + printk("%s: SkGeInitPort B failed.\n", pAC->dev[1]->name); + } + } + SkAddrMcUpdate(pAC,IoC, FromPort); + PortReInitBmu(pAC, FromPort); + SkGePollTxD(pAC, IoC, FromPort, SK_TRUE); + CLEAR_AND_START_RX(FromPort); + } + spin_unlock_irqrestore( + &pAC->TxPort[FromPort][TX_PRIO_LOW].TxDesRingLock, + Flags); + + /* Map any waiting RX buffers to HW */ + FillReceiveTableYukon2(pAC, pAC->IoBase, FromPort); + + pNet->InRecover = SK_FALSE; + /* enable Interrupts */ + SK_OUT32(pAC->IoBase, B0_IMSK, pAC->GIni.GIValIrqMask); + SK_OUT32(pAC->IoBase, B0_HWE_IMSK, IRQ_HWE_MASK); + netif_wake_queue(pAC->dev[FromPort]); + spin_unlock_irqrestore(&pAC->InitLock, InitFlags); + break; default: break; } SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_EVENT, ("END EVENT ")); - + return (0); } /* SkDrvEvent */ +/****************************************************************************** + * + * SkLocalEventQueue() - add event to queue + * + * Description: + * This function adds an event to the event queue and run the + * SkEventDispatcher. At least Init Level 1 is required to queue events, + * but will be scheduled add Init Level 2. + * + * returns: + * nothing + */ +void SkLocalEventQueue( +SK_AC *pAC, /* Adapters context */ +SK_U32 Class, /* Event Class */ +SK_U32 Event, /* Event to be queued */ +SK_U32 Param1, /* Event parameter 1 */ +SK_U32 Param2, /* Event parameter 2 */ +SK_BOOL Dispatcher) /* Dispatcher flag: + * TRUE == Call SkEventDispatcher + * FALSE == Don't execute SkEventDispatcher + */ +{ + SK_EVPARA EvPara; + EvPara.Para32[0] = Param1; + EvPara.Para32[1] = Param2; + + + if (Class == SKGE_PNMI) { + SkPnmiEvent( pAC, + pAC->IoBase, + Event, + EvPara); + } else { + SkEventQueue( pAC, + Class, + Event, + EvPara); + } + + /* Run the dispatcher */ + if (Dispatcher) { + SkEventDispatcher(pAC, pAC->IoBase); + } + +} + +/****************************************************************************** + * + * SkLocalEventQueue64() - add event to queue (64bit version) + * + * Description: + * This function adds an event to the event queue and run the + * SkEventDispatcher. At least Init Level 1 is required to queue events, + * but will be scheduled add Init Level 2. + * + * returns: + * nothing + */ +void SkLocalEventQueue64( +SK_AC *pAC, /* Adapters context */ +SK_U32 Class, /* Event Class */ +SK_U32 Event, /* Event to be queued */ +SK_U64 Param, /* Event parameter */ +SK_BOOL Dispatcher) /* Dispatcher flag: + * TRUE == Call SkEventDispatcher + * FALSE == Don't execute SkEventDispatcher + */ +{ + SK_EVPARA EvPara; + EvPara.Para64 = Param; + + + if (Class == SKGE_PNMI) { + SkPnmiEvent( pAC, + pAC->IoBase, + Event, + EvPara); + } else { + SkEventQueue( pAC, + Class, + Event, + EvPara); + } + + /* Run the dispatcher */ + if (Dispatcher) { + SkEventDispatcher(pAC, pAC->IoBase); + } + +} + + /***************************************************************************** * * SkErrorLog - log errors @@ -4925,8 +5860,6 @@ } /* SkErrorLog */ -#ifdef SK_DIAG_SUPPORT - /***************************************************************************** * * SkDrvEnterDiagMode - handles DIAG attach request @@ -4952,7 +5885,7 @@ pAC->DiagModeActive = DIAG_ACTIVE; if (pAC->BoardLevel > SK_INIT_DATA) { - if (pNet->Up) { + if (netif_running(pAC->dev[0])) { pAC->WasIfUp[0] = SK_TRUE; pAC->DiagFlowCtrl = SK_TRUE; /* for SkGeClose */ DoPrintInterfaceChange = SK_FALSE; @@ -4960,9 +5893,10 @@ } else { pAC->WasIfUp[0] = SK_FALSE; } + if (pNet != (DEV_NET *) pAc->dev[1]->priv) { pNet = (DEV_NET *) pAc->dev[1]->priv; - if (pNet->Up) { + if (netif_running(pAC->dev[1])) { pAC->WasIfUp[1] = SK_TRUE; pAC->DiagFlowCtrl = SK_TRUE; /* for SkGeClose */ DoPrintInterfaceChange = SK_FALSE; @@ -4994,16 +5928,16 @@ sizeof(SK_PNMI_STRUCT_DATA)); pAc->DiagModeActive = DIAG_NOTACTIVE; pAc->Pnmi.DiagAttached = SK_DIAG_IDLE; - if (pAc->WasIfUp[0] == SK_TRUE) { - pAc->DiagFlowCtrl = SK_TRUE; /* for SkGeClose */ + if (pAc->WasIfUp[0] == SK_TRUE) { + pAc->DiagFlowCtrl = SK_TRUE; /* for SkGeClose */ DoPrintInterfaceChange = SK_FALSE; - SkDrvInitAdapter(pAc, 0); /* first device */ - } - if (pAc->WasIfUp[1] == SK_TRUE) { - pAc->DiagFlowCtrl = SK_TRUE; /* for SkGeClose */ + SkDrvInitAdapter(pAc, 0); /* first device */ + } + if (pAc->WasIfUp[1] == SK_TRUE) { + pAc->DiagFlowCtrl = SK_TRUE; /* for SkGeClose */ DoPrintInterfaceChange = SK_FALSE; - SkDrvInitAdapter(pAc, 1); /* second device */ - } + SkDrvInitAdapter(pAc, 1); /* second device */ + } return(0); } @@ -5146,14 +6080,25 @@ } /* SkDrvInitAdapter */ -#endif +static int __init sk98lin_init(void) +{ + return pci_module_init(&sk98lin_driver); +} + +static void __exit sk98lin_cleanup(void) +{ + pci_unregister_driver(&sk98lin_driver); +} + +module_init(sk98lin_init); +module_exit(sk98lin_cleanup); + #ifdef DEBUG /****************************************************************************/ /* "debug only" section *****************************************************/ /****************************************************************************/ - /***************************************************************************** * * DumpMsg - print a frame @@ -5164,9 +6109,11 @@ * Returns: N/A * */ -static void DumpMsg(struct sk_buff *skb, char *str) +static void DumpMsg( +struct sk_buff *skb, /* linux' socket buffer */ +char *str) /* additional msg string */ { - int msglen; + int msglen = (skb->len > 64) ? 64 : skb->len; if (skb == NULL) { printk("DumpMsg(): NULL-Message\n"); @@ -5178,19 +6125,14 @@ return; } - msglen = skb->len; - if (msglen > 64) - msglen = 64; - - printk("--- Begin of message from %s , len %d (from %d) ----\n", str, msglen, skb->len); - + printk("DumpMsg: PhysPage: %p\n", + page_address(virt_to_page(skb->data))); + printk("--- Begin of message from %s , len %d (from %d) ----\n", + str, msglen, skb->len); DumpData((char *)skb->data, msglen); - printk("------- End of message ---------\n"); } /* DumpMsg */ - - /***************************************************************************** * * DumpData - print a data area @@ -5202,23 +6144,22 @@ * Returns: N/A * */ -static void DumpData(char *p, int size) -{ -register int i; -int haddr, addr; -char hex_buffer[180]; -char asc_buffer[180]; -char HEXCHAR[] = "0123456789ABCDEF"; - - addr = 0; - haddr = 0; - hex_buffer[0] = 0; - asc_buffer[0] = 0; +static void DumpData( +char *p, /* pointer to area containing the data */ +int size) /* the size of that data area in bytes */ +{ + register int i; + int haddr = 0, addr = 0; + char hex_buffer[180] = { '\0' }; + char asc_buffer[180] = { '\0' }; + char HEXCHAR[] = "0123456789ABCDEF"; + for (i=0; i < size; ) { - if (*p >= '0' && *p <='z') + if (*p >= '0' && *p <='z') { asc_buffer[addr] = *p; - else + } else { asc_buffer[addr] = '.'; + } addr++; asc_buffer[addr] = 0; hex_buffer[haddr] = HEXCHAR[(*p & 0xf0) >> 4]; @@ -5244,27 +6185,24 @@ * DumpLong - print a data area as long values * * Description: - * This function prints a area of data to the system logfile/to the + * This function prints a long variable to the system logfile/to the * console. * * Returns: N/A * */ -static void DumpLong(char *pc, int size) -{ -register int i; -int haddr, addr; -char hex_buffer[180]; -char asc_buffer[180]; -char HEXCHAR[] = "0123456789ABCDEF"; -long *p; -int l; - - addr = 0; - haddr = 0; - hex_buffer[0] = 0; - asc_buffer[0] = 0; - p = (long*) pc; +static void DumpLong( +char *pc, /* location of the variable to print */ +int size) /* how large is the variable? */ +{ + register int i; + int haddr = 0, addr = 0; + char hex_buffer[180] = { '\0' }; + char asc_buffer[180] = { '\0' }; + char HEXCHAR[] = "0123456789ABCDEF"; + long *p = (long*) pc; + int l; + for (i=0; i < size; ) { l = (long) *p; hex_buffer[haddr] = HEXCHAR[(l >> 28) & 0xf]; @@ -5303,3 +6241,4 @@ * End of file * ******************************************************************************/ + diff -urN linux-2.4.32-600/drivers/net/sk98lin/skgehwt.c linux-2.4.32-600-sk98_831/drivers/net/sk98lin/skgehwt.c --- linux-2.4.32-600/drivers/net/sk98lin/skgehwt.c Sat Mar 20 10:08:19 2004 +++ linux-2.4.32-600-sk98_831/drivers/net/sk98lin/skgehwt.c Sun Feb 26 11:12:56 2006 @@ -2,6 +2,8 @@ * * Name: skgehwt.c * Project: Gigabit Ethernet Adapters, Event Scheduler Module + * Version: $Revision: 2.2 $ + * Date: $Date: 2004/05/28 13:39:04 $ * Purpose: Hardware Timer * ******************************************************************************/ @@ -9,7 +11,7 @@ /****************************************************************************** * * (C)Copyright 1998-2002 SysKonnect GmbH. - * (C)Copyright 2002-2003 Marvell. + * (C)Copyright 2002-2004 Marvell. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -25,7 +27,7 @@ */ #if (defined(DEBUG) || ((!defined(LINT)) && (!defined(SK_SLIM)))) static const char SysKonnectFileId[] = - "@(#) $Id: skgehwt.c,v 1.15 2003/09/16 13:41:23 rschmidt Exp $ (C) Marvell."; + "@(#) $Id: skgehwt.c,v 2.2 2004/05/28 13:39:04 rschmidt Exp $ (C) Marvell."; #endif #include "h/skdrv1st.h" /* Driver Specific Definitions */ @@ -42,10 +44,10 @@ /* * Prototypes of local functions. */ -#define SK_HWT_MAX (65000) +#define SK_HWT_MAX 65000UL * 160 /* ca. 10 sec. */ /* correction factor */ -#define SK_HWT_FAC (1000 * (SK_U32)pAC->GIni.GIHstClkFact / 100) +#define SK_HWT_FAC (10 * (SK_U32)pAC->GIni.GIHstClkFact / 16) /* * Initialize hardware timer. @@ -71,29 +73,21 @@ void SkHwtStart( SK_AC *pAC, /* Adapters context */ SK_IOC Ioc, /* IoContext */ -SK_U32 Time) /* Time in units of 16us to load the timer with. */ +SK_U32 Time) /* Time in usec to load the timer */ { - SK_U32 Cnt; - if (Time > SK_HWT_MAX) Time = SK_HWT_MAX; pAC->Hwt.TStart = Time; pAC->Hwt.TStop = 0L; - Cnt = Time; - - /* - * if time < 16 us - * time = 16 us - */ - if (!Cnt) { - Cnt++; + if (!Time) { + Time = 1L; } - SK_OUT32(Ioc, B2_TI_INI, Cnt * SK_HWT_FAC); - - SK_OUT16(Ioc, B2_TI_CTRL, TIM_START); /* Start timer. */ + SK_OUT32(Ioc, B2_TI_INI, Time * SK_HWT_FAC); + + SK_OUT16(Ioc, B2_TI_CTRL, TIM_START); /* Start timer */ pAC->Hwt.TActive = SK_TRUE; } @@ -107,13 +101,12 @@ SK_IOC Ioc) /* IoContext */ { SK_OUT16(Ioc, B2_TI_CTRL, TIM_STOP); - + SK_OUT16(Ioc, B2_TI_CTRL, TIM_CLR_IRQ); pAC->Hwt.TActive = SK_FALSE; } - /* * Stop hardware timer and read time elapsed since last start. * @@ -127,6 +120,9 @@ { SK_U32 TRead; SK_U32 IStatus; + SK_U32 TimerInt; + + TimerInt = CHIP_ID_YUKON_2(pAC) ? Y2_IS_TIMINT : IS_TIMINT; if (pAC->Hwt.TActive) { @@ -137,15 +133,15 @@ SK_IN32(Ioc, B0_ISRC, &IStatus); - /* Check if timer expired (or wraped around) */ - if ((TRead > pAC->Hwt.TStart) || (IStatus & IS_TIMINT)) { - + /* Check if timer expired (or wrapped around) */ + if ((TRead > pAC->Hwt.TStart) || ((IStatus & TimerInt) != 0)) { + SkHwtStop(pAC, Ioc); - + pAC->Hwt.TStop = pAC->Hwt.TStart; } else { - + pAC->Hwt.TStop = pAC->Hwt.TStart - TRead; } } @@ -160,9 +156,9 @@ SK_IOC Ioc) /* IoContext */ { SkHwtStop(pAC, Ioc); - + pAC->Hwt.TStop = pAC->Hwt.TStart; - + SkTimerDone(pAC, Ioc); } diff -urN linux-2.4.32-600/drivers/net/sk98lin/skgeinit.c linux-2.4.32-600-sk98_831/drivers/net/sk98lin/skgeinit.c --- linux-2.4.32-600/drivers/net/sk98lin/skgeinit.c Sat Mar 20 10:08:19 2004 +++ linux-2.4.32-600-sk98_831/drivers/net/sk98lin/skgeinit.c Sun Feb 26 11:13:02 2006 @@ -2,25 +2,27 @@ * * Name: skgeinit.c * Project: Gigabit Ethernet Adapters, Common Modules + * Version: $Revision: 2.93 $ + * Date: $Date: 2005/12/14 16:11:34 $ * Purpose: Contains functions to initialize the adapter * ******************************************************************************/ /****************************************************************************** * + * LICENSE: * (C)Copyright 1998-2002 SysKonnect. - * (C)Copyright 2002-2003 Marvell. + * (C)Copyright 2002-2005 Marvell. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. - * * The information in this file is provided "AS IS" without warranty. + * /LICENSE * ******************************************************************************/ - #include "h/skdrv1st.h" #include "h/skdrv2nd.h" @@ -30,7 +32,7 @@ #if (defined(DEBUG) || ((!defined(LINT)) && (!defined(SK_SLIM)))) static const char SysKonnectFileId[] = - "@(#) $Id: skgeinit.c,v 1.97 2003/10/02 16:45:31 rschmidt Exp $ (C) Marvell."; + "@(#) $Id: skgeinit.c,v 2.93 2005/12/14 16:11:34 ibrueder Exp $ (C) Marvell."; #endif struct s_QOffTab { @@ -38,6 +40,7 @@ int XsQOff; /* Sync Tx Queue Address Offset */ int XaQOff; /* Async Tx Queue Address Offset */ }; + static struct s_QOffTab QOffTab[] = { {Q_R1, Q_XS1, Q_XA1}, {Q_R2, Q_XS2, Q_XA2} }; @@ -56,6 +59,97 @@ #endif }; +#ifndef SK_SLIM +/****************************************************************************** + * + * SkGePortVlan() - Enable / Disable VLAN support + * + * Description: + * Enable or disable the VLAN support of the selected port. + * The new configuration is *not* saved over any SkGeStopPort() and + * SkGeInitPort() calls. + * Currently this function is only supported on Yukon-2/EC adapters. + * + * Returns: + * nothing + */ +void SkGePortVlan( +SK_AC *pAC, /* Adapter Context */ +SK_IOC IoC, /* I/O Context */ +int Port, /* Port number */ +SK_BOOL Enable) /* Flag */ +{ + SK_U32 RxCtrl; + SK_U32 TxCtrl; + + if (CHIP_ID_YUKON_2(pAC)) { + if (Enable) { + RxCtrl = RX_VLAN_STRIP_ON; + TxCtrl = TX_VLAN_TAG_ON; + } + else { + RxCtrl = RX_VLAN_STRIP_OFF; + TxCtrl = TX_VLAN_TAG_OFF; + } + + SK_OUT32(IoC, MR_ADDR(Port, RX_GMF_CTRL_T), RxCtrl); + SK_OUT32(IoC, MR_ADDR(Port, TX_GMF_CTRL_T), TxCtrl); + } +} /* SkGePortVlan */ + + +/****************************************************************************** + * + * SkGeRxRss() - Enable / Disable RSS Hash Calculation + * + * Description: + * Enable or disable the RSS hash calculation of the selected port. + * The new configuration is *not* saved over any SkGeStopPort() and + * SkGeInitPort() calls. + * Currently this function is only supported on Yukon-2/EC adapters. + * + * Returns: + * nothing + */ +void SkGeRxRss( +SK_AC *pAC, /* Adapter Context */ +SK_IOC IoC, /* I/O Context */ +int Port, /* Port number */ +SK_BOOL Enable) /* Flag */ +{ + if (CHIP_ID_YUKON_2(pAC)) { + SK_OUT32(IoC, Q_ADDR(pAC->GIni.GP[Port].PRxQOff, Q_CSR), + Enable ? BMU_ENA_RX_RSS_HASH : BMU_DIS_RX_RSS_HASH); + } +} /* SkGeRxRss */ + + +/****************************************************************************** + * + * SkGeRxCsum() - Enable / Disable Receive Checksum + * + * Description: + * Enable or disable the checksum of the selected port. + * The new configuration is *not* saved over any SkGeStopPort() and + * SkGeInitPort() calls. + * Currently this function is only supported on Yukon-2/EC adapters. + * + * Returns: + * nothing + */ +void SkGeRxCsum( +SK_AC *pAC, /* Adapter Context */ +SK_IOC IoC, /* I/O Context */ +int Port, /* Port number */ +SK_BOOL Enable) /* Flag */ +{ + if (CHIP_ID_YUKON_2(pAC)) { + SK_OUT32(IoC, Q_ADDR(pAC->GIni.GP[Port].PRxQOff, Q_CSR), + Enable ? BMU_ENA_RX_CHKSUM : BMU_DIS_RX_CHKSUM); + } +} /* SkGeRxCsum */ +#endif /* !SK_SLIM */ + /****************************************************************************** * * SkGePollRxD() - Enable / Disable Descriptor Polling of RxD Ring @@ -70,8 +164,8 @@ * nothing */ void SkGePollRxD( -SK_AC *pAC, /* adapter context */ -SK_IOC IoC, /* IO context */ +SK_AC *pAC, /* Adapter Context */ +SK_IOC IoC, /* I/O Context */ int Port, /* Port Index (MAC_1 + n) */ SK_BOOL PollRxD) /* SK_TRUE (enable pol.), SK_FALSE (disable pol.) */ { @@ -79,8 +173,8 @@ pPrt = &pAC->GIni.GP[Port]; - SK_OUT32(IoC, Q_ADDR(pPrt->PRxQOff, Q_CSR), (PollRxD) ? - CSR_ENA_POL : CSR_DIS_POL); + SK_OUT32(IoC, Q_ADDR(pPrt->PRxQOff, Q_CSR), (SK_U32)((PollRxD) ? + CSR_ENA_POL : CSR_DIS_POL)); } /* SkGePollRxD */ @@ -98,8 +192,8 @@ * nothing */ void SkGePollTxD( -SK_AC *pAC, /* adapter context */ -SK_IOC IoC, /* IO context */ +SK_AC *pAC, /* Adapter Context */ +SK_IOC IoC, /* I/O Context */ int Port, /* Port Index (MAC_1 + n) */ SK_BOOL PollTxD) /* SK_TRUE (enable pol.), SK_FALSE (disable pol.) */ { @@ -113,13 +207,13 @@ if (pPrt->PXSQSize != 0) { SK_OUT32(IoC, Q_ADDR(pPrt->PXsQOff, Q_CSR), DWord); } - + if (pPrt->PXAQSize != 0) { SK_OUT32(IoC, Q_ADDR(pPrt->PXaQOff, Q_CSR), DWord); } } /* SkGePollTxD */ - +#ifndef SK_SLIM /****************************************************************************** * * SkGeYellowLED() - Switch the yellow LED on or off. @@ -134,20 +228,30 @@ * nothing */ void SkGeYellowLED( -SK_AC *pAC, /* adapter context */ -SK_IOC IoC, /* IO context */ +SK_AC *pAC, /* Adapter Context */ +SK_IOC IoC, /* I/O Context */ int State) /* yellow LED state, 0 = OFF, 0 != ON */ { + int LedReg; + + if (CHIP_ID_YUKON_2(pAC)) { + /* different mapping on Yukon-2 */ + LedReg = B0_CTST + 1; + } + else { + LedReg = B0_LED; + } + if (State == 0) { - /* Switch yellow LED OFF */ - SK_OUT8(IoC, B0_LED, LED_STAT_OFF); + /* Switch state LED OFF */ + SK_OUT8(IoC, LedReg, LED_STAT_OFF); } else { - /* Switch yellow LED ON */ - SK_OUT8(IoC, B0_LED, LED_STAT_ON); + /* Switch state LED ON */ + SK_OUT8(IoC, LedReg, LED_STAT_ON); } } /* SkGeYellowLED */ - +#endif /* !SK_SLIM */ #if (!defined(SK_SLIM) || defined(GENESIS)) /****************************************************************************** @@ -168,8 +272,8 @@ * nothing */ void SkGeXmitLED( -SK_AC *pAC, /* adapter context */ -SK_IOC IoC, /* IO context */ +SK_AC *pAC, /* Adapter Context */ +SK_IOC IoC, /* I/O Context */ int Led, /* offset to the LED Init Value register */ int Mode) /* Mode may be SK_LED_DIS, SK_LED_ENA, SK_LED_TST */ { @@ -194,18 +298,17 @@ */ SK_OUT32(IoC, Led + XMIT_LED_CNT, 0); SK_OUT8(IoC, Led + XMIT_LED_TST, LED_T_OFF); - break; } - + /* - * 1000BT: The Transmit LED is driven by the PHY. + * 1000BT: the Transmit LED is driven by the PHY. * But the default LED configuration is used for * Level One and Broadcom PHYs. - * (Broadcom: It may be that PHY_B_PEC_EN_LTR has to be set.) - * (In this case it has to be added here. But we will see. XXX) + * (Broadcom: It may be that PHY_B_PEC_EN_LTR has to be set. + * In this case it has to be added here.) */ } /* SkGeXmitLED */ -#endif /* !SK_SLIM || GENESIS */ +#endif /* !SK_SLIM || GENESIS */ /****************************************************************************** @@ -226,7 +329,7 @@ * 1: configuration error */ static int DoCalcAddr( -SK_AC *pAC, /* adapter context */ +SK_AC *pAC, /* Adapter Context */ SK_GEPORT SK_FAR *pPrt, /* port index */ int QuSize, /* size of the queue to configure in kB */ SK_U32 SK_FAR *StartVal, /* start value for address calculation */ @@ -263,12 +366,35 @@ /****************************************************************************** * + * SkGeRoundQueueSize() - Round the given queue size to the adpaters QZ units + * + * Description: + * This function rounds the given queue size in kBs to adapter specific + * queue size units (Genesis and Yukon: 8 kB, Yukon-2/EC: 1 kB). + * + * Returns: + * the rounded queue size in kB + */ +static int SkGeRoundQueueSize( +SK_AC *pAC, /* Adapter Context */ +int QueueSizeKB) /* Queue size in kB */ +{ + int QueueSizeSteps; + + QueueSizeSteps = (CHIP_ID_YUKON_2(pAC)) ? QZ_STEP_Y2 : QZ_STEP; + + return((QueueSizeKB + QueueSizeSteps - 1) & ~(QueueSizeSteps - 1)); +} /* SkGeRoundQueueSize */ + + +/****************************************************************************** + * * SkGeInitAssignRamToQueues() - allocate default queue sizes * * Description: * This function assigns the memory to the different queues and ports. * When DualNet is set to SK_TRUE all ports get the same amount of memory. - * Otherwise the first port gets most of the memory and all the + * Otherwise the first port gets most of the memory and all the * other ports just the required minimum. * This function can only be called when pAC->GIni.GIRamSize and * pAC->GIni.GIMacsFound have been initialized, usually this happens @@ -281,102 +407,146 @@ */ int SkGeInitAssignRamToQueues( -SK_AC *pAC, /* Adapter context */ +SK_AC *pAC, /* Adapter Context */ int ActivePort, /* Active Port in RLMT mode */ -SK_BOOL DualNet) /* adapter context */ +SK_BOOL DualNet) /* Dual Net active */ { int i; int UsedKilobytes; /* memory already assigned */ int ActivePortKilobytes; /* memory available for active port */ - SK_GEPORT *pGePort; - - UsedKilobytes = 0; + int MinQueueSize; /* min. memory for queues */ + int TotalRamSize; /* total memory for queues */ + SK_BOOL DualPortYukon2; + SK_GEPORT *pPrt; if (ActivePort >= pAC->GIni.GIMacsFound) { + SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_INIT, ("SkGeInitAssignRamToQueues: ActivePort (%d) invalid\n", ActivePort)); return(1); } - if (((pAC->GIni.GIMacsFound * (SK_MIN_RXQ_SIZE + SK_MIN_TXQ_SIZE)) + - ((RAM_QUOTA_SYNC == 0) ? 0 : SK_MIN_TXQ_SIZE)) > pAC->GIni.GIRamSize) { + + DualPortYukon2 = (CHIP_ID_YUKON_2(pAC) && pAC->GIni.GIMacsFound == 2); + + TotalRamSize = pAC->GIni.GIRamSize; + + if (DualPortYukon2) { + TotalRamSize *= 2; + } + + MinQueueSize = SK_MIN_RXQ_SIZE + SK_MIN_TXQ_SIZE; + + if (MinQueueSize > pAC->GIni.GIRamSize) { + MinQueueSize = pAC->GIni.GIRamSize; + } + + if ((pAC->GIni.GIMacsFound * MinQueueSize + + RAM_QUOTA_SYNC * SK_MIN_TXQ_SIZE) > TotalRamSize) { + SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_INIT, ("SkGeInitAssignRamToQueues: Not enough memory (%d)\n", - pAC->GIni.GIRamSize)); + TotalRamSize)); return(2); } if (DualNet) { /* every port gets the same amount of memory */ - ActivePortKilobytes = pAC->GIni.GIRamSize / pAC->GIni.GIMacsFound; + ActivePortKilobytes = TotalRamSize / pAC->GIni.GIMacsFound; + for (i = 0; i < pAC->GIni.GIMacsFound; i++) { - pGePort = &pAC->GIni.GP[i]; - + pPrt = &pAC->GIni.GP[i]; + + if (DualPortYukon2) { + ActivePortKilobytes = pAC->GIni.GIRamSize; + } /* take away the minimum memory for active queues */ - ActivePortKilobytes -= (SK_MIN_RXQ_SIZE + SK_MIN_TXQ_SIZE); + ActivePortKilobytes -= MinQueueSize; /* receive queue gets the minimum + 80% of the rest */ - pGePort->PRxQSize = (int) (ROUND_QUEUE_SIZE_KB(( - ActivePortKilobytes * (unsigned long) RAM_QUOTA_RX) / 100)) + pPrt->PRxQSize = SkGeRoundQueueSize(pAC, + (int)((long)ActivePortKilobytes * RAM_QUOTA_RX) / 100) + SK_MIN_RXQ_SIZE; - ActivePortKilobytes -= (pGePort->PRxQSize - SK_MIN_RXQ_SIZE); + ActivePortKilobytes -= (pPrt->PRxQSize - SK_MIN_RXQ_SIZE); /* synchronous transmit queue */ - pGePort->PXSQSize = 0; + pPrt->PXSQSize = 0; /* asynchronous transmit queue */ - pGePort->PXAQSize = (int) ROUND_QUEUE_SIZE_KB(ActivePortKilobytes + - SK_MIN_TXQ_SIZE); + pPrt->PXAQSize = SkGeRoundQueueSize(pAC, + ActivePortKilobytes + SK_MIN_TXQ_SIZE); } } - else { - /* Rlmt Mode or single link adapter */ + else { /* RLMT Mode or single link adapter */ - /* Set standby queue size defaults for all standby ports */ + UsedKilobytes = 0; + + /* set standby queue size defaults for all standby ports */ for (i = 0; i < pAC->GIni.GIMacsFound; i++) { if (i != ActivePort) { - pGePort = &pAC->GIni.GP[i]; + pPrt = &pAC->GIni.GP[i]; + + if (DualPortYukon2) { + pPrt->PRxQSize = SkGeRoundQueueSize(pAC, + (int)((long)(pAC->GIni.GIRamSize - MinQueueSize) * + RAM_QUOTA_RX) / 100) + SK_MIN_RXQ_SIZE; - pGePort->PRxQSize = SK_MIN_RXQ_SIZE; - pGePort->PXAQSize = SK_MIN_TXQ_SIZE; - pGePort->PXSQSize = 0; + pPrt->PXAQSize = pAC->GIni.GIRamSize - pPrt->PRxQSize; + } + else { + pPrt->PRxQSize = SK_MIN_RXQ_SIZE; + pPrt->PXAQSize = SK_MIN_TXQ_SIZE; + } + pPrt->PXSQSize = 0; /* Count used RAM */ - UsedKilobytes += pGePort->PRxQSize + pGePort->PXAQSize; + UsedKilobytes += pPrt->PRxQSize + pPrt->PXAQSize; } } /* what's left? */ - ActivePortKilobytes = pAC->GIni.GIRamSize - UsedKilobytes; + ActivePortKilobytes = TotalRamSize - UsedKilobytes; /* assign it to the active port */ /* first take away the minimum memory */ - ActivePortKilobytes -= (SK_MIN_RXQ_SIZE + SK_MIN_TXQ_SIZE); - pGePort = &pAC->GIni.GP[ActivePort]; + ActivePortKilobytes -= MinQueueSize; + pPrt = &pAC->GIni.GP[ActivePort]; - /* receive queue get's the minimum + 80% of the rest */ - pGePort->PRxQSize = (int) (ROUND_QUEUE_SIZE_KB((ActivePortKilobytes * - (unsigned long) RAM_QUOTA_RX) / 100)) + SK_MIN_RXQ_SIZE; + /* receive queue gets 80% of the rest */ + pPrt->PRxQSize = SkGeRoundQueueSize(pAC, + (int)((long)ActivePortKilobytes * RAM_QUOTA_RX) / 100); - ActivePortKilobytes -= (pGePort->PRxQSize - SK_MIN_RXQ_SIZE); + ActivePortKilobytes -= pPrt->PRxQSize; + + /* add the minimum memory for Rx queue */ + pPrt->PRxQSize += MinQueueSize/2; /* synchronous transmit queue */ - pGePort->PXSQSize = 0; + pPrt->PXSQSize = 0; - /* asynchronous transmit queue */ - pGePort->PXAQSize = (int) ROUND_QUEUE_SIZE_KB(ActivePortKilobytes) + - SK_MIN_TXQ_SIZE; + /* asynchronous transmit queue gets 20% of the rest */ + pPrt->PXAQSize = SkGeRoundQueueSize(pAC, ActivePortKilobytes) + + /* add the minimum memory for Tx queue */ + MinQueueSize/2; } -#ifdef VCPU - VCPUprintf(0, "PRxQSize=%u, PXSQSize=%u, PXAQSize=%u\n", - pGePort->PRxQSize, pGePort->PXSQSize, pGePort->PXAQSize); -#endif /* VCPU */ + +#ifdef DEBUG + for (i = 0; i < pAC->GIni.GIMacsFound; i++) { + + pPrt = &pAC->GIni.GP[i]; + + SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_INIT, + ("Port %d: RxQSize=%u, TxAQSize=%u, TxSQSize=%u\n", + i, pPrt->PRxQSize, pPrt->PXAQSize, pPrt->PXSQSize)); + } +#endif /* DEBUG */ return(0); } /* SkGeInitAssignRamToQueues */ + /****************************************************************************** * * SkGeCheckQSize() - Checks the Adapters Queue Size Configuration @@ -387,12 +557,12 @@ * used ports. * This requirements must be fullfilled to have a valid configuration: * - The size of all queues must not exceed GIRamSize. - * - The queue sizes must be specified in units of 8 kB. + * - The queue sizes must be specified in units of 8 kB (Genesis & Yukon). * - The size of Rx queues of available ports must not be - * smaller than 16 kB. + * smaller than 16 kB (Genesis & Yukon) resp. 10 kB (Yukon-2). * - The size of at least one Tx queue (synch. or asynch.) - * of available ports must not be smaller than 16 kB - * when Jumbo Frames are used. + * of available ports must not be smaller than 16 kB (Genesis & Yukon), + * resp. 10 kB (Yukon-2) when Jumbo Frames are used. * - The RAM start and end addresses must not be changed * for ports which are already initialized. * Furthermore SkGeCheckQSize() defines the Start and End Addresses @@ -403,7 +573,7 @@ * 1: Queue Size Configuration invalid */ static int SkGeCheckQSize( -SK_AC *pAC, /* adapter context */ +SK_AC *pAC, /* Adapter Context */ int Port) /* port index */ { SK_GEPORT *pPrt; @@ -413,55 +583,68 @@ SK_U32 StartAddr; #ifndef SK_SLIM int UsedMem; /* total memory used (max. found ports) */ -#endif +#endif Rtv = 0; - + #ifndef SK_SLIM UsedMem = 0; + for (i = 0; i < pAC->GIni.GIMacsFound; i++) { pPrt = &pAC->GIni.GP[i]; - if ((pPrt->PRxQSize & QZ_UNITS) != 0 || - (pPrt->PXSQSize & QZ_UNITS) != 0 || - (pPrt->PXAQSize & QZ_UNITS) != 0) { + if (CHIP_ID_YUKON_2(pAC)) { + UsedMem = 0; + } + else if (((pPrt->PRxQSize & QZ_UNITS) != 0 || + (pPrt->PXSQSize & QZ_UNITS) != 0 || + (pPrt->PXAQSize & QZ_UNITS) != 0)) { SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E012, SKERR_HWI_E012MSG); return(1); } - if (i == Port && pPrt->PRxQSize < SK_MIN_RXQ_SIZE) { +#ifndef SK_DIAG + if (i == Port && pAC->GIni.GIRamSize > SK_MIN_RXQ_SIZE && + pPrt->PRxQSize < SK_MIN_RXQ_SIZE) { SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E011, SKERR_HWI_E011MSG); return(1); } - + /* * the size of at least one Tx queue (synch. or asynch.) has to be > 0. * if Jumbo Frames are used, this size has to be >= 16 kB. */ if ((i == Port && pPrt->PXSQSize == 0 && pPrt->PXAQSize == 0) || - (pAC->GIni.GIPortUsage == SK_JUMBO_LINK && - ((pPrt->PXSQSize > 0 && pPrt->PXSQSize < SK_MIN_TXQ_SIZE) || + (pPrt->PPortUsage == SK_JUMBO_LINK && + ((pPrt->PXSQSize > 0 && pPrt->PXSQSize < SK_MIN_TXQ_SIZE) || (pPrt->PXAQSize > 0 && pPrt->PXAQSize < SK_MIN_TXQ_SIZE)))) { SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E023, SKERR_HWI_E023MSG); return(1); } - +#endif /* !SK_DIAG */ + UsedMem += pPrt->PRxQSize + pPrt->PXSQSize + pPrt->PXAQSize; + + if (UsedMem > pAC->GIni.GIRamSize) { + SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E012, SKERR_HWI_E012MSG); + return(1); + } } - - if (UsedMem > pAC->GIni.GIRamSize) { - SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E012, SKERR_HWI_E012MSG); - return(1); - } -#endif /* !SK_SLIM */ + +#endif /* !SK_SLIM */ /* Now start address calculation */ StartAddr = pAC->GIni.GIRamOffs; for (i = 0; i < pAC->GIni.GIMacsFound; i++) { + pPrt = &pAC->GIni.GP[i]; + if (CHIP_ID_YUKON_2(pAC)) { + StartAddr = 0; + } + /* Calculate/Check values for the receive queue */ Rtv2 = DoCalcAddr(pAC, pPrt, pPrt->PRxQSize, &StartAddr, &pPrt->PRxQRamStart, &pPrt->PRxQRamEnd); @@ -501,8 +684,8 @@ * nothing */ static void SkGeInitMacArb( -SK_AC *pAC, /* adapter context */ -SK_IOC IoC) /* IO context */ +SK_AC *pAC, /* Adapter Context */ +SK_IOC IoC) /* I/O Context */ { /* release local reset */ SK_OUT16(IoC, B3_MA_TO_CTRL, MA_RST_CLR); @@ -541,8 +724,8 @@ * nothing */ static void SkGeInitPktArb( -SK_AC *pAC, /* adapter context */ -SK_IOC IoC) /* IO context */ +SK_AC *pAC, /* Adapter Context */ +SK_IOC IoC) /* I/O Context */ { /* release local reset */ SK_OUT16(IoC, B3_PA_CTRL, PA_RST_CLR); @@ -558,7 +741,8 @@ * NOTE: the packet arbiter timeout interrupt is needed for * half duplex hangup workaround */ - if (pAC->GIni.GIPortUsage != SK_JUMBO_LINK) { + if (pAC->GIni.GP[MAC_1].PPortUsage != SK_JUMBO_LINK && + pAC->GIni.GP[MAC_2].PPortUsage != SK_JUMBO_LINK) { if (pAC->GIni.GIMacsFound == 1) { SK_OUT16(IoC, B3_PA_CTRL, PA_ENA_TO_TX1); } @@ -581,14 +765,11 @@ * nothing */ static void SkGeInitMacFifo( -SK_AC *pAC, /* adapter context */ -SK_IOC IoC, /* IO context */ +SK_AC *pAC, /* Adapter Context */ +SK_IOC IoC, /* I/O Context */ int Port) /* Port Index (MAC_1 + n) */ { SK_U16 Word; -#ifdef VCPU - SK_U32 DWord; -#endif /* VCPU */ /* * For each FIFO: * - release local reset @@ -596,63 +777,101 @@ * - setup defaults for the control register * - enable the FIFO */ - + #ifdef GENESIS if (pAC->GIni.GIGenesis) { - /* Configure Rx MAC FIFO */ + /* configure Rx MAC FIFO */ SK_OUT8(IoC, MR_ADDR(Port, RX_MFF_CTRL2), MFF_RST_CLR); SK_OUT16(IoC, MR_ADDR(Port, RX_MFF_CTRL1), MFF_RX_CTRL_DEF); SK_OUT8(IoC, MR_ADDR(Port, RX_MFF_CTRL2), MFF_ENA_OP_MD); - - /* Configure Tx MAC FIFO */ + + /* configure Tx MAC FIFO */ SK_OUT8(IoC, MR_ADDR(Port, TX_MFF_CTRL2), MFF_RST_CLR); SK_OUT16(IoC, MR_ADDR(Port, TX_MFF_CTRL1), MFF_TX_CTRL_DEF); SK_OUT8(IoC, MR_ADDR(Port, TX_MFF_CTRL2), MFF_ENA_OP_MD); - - /* Enable frame flushing if jumbo frames used */ - if (pAC->GIni.GIPortUsage == SK_JUMBO_LINK) { + + /* enable frame flushing if jumbo frames used */ + if (pAC->GIni.GP[Port].PPortUsage == SK_JUMBO_LINK) { SK_OUT16(IoC, MR_ADDR(Port, RX_MFF_CTRL1), MFF_ENA_FLUSH); } } #endif /* GENESIS */ - + #ifdef YUKON if (pAC->GIni.GIYukon) { - /* set Rx GMAC FIFO Flush Mask */ - SK_OUT16(IoC, MR_ADDR(Port, RX_GMF_FL_MSK), (SK_U16)RX_FF_FL_DEF_MSK); - + Word = (SK_U16)GMF_RX_CTRL_DEF; /* disable Rx GMAC FIFO Flush for YUKON-Lite Rev. A0 only */ - if (pAC->GIni.GIYukonLite && pAC->GIni.GIChipId == CHIP_ID_YUKON) { + if (pAC->GIni.GIYukonLite /* && pAC->GIni.GIChipId == CHIP_ID_YUKON */) { Word &= ~GMF_RX_F_FL_ON; } - - /* Configure Rx MAC FIFO */ + + /* configure Rx GMAC FIFO */ SK_OUT8(IoC, MR_ADDR(Port, RX_GMF_CTRL_T), (SK_U8)GMF_RST_CLR); SK_OUT16(IoC, MR_ADDR(Port, RX_GMF_CTRL_T), Word); - - /* set Rx GMAC FIFO Flush Threshold (default: 0x0a -> 56 bytes) */ - SK_OUT16(IoC, MR_ADDR(Port, RX_GMF_FL_THR), RX_GMF_FL_THR_DEF); - - /* Configure Tx MAC FIFO */ + + Word = RX_FF_FL_DEF_MSK; + +#ifndef SK_DIAG + if (HW_FEATURE(pAC, HWF_WA_DEV_4115)) { + /* + * Flushing must be enabled (needed for ASF see dev. #4.29), + * but the flushing mask should be disabled (see dev. #4.115) + */ + Word = 0; + } +#endif /* !SK_DIAG */ + + /* set Rx GMAC FIFO Flush Mask (after clearing reset) */ + SK_OUT16(IoC, MR_ADDR(Port, RX_GMF_FL_MSK), Word); + + /* default: 0x0a -> 56 bytes on Yukon-1 and 64 bytes on Yukon-2 */ + Word = (SK_U16)RX_GMF_FL_THR_DEF; + + if (CHIP_ID_YUKON_2(pAC)) { + if (pAC->GIni.GIChipId == CHIP_ID_YUKON_EC && + pAC->GIni.GIAsfEnabled) { + /* WA for dev. #4.30 (reduce to 0x08 -> 48 bytes) */ + Word -= 2; + } + } + else { + /* + * because Pause Packet Truncation in GMAC is not working + * we have to increase the Flush Threshold to 64 bytes + * in order to flush pause packets in Rx FIFO on Yukon-1 + */ + Word++; + } + + /* set Rx GMAC FIFO Flush Threshold (after clearing reset) */ + SK_OUT16(IoC, MR_ADDR(Port, RX_GMF_FL_THR), Word); + + /* configure Tx GMAC FIFO */ SK_OUT8(IoC, MR_ADDR(Port, TX_GMF_CTRL_T), (SK_U8)GMF_RST_CLR); SK_OUT16(IoC, MR_ADDR(Port, TX_GMF_CTRL_T), (SK_U16)GMF_TX_CTRL_DEF); - -#ifdef VCPU - SK_IN32(IoC, MR_ADDR(Port, RX_GMF_AF_THR), &DWord); - SK_IN32(IoC, MR_ADDR(Port, TX_GMF_AE_THR), &DWord); -#endif /* VCPU */ - - /* set Tx GMAC FIFO Almost Empty Threshold */ -/* SK_OUT32(IoC, MR_ADDR(Port, TX_GMF_AE_THR), 0); */ + + if (pAC->GIni.GIChipId == CHIP_ID_YUKON_EC_U) { + /* set Rx Pause Threshold */ + SK_OUT16(IoC, MR_ADDR(Port, RX_GMF_LP_THR), (SK_U16)SK_ECU_LLPP); + SK_OUT16(IoC, MR_ADDR(Port, RX_GMF_UP_THR), (SK_U16)SK_ECU_ULPP); + + if (pAC->GIni.GP[Port].PPortUsage == SK_JUMBO_LINK) { + /* set Tx GMAC FIFO Almost Empty Threshold */ + SK_OUT16(IoC, MR_ADDR(Port, TX_GMF_AE_THR), + (SK_U16)SK_ECU_AE_THR); + /* disable Store & Forward mode for TX */ + SK_OUT32(IoC, MR_ADDR(Port, TX_GMF_CTRL_T), TX_STFW_DIS); + } + } } #endif /* YUKON */ } /* SkGeInitMacFifo */ -#ifdef SK_LNK_SYNC_CNT +#ifdef SK_LNK_SYNC_CNT /****************************************************************************** * * SkGeLoadLnkSyncCnt() - Load the Link Sync Counter and starts counting @@ -673,8 +892,8 @@ * nothing */ void SkGeLoadLnkSyncCnt( -SK_AC *pAC, /* adapter context */ -SK_IOC IoC, /* IO context */ +SK_AC *pAC, /* Adapter Context */ +SK_IOC IoC, /* I/O Context */ int Port, /* Port Index (MAC_1 + n) */ SK_U32 CntVal) /* Counter value */ { @@ -684,7 +903,7 @@ SK_BOOL IrqPend; /* stop counter */ - SK_OUT8(IoC, MR_ADDR(Port, LNK_SYNC_CTRL), LED_STOP); + SK_OUT8(IoC, MR_ADDR(Port, LNK_SYNC_CTRL), LNK_STOP); /* * ASIC problem: @@ -697,6 +916,7 @@ IrqPend = SK_FALSE; SK_IN32(IoC, B0_ISRC, &ISrc); SK_IN32(IoC, B0_IMSK, &OrgIMsk); + if (Port == MAC_1) { NewIMsk = OrgIMsk & ~IS_LNK_SYNC_M1; if ((ISrc & IS_LNK_SYNC_M1) != 0) { @@ -709,6 +929,7 @@ IrqPend = SK_TRUE; } } + if (!IrqPend) { SK_OUT32(IoC, B0_IMSK, NewIMsk); } @@ -717,15 +938,17 @@ SK_OUT32(IoC, MR_ADDR(Port, LNK_SYNC_INI), CntVal); /* start counter */ - SK_OUT8(IoC, MR_ADDR(Port, LNK_SYNC_CTRL), LED_START); + SK_OUT8(IoC, MR_ADDR(Port, LNK_SYNC_CTRL), LNK_START); if (!IrqPend) { - /* clear the unexpected IRQ, and restore the interrupt mask */ - SK_OUT8(IoC, MR_ADDR(Port, LNK_SYNC_CTRL), LED_CLR_IRQ); + /* clear the unexpected IRQ */ + SK_OUT8(IoC, MR_ADDR(Port, LNK_SYNC_CTRL), LNK_CLR_IRQ); + + /* restore the interrupt mask */ SK_OUT32(IoC, B0_IMSK, OrgIMsk); } } /* SkGeLoadLnkSyncCnt*/ -#endif /* SK_LNK_SYNC_CNT */ +#endif /* SK_LNK_SYNC_CNT */ #if defined(SK_DIAG) || defined(SK_CFG_SYNC) /****************************************************************************** @@ -757,8 +980,8 @@ * synchronous queue is configured */ int SkGeCfgSync( -SK_AC *pAC, /* adapter context */ -SK_IOC IoC, /* IO context */ +SK_AC *pAC, /* Adapter Context */ +SK_IOC IoC, /* I/O Context */ int Port, /* Port Index (MAC_1 + n) */ SK_U32 IntTime, /* Interval Timer Value in units of 8ns */ SK_U32 LimCount, /* Number of bytes to transfer during IntTime */ @@ -776,16 +999,16 @@ SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E010, SKERR_HWI_E010MSG); return(1); } - + if (pAC->GIni.GP[Port].PXSQSize == 0) { SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E009, SKERR_HWI_E009MSG); return(2); } - + /* calculate register values */ IntTime = (IntTime / 2) * pAC->GIni.GIHstClkFact / 100; LimCount = LimCount / 8; - + if (IntTime > TXA_MAX_VAL || LimCount > TXA_MAX_VAL) { SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E010, SKERR_HWI_E010MSG); return(1); @@ -803,13 +1026,13 @@ */ SK_OUT8(IoC, MR_ADDR(Port, TXA_CTRL), TXA_ENA_FSYNC | TXA_DIS_ALLOC | TXA_STOP_RC); - + SK_OUT32(IoC, MR_ADDR(Port, TXA_ITI_INI), IntTime); SK_OUT32(IoC, MR_ADDR(Port, TXA_LIM_INI), LimCount); - + SK_OUT8(IoC, MR_ADDR(Port, TXA_CTRL), (SK_U8)(SyncMode & (TXA_ENA_ALLOC | TXA_DIS_ALLOC))); - + if (IntTime != 0 || LimCount != 0) { SK_OUT8(IoC, MR_ADDR(Port, TXA_CTRL), TXA_DIS_FSYNC | TXA_START_RC); } @@ -830,10 +1053,10 @@ * Returns: * nothing */ -static void DoInitRamQueue( -SK_AC *pAC, /* adapter context */ -SK_IOC IoC, /* IO context */ -int QuIoOffs, /* Queue IO Address Offset */ +void DoInitRamQueue( +SK_AC *pAC, /* Adapter Context */ +SK_IOC IoC, /* I/O Context */ +int QuIoOffs, /* Queue I/O Address Offset */ SK_U32 QuStartAddr, /* Queue Start Address */ SK_U32 QuEndAddr, /* Queue End Address */ int QuType) /* Queue Type (SK_RX_SRAM_Q|SK_RX_BRAM_Q|SK_TX_RAM_Q) */ @@ -866,8 +1089,7 @@ /* continue with SK_RX_BRAM_Q */ case SK_RX_BRAM_Q: - /* write threshold for Rx Queue */ - + /* write threshold for Rx Queue (Pause packets) */ SK_OUT32(IoC, RB_ADDR(QuIoOffs, RB_RX_UTPP), RxUpThresVal); SK_OUT32(IoC, RB_ADDR(QuIoOffs, RB_RX_LTPP), RxLoThresVal); @@ -881,7 +1103,8 @@ * or YUKON is used ((GMAC Tx FIFO is only 1 kB) * we NEED Store & Forward of the RAM buffer. */ - if (pAC->GIni.GIPortUsage == SK_JUMBO_LINK || + if (pAC->GIni.GP[MAC_1].PPortUsage == SK_JUMBO_LINK || + pAC->GIni.GP[MAC_2].PPortUsage == SK_JUMBO_LINK || pAC->GIni.GIYukon) { /* enable Store & Forward Mode for the Tx Side */ SK_OUT8(IoC, RB_ADDR(QuIoOffs, RB_CTRL), RB_ENA_STFWD); @@ -910,8 +1133,8 @@ * nothing */ static void SkGeInitRamBufs( -SK_AC *pAC, /* adapter context */ -SK_IOC IoC, /* IO context */ +SK_AC *pAC, /* Adapter Context */ +SK_IOC IoC, /* I/O Context */ int Port) /* Port Index (MAC_1 + n) */ { SK_GEPORT *pPrt; @@ -919,8 +1142,8 @@ pPrt = &pAC->GIni.GP[Port]; - if (pPrt->PRxQSize == SK_MIN_RXQ_SIZE) { - RxQType = SK_RX_SRAM_Q; /* small Rx Queue */ + if (pPrt->PRxQSize <= SK_MIN_RXQ_SIZE) { + RxQType = SK_RX_SRAM_Q; /* small Rx Queue */ } else { RxQType = SK_RX_BRAM_Q; /* big Rx Queue */ @@ -928,10 +1151,10 @@ DoInitRamQueue(pAC, IoC, pPrt->PRxQOff, pPrt->PRxQRamStart, pPrt->PRxQRamEnd, RxQType); - + DoInitRamQueue(pAC, IoC, pPrt->PXsQOff, pPrt->PXsQRamStart, pPrt->PXsQRamEnd, SK_TX_RAM_Q); - + DoInitRamQueue(pAC, IoC, pPrt->PXaQOff, pPrt->PXaQRamStart, pPrt->PXaQRamEnd, SK_TX_RAM_Q); @@ -952,26 +1175,37 @@ * nothing */ void SkGeInitRamIface( -SK_AC *pAC, /* adapter context */ -SK_IOC IoC) /* IO context */ +SK_AC *pAC, /* Adapter Context */ +SK_IOC IoC) /* I/O Context */ { - /* release local reset */ - SK_OUT16(IoC, B3_RI_CTRL, RI_RST_CLR); + int i; + int RamBuffers; - /* configure timeout values */ - SK_OUT8(IoC, B3_RI_WTO_R1, SK_RI_TO_53); - SK_OUT8(IoC, B3_RI_WTO_XA1, SK_RI_TO_53); - SK_OUT8(IoC, B3_RI_WTO_XS1, SK_RI_TO_53); - SK_OUT8(IoC, B3_RI_RTO_R1, SK_RI_TO_53); - SK_OUT8(IoC, B3_RI_RTO_XA1, SK_RI_TO_53); - SK_OUT8(IoC, B3_RI_RTO_XS1, SK_RI_TO_53); - SK_OUT8(IoC, B3_RI_WTO_R2, SK_RI_TO_53); - SK_OUT8(IoC, B3_RI_WTO_XA2, SK_RI_TO_53); - SK_OUT8(IoC, B3_RI_WTO_XS2, SK_RI_TO_53); - SK_OUT8(IoC, B3_RI_RTO_R2, SK_RI_TO_53); - SK_OUT8(IoC, B3_RI_RTO_XA2, SK_RI_TO_53); - SK_OUT8(IoC, B3_RI_RTO_XS2, SK_RI_TO_53); + if (CHIP_ID_YUKON_2(pAC)) { + RamBuffers = pAC->GIni.GIMacsFound; + } + else { + RamBuffers = 1; + } + + for (i = 0; i < RamBuffers; i++) { + /* release local reset */ + SK_OUT8(IoC, SELECT_RAM_BUFFER(i, B3_RI_CTRL), (SK_U8)RI_RST_CLR); + /* configure timeout values */ + SK_OUT8(IoC, SELECT_RAM_BUFFER(i, B3_RI_WTO_R1), SK_RI_TO_53); + SK_OUT8(IoC, SELECT_RAM_BUFFER(i, B3_RI_WTO_XA1), SK_RI_TO_53); + SK_OUT8(IoC, SELECT_RAM_BUFFER(i, B3_RI_WTO_XS1), SK_RI_TO_53); + SK_OUT8(IoC, SELECT_RAM_BUFFER(i, B3_RI_RTO_R1), SK_RI_TO_53); + SK_OUT8(IoC, SELECT_RAM_BUFFER(i, B3_RI_RTO_XA1), SK_RI_TO_53); + SK_OUT8(IoC, SELECT_RAM_BUFFER(i, B3_RI_RTO_XS1), SK_RI_TO_53); + SK_OUT8(IoC, SELECT_RAM_BUFFER(i, B3_RI_WTO_R2), SK_RI_TO_53); + SK_OUT8(IoC, SELECT_RAM_BUFFER(i, B3_RI_WTO_XA2), SK_RI_TO_53); + SK_OUT8(IoC, SELECT_RAM_BUFFER(i, B3_RI_WTO_XS2), SK_RI_TO_53); + SK_OUT8(IoC, SELECT_RAM_BUFFER(i, B3_RI_RTO_R2), SK_RI_TO_53); + SK_OUT8(IoC, SELECT_RAM_BUFFER(i, B3_RI_RTO_XA2), SK_RI_TO_53); + SK_OUT8(IoC, SELECT_RAM_BUFFER(i, B3_RI_RTO_XS2), SK_RI_TO_53); + } } /* SkGeInitRamIface */ @@ -986,41 +1220,91 @@ * nothing */ static void SkGeInitBmu( -SK_AC *pAC, /* adapter context */ -SK_IOC IoC, /* IO context */ +SK_AC *pAC, /* Adapter Context */ +SK_IOC IoC, /* I/O Context */ int Port) /* Port Index (MAC_1 + n) */ { SK_GEPORT *pPrt; - SK_U32 RxWm; - SK_U32 TxWm; + SK_U16 RxWm; + SK_U16 TxWm; pPrt = &pAC->GIni.GP[Port]; RxWm = SK_BMU_RX_WM; TxWm = SK_BMU_TX_WM; - - if (!pAC->GIni.GIPciSlot64 && !pAC->GIni.GIPciClock66) { - /* for better performance */ - RxWm /= 2; - TxWm /= 2; - } - /* Rx Queue: Release all local resets and set the watermark */ - SK_OUT32(IoC, Q_ADDR(pPrt->PRxQOff, Q_CSR), CSR_CLR_RESET); - SK_OUT32(IoC, Q_ADDR(pPrt->PRxQOff, Q_F), RxWm); + if (CHIP_ID_YUKON_2(pAC)) { - /* - * Tx Queue: Release all local resets if the queue is used ! - * set watermark - */ - if (pPrt->PXSQSize != 0) { - SK_OUT32(IoC, Q_ADDR(pPrt->PXsQOff, Q_CSR), CSR_CLR_RESET); - SK_OUT32(IoC, Q_ADDR(pPrt->PXsQOff, Q_F), TxWm); + if (pAC->GIni.GIPciBus == SK_PEX_BUS) { + /* for better performance set it to 128 */ + RxWm = SK_BMU_RX_WM_PEX; + } + + /* Rx Queue: Release all local resets and set the watermark */ + SK_OUT32(IoC, Q_ADDR(pPrt->PRxQOff, Q_CSR), BMU_CLR_RESET); + SK_OUT32(IoC, Q_ADDR(pPrt->PRxQOff, Q_CSR), BMU_OPER_INIT); + SK_OUT32(IoC, Q_ADDR(pPrt->PRxQOff, Q_CSR), BMU_FIFO_OP_ON); + + SK_OUT16(IoC, Q_ADDR(pPrt->PRxQOff, Q_WM), RxWm); + + if (pAC->GIni.GIChipId == CHIP_ID_YUKON_EC_U && + pAC->GIni.GIChipRev == CHIP_REV_YU_EC_U_A1) { + /* MAC Rx RAM Read is controlled by hardware */ + SK_OUT32(IoC, Q_ADDR(pPrt->PRxQOff, Q_F), F_M_RX_RAM_DIS); + } + + /* + * Tx Queue: Release all local resets if the queue is used ! + * set watermark + */ + if (pPrt->PXSQSize != 0 && HW_SYNC_TX_SUPPORTED(pAC)) { + /* Yukon-EC doesn't have a synchronous Tx queue */ + SK_OUT32(IoC, Q_ADDR(pPrt->PXsQOff, Q_CSR), BMU_CLR_RESET); + SK_OUT32(IoC, Q_ADDR(pPrt->PXsQOff, Q_CSR), BMU_OPER_INIT); + SK_OUT32(IoC, Q_ADDR(pPrt->PXsQOff, Q_CSR), BMU_FIFO_OP_ON); + + SK_OUT16(IoC, Q_ADDR(pPrt->PXsQOff, Q_WM), TxWm); + } + + if (pPrt->PXAQSize != 0) { + + SK_OUT32(IoC, Q_ADDR(pPrt->PXaQOff, Q_CSR), BMU_CLR_RESET); + SK_OUT32(IoC, Q_ADDR(pPrt->PXaQOff, Q_CSR), BMU_OPER_INIT); + SK_OUT32(IoC, Q_ADDR(pPrt->PXaQOff, Q_CSR), BMU_FIFO_OP_ON); + + SK_OUT16(IoC, Q_ADDR(pPrt->PXaQOff, Q_WM), TxWm); + + if (pAC->GIni.GIChipId == CHIP_ID_YUKON_EC_U && + pAC->GIni.GIChipRev == CHIP_REV_YU_EC_U_A0) { + /* fix for Yukon-EC Ultra: set BMU FIFO level */ + SK_OUT16(IoC, Q_ADDR(pPrt->PXaQOff, Q_AL), SK_ECU_TXFF_LEV); + } + } } - - if (pPrt->PXAQSize != 0) { - SK_OUT32(IoC, Q_ADDR(pPrt->PXaQOff, Q_CSR), CSR_CLR_RESET); - SK_OUT32(IoC, Q_ADDR(pPrt->PXaQOff, Q_F), TxWm); + else { + if (!pAC->GIni.GIPciSlot64 && !pAC->GIni.GIPciClock66) { + /* for better performance */ + RxWm /= 2; + TxWm /= 2; + } + + /* Rx Queue: Release all local resets and set the watermark */ + SK_OUT32(IoC, Q_ADDR(pPrt->PRxQOff, Q_CSR), CSR_CLR_RESET); + SK_OUT32(IoC, Q_ADDR(pPrt->PRxQOff, Q_F), RxWm); + + /* + * Tx Queue: Release all local resets if the queue is used ! + * set watermark + */ + if (pPrt->PXSQSize != 0) { + SK_OUT32(IoC, Q_ADDR(pPrt->PXsQOff, Q_CSR), CSR_CLR_RESET); + SK_OUT32(IoC, Q_ADDR(pPrt->PXsQOff, Q_F), TxWm); + } + + if (pPrt->PXAQSize != 0) { + SK_OUT32(IoC, Q_ADDR(pPrt->PXaQOff, Q_CSR), CSR_CLR_RESET); + SK_OUT32(IoC, Q_ADDR(pPrt->PXaQOff, Q_F), TxWm); + } } /* * Do NOT enable the descriptor poll timers here, because @@ -1044,20 +1328,29 @@ */ static SK_U32 TestStopBit( SK_AC *pAC, /* Adapter Context */ -SK_IOC IoC, /* IO Context */ -int QuIoOffs) /* Queue IO Address Offset */ +SK_IOC IoC, /* I/O Context */ +int QuIoOffs) /* Queue I/O Address Offset */ { SK_U32 QuCsr; /* CSR contents */ SK_IN32(IoC, Q_ADDR(QuIoOffs, Q_CSR), &QuCsr); - - if ((QuCsr & (CSR_STOP | CSR_SV_IDLE)) == 0) { - /* Stop Descriptor overridden by start command */ - SK_OUT32(IoC, Q_ADDR(QuIoOffs, Q_CSR), CSR_STOP); - SK_IN32(IoC, Q_ADDR(QuIoOffs, Q_CSR), &QuCsr); + if (CHIP_ID_YUKON_2(pAC)) { + if ((QuCsr & (BMU_STOP | BMU_IDLE)) == 0) { + /* Stop Descriptor overridden by start command */ + SK_OUT32(IoC, Q_ADDR(QuIoOffs, Q_CSR), BMU_STOP); + + SK_IN32(IoC, Q_ADDR(QuIoOffs, Q_CSR), &QuCsr); + } + } + else { + if ((QuCsr & (CSR_STOP | CSR_SV_IDLE)) == 0) { + /* Stop Descriptor overridden by start command */ + SK_OUT32(IoC, Q_ADDR(QuIoOffs, Q_CSR), CSR_STOP); + + SK_IN32(IoC, Q_ADDR(QuIoOffs, Q_CSR), &QuCsr); + } } - return(QuCsr); } /* TestStopBit */ @@ -1081,8 +1374,8 @@ * has to be stopped once before. * SK_STOP_ALL SK_STOP_TX + SK_STOP_RX * - * RstMode = SK_SOFT_RST Resets the MAC. The PHY is still alive. - * SK_HARD_RST Resets the MAC and the PHY. + * RstMode = SK_SOFT_RST Resets the MAC, the PHY is still alive. + * SK_HARD_RST Resets the MAC and the PHY. * * Example: * 1) A Link Down event was signaled for a port. Therefore the activity @@ -1141,56 +1434,82 @@ * SWITCH_PORT. */ void SkGeStopPort( -SK_AC *pAC, /* adapter context */ -SK_IOC IoC, /* I/O context */ -int Port, /* port to stop (MAC_1 + n) */ +SK_AC *pAC, /* Adapter Context */ +SK_IOC IoC, /* I/O Context */ +int Port, /* Port to stop (MAC_1 + n) */ int Dir, /* Direction to Stop (SK_STOP_RX, SK_STOP_TX, SK_STOP_ALL) */ int RstMode)/* Reset Mode (SK_SOFT_RST, SK_HARD_RST) */ { -#ifndef SK_DIAG - SK_EVPARA Para; -#endif /* !SK_DIAG */ SK_GEPORT *pPrt; - SK_U32 DWord; + SK_U32 RxCsr; SK_U32 XsCsr; SK_U32 XaCsr; SK_U64 ToutStart; + SK_U32 CsrStart; + SK_U32 CsrStop; + SK_U32 CsrIdle; + SK_U32 CsrTest; + SK_U8 rsl; /* FIFO read shadow level */ + SK_U8 rl; /* FIFO read level */ int i; int ToutCnt; pPrt = &pAC->GIni.GP[Port]; + /* set the proper values of Q_CSR register layout depending on the chip */ + if (CHIP_ID_YUKON_2(pAC)) { + CsrStart = BMU_START; + CsrStop = BMU_STOP; + CsrIdle = BMU_IDLE; + CsrTest = BMU_IDLE; + } + else { + CsrStart = CSR_START; + CsrStop = CSR_STOP; + CsrIdle = CSR_SV_IDLE; + CsrTest = CSR_SV_IDLE | CSR_STOP; + } + if ((Dir & SK_STOP_TX) != 0) { - /* disable receiver and transmitter */ - SkMacRxTxDisable(pAC, IoC, Port); - + + if (!pAC->GIni.GIAsfEnabled) { + /* disable receiver and transmitter */ + SkMacRxTxDisable(pAC, IoC, Port); + } + /* stop both transmit queues */ + SK_OUT32(IoC, Q_ADDR(pPrt->PXsQOff, Q_CSR), CsrStop); + SK_OUT32(IoC, Q_ADDR(pPrt->PXaQOff, Q_CSR), CsrStop); /* * If the BMU is in the reset state CSR_STOP will terminate * immediately. */ - SK_OUT32(IoC, Q_ADDR(pPrt->PXsQOff, Q_CSR), CSR_STOP); - SK_OUT32(IoC, Q_ADDR(pPrt->PXaQOff, Q_CSR), CSR_STOP); ToutStart = SkOsGetTime(pAC); ToutCnt = 0; do { - /* - * Clear packet arbiter timeout to make sure - * this loop will terminate. - */ - SK_OUT16(IoC, B3_PA_CTRL, (SK_U16)((Port == MAC_1) ? - PA_CLR_TO_TX1 : PA_CLR_TO_TX2)); - - /* - * If the transfer stucks at the MAC the STOP command will not - * terminate if we don't flush the XMAC's transmit FIFO ! - */ - SkMacFlushTxFifo(pAC, IoC, Port); +#ifdef GENESIS + if (pAC->GIni.GIGenesis) { + /* clear Tx packet arbiter timeout IRQ */ + SK_OUT16(IoC, B3_PA_CTRL, (SK_U16)((Port == MAC_1) ? + PA_CLR_TO_TX1 : PA_CLR_TO_TX2)); + /* + * If the transfer stucks at the XMAC the STOP command will not + * terminate if we don't flush the XMAC's transmit FIFO ! + */ + SkMacFlushTxFifo(pAC, IoC, Port); + } +#endif /* GENESIS */ - XsCsr = TestStopBit(pAC, IoC, pPrt->PXsQOff); XaCsr = TestStopBit(pAC, IoC, pPrt->PXaQOff); + if (HW_SYNC_TX_SUPPORTED(pAC)) { + XsCsr = TestStopBit(pAC, IoC, pPrt->PXsQOff); + } + else { + XsCsr = XaCsr; + } + if (SkOsGetTime(pAC) - ToutStart > (SK_TICKS_PER_SEC / 18)) { /* * Timeout of 1/18 second reached. @@ -1198,67 +1517,115 @@ */ ToutCnt++; if (ToutCnt > 1) { - /* Might be a problem when the driver event handler - * calls StopPort again. XXX. + /* + * If BMU stop doesn't terminate, we assume that + * we have a stable state and can reset the BMU, + * the Prefetch Unit, and RAM buffer now. */ - - /* Fatal Error, Loop aborted */ - SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_HWI_E018, - SKERR_HWI_E018MSG); -#ifndef SK_DIAG - Para.Para64 = Port; - SkEventQueue(pAC, SKGE_DRV, SK_DRV_PORT_FAIL, Para); -#endif /* !SK_DIAG */ - return; + break; /* ===> leave do/while loop here */ } /* - * Cache incoherency workaround: Assume a start command + * Cache incoherency workaround: assume a start command * has been lost while sending the frame. */ ToutStart = SkOsGetTime(pAC); - if ((XsCsr & CSR_STOP) != 0) { - SK_OUT32(IoC, Q_ADDR(pPrt->PXsQOff, Q_CSR), CSR_START); + if ((XsCsr & CsrStop) != 0) { + SK_OUT32(IoC, Q_ADDR(pPrt->PXsQOff, Q_CSR), CsrStart); } - if ((XaCsr & CSR_STOP) != 0) { - SK_OUT32(IoC, Q_ADDR(pPrt->PXaQOff, Q_CSR), CSR_START); + + if ((XaCsr & CsrStop) != 0) { + SK_OUT32(IoC, Q_ADDR(pPrt->PXaQOff, Q_CSR), CsrStart); } - } + /* + * After the previous operations the X(s|a)Csr does no + * longer contain the proper values + */ + XaCsr = TestStopBit(pAC, IoC, pPrt->PXaQOff); + + if (HW_SYNC_TX_SUPPORTED(pAC)) { + XsCsr = TestStopBit(pAC, IoC, pPrt->PXsQOff); + } + else { + XsCsr = XaCsr; + } + } /* * Because of the ASIC problem report entry from 21.08.1998 it is * required to wait until CSR_STOP is reset and CSR_SV_IDLE is set. + * (valid for GENESIS only) */ - } while ((XsCsr & (CSR_STOP | CSR_SV_IDLE)) != CSR_SV_IDLE || - (XaCsr & (CSR_STOP | CSR_SV_IDLE)) != CSR_SV_IDLE); + } while (((XsCsr & CsrTest) != CsrIdle || + (XaCsr & CsrTest) != CsrIdle)); - /* Reset the MAC depending on the RstMode */ - if (RstMode == SK_SOFT_RST) { - SkMacSoftRst(pAC, IoC, Port); + if (pAC->GIni.GIAsfEnabled) { + + pPrt->PState = (RstMode == SK_SOFT_RST) ? SK_PRT_STOP : + SK_PRT_RESET; } else { - SkMacHardRst(pAC, IoC, Port); - } - - /* Disable Force Sync bit and Enable Alloc bit */ + /* Reset the MAC depending on the RstMode */ + if (RstMode == SK_SOFT_RST) { + + SkMacSoftRst(pAC, IoC, Port); + } + else { +#ifdef SK_DIAG + if (HW_FEATURE(pAC, HWF_WA_DEV_472) && Port == MAC_1 && + pAC->GIni.GP[MAC_2].PState == SK_PRT_RUN) { + + pAC->GIni.GP[MAC_1].PState = SK_PRT_RESET; + + /* set GPHY Control reset */ + SK_OUT8(IoC, MR_ADDR(MAC_1, GPHY_CTRL), (SK_U8)GPC_RST_SET); + } + else { + + SkMacHardRst(pAC, IoC, Port); + } +#else /* !SK_DIAG */ + SkMacHardRst(pAC, IoC, Port); +#endif /* !SK_DIAG */ + } + } + + /* disable Force Sync bit and Enable Alloc bit */ SK_OUT8(IoC, MR_ADDR(Port, TXA_CTRL), TXA_DIS_FSYNC | TXA_DIS_ALLOC | TXA_STOP_RC); - + /* Stop Interval Timer and Limit Counter of Tx Arbiter */ SK_OUT32(IoC, MR_ADDR(Port, TXA_ITI_INI), 0L); SK_OUT32(IoC, MR_ADDR(Port, TXA_LIM_INI), 0L); /* Perform a local reset of the port's Tx path */ + if (CHIP_ID_YUKON_2(pAC)) { + /* Reset the PCI FIFO of the async Tx queue */ + SK_OUT32(IoC, Q_ADDR(pPrt->PXaQOff, Q_CSR), + BMU_RST_SET | BMU_FIFO_RST); + + /* Reset the PCI FIFO of the sync Tx queue */ + SK_OUT32(IoC, Q_ADDR(pPrt->PXsQOff, Q_CSR), + BMU_RST_SET | BMU_FIFO_RST); + + /* Reset the Tx prefetch units */ + SK_OUT32(IoC, Y2_PREF_Q_ADDR(pPrt->PXaQOff, PREF_UNIT_CTRL_REG), + PREF_UNIT_RST_SET); + SK_OUT32(IoC, Y2_PREF_Q_ADDR(pPrt->PXsQOff, PREF_UNIT_CTRL_REG), + PREF_UNIT_RST_SET); + } + else { + /* Reset the PCI FIFO of the async Tx queue */ + SK_OUT32(IoC, Q_ADDR(pPrt->PXaQOff, Q_CSR), CSR_SET_RESET); + /* Reset the PCI FIFO of the sync Tx queue */ + SK_OUT32(IoC, Q_ADDR(pPrt->PXsQOff, Q_CSR), CSR_SET_RESET); + } - /* Reset the PCI FIFO of the async Tx queue */ - SK_OUT32(IoC, Q_ADDR(pPrt->PXaQOff, Q_CSR), CSR_SET_RESET); - /* Reset the PCI FIFO of the sync Tx queue */ - SK_OUT32(IoC, Q_ADDR(pPrt->PXsQOff, Q_CSR), CSR_SET_RESET); /* Reset the RAM Buffer async Tx queue */ SK_OUT8(IoC, RB_ADDR(pPrt->PXaQOff, RB_CTRL), RB_RST_SET); /* Reset the RAM Buffer sync Tx queue */ SK_OUT8(IoC, RB_ADDR(pPrt->PXsQOff, RB_CTRL), RB_RST_SET); - + /* Reset Tx MAC FIFO */ #ifdef GENESIS if (pAC->GIni.GIGenesis) { @@ -1270,74 +1637,129 @@ SkGeXmitLED(pAC, IoC, MR_ADDR(Port, TX_LED_INI), SK_LED_DIS); } #endif /* GENESIS */ - + #ifdef YUKON if (pAC->GIni.GIYukon) { - /* Reset TX MAC FIFO */ - SK_OUT8(IoC, MR_ADDR(Port, TX_GMF_CTRL_T), (SK_U8)GMF_RST_SET); + /* do the reset only if ASF is not enabled */ + if (!pAC->GIni.GIAsfEnabled) { + /* Reset Tx MAC FIFO */ + SK_OUT8(IoC, MR_ADDR(Port, TX_GMF_CTRL_T), (SK_U8)GMF_RST_SET); + } + + /* set Pause Off */ + SK_OUT8(IoC, MR_ADDR(Port, GMAC_CTRL), (SK_U8)GMC_PAUSE_OFF); } #endif /* YUKON */ } if ((Dir & SK_STOP_RX) != 0) { - /* - * The RX Stop Command will not terminate if no buffers - * are queued in the RxD ring. But it will always reach - * the Idle state. Therefore we can use this feature to - * stop the transfer of received packets. - */ - /* stop the port's receive queue */ - SK_OUT32(IoC, Q_ADDR(pPrt->PRxQOff, Q_CSR), CSR_STOP); - - i = 100; - do { + + if (CHIP_ID_YUKON_2(pAC)) { /* - * Clear packet arbiter timeout to make sure - * this loop will terminate + * The RX Stop command will not work for Yukon-2 if the BMU does not + * reach the end of packet and since we can't make sure that we have + * incoming data, we must reset the BMU while it is not during a DMA + * transfer. Since it is possible that the RX path is still active, + * the RX RAM buffer will be stopped first, so any possible incoming + * data will not trigger a DMA. After the RAM buffer is stopped, the + * BMU is polled until any DMA in progress is ended and only then it + * will be reset. */ - SK_OUT16(IoC, B3_PA_CTRL, (SK_U16)((Port == MAC_1) ? - PA_CLR_TO_RX1 : PA_CLR_TO_RX2)); - DWord = TestStopBit(pAC, IoC, pPrt->PRxQOff); + /* disable the RAM Buffer receive queue */ + SK_OUT8(IoC, RB_ADDR(pPrt->PRxQOff, RB_CTRL), RB_DIS_OP_MD); - /* timeout if i==0 (bug fix for #10748) */ - if (--i == 0) { - SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_HWI_E024, - SKERR_HWI_E024MSG); - break; + i = 0xffff; + while (--i) { + SK_IN8(IoC, RB_ADDR(pPrt->PRxQOff, Q_RX_RSL), &rsl); + SK_IN8(IoC, RB_ADDR(pPrt->PRxQOff, Q_RX_RL), &rl); + + if (rsl == rl) { + break; + } } + /* - * because of the ASIC problem report entry from 21.08.98 - * it is required to wait until CSR_STOP is reset and - * CSR_SV_IDLE is set. + * If the Rx side is blocked, the above loop cannot terminate. + * But, if there was any traffic it should be terminated, now. + * However, stop the Rx BMU and the Prefetch Unit ! */ - } while ((DWord & (CSR_STOP | CSR_SV_IDLE)) != CSR_SV_IDLE); + SK_OUT32(IoC, Q_ADDR(pPrt->PRxQOff, Q_CSR), + BMU_RST_SET | BMU_FIFO_RST); + /* reset the Rx prefetch unit */ + SK_OUT32(IoC, Y2_PREF_Q_ADDR(pPrt->PRxQOff, PREF_UNIT_CTRL_REG), + PREF_UNIT_RST_SET); + } + else { + /* + * The RX Stop Command will not terminate if no buffers + * are queued in the RxD ring. But it will always reach + * the Idle state. Therefore we can use this feature to + * stop the transfer of received packets. + */ + /* stop the port's receive queue */ + SK_OUT32(IoC, Q_ADDR(pPrt->PRxQOff, Q_CSR), CsrStop); - /* The path data transfer activity is fully stopped now */ + i = 100; + do { +#ifdef GENESIS + if (pAC->GIni.GIGenesis) { + /* clear Rx packet arbiter timeout IRQ */ + SK_OUT16(IoC, B3_PA_CTRL, (SK_U16)((Port == MAC_1) ? + PA_CLR_TO_RX1 : PA_CLR_TO_RX2)); + } +#endif /* GENESIS */ + + RxCsr = TestStopBit(pAC, IoC, pPrt->PRxQOff); + + /* timeout if i==0 (bug fix for #10748) */ + if (--i == 0) { + SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_HWI_E024, + SKERR_HWI_E024MSG); + break; + } + /* + * Because of the ASIC problem report entry from 21.08.1998 it is + * required to wait until CSR_STOP is reset and CSR_SV_IDLE is set. + * (valid for GENESIS only) + */ + } while ((RxCsr & CsrTest) != CsrIdle); + /* The path data transfer activity is fully stopped now */ - /* Perform a local reset of the port's Rx path */ + /* Perform a local reset of the port's Rx path */ + /* Reset the PCI FIFO of the Rx queue */ + SK_OUT32(IoC, Q_ADDR(pPrt->PRxQOff, Q_CSR), CSR_SET_RESET); + } - /* Reset the PCI FIFO of the Rx queue */ - SK_OUT32(IoC, Q_ADDR(pPrt->PRxQOff, Q_CSR), CSR_SET_RESET); /* Reset the RAM Buffer receive queue */ SK_OUT8(IoC, RB_ADDR(pPrt->PRxQOff, RB_CTRL), RB_RST_SET); /* Reset Rx MAC FIFO */ #ifdef GENESIS if (pAC->GIni.GIGenesis) { - + SK_OUT8(IoC, MR_ADDR(Port, RX_MFF_CTRL2), MFF_RST_SET); /* switch Rx LED off, stop the LED counter */ SkGeXmitLED(pAC, IoC, MR_ADDR(Port, RX_LED_INI), SK_LED_DIS); } #endif /* GENESIS */ - #ifdef YUKON - if (pAC->GIni.GIYukon) { + if (pAC->GIni.GIYukon && !pAC->GIni.GIAsfEnabled) { /* Reset Rx MAC FIFO */ SK_OUT8(IoC, MR_ADDR(Port, RX_GMF_CTRL_T), (SK_U8)GMF_RST_SET); } + + if (((pAC->GIni.GIChipId == CHIP_ID_YUKON) || + (pAC->GIni.GIChipId == CHIP_ID_YUKON_LITE)) && + (RstMode == SK_HARD_RST)) { + /* set Link Control reset */ + SK_OUT8(IoC, MR_ADDR(Port, GMAC_LINK_CTRL), (SK_U8)GMLC_RST_SET); + + /* clear Link Control reset */ + SK_OUT8(IoC, MR_ADDR(Port, GMAC_LINK_CTRL), (SK_U8)GMLC_RST_CLR); + } + #endif /* YUKON */ } } /* SkGeStopPort */ @@ -1354,8 +1776,8 @@ * nothing */ static void SkGeInit0( -SK_AC *pAC, /* adapter context */ -SK_IOC IoC) /* IO context */ +SK_AC *pAC, /* Adapter Context */ +SK_IOC IoC) /* I/O Context */ { int i; SK_GEPORT *pPrt; @@ -1364,6 +1786,7 @@ pPrt = &pAC->GIni.GP[i]; pPrt->PState = SK_PRT_RESET; + pPrt->PPortUsage = SK_RED_LINK; pPrt->PRxQOff = QOffTab[i].RxQOff; pPrt->PXsQOff = QOffTab[i].XsQOff; pPrt->PXaQOff = QOffTab[i].XaQOff; @@ -1392,24 +1815,30 @@ pPrt->PLipaAutoNeg = (SK_U8)SK_LIPA_UNKNOWN; pPrt->PAutoNegFail = SK_FALSE; pPrt->PHWLinkUp = SK_FALSE; - pPrt->PLinkBroken = SK_TRUE; /* See WA code */ + pPrt->PLinkBroken = SK_TRUE; /* See WA code */ pPrt->PPhyPowerState = PHY_PM_OPERATIONAL_MODE; pPrt->PMacColThres = TX_COL_DEF; pPrt->PMacJamLen = TX_JAM_LEN_DEF; pPrt->PMacJamIpgVal = TX_JAM_IPG_DEF; pPrt->PMacJamIpgData = TX_IPG_JAM_DEF; + pPrt->PMacBackOffLim = TX_BOF_LIM_DEF; + pPrt->PMacDataBlind = DATA_BLIND_DEF; pPrt->PMacIpgData = IPG_DATA_DEF; pPrt->PMacLimit4 = SK_FALSE; } - pAC->GIni.GIPortUsage = SK_RED_LINK; pAC->GIni.GILedBlinkCtrl = (SK_U16)OemConfig.Value; - pAC->GIni.GIValIrqMask = IS_ALL_MSK; + pAC->GIni.GIChipCap = 0; + + for (i = 0; i < 4; i++) { + pAC->GIni.HwF.Features[i]= 0x00000000; + pAC->GIni.HwF.OnMask[i] = 0x00000000; + pAC->GIni.HwF.OffMask[i] = 0x00000000; + } } /* SkGeInit0*/ #ifdef SK_PCI_RESET - /****************************************************************************** * * SkGePciReset() - Reset PCI interface @@ -1425,8 +1854,8 @@ * 1: Power state could not be changed to 3. */ static int SkGePciReset( -SK_AC *pAC, /* adapter context */ -SK_IOC IoC) /* IO context */ +SK_AC *pAC, /* Adapter Context */ +SK_IOC IoC) /* I/O Context */ { int i; SK_U16 PmCtlSts; @@ -1449,7 +1878,7 @@ /* We know the RAM Interface Arbiter is enabled. */ SkPciWriteCfgWord(pAC, PCI_PM_CTL_STS, PCI_PM_STATE_D3); SkPciReadCfgWord(pAC, PCI_PM_CTL_STS, &PmCtlSts); - + if ((PmCtlSts & PCI_PM_STATE_MSK) != PCI_PM_STATE_D3) { return(1); } @@ -1459,7 +1888,7 @@ /* Check for D0 state. */ SkPciReadCfgWord(pAC, PCI_PM_CTL_STS, &PmCtlSts); - + if ((PmCtlSts & PCI_PM_STATE_MSK) != PCI_PM_STATE_D0) { return(1); } @@ -1468,11 +1897,24 @@ SkPciReadCfgWord(pAC, PCI_COMMAND, &PciCmd); SkPciReadCfgByte(pAC, PCI_CACHE_LSZ, &Cls); SkPciReadCfgDWord(pAC, PCI_BASE_1ST, &Bp1); - SkPciReadCfgDWord(pAC, PCI_BASE_2ND, &Bp2); + + /* + * Compute the location in PCI config space of BAR2 + * relativ to the location of BAR1 + */ + if ((Bp1 & PCI_MEM_TYP_MSK) == PCI_MEM64BIT) { + /* BAR1 is 64 bits wide */ + i = 8; + } + else { + i = 4; + } + + SkPciReadCfgDWord(pAC, PCI_BASE_1ST + i, &Bp2); SkPciReadCfgByte(pAC, PCI_LAT_TIM, &Lat); - - if (PciCmd != 0 || Cls != (SK_U8)0 || Lat != (SK_U8)0 || - (Bp1 & 0xfffffff0L) != 0 || Bp2 != 1) { + + if (PciCmd != 0 || Cls != 0 || (Bp1 & 0xfffffff0L) != 0 || Bp2 != 1 || + Lat != 0) { return(1); } @@ -1483,9 +1925,115 @@ return(0); } /* SkGePciReset */ - #endif /* SK_PCI_RESET */ + +#ifndef SK_SLIM +/****************************************************************************** + * + * SkGeSetUpSupFeatures() - Collect Feature List for HW_FEATURE Macro + * + * Description: + * This function collects the available features and required + * deviation services of the Adapter and provides these + * information in the GIHwF struct. This information is used as + * default value and may be overritten by the driver using the + * SET_HW_FEATURE_MASK() macro in its Init0 phase. + * + * Notice: + * Using the On and Off mask: Never switch on the same bit in both + * masks simultaneously. However, if doing the Off mask will win. + * + * Returns: + * nothing + */ +static void SkGeSetUpSupFeatures( +SK_AC *pAC, /* Adapter Context */ +SK_IOC IoC) /* I/O Context */ +{ + int i; + SK_U16 Word; + + switch (pAC->GIni.GIChipId) { + case CHIP_ID_YUKON_EC: + if (pAC->GIni.GIChipRev == CHIP_REV_YU_EC_A1) { + /* A0/A1 */ + pAC->GIni.HwF.Features[HW_DEV_LIST] = + HWF_WA_DEV_42 | HWF_WA_DEV_46 | HWF_WA_DEV_43_418 | + HWF_WA_DEV_420 | HWF_WA_DEV_423 | + HWF_WA_DEV_424 | HWF_WA_DEV_425 | HWF_WA_DEV_427 | + HWF_WA_DEV_428 | HWF_WA_DEV_483 | HWF_WA_DEV_4109 | + HWF_WA_DEV_4152| HWF_WA_DEV_4167; + } + else { + /* A2/A3 */ + pAC->GIni.HwF.Features[HW_DEV_LIST] = + HWF_WA_DEV_424 | HWF_WA_DEV_425 | HWF_WA_DEV_427 | + HWF_WA_DEV_428 | HWF_WA_DEV_483 | HWF_WA_DEV_4109 | + HWF_WA_DEV_4152| HWF_WA_DEV_4167; + } + break; + case CHIP_ID_YUKON_FE: + pAC->GIni.HwF.Features[HW_DEV_LIST] = + HWF_WA_DEV_427 | HWF_WA_DEV_4109 | + HWF_WA_DEV_4152| HWF_WA_DEV_4167; + break; + case CHIP_ID_YUKON_XL: + switch (pAC->GIni.GIChipRev) { + case CHIP_REV_YU_XL_A0: /* still needed for Diag */ + pAC->GIni.HwF.Features[HW_DEV_LIST] = + HWF_WA_DEV_427 | HWF_WA_DEV_463 | HWF_WA_DEV_472 | + HWF_WA_DEV_479 | HWF_WA_DEV_483 | HWF_WA_DEV_4115 | + HWF_WA_DEV_4152| HWF_WA_DEV_4167; + break; + + case CHIP_REV_YU_XL_A1: + pAC->GIni.HwF.Features[HW_DEV_LIST] = + HWF_WA_DEV_427 | HWF_WA_DEV_483 | HWF_WA_DEV_4109 | + HWF_WA_DEV_4115| HWF_WA_DEV_4152| HWF_WA_DEV_4167; + break; + + case CHIP_REV_YU_XL_A2: + pAC->GIni.HwF.Features[HW_DEV_LIST] = + HWF_WA_DEV_427 | HWF_WA_DEV_483 | HWF_WA_DEV_4109 | + HWF_WA_DEV_4115 |HWF_WA_DEV_4167; + break; + + case CHIP_REV_YU_XL_A3: + pAC->GIni.HwF.Features[HW_DEV_LIST] = + HWF_WA_DEV_427 | HWF_WA_DEV_483 | HWF_WA_DEV_4109 | + HWF_WA_DEV_4115; + break; + } + break; + case CHIP_ID_YUKON_EC_U: + if (pAC->GIni.GIChipRev == CHIP_REV_YU_EC_U_A0) { + pAC->GIni.HwF.Features[HW_DEV_LIST] = + HWF_WA_DEV_427 | HWF_WA_DEV_483 | HWF_WA_DEV_4109; + } + else if (pAC->GIni.GIChipRev == CHIP_REV_YU_EC_U_A1) { + pAC->GIni.HwF.Features[HW_DEV_LIST] = + HWF_WA_DEV_427 | HWF_WA_DEV_4109 | HWF_WA_DEV_4185; + + /* check for A1b */ + SK_IN16(IoC, Q_ADDR(Q_XA1, Q_WM), &Word); + if (Word == 0) { + pAC->GIni.HwF.Features[HW_DEV_LIST] |= + HWF_WA_DEV_4185CS | HWF_WA_DEV_4200; + } + } + break; + } + + for (i = 0; i < 4; i++) { + pAC->GIni.HwF.Features[i] = + (pAC->GIni.HwF.Features[i] | pAC->GIni.HwF.OnMask[i]) & + ~pAC->GIni.HwF.OffMask[i]; + } +} /* SkGeSetUpSupFeatures */ +#endif /* !SK_SLIM */ + + /****************************************************************************** * * SkGeInit1() - Level 1 Initialization @@ -1508,80 +2056,235 @@ * 6: HW self test failed */ static int SkGeInit1( -SK_AC *pAC, /* adapter context */ -SK_IOC IoC) /* IO context */ +SK_AC *pAC, /* Adapter Context */ +SK_IOC IoC) /* I/O Context */ { SK_U8 Byte; SK_U16 Word; - SK_U16 CtrlStat; + SK_U32 CtrlStat; + SK_U32 VauxAvail; SK_U32 DWord; + SK_U32 Our1; + SK_U32 PowerDownBit; + SK_BOOL FiberType; + SK_GEPORT *pPrt; int RetVal; - int i; + int i, j; RetVal = 0; - /* save CLK_RUN bits (YUKON-Lite) */ - SK_IN16(IoC, B0_CTST, &CtrlStat); + /* save CLK_RUN & ASF_ENABLE bits (YUKON-Lite, YUKON-EC) */ + SK_IN32(IoC, B0_CTST, &CtrlStat); #ifdef SK_PCI_RESET (void)SkGePciReset(pAC, IoC); #endif /* SK_PCI_RESET */ - /* do the SW-reset */ - SK_OUT8(IoC, B0_CTST, CS_RST_SET); - /* release the SW-reset */ + /* Important: SW-reset has to be cleared here, to ensure + * the CHIP_ID can be read IO-mapped based, too - + * remember the RAP register can only be written if + * SW-reset is cleared. + */ SK_OUT8(IoC, B0_CTST, CS_RST_CLR); + /* read Chip Identification Number */ + SK_IN8(IoC, B2_CHIP_ID, &Byte); + pAC->GIni.GIChipId = Byte; + + pAC->GIni.GIAsfEnabled = SK_FALSE; + + /* ASF support only for Yukon-2 */ + if ((pAC->GIni.GIChipId >= CHIP_ID_YUKON_XL) && + (pAC->GIni.GIChipId <= CHIP_ID_YUKON_EC)) { +#ifdef SK_ASF + if ((CtrlStat & Y2_ASF_ENABLE) != 0) { + /* do the SW-reset only if ASF is not enabled */ + pAC->GIni.GIAsfEnabled = SK_TRUE; + } +#else /* !SK_ASF */ + + SK_IN8(IoC, B28_Y2_ASF_STAT_CMD, &Byte); + + pAC->GIni.GIAsfRunning = Byte & Y2_ASF_RUNNING; + + /* put ASF system in reset state */ + SK_OUT8(IoC, B28_Y2_ASF_STAT_CMD, (SK_U8)Y2_ASF_RESET); + + /* disable ASF Unit */ + SK_OUT16(IoC, B0_CTST, Y2_ASF_DISABLE); +#endif /* !SK_ASF */ + } + + if (!pAC->GIni.GIAsfEnabled) { + /* Yukon-2: required for Diag and Power Management */ + /* set the SW-reset */ + SK_OUT8(IoC, B0_CTST, CS_RST_SET); + + /* release the SW-reset */ + SK_OUT8(IoC, B0_CTST, CS_RST_CLR); + } + + /* enable Config Write */ + SK_OUT8(IoC, B2_TST_CTRL1, TST_CFG_WRITE_ON); + /* reset all error bits in the PCI STATUS register */ /* * Note: PCI Cfg cycles cannot be used, because they are not * available on some platforms after 'boot time'. */ - SK_IN16(IoC, PCI_C(PCI_STATUS), &Word); - - SK_OUT8(IoC, B2_TST_CTRL1, TST_CFG_WRITE_ON); - SK_OUT16(IoC, PCI_C(PCI_STATUS), (SK_U16)(Word | PCI_ERRBITS)); - SK_OUT8(IoC, B2_TST_CTRL1, TST_CFG_WRITE_OFF); + SK_IN16(IoC, PCI_C(pAC, PCI_STATUS), &Word); + + SK_OUT16(IoC, PCI_C(pAC, PCI_STATUS), Word | (SK_U16)PCI_ERRBITS); /* release Master Reset */ SK_OUT8(IoC, B0_CTST, CS_MRST_CLR); #ifdef CLK_RUN CtrlStat |= CS_CLK_RUN_ENA; -#endif /* CLK_RUN */ /* restore CLK_RUN bits */ SK_OUT16(IoC, B0_CTST, (SK_U16)(CtrlStat & (CS_CLK_RUN_HOT | CS_CLK_RUN_RST | CS_CLK_RUN_ENA))); +#endif /* CLK_RUN */ + + if ((pAC->GIni.GIChipId >= CHIP_ID_YUKON_XL) && + (pAC->GIni.GIChipId <= CHIP_ID_YUKON_FE)) { + + pAC->GIni.GIYukon2 = SK_TRUE; + pAC->GIni.GIValIrqMask = Y2_IS_ALL_MSK; + pAC->GIni.GIValHwIrqMask = Y2_HWE_ALL_MSK; + + VauxAvail = Y2_VAUX_AVAIL; + + SK_IN32(IoC, PCI_C(pAC, PCI_OUR_STATUS), &DWord); + + if ((DWord & PCI_OS_PCI_X) != 0) { +#ifndef SK_SLIM + /* this is a PCI / PCI-X bus */ + if ((DWord & PCI_OS_PCIX) != 0) { + /* this is a PCI-X bus */ + pAC->GIni.GIPciBus = SK_PCIX_BUS; + + /* PCI-X is always 64-bit wide */ + pAC->GIni.GIPciSlot64 = SK_TRUE; + + pAC->GIni.GIPciMode = (SK_U8)(PCI_OS_SPEED(DWord)); + } + else { + /* this is a conventional PCI bus */ + pAC->GIni.GIPciBus = SK_PCI_BUS; + + SK_IN16(IoC, PCI_C(pAC, PCI_OUR_REG_2), &Word); + + /* check if 64-bit width is used */ + pAC->GIni.GIPciSlot64 = (SK_BOOL) + (((DWord & PCI_OS_PCI64B) != 0) && + ((Word & PCI_USEDATA64) != 0)); + + /* check if 66 MHz PCI Clock is active */ + pAC->GIni.GIPciClock66 = (SK_BOOL)((DWord & PCI_OS_PCI66M) != 0); + } +#endif /* !SK_SLIM */ + } + else { + /* this is a PEX bus */ + pAC->GIni.GIPciBus = SK_PEX_BUS; + + /* clear any PEX errors */ + SK_OUT32(IoC, PCI_C(pAC, PEX_UNC_ERR_STAT), 0xffffffffUL); + + SK_IN16(IoC, PCI_C(pAC, PEX_LNK_STAT), &Word); + + pAC->GIni.GIPexWidth = (SK_U8)((Word & PEX_LS_LINK_WI_MSK) >> 4); + } + /* + * Yukon-2 chips family has a different way of providing + * the number of MACs available + */ + pAC->GIni.GIMacsFound = 1; + + SK_IN8(IoC, B2_Y2_HW_RES, &Byte); + + if (CHIP_ID_YUKON_2(pAC)) { + /* + * OEM config value is overwritten and should not + * be used for Yukon-2 + */ + pAC->GIni.GILedBlinkCtrl |= SK_ACT_LED_BLINK; + + if (CFG_LED_MODE(Byte) == CFG_LED_DUAL_ACT_LNK) { + + pAC->GIni.GILedBlinkCtrl |= SK_DUAL_LED_ACT_LNK; + } + } + + if ((Byte & CFG_DUAL_MAC_MSK) == CFG_DUAL_MAC_MSK) { + + SK_IN8(IoC, B2_Y2_CLK_GATE, &Byte); + + if (!(Byte & Y2_STATUS_LNK2_INAC)) { + /* Link 2 activ */ + pAC->GIni.GIMacsFound++; + } + } + +#ifdef VCPU + if (pAC->GIni.GIChipId == CHIP_ID_YUKON_XL) { + /* temporary WA for reported number of links */ + pAC->GIni.GIMacsFound = 2; + } +#endif /* VCPU */ + +#ifdef REPLAY_TIMER + if (pAC->GIni.GIChipId == CHIP_ID_YUKON_EC) { + SK_OUT16(IoC, PCI_C(pAC, PEX_ACK_RPLY_TOX1), 0x2710); /* 40 us */ + } +#endif + + /* read Chip Revision */ + SK_IN8(IoC, B2_MAC_CFG, &Byte); + + pAC->GIni.GIChipCap = Byte & 0x0f; + } + else { + pAC->GIni.GIYukon2 = SK_FALSE; + pAC->GIni.GIValIrqMask = IS_ALL_MSK; + pAC->GIni.GIValHwIrqMask = 0; /* not activated */ + + VauxAvail = CS_VAUX_AVAIL; + + /* read number of MACs and Chip Revision */ + SK_IN8(IoC, B2_MAC_CFG, &Byte); + + pAC->GIni.GIMacsFound = (Byte & CFG_SNG_MAC) ? 1 : 2; + } - /* read Chip Identification Number */ - SK_IN8(IoC, B2_CHIP_ID, &Byte); - pAC->GIni.GIChipId = Byte; - - /* read number of MACs */ - SK_IN8(IoC, B2_MAC_CFG, &Byte); - pAC->GIni.GIMacsFound = (Byte & CFG_SNG_MAC) ? 1 : 2; - /* get Chip Revision Number */ pAC->GIni.GIChipRev = (SK_U8)((Byte & CFG_CHIP_R_MSK) >> 4); - /* get diff. PCI parameters */ - SK_IN16(IoC, B0_CTST, &CtrlStat); - +#ifndef SK_DIAG + if (pAC->GIni.GIChipId == CHIP_ID_YUKON_XL && + pAC->GIni.GIChipRev == CHIP_REV_YU_XL_A0) { + /* Yukon-2 Chip Rev. A0 */ + return(6); + } +#endif /* !SK_DIAG */ + /* read the adapters RAM size */ SK_IN8(IoC, B2_E_0, &Byte); - + pAC->GIni.GIGenesis = SK_FALSE; pAC->GIni.GIYukon = SK_FALSE; pAC->GIni.GIYukonLite = SK_FALSE; + pAC->GIni.GIVauxAvail = SK_FALSE; #ifdef GENESIS if (pAC->GIni.GIChipId == CHIP_ID_GENESIS) { pAC->GIni.GIGenesis = SK_TRUE; - if (Byte == (SK_U8)3) { + if (Byte == (SK_U8)3) { /* special case: 4 x 64k x 36, offset = 0x80000 */ pAC->GIni.GIRamSize = 1024; pAC->GIni.GIRamOffs = (SK_U32)512 * 1024; @@ -1590,57 +2293,83 @@ pAC->GIni.GIRamSize = (int)Byte * 512; pAC->GIni.GIRamOffs = 0; } - /* all GE adapters work with 53.125 MHz host clock */ + /* all GENESIS adapters work with 53.125 MHz host clock */ pAC->GIni.GIHstClkFact = SK_FACT_53; - + /* set Descr. Poll Timer Init Value to 250 ms */ pAC->GIni.GIPollTimerVal = SK_DPOLL_DEF * (SK_U32)pAC->GIni.GIHstClkFact / 100; } #endif /* GENESIS */ - + #ifdef YUKON if (pAC->GIni.GIChipId != CHIP_ID_GENESIS) { - + pAC->GIni.GIYukon = SK_TRUE; - + pAC->GIni.GIRamSize = (Byte == (SK_U8)0) ? 128 : (int)Byte * 4; - + +#ifndef SK_SLIM pAC->GIni.GIRamOffs = 0; - - /* WA for chip Rev. A */ + + /* WA for Yukon chip Rev. A */ pAC->GIni.GIWolOffs = (pAC->GIni.GIChipId == CHIP_ID_YUKON && pAC->GIni.GIChipRev == 0) ? WOL_REG_OFFS : 0; - + /* get PM Capabilities of PCI config space */ - SK_IN16(IoC, PCI_C(PCI_PM_CAP_REG), &Word); + SK_IN16(IoC, PCI_C(pAC, PCI_PM_CAP_REG), &Word); /* check if VAUX is available */ - if (((CtrlStat & CS_VAUX_AVAIL) != 0) && + if (((CtrlStat & VauxAvail) != 0) && /* check also if PME from D3cold is set */ ((Word & PCI_PME_D3C_SUP) != 0)) { /* set entry in GE init struct */ pAC->GIni.GIVauxAvail = SK_TRUE; } - - if (pAC->GIni.GIChipId == CHIP_ID_YUKON_LITE) { - /* this is Rev. A1 */ - pAC->GIni.GIYukonLite = SK_TRUE; - } - else { - /* save Flash-Address Register */ - SK_IN32(IoC, B2_FAR, &DWord); +#endif /* !SK_SLIM */ - /* test Flash-Address Register */ - SK_OUT8(IoC, B2_FAR + 3, 0xff); - SK_IN8(IoC, B2_FAR + 3, &Byte); + if (!CHIP_ID_YUKON_2(pAC)) { - if (Byte != 0) { - /* this is Rev. A0 */ + if (pAC->GIni.GIChipId == CHIP_ID_YUKON_LITE) { + /* this is Rev. A1 */ pAC->GIni.GIYukonLite = SK_TRUE; + } +#ifndef SK_SLIM + else { + /* save Flash-Address Register */ + SK_IN32(IoC, B2_FAR, &DWord); + + /* test Flash-Address Register */ + SK_OUT8(IoC, B2_FAR + 3, 0xff); + SK_IN8(IoC, B2_FAR + 3, &Byte); + + if (Byte != 0) { + /* this is Rev. A0 */ + pAC->GIni.GIYukonLite = SK_TRUE; - /* restore Flash-Address Register */ - SK_OUT32(IoC, B2_FAR, DWord); + /* restore Flash-Address Register */ + SK_OUT32(IoC, B2_FAR, DWord); + } + } +#endif /* !SK_SLIM */ + } + else { + /* Check for CLS = 0 (dev. #4.55) */ + if (pAC->GIni.GIPciBus != SK_PEX_BUS) { + /* PCI and PCI-X */ + SK_IN8(IoC, PCI_C(pAC, PCI_CACHE_LSZ), &Byte); + + if (Byte == 0) { + /* set CLS to 2 if configured to 0 */ + SK_OUT8(IoC, PCI_C(pAC, PCI_CACHE_LSZ), 2); + } + + if (pAC->GIni.GIPciBus == SK_PCIX_BUS) { + /* set Cache Line Size opt. */ + SK_IN32(IoC, PCI_C(pAC, PCI_OUR_REG_1), &DWord); + DWord |= PCI_CLS_OPT; + SK_OUT32(IoC, PCI_C(pAC, PCI_OUR_REG_1), DWord); + } } } @@ -1648,138 +2377,282 @@ SK_OUT8(IoC, B0_POWER_CTRL, (SK_U8)(PC_VAUX_ENA | PC_VCC_ENA | PC_VAUX_OFF | PC_VCC_ON)); - /* read the Interrupt source */ - SK_IN32(IoC, B0_ISRC, &DWord); - - if ((DWord & IS_HW_ERR) != 0) { - /* read the HW Error Interrupt source */ - SK_IN32(IoC, B0_HWE_ISRC, &DWord); - - if ((DWord & IS_IRQ_SENSOR) != 0) { - /* disable HW Error IRQ */ - pAC->GIni.GIValIrqMask &= ~IS_HW_ERR; + Byte = 0; + + if (CHIP_ID_YUKON_2(pAC)) { + switch (pAC->GIni.GIChipId) { + /* PEX adapters work with different host clock */ + case CHIP_ID_YUKON_EC: + case CHIP_ID_YUKON_EC_U: + /* Yukon-EC works with 125 MHz host clock */ + pAC->GIni.GIHstClkFact = SK_FACT_125; + break; + case CHIP_ID_YUKON_FE: + /* Yukon-FE works with 100 MHz host clock */ + pAC->GIni.GIHstClkFact = SK_FACT_100; + break; + case CHIP_ID_YUKON_XL: + /* all Yukon-2 adapters work with 156 MHz host clock */ + pAC->GIni.GIHstClkFact = 2 * SK_FACT_78; + + if (pAC->GIni.GIChipRev > CHIP_REV_YU_XL_A1) { + /* enable bits are inverted */ + Byte = (SK_U8)(Y2_PCI_CLK_LNK1_DIS | Y2_COR_CLK_LNK1_DIS | + Y2_CLK_GAT_LNK1_DIS | Y2_PCI_CLK_LNK2_DIS | + Y2_COR_CLK_LNK2_DIS | Y2_CLK_GAT_LNK2_DIS); + } + break; + default: + SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_HWI_E006, + SKERR_HWI_E006MSG); } + + pAC->GIni.GIPollTimerVal = + SK_DPOLL_DEF_Y2 * (SK_U32)pAC->GIni.GIHstClkFact / 100; + + /* set power down bit */ + PowerDownBit = PCI_Y2_PHY1_POWD | PCI_Y2_PHY2_POWD; + + /* disable Core Clock Division, set Clock Select to 0 (Yukon-2) */ + SK_OUT32(IoC, B2_Y2_CLK_CTRL, Y2_CLK_DIV_DIS); + + /* enable MAC/PHY, PCI and Core Clock for both Links */ + SK_OUT8(IoC, B2_Y2_CLK_GATE, Byte); } - - for (i = 0; i < pAC->GIni.GIMacsFound; i++) { - /* set GMAC Link Control reset */ - SK_OUT16(IoC, MR_ADDR(i, GMAC_LINK_CTRL), GMLC_RST_SET); + else { + /* YUKON adapters work with 78 MHz host clock */ + pAC->GIni.GIHstClkFact = SK_FACT_78; + + pAC->GIni.GIPollTimerVal = SK_DPOLL_MAX; /* 215 ms */ + + /* read the Interrupt source */ + SK_IN32(IoC, B0_ISRC, &DWord); + + if ((DWord & IS_HW_ERR) != 0) { + /* read the HW Error Interrupt source */ + SK_IN32(IoC, B0_HWE_ISRC, &DWord); - /* clear GMAC Link Control reset */ - SK_OUT16(IoC, MR_ADDR(i, GMAC_LINK_CTRL), GMLC_RST_CLR); + if ((DWord & IS_IRQ_SENSOR) != 0) { + /* disable HW Error IRQ */ + pAC->GIni.GIValIrqMask &= ~IS_HW_ERR; + } + } + /* set power down bit */ + PowerDownBit = PCI_PHY_COMA; + } + + SK_IN32(IoC, PCI_C(pAC, PCI_OUR_REG_1), &Our1); + + Our1 &= ~PowerDownBit; + + if (pAC->GIni.GIChipId == CHIP_ID_YUKON_XL && + pAC->GIni.GIChipRev > CHIP_REV_YU_XL_A1) { + /* deassert Low Power for 1st PHY */ + Our1 |= PCI_Y2_PHY1_COMA; + + if (pAC->GIni.GIMacsFound > 1) { + /* deassert Low Power for 2nd PHY */ + Our1 |= PCI_Y2_PHY2_COMA; + } + } + else if (pAC->GIni.GIChipId == CHIP_ID_YUKON_EC_U) { + /* enable HW WOL */ + SK_OUT16(IoC, B0_CTST, (SK_U16)Y2_HW_WOL_ON); + + /* enable all clocks */ + SK_OUT32(IoC, PCI_C(pAC, PCI_OUR_REG_3), 0); + + SK_IN32(IoC, PCI_C(pAC, PCI_OUR_REG_4), &DWord); + + DWord &= P_ASPM_CONTROL_MSK; + /* set all bits to 0 except bits 15..12 */ + SK_OUT32(IoC, PCI_C(pAC, PCI_OUR_REG_4), DWord); + + /* set to default value */ + SK_OUT32(IoC, PCI_C(pAC, PCI_OUR_REG_5), 0); + } + + /* release PHY from PowerDown/COMA Mode */ + SK_OUT32(IoC, PCI_C(pAC, PCI_OUR_REG_1), Our1); + + if (!pAC->GIni.GIAsfEnabled) { + + for (i = 0; i < pAC->GIni.GIMacsFound; i++) { + /* set Link Control reset */ + SK_OUT8(IoC, MR_ADDR(i, GMAC_LINK_CTRL), (SK_U8)GMLC_RST_SET); + + /* clear Link Control reset */ + SK_OUT8(IoC, MR_ADDR(i, GMAC_LINK_CTRL), (SK_U8)GMLC_RST_CLR); + } } - /* all YU chips work with 78.125 MHz host clock */ - pAC->GIni.GIHstClkFact = SK_FACT_78; - - pAC->GIni.GIPollTimerVal = SK_DPOLL_MAX; /* 215 ms */ } #endif /* YUKON */ - /* check if 64-bit PCI Slot is present */ - pAC->GIni.GIPciSlot64 = (SK_BOOL)((CtrlStat & CS_BUS_SLOT_SZ) != 0); - - /* check if 66 MHz PCI Clock is active */ - pAC->GIni.GIPciClock66 = (SK_BOOL)((CtrlStat & CS_BUS_CLOCK) != 0); + SK_OUT8(IoC, B2_TST_CTRL1, TST_CFG_WRITE_OFF); + +#ifndef SK_SLIM + if (!CHIP_ID_YUKON_2(pAC)) { + /* this is a conventional PCI bus */ + pAC->GIni.GIPciBus = SK_PCI_BUS; + + /* check if 64-bit PCI Slot is present */ + pAC->GIni.GIPciSlot64 = (SK_BOOL)((CtrlStat & CS_BUS_SLOT_SZ) != 0); + + /* check if 66 MHz PCI Clock is active */ + pAC->GIni.GIPciClock66 = (SK_BOOL)((CtrlStat & CS_BUS_CLOCK) != 0); + } /* read PCI HW Revision Id. */ - SK_IN8(IoC, PCI_C(PCI_REV_ID), &Byte); + SK_IN8(IoC, PCI_C(pAC, PCI_REV_ID), &Byte); pAC->GIni.GIPciHwRev = Byte; + /* read connector type */ + SK_IN8(IoC, B2_CONN_TYP, &pAC->GIni.GIConTyp); +#endif /* !SK_SLIM */ + /* read the PMD type */ SK_IN8(IoC, B2_PMD_TYP, &Byte); - pAC->GIni.GICopperType = (SK_U8)(Byte == 'T'); - /* read the PHY type */ + pAC->GIni.GIPmdTyp = Byte; + + FiberType = (Byte == 'L' || Byte == 'S' || Byte == 'P'); + + pAC->GIni.GICopperType = (SK_BOOL)(Byte == 'T' || Byte == '1' || + (pAC->GIni.GIYukon2 && !FiberType)); + + /* read the PHY type (Yukon and Genesis) */ SK_IN8(IoC, B2_E_1, &Byte); Byte &= 0x0f; /* the PHY type is stored in the lower nibble */ for (i = 0; i < pAC->GIni.GIMacsFound; i++) { - + + pPrt = &pAC->GIni.GP[i]; + + /* get the MAC addresses */ + for (j = 0; j < 3; j++) { + SK_IN16(IoC, B2_MAC_1 + i * 8 + j * 2, &pPrt->PMacAddr[j]); + } + #ifdef GENESIS if (pAC->GIni.GIGenesis) { switch (Byte) { case SK_PHY_XMAC: - pAC->GIni.GP[i].PhyAddr = PHY_ADDR_XMAC; + pPrt->PhyAddr = PHY_ADDR_XMAC; break; case SK_PHY_BCOM: - pAC->GIni.GP[i].PhyAddr = PHY_ADDR_BCOM; - pAC->GIni.GP[i].PMSCap = (SK_U8)(SK_MS_CAP_AUTO | + pPrt->PhyAddr = PHY_ADDR_BCOM; + pPrt->PMSCap = (SK_U8)(SK_MS_CAP_AUTO | SK_MS_CAP_MASTER | SK_MS_CAP_SLAVE); break; #ifdef OTHER_PHY case SK_PHY_LONE: - pAC->GIni.GP[i].PhyAddr = PHY_ADDR_LONE; + pPrt->PhyAddr = PHY_ADDR_LONE; break; case SK_PHY_NAT: - pAC->GIni.GP[i].PhyAddr = PHY_ADDR_NAT; + pPrt->PhyAddr = PHY_ADDR_NAT; break; #endif /* OTHER_PHY */ default: /* ERROR: unexpected PHY type detected */ RetVal = 5; - break; } } #endif /* GENESIS */ - + #ifdef YUKON if (pAC->GIni.GIYukon) { - - if (Byte < (SK_U8)SK_PHY_MARV_COPPER) { + + if (((Byte < (SK_U8)SK_PHY_MARV_COPPER) || pAC->GIni.GIYukon2) && + !FiberType) { /* if this field is not initialized */ Byte = (SK_U8)SK_PHY_MARV_COPPER; - + pAC->GIni.GICopperType = SK_TRUE; } - - pAC->GIni.GP[i].PhyAddr = PHY_ADDR_MARV; - + + pPrt->PhyAddr = PHY_ADDR_MARV; + if (pAC->GIni.GICopperType) { - pAC->GIni.GP[i].PLinkSpeedCap = (SK_U8)(SK_LSPEED_CAP_AUTO | - SK_LSPEED_CAP_10MBPS | SK_LSPEED_CAP_100MBPS | - SK_LSPEED_CAP_1000MBPS); - - pAC->GIni.GP[i].PLinkSpeed = (SK_U8)SK_LSPEED_AUTO; - - pAC->GIni.GP[i].PMSCap = (SK_U8)(SK_MS_CAP_AUTO | + if (pAC->GIni.GIChipId == CHIP_ID_YUKON_FE || + (pAC->GIni.GIChipId == CHIP_ID_YUKON_EC && + pAC->GIni.GIChipCap == 2)) { + + pPrt->PLinkSpeedCap = (SK_U8)(SK_LSPEED_CAP_100MBPS | + SK_LSPEED_CAP_10MBPS); + + pAC->GIni.GIRamSize = 4; + } + else { + pPrt->PLinkSpeedCap = (SK_U8)(SK_LSPEED_CAP_1000MBPS | + SK_LSPEED_CAP_100MBPS | SK_LSPEED_CAP_10MBPS | + SK_LSPEED_CAP_AUTO); + } + + pPrt->PLinkSpeed = (SK_U8)SK_LSPEED_AUTO; + + pPrt->PMSCap = (SK_U8)(SK_MS_CAP_AUTO | SK_MS_CAP_MASTER | SK_MS_CAP_SLAVE); } else { Byte = (SK_U8)SK_PHY_MARV_FIBER; } } + + /* clear TWSI IRQ */ + SK_OUT32(IoC, B2_I2C_IRQ, I2C_CLR_IRQ); + #endif /* YUKON */ - - pAC->GIni.GP[i].PhyType = (int)Byte; - + + pPrt->PhyType = (int)Byte; + SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_INIT, - ("PHY type: %d PHY addr: %04x\n", Byte, - pAC->GIni.GP[i].PhyAddr)); + ("PHY type: %d PHY addr: %04x\n", + Byte, pPrt->PhyAddr)); } - + /* get MAC Type & set function pointers dependent on */ #ifdef GENESIS if (pAC->GIni.GIGenesis) { - + pAC->GIni.GIMacType = SK_MAC_XMAC; pAC->GIni.GIFunc.pFnMacUpdateStats = SkXmUpdateStats; pAC->GIni.GIFunc.pFnMacStatistic = SkXmMacStatistic; pAC->GIni.GIFunc.pFnMacResetCounter = SkXmResetCounter; pAC->GIni.GIFunc.pFnMacOverflow = SkXmOverflowStatus; +#ifdef SK_DIAG + pAC->GIni.GIFunc.pFnMacPhyRead = SkXmPhyRead; + pAC->GIni.GIFunc.pFnMacPhyWrite = SkXmPhyWrite; +#else /* SK_DIAG */ + pAC->GIni.GIFunc.pSkGeSirqIsr = SkGeYuSirqIsr; +#endif /* !SK_DIAG */ } #endif /* GENESIS */ - + #ifdef YUKON if (pAC->GIni.GIYukon) { - + +#ifndef SK_SLIM pAC->GIni.GIMacType = SK_MAC_GMAC; pAC->GIni.GIFunc.pFnMacUpdateStats = SkGmUpdateStats; pAC->GIni.GIFunc.pFnMacStatistic = SkGmMacStatistic; pAC->GIni.GIFunc.pFnMacResetCounter = SkGmResetCounter; pAC->GIni.GIFunc.pFnMacOverflow = SkGmOverflowStatus; +#endif /* !SK_SLIM */ + +#ifdef SK_DIAG + pAC->GIni.GIFunc.pFnMacPhyRead = SkGmPhyRead; + pAC->GIni.GIFunc.pFnMacPhyWrite = SkGmPhyWrite; +#else /* SK_DIAG */ + if (CHIP_ID_YUKON_2(pAC)) { + pAC->GIni.GIFunc.pSkGeSirqIsr = SkYuk2SirqIsr; + } + else { + pAC->GIni.GIFunc.pSkGeSirqIsr = SkGeYuSirqIsr; + } +#endif /* !SK_DIAG */ #ifdef SPECIAL_HANDLING if (pAC->GIni.GIChipId == CHIP_ID_YUKON) { @@ -1792,7 +2665,13 @@ #endif } #endif /* YUKON */ - + +#ifndef SK_SLIM + + SkGeSetUpSupFeatures(pAC, IoC); + +#endif /* !SK_SLIM */ + return(RetVal); } /* SkGeInit1 */ @@ -1813,9 +2692,12 @@ * nothing */ static void SkGeInit2( -SK_AC *pAC, /* adapter context */ -SK_IOC IoC) /* IO context */ +SK_AC *pAC, /* Adapter Context */ +SK_IOC IoC) /* I/O Context */ { +#ifdef YUKON + SK_U16 Word; +#endif /* YUKON */ #ifdef GENESIS SK_U32 DWord; #endif /* GENESIS */ @@ -1849,13 +2731,13 @@ SkGeInitPktArb(pAC, IoC); } #endif /* GENESIS */ - -#ifdef YUKON + +#ifdef xSK_DIAG if (pAC->GIni.GIYukon) { /* start Time Stamp Timer */ SK_OUT8(IoC, GMAC_TI_ST_CTRL, (SK_U8)GMT_ST_START); } -#endif /* YUKON */ +#endif /* SK_DIAG */ /* enable the Tx Arbiters */ for (i = 0; i < pAC->GIni.GIMacsFound; i++) { @@ -1865,8 +2747,34 @@ /* enable the RAM Interface Arbiter */ SkGeInitRamIface(pAC, IoC); +#ifdef YUKON + if (CHIP_ID_YUKON_2(pAC)) { + + if (pAC->GIni.GIPciBus == SK_PEX_BUS) { + + SK_IN16(IoC, PCI_C(pAC, PEX_DEV_CTRL), &Word); + + /* change Max. Read Request Size to 2048 bytes */ + Word &= ~PEX_DC_MAX_RRS_MSK; + Word |= PEX_DC_MAX_RD_RQ_SIZE(4); + + SK_OUT8(IoC, B2_TST_CTRL1, TST_CFG_WRITE_ON); + + SK_OUT16(IoC, PCI_C(pAC, PEX_DEV_CTRL), Word); + + SK_OUT8(IoC, B2_TST_CTRL1, TST_CFG_WRITE_OFF); + } + + /* + * Writing the HW Error Mask Reg. will not generate an IRQ + * as long as the B0_IMSK is not set by the driver. + */ + SK_OUT32(IoC, B0_HWE_IMSK, pAC->GIni.GIValHwIrqMask); + } +#endif /* YUKON */ } /* SkGeInit2 */ + /****************************************************************************** * * SkGeInit() - Initialize the GE Adapter with the specified level. @@ -1888,7 +2796,7 @@ * if Number of MACs > SK_MAX_MACS * * After returning from Level 0 the adapter - * may be accessed with IO operations. + * may be accessed with I/O operations. * * Level 2: start the Blink Source Counter * @@ -1897,14 +2805,14 @@ * 1: Number of MACs exceeds SK_MAX_MACS (after level 1) * 2: Adapter not present or not accessible * 3: Illegal initialization level - * 4: Initialization Level 1 Call missing + * 4: Initialization level 1 call missing * 5: Unexpected PHY type detected * 6: HW self test failed */ int SkGeInit( -SK_AC *pAC, /* adapter context */ -SK_IOC IoC, /* IO context */ -int Level) /* initialization level */ +SK_AC *pAC, /* Adapter Context */ +SK_IOC IoC, /* I/O Context */ +int Level) /* Initialization Level */ { int RetVal; /* return value */ SK_U32 DWord; @@ -1919,7 +2827,7 @@ SkGeInit0(pAC, IoC); pAC->GIni.GILevel = SK_INIT_DATA; break; - + case SK_INIT_IO: /* Initialization Level 1 */ RetVal = SkGeInit1(pAC, IoC); @@ -1931,22 +2839,24 @@ SK_OUT32(IoC, B2_IRQM_INI, SK_TEST_VAL); SK_IN32(IoC, B2_IRQM_INI, &DWord); SK_OUT32(IoC, B2_IRQM_INI, 0L); - + if (DWord != SK_TEST_VAL) { RetVal = 2; break; } +#ifdef DEBUG /* check if the number of GIMacsFound matches SK_MAX_MACS */ if (pAC->GIni.GIMacsFound > SK_MAX_MACS) { RetVal = 1; break; } +#endif /* DEBUG */ /* Level 1 successfully passed */ pAC->GIni.GILevel = SK_INIT_IO; break; - + case SK_INIT_RUN: /* Initialization Level 2 */ if (pAC->GIni.GILevel != SK_INIT_IO) { @@ -1956,12 +2866,13 @@ RetVal = 4; break; } + SkGeInit2(pAC, IoC); /* Level 2 successfully passed */ pAC->GIni.GILevel = SK_INIT_RUN; break; - + default: SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E003, SKERR_HWI_E003MSG); RetVal = 3; @@ -1984,77 +2895,82 @@ * nothing */ void SkGeDeInit( -SK_AC *pAC, /* adapter context */ -SK_IOC IoC) /* IO context */ +SK_AC *pAC, /* Adapter Context */ +SK_IOC IoC) /* I/O Context */ { int i; SK_U16 Word; -#ifdef SK_PHY_LP_MODE - SK_U8 Byte; +#ifdef SK_PHY_LP_MODE_DEEP_SLEEP SK_U16 PmCtlSts; -#endif /* SK_PHY_LP_MODE */ +#endif #if (!defined(SK_SLIM) && !defined(VCPU)) /* ensure I2C is ready */ SkI2cWaitIrq(pAC, IoC); -#endif - - /* stop all current transfer activity */ - for (i = 0; i < pAC->GIni.GIMacsFound; i++) { - if (pAC->GIni.GP[i].PState != SK_PRT_STOP && - pAC->GIni.GP[i].PState != SK_PRT_RESET) { - - SkGeStopPort(pAC, IoC, i, SK_STOP_ALL, SK_HARD_RST); - } - } +#endif -#ifdef SK_PHY_LP_MODE - /* +#ifdef SK_PHY_LP_MODE_DEEP_SLEEP + /* * for power saving purposes within mobile environments - * we set the PHY to coma mode and switch to D3 power state. + * we set the PHY to coma mode. */ - if (pAC->GIni.GIYukonLite && - pAC->GIni.GIChipRev == CHIP_REV_YU_LITE_A3) { +#ifdef XXX + if (pAC->GIni.GIVauxAvail) { + /* switch power to VAUX */ + SK_OUT8(IoC, B0_POWER_CTRL, (SK_U8)(PC_VAUX_ENA | PC_VCC_ENA | + PC_VAUX_ON | PC_VCC_OFF)); + } +#endif /* XXX */ + + if (CHIP_ID_YUKON_2(pAC) && /* pAC->GIni.GIMacsFound == 1 && */ + !pAC->GIni.GIAsfEnabled +#ifdef XXX + || (pAC->GIni.GIYukonLite && pAC->GIni.GIChipRev >= CHIP_REV_YU_LITE_A3) +#endif /* XXX */ + ) { + + /* flag for SkGmEnterLowPowerMode() that the call was from here */ + pAC->GIni.GILevel = SK_INIT_IO; /* for all ports switch PHY to coma mode */ for (i = 0; i < pAC->GIni.GIMacsFound; i++) { - - SkGmEnterLowPowerMode(pAC, IoC, i, PHY_PM_DEEP_SLEEP); - } - - if (pAC->GIni.GIVauxAvail) { - /* switch power to VAUX */ - Byte = PC_VAUX_ENA | PC_VCC_ENA | PC_VAUX_ON | PC_VCC_OFF; - SK_OUT8(IoC, B0_POWER_CTRL, Byte); + (void)SkGmEnterLowPowerMode(pAC, IoC, i, PHY_PM_DEEP_SLEEP); } - - /* switch to D3 state */ - SK_IN16(IoC, PCI_C(PCI_PM_CTL_STS), &PmCtlSts); - - PmCtlSts |= PCI_PM_STATE_D3; + } +#else /* !SK_PHY_LP_MODE_DEEP_SLEEP */ - SK_OUT8(IoC, B2_TST_CTRL1, TST_CFG_WRITE_ON); + if (!pAC->GIni.GIAsfEnabled) { + /* stop all current transfer activity */ + for (i = 0; i < pAC->GIni.GIMacsFound; i++) { + if (pAC->GIni.GP[i].PState != SK_PRT_STOP && + pAC->GIni.GP[i].PState != SK_PRT_RESET) { - SK_OUT16(IoC, PCI_C(PCI_PM_CTL_STS), PmCtlSts); + SkGeStopPort(pAC, IoC, i, SK_STOP_ALL, SK_HARD_RST); + } + } } -#endif /* SK_PHY_LP_MODE */ - /* Reset all bits in the PCI STATUS register */ + /* reset all bits in the PCI STATUS register */ /* * Note: PCI Cfg cycles cannot be used, because they are not * available on some platforms after 'boot time'. */ - SK_IN16(IoC, PCI_C(PCI_STATUS), &Word); - + SK_IN16(IoC, PCI_C(pAC, PCI_STATUS), &Word); + SK_OUT8(IoC, B2_TST_CTRL1, TST_CFG_WRITE_ON); - SK_OUT16(IoC, PCI_C(PCI_STATUS), (SK_U16)(Word | PCI_ERRBITS)); + + SK_OUT16(IoC, PCI_C(pAC, PCI_STATUS), Word | (SK_U16)PCI_ERRBITS); + SK_OUT8(IoC, B2_TST_CTRL1, TST_CFG_WRITE_OFF); - /* do the reset, all LEDs are switched off now */ - SK_OUT8(IoC, B0_CTST, CS_RST_SET); - + if (!pAC->GIni.GIAsfEnabled) { + /* set the SW-reset */ + SK_OUT8(IoC, B0_CTST, CS_RST_SET); + } +#endif /* !SK_PHY_LP_MODE_DEEP_SLEEP */ + pAC->GIni.GILevel = SK_INIT_DATA; } /* SkGeDeInit */ @@ -2088,8 +3004,8 @@ * 2: The port has to be stopped before it can be initialized again. */ int SkGeInitPort( -SK_AC *pAC, /* adapter context */ -SK_IOC IoC, /* IO context */ +SK_AC *pAC, /* Adapter Context */ +SK_IOC IoC, /* I/O Context */ int Port) /* Port to configure */ { SK_GEPORT *pPrt; @@ -2100,8 +3016,8 @@ SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E004, SKERR_HWI_E004MSG); return(1); } - - if (pPrt->PState == SK_PRT_INIT || pPrt->PState == SK_PRT_RUN) { + + if (pPrt->PState >= SK_PRT_INIT) { SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E005, SKERR_HWI_E005MSG); return(2); } @@ -2118,29 +3034,29 @@ SkGeXmitLED(pAC, IoC, MR_ADDR(Port, TX_LED_INI), SK_LED_ENA); SkGeXmitLED(pAC, IoC, MR_ADDR(Port, RX_LED_INI), SK_LED_ENA); /* The Link LED is initialized by RLMT or Diagnostics itself */ - + SkXmInitMac(pAC, IoC, Port); } #endif /* GENESIS */ - + #ifdef YUKON if (pAC->GIni.GIYukon) { SkGmInitMac(pAC, IoC, Port); } #endif /* YUKON */ - + /* do NOT initialize the Link Sync Counter */ SkGeInitMacFifo(pAC, IoC, Port); - + SkGeInitRamBufs(pAC, IoC, Port); - + if (pPrt->PXSQSize != 0) { /* enable Force Sync bit if synchronous queue available */ SK_OUT8(IoC, MR_ADDR(Port, TXA_CTRL), TXA_ENA_FSYNC); } - + SkGeInitBmu(pAC, IoC, Port); /* mark port as initialized */ @@ -2148,3 +3064,192 @@ return(0); } /* SkGeInitPort */ + + +#if (defined(YUK2) && !defined(SK_SLIM)) +/****************************************************************************** + * + * SkGeRamWrite() - Writes One quadword to RAM + * + * Returns: + * 0 + */ +static void SkGeRamWrite( +SK_AC *pAC, /* Adapter Context */ +SK_IOC IoC, /* I/O Context */ +SK_U32 Addr, /* Address to be written to (in quadwords) */ +SK_U32 LowDword, /* Lower Dword to be written */ +SK_U32 HighDword, /* Upper Dword to be written */ +int Port) /* Select RAM buffer (Yukon-2 has 2 RAM buffers) */ +{ + SK_OUT32(IoC, SELECT_RAM_BUFFER(Port, B3_RAM_ADDR), Addr); + + /* Write Access is initiated by writing the upper Dword */ + SK_OUT32(IoC, SELECT_RAM_BUFFER(Port, B3_RAM_DATA_LO), LowDword); + SK_OUT32(IoC, SELECT_RAM_BUFFER(Port, B3_RAM_DATA_HI), HighDword); +} + +/****************************************************************************** + * + * SkYuk2RestartRxBmu() - Restart Receive BMU on Yukon-2 + * + * return: + * 0 o.k. + * 1 timeout + */ +int SkYuk2RestartRxBmu( +SK_AC *pAC, /* Adapter Context */ +SK_IOC IoC, /* I/O Context */ +int Port) /* Port Index (MAC_1 + n) */ +{ + SK_U16 Word; + SK_U16 MacCtrl; + SK_U16 RxCtrl; + SK_U16 FlushMask; + SK_U16 FlushTrsh; + SK_U32 RamAdr; + SK_U32 StartTime; + SK_U32 CurrTime; + SK_U32 Delta; + SK_U32 TimeOut; + SK_GEPORT *pPrt; /* GIni Port struct pointer */ + int Rtv; + + Rtv = 0; + + pPrt = &pAC->GIni.GP[Port]; + +/* + 1. save Rx MAC FIFO Flush Mask and Rx MAC FIFO Flush Threshold + 2. save GMAC Rx Control Register + 3. re-initialize MAC Rx FIFO, Rx RAM Buffer Queue, PCI Rx FIFO, + Rx BMU and Rx Prefetch Unit of the link. + 4. set Rx MAC FIFO Flush Mask to 0xffff + set Rx MAC FIFO Flush Threshold to a high value, e.g. 0x20 + 5. set GMAC to loopback mode and switch GMAC back to Rx/Tx enable + 6. clear Rx/Tx Frame Complete IRQ in Rx/T MAC FIFO Control Register + 7. send one packet with a size of 64bytes (size below flush threshold) + from TXA RAM Buffer Queue to set the rx_sop flop: + - set TxAQ Write Pointer to (packet size in qwords + 2) + - set TxAQ Level to (packet size in qwords + 2) + - write Internal Status Word 1 and 2 to TxAQ RAM Buffer Queue QWord 0,1 + according to figure 61 on page 330 of Yukon-2 Spec. + - write MAC header with Destination Address = own MAC address to + TxAQ RAM Buffer Queue QWords 2 and 3 + - set TxAQ Packet Counter to 1 -> packet is transmitted immediately + 8. poll GMAC IRQ Source Register for IRQ Rx/Tx Frame Complete + 9. restore GMAC Rx Control Register +10. restore Rx MAC FIFO Flush Mask and Rx MAC FIFO Flush Threshold +11. set GMAC back to GMII mode +*/ + + /* save Rx GMAC FIFO Flush Mask */ + SK_IN16(IoC, MR_ADDR(Port, RX_GMF_FL_MSK), &FlushMask); + + /* save Rx GMAC FIFO Flush Threshold */ + SK_IN16(IoC, MR_ADDR(Port, RX_GMF_FL_THR), &FlushTrsh); + + /* save GMAC Rx Control Register */ + GM_IN16(IoC, Port, GM_RX_CTRL, &RxCtrl); + + /* configure the GMAC FIFOs */ + SkGeInitMacFifo(pAC, IoC, Port); + + SkGeInitRamBufs(pAC, IoC, Port); + + SkGeInitBmu(pAC, IoC, Port); + + /* configure Rx GMAC FIFO */ + SK_OUT16(IoC, MR_ADDR(Port, RX_GMF_CTRL_T), GMF_RX_CTRL_DEF); + + /* set Rx GMAC FIFO Flush Mask */ + SK_OUT16(IoC, MR_ADDR(Port, RX_GMF_FL_MSK), 0xffff); + + /* set Rx GMAC FIFO Flush Threshold */ + SK_OUT16(IoC, MR_ADDR(Port, RX_GMF_FL_THR), 0x20); + + /* set to promiscuous mode */ + Word = RxCtrl & ~(GM_RXCR_UCF_ENA | GM_RXCR_MCF_ENA); + + /* set GMAC Rx Control Register */ + GM_OUT16(IoC, Port, GM_RX_CTRL, Word); + + /* get General Purpose Control */ + GM_IN16(IoC, Port, GM_GP_CTRL, &MacCtrl); + + /* enable MAC Loopback Mode*/ + GM_OUT16(IoC, Port, GM_GP_CTRL, MacCtrl | GM_GPCR_LOOP_ENA); + + /* enable MAC Loopback Mode and Rx/Tx */ + GM_OUT16(IoC, Port, GM_GP_CTRL, MacCtrl | GM_GPCR_LOOP_ENA | + GM_GPCR_RX_ENA | GM_GPCR_TX_ENA); + + /* clear GMAC IRQ Rx Frame Complete */ + SK_OUT8(IoC, MR_ADDR(Port, RX_GMF_CTRL_T), (SK_U8)GMF_CLI_RX_FC); + + /* clear GMAC IRQ Tx Frame Complete */ + SK_OUT8(IoC, MR_ADDR(Port, TX_GMF_CTRL_T), (SK_U8)GMF_CLI_TX_FC); + + /* send one packet with a size of 64bytes from RAM buffer*/ + + RamAdr = pPrt->PXaQRamStart / 8; + + SK_OUT32(IoC, RB_ADDR(pPrt->PXaQOff, RB_WP), RamAdr + 10); + + SK_OUT32(IoC, RB_ADDR(pPrt->PXaQOff, RB_LEV), 10); + + /* write 1st status quad word (packet end address in RAM, packet length */ + SkGeRamWrite(pAC, IoC, RamAdr, (RamAdr + 9) << 16, 64, Port); + + /* write 2nd status quad word */ + SkGeRamWrite(pAC, IoC, RamAdr + 1, 0, 0, Port); + + /* write DA to MAC header */ + SkGeRamWrite(pAC, IoC, RamAdr + 2, *(SK_U32 *)&pPrt->PMacAddr[0], + *(SK_U32 *)&pPrt->PMacAddr[2], Port); + + SK_OUT32(IoC, RB_ADDR(pPrt->PXaQOff, RB_PC), 1); + + SK_IN32(IoC, GMAC_TI_ST_VAL, &StartTime); + + /* set timeout to 10 ms */ + TimeOut = HW_MS_TO_TICKS(pAC, 10); + + do { + SK_IN32(IoC, GMAC_TI_ST_VAL, &CurrTime); + + if (CurrTime >= StartTime) { + Delta = CurrTime - StartTime; + } + else { + Delta = CurrTime + ~StartTime + 1; + } + + if (Delta > TimeOut) { + Rtv = 1; + break; + } + + /* read the GMAC Interrupt source register */ + SK_IN16(IoC, MR_ADDR(Port, GMAC_IRQ_SRC), &Word); + + } while ((Word & (GM_IS_TX_COMPL | GM_IS_RX_COMPL)) != + (GM_IS_TX_COMPL | GM_IS_RX_COMPL)); + + /* disable MAC Loopback Mode and Rx/Tx */ + GM_OUT16(IoC, Port, GM_GP_CTRL, MacCtrl); + + /* restore GMAC Rx Control Register */ + GM_OUT16(IoC, Port, GM_RX_CTRL, RxCtrl); + + /* restore Rx GMAC FIFO Flush Mask */ + SK_OUT16(IoC, MR_ADDR(Port, RX_GMF_FL_MSK), FlushMask); + + /* restore Rx GMAC FIFO Flush Threshold */ + SK_OUT16(IoC, MR_ADDR(Port, RX_GMF_FL_THR), FlushTrsh); + + return(Rtv); + +} /* SkYuk2RestartRxBmu */ +#endif /* YUK2 && !SK_SLIM */ + diff -urN linux-2.4.32-600/drivers/net/sk98lin/skgemib.c linux-2.4.32-600-sk98_831/drivers/net/sk98lin/skgemib.c --- linux-2.4.32-600/drivers/net/sk98lin/skgemib.c Sat Mar 20 10:08:19 2004 +++ linux-2.4.32-600-sk98_831/drivers/net/sk98lin/skgemib.c Sun Feb 26 11:13:02 2006 @@ -1,1080 +1,1264 @@ -/***************************************************************************** - * - * Name: skgemib.c - * Project: GEnesis, PCI Gigabit Ethernet Adapter - * Purpose: Private Network Management Interface Management Database - * - ****************************************************************************/ - -/****************************************************************************** - * - * (C)Copyright 1998-2002 SysKonnect GmbH. - * (C)Copyright 2002-2003 Marvell. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * The information in this file is provided "AS IS" without warranty. - * - ******************************************************************************/ - -/* - * PRIVATE OID handler function prototypes - */ -PNMI_STATIC int Addr(SK_AC *pAC, SK_IOC IoC, int action, - SK_U32 Id, char *pBuf, unsigned int *pLen, SK_U32 Instance, - unsigned int TableIndex, SK_U32 NetIndex); -PNMI_STATIC int CsumStat(SK_AC *pAC, SK_IOC IoC, int action, SK_U32 Id, - char *pBuf, unsigned int *pLen, SK_U32 Instance, - unsigned int TableIndex, SK_U32 NetIndex); -PNMI_STATIC int General(SK_AC *pAC, SK_IOC IoC, int action, SK_U32 Id, - char *pBuf, unsigned int *pLen, SK_U32 Instance, - unsigned int TableIndex, SK_U32 NetIndex); -PNMI_STATIC int Mac8023Stat(SK_AC *pAC, SK_IOC IoC, int action, SK_U32 Id, - char *pBuf, unsigned int *pLen, SK_U32 Instance, - unsigned int TableIndex, SK_U32 NetIndex); -PNMI_STATIC int MacPrivateConf(SK_AC *pAC, SK_IOC IoC, int action, SK_U32 Id, - char *pBuf, unsigned int *pLen, SK_U32 Instance, - unsigned int TableIndex, SK_U32 NetIndex); -PNMI_STATIC int MacPrivateStat(SK_AC *pAC, SK_IOC IoC, int action, SK_U32 Id, - char *pBuf, unsigned int *pLen, SK_U32 Instance, - unsigned int TableIndex, SK_U32 NetIndex); -PNMI_STATIC int Monitor(SK_AC *pAC, SK_IOC IoC, int action, - SK_U32 Id, char *pBuf, unsigned int *pLen, SK_U32 Instance, - unsigned int TableIndex, SK_U32 NetIndex); -PNMI_STATIC int OidStruct(SK_AC *pAC, SK_IOC IoC, int action, SK_U32 Id, - char *pBuf, unsigned int *pLen, SK_U32 Instance, - unsigned int TableIndex, SK_U32 NetIndex); -PNMI_STATIC int Perform(SK_AC *pAC, SK_IOC IoC, int action, SK_U32 Id, - char *pBuf, unsigned int* pLen, SK_U32 Instance, - unsigned int TableIndex, SK_U32 NetIndex); -PNMI_STATIC int Rlmt(SK_AC *pAC, SK_IOC IoC, int action, SK_U32 Id, - char *pBuf, unsigned int *pLen, SK_U32 Instance, - unsigned int TableIndex, SK_U32 NetIndex); -PNMI_STATIC int RlmtStat(SK_AC *pAC, SK_IOC IoC, int action, SK_U32 Id, - char *pBuf, unsigned int *pLen, SK_U32 Instance, - unsigned int TableIndex, SK_U32 NetIndex); -PNMI_STATIC int SensorStat(SK_AC *pAC, SK_IOC IoC, int action, SK_U32 Id, - char *pBuf, unsigned int *pLen, SK_U32 Instance, - unsigned int TableIndex, SK_U32 NetIndex); -PNMI_STATIC int Vpd(SK_AC *pAC, SK_IOC IoC, int action, SK_U32 Id, - char *pBuf, unsigned int *pLen, SK_U32 Instance, - unsigned int TableIndex, SK_U32 NetIndex); -PNMI_STATIC int Vct(SK_AC *pAC, SK_IOC IoC, int action, SK_U32 Id, - char *pBuf, unsigned int *pLen, SK_U32 Instance, - unsigned int TableIndex, SK_U32 NetIndex); - -#ifdef SK_POWER_MGMT -PNMI_STATIC int PowerManagement(SK_AC *pAC, SK_IOC IoC, int action, SK_U32 Id, - char *pBuf, unsigned int *pLen, SK_U32 Instance, - unsigned int TableIndex, SK_U32 NetIndex); -#endif /* SK_POWER_MGMT */ - -#ifdef SK_DIAG_SUPPORT -PNMI_STATIC int DiagActions(SK_AC *pAC, SK_IOC IoC, int action, SK_U32 Id, - char *pBuf, unsigned int *pLen, SK_U32 Instance, - unsigned int TableIndex, SK_U32 NetIndex); -#endif /* SK_DIAG_SUPPORT */ - - -/* defines *******************************************************************/ -#define ID_TABLE_SIZE (sizeof(IdTable)/sizeof(IdTable[0])) - - -/* global variables **********************************************************/ - -/* - * Table to correlate OID with handler function and index to - * hardware register stored in StatAddress if applicable. - */ -PNMI_STATIC const SK_PNMI_TAB_ENTRY IdTable[] = { - {OID_GEN_XMIT_OK, - 0, - 0, - 0, - SK_PNMI_RO, Mac8023Stat, SK_PNMI_HTX}, - {OID_GEN_RCV_OK, - 0, - 0, - 0, - SK_PNMI_RO, Mac8023Stat, SK_PNMI_HRX}, - {OID_GEN_XMIT_ERROR, - 0, - 0, - 0, - SK_PNMI_RO, General, 0}, - {OID_GEN_RCV_ERROR, - 0, - 0, - 0, - SK_PNMI_RO, General, 0}, - {OID_GEN_RCV_NO_BUFFER, - 0, - 0, - 0, - SK_PNMI_RO, General, 0}, - {OID_GEN_DIRECTED_FRAMES_XMIT, - 0, - 0, - 0, - SK_PNMI_RO, Mac8023Stat, SK_PNMI_HTX_UNICAST}, - {OID_GEN_MULTICAST_FRAMES_XMIT, - 0, - 0, - 0, - SK_PNMI_RO, Mac8023Stat, SK_PNMI_HTX_MULTICAST}, - {OID_GEN_BROADCAST_FRAMES_XMIT, - 0, - 0, - 0, - SK_PNMI_RO, Mac8023Stat, SK_PNMI_HTX_BROADCAST}, - {OID_GEN_DIRECTED_FRAMES_RCV, - 0, - 0, - 0, - SK_PNMI_RO, Mac8023Stat, SK_PNMI_HRX_UNICAST}, - {OID_GEN_MULTICAST_FRAMES_RCV, - 0, - 0, - 0, - SK_PNMI_RO, Mac8023Stat, SK_PNMI_HRX_MULTICAST}, - {OID_GEN_BROADCAST_FRAMES_RCV, - 0, - 0, - 0, - SK_PNMI_RO, Mac8023Stat, SK_PNMI_HRX_BROADCAST}, - {OID_GEN_RCV_CRC_ERROR, - 0, - 0, - 0, - SK_PNMI_RO, Mac8023Stat, SK_PNMI_HRX_FCS}, - {OID_GEN_TRANSMIT_QUEUE_LENGTH, - 0, - 0, - 0, - SK_PNMI_RO, General, 0}, - {OID_802_3_PERMANENT_ADDRESS, - 0, - 0, - 0, - SK_PNMI_RO, Mac8023Stat, 0}, - {OID_802_3_CURRENT_ADDRESS, - 0, - 0, - 0, - SK_PNMI_RO, Mac8023Stat, 0}, - {OID_802_3_RCV_ERROR_ALIGNMENT, - 0, - 0, - 0, - SK_PNMI_RO, Mac8023Stat, SK_PNMI_HRX_FRAMING}, - {OID_802_3_XMIT_ONE_COLLISION, - 0, - 0, - 0, - SK_PNMI_RO, Mac8023Stat, SK_PNMI_HTX_SINGLE_COL}, - {OID_802_3_XMIT_MORE_COLLISIONS, - 0, - 0, - 0, - SK_PNMI_RO, Mac8023Stat, SK_PNMI_HTX_MULTI_COL}, - {OID_802_3_XMIT_DEFERRED, - 0, - 0, - 0, - SK_PNMI_RO, Mac8023Stat, SK_PNMI_HTX_DEFFERAL}, - {OID_802_3_XMIT_MAX_COLLISIONS, - 0, - 0, - 0, - SK_PNMI_RO, Mac8023Stat, SK_PNMI_HTX_EXCESS_COL}, - {OID_802_3_RCV_OVERRUN, - 0, - 0, - 0, - SK_PNMI_RO, Mac8023Stat, SK_PNMI_HRX_OVERFLOW}, - {OID_802_3_XMIT_UNDERRUN, - 0, - 0, - 0, - SK_PNMI_RO, Mac8023Stat, SK_PNMI_HTX_UNDERRUN}, - {OID_802_3_XMIT_TIMES_CRS_LOST, - 0, - 0, - 0, - SK_PNMI_RO, Mac8023Stat, SK_PNMI_HTX_CARRIER}, - {OID_802_3_XMIT_LATE_COLLISIONS, - 0, - 0, - 0, - SK_PNMI_RO, Mac8023Stat, SK_PNMI_HTX_LATE_COL}, -#ifdef SK_POWER_MGMT - {OID_PNP_CAPABILITIES, - 0, - 0, - 0, - SK_PNMI_RO, PowerManagement, 0}, - {OID_PNP_SET_POWER, - 0, - 0, - 0, - SK_PNMI_WO, PowerManagement, 0}, - {OID_PNP_QUERY_POWER, - 0, - 0, - 0, - SK_PNMI_RO, PowerManagement, 0}, - {OID_PNP_ADD_WAKE_UP_PATTERN, - 0, - 0, - 0, - SK_PNMI_WO, PowerManagement, 0}, - {OID_PNP_REMOVE_WAKE_UP_PATTERN, - 0, - 0, - 0, - SK_PNMI_WO, PowerManagement, 0}, - {OID_PNP_ENABLE_WAKE_UP, - 0, - 0, - 0, - SK_PNMI_RW, PowerManagement, 0}, -#endif /* SK_POWER_MGMT */ -#ifdef SK_DIAG_SUPPORT - {OID_SKGE_DIAG_MODE, - 0, - 0, - 0, - SK_PNMI_RW, DiagActions, 0}, -#endif /* SK_DIAG_SUPPORT */ - {OID_SKGE_MDB_VERSION, - 1, - 0, - SK_PNMI_MAI_OFF(MgmtDBVersion), - SK_PNMI_RO, General, 0}, - {OID_SKGE_SUPPORTED_LIST, - 0, - 0, - 0, - SK_PNMI_RO, General, 0}, - {OID_SKGE_ALL_DATA, - 0, - 0, - 0, - SK_PNMI_RW, OidStruct, 0}, - {OID_SKGE_VPD_FREE_BYTES, - 1, - 0, - SK_PNMI_MAI_OFF(VpdFreeBytes), - SK_PNMI_RO, Vpd, 0}, - {OID_SKGE_VPD_ENTRIES_LIST, - 1, - 0, - SK_PNMI_MAI_OFF(VpdEntriesList), - SK_PNMI_RO, Vpd, 0}, - {OID_SKGE_VPD_ENTRIES_NUMBER, - 1, - 0, - SK_PNMI_MAI_OFF(VpdEntriesNumber), - SK_PNMI_RO, Vpd, 0}, - {OID_SKGE_VPD_KEY, - SK_PNMI_VPD_ENTRIES, - sizeof(SK_PNMI_VPD), - SK_PNMI_OFF(Vpd) + SK_PNMI_VPD_OFF(VpdKey), - SK_PNMI_RO, Vpd, 0}, - {OID_SKGE_VPD_VALUE, - SK_PNMI_VPD_ENTRIES, - sizeof(SK_PNMI_VPD), - SK_PNMI_OFF(Vpd) + SK_PNMI_VPD_OFF(VpdValue), - SK_PNMI_RO, Vpd, 0}, - {OID_SKGE_VPD_ACCESS, - SK_PNMI_VPD_ENTRIES, - sizeof(SK_PNMI_VPD), - SK_PNMI_OFF(Vpd) + SK_PNMI_VPD_OFF(VpdAccess), - SK_PNMI_RO, Vpd, 0}, - {OID_SKGE_VPD_ACTION, - SK_PNMI_VPD_ENTRIES, - sizeof(SK_PNMI_VPD), - SK_PNMI_OFF(Vpd) + SK_PNMI_VPD_OFF(VpdAction), - SK_PNMI_RW, Vpd, 0}, - {OID_SKGE_PORT_NUMBER, - 1, - 0, - SK_PNMI_MAI_OFF(PortNumber), - SK_PNMI_RO, General, 0}, - {OID_SKGE_DEVICE_TYPE, - 1, - 0, - SK_PNMI_MAI_OFF(DeviceType), - SK_PNMI_RO, General, 0}, - {OID_SKGE_DRIVER_DESCR, - 1, - 0, - SK_PNMI_MAI_OFF(DriverDescr), - SK_PNMI_RO, General, 0}, - {OID_SKGE_DRIVER_VERSION, - 1, - 0, - SK_PNMI_MAI_OFF(DriverVersion), - SK_PNMI_RO, General, 0}, - {OID_SKGE_DRIVER_RELDATE, - 1, - 0, - SK_PNMI_MAI_OFF(DriverReleaseDate), - SK_PNMI_RO, General, 0}, - {OID_SKGE_DRIVER_FILENAME, - 1, - 0, - SK_PNMI_MAI_OFF(DriverFileName), - SK_PNMI_RO, General, 0}, - {OID_SKGE_HW_DESCR, - 1, - 0, - SK_PNMI_MAI_OFF(HwDescr), - SK_PNMI_RO, General, 0}, - {OID_SKGE_HW_VERSION, - 1, - 0, - SK_PNMI_MAI_OFF(HwVersion), - SK_PNMI_RO, General, 0}, - {OID_SKGE_CHIPSET, - 1, - 0, - SK_PNMI_MAI_OFF(Chipset), - SK_PNMI_RO, General, 0}, - {OID_SKGE_CHIPID, - 1, - 0, - SK_PNMI_MAI_OFF(ChipId), - SK_PNMI_RO, General, 0}, - {OID_SKGE_RAMSIZE, - 1, - 0, - SK_PNMI_MAI_OFF(RamSize), - SK_PNMI_RO, General, 0}, - {OID_SKGE_VAUXAVAIL, - 1, - 0, - SK_PNMI_MAI_OFF(VauxAvail), - SK_PNMI_RO, General, 0}, - {OID_SKGE_ACTION, - 1, - 0, - SK_PNMI_MAI_OFF(Action), - SK_PNMI_RW, Perform, 0}, - {OID_SKGE_RESULT, - 1, - 0, - SK_PNMI_MAI_OFF(TestResult), - SK_PNMI_RO, General, 0}, - {OID_SKGE_BUS_TYPE, - 1, - 0, - SK_PNMI_MAI_OFF(BusType), - SK_PNMI_RO, General, 0}, - {OID_SKGE_BUS_SPEED, - 1, - 0, - SK_PNMI_MAI_OFF(BusSpeed), - SK_PNMI_RO, General, 0}, - {OID_SKGE_BUS_WIDTH, - 1, - 0, - SK_PNMI_MAI_OFF(BusWidth), - SK_PNMI_RO, General, 0}, - {OID_SKGE_TX_SW_QUEUE_LEN, - 1, - 0, - SK_PNMI_MAI_OFF(TxSwQueueLen), - SK_PNMI_RO, General, 0}, - {OID_SKGE_TX_SW_QUEUE_MAX, - 1, - 0, - SK_PNMI_MAI_OFF(TxSwQueueMax), - SK_PNMI_RO, General, 0}, - {OID_SKGE_TX_RETRY, - 1, - 0, - SK_PNMI_MAI_OFF(TxRetryCts), - SK_PNMI_RO, General, 0}, - {OID_SKGE_RX_INTR_CTS, - 1, - 0, - SK_PNMI_MAI_OFF(RxIntrCts), - SK_PNMI_RO, General, 0}, - {OID_SKGE_TX_INTR_CTS, - 1, - 0, - SK_PNMI_MAI_OFF(TxIntrCts), - SK_PNMI_RO, General, 0}, - {OID_SKGE_RX_NO_BUF_CTS, - 1, - 0, - SK_PNMI_MAI_OFF(RxNoBufCts), - SK_PNMI_RO, General, 0}, - {OID_SKGE_TX_NO_BUF_CTS, - 1, - 0, - SK_PNMI_MAI_OFF(TxNoBufCts), - SK_PNMI_RO, General, 0}, - {OID_SKGE_TX_USED_DESCR_NO, - 1, - 0, - SK_PNMI_MAI_OFF(TxUsedDescrNo), - SK_PNMI_RO, General, 0}, - {OID_SKGE_RX_DELIVERED_CTS, - 1, - 0, - SK_PNMI_MAI_OFF(RxDeliveredCts), - SK_PNMI_RO, General, 0}, - {OID_SKGE_RX_OCTETS_DELIV_CTS, - 1, - 0, - SK_PNMI_MAI_OFF(RxOctetsDeliveredCts), - SK_PNMI_RO, General, 0}, - {OID_SKGE_RX_HW_ERROR_CTS, - 1, - 0, - SK_PNMI_MAI_OFF(RxHwErrorsCts), - SK_PNMI_RO, General, 0}, - {OID_SKGE_TX_HW_ERROR_CTS, - 1, - 0, - SK_PNMI_MAI_OFF(TxHwErrorsCts), - SK_PNMI_RO, General, 0}, - {OID_SKGE_IN_ERRORS_CTS, - 1, - 0, - SK_PNMI_MAI_OFF(InErrorsCts), - SK_PNMI_RO, General, 0}, - {OID_SKGE_OUT_ERROR_CTS, - 1, - 0, - SK_PNMI_MAI_OFF(OutErrorsCts), - SK_PNMI_RO, General, 0}, - {OID_SKGE_ERR_RECOVERY_CTS, - 1, - 0, - SK_PNMI_MAI_OFF(ErrRecoveryCts), - SK_PNMI_RO, General, 0}, - {OID_SKGE_SYSUPTIME, - 1, - 0, - SK_PNMI_MAI_OFF(SysUpTime), - SK_PNMI_RO, General, 0}, - {OID_SKGE_SENSOR_NUMBER, - 1, - 0, - SK_PNMI_MAI_OFF(SensorNumber), - SK_PNMI_RO, General, 0}, - {OID_SKGE_SENSOR_INDEX, - SK_PNMI_SENSOR_ENTRIES, - sizeof(SK_PNMI_SENSOR), - SK_PNMI_OFF(Sensor) + SK_PNMI_SEN_OFF(SensorIndex), - SK_PNMI_RO, SensorStat, 0}, - {OID_SKGE_SENSOR_DESCR, - SK_PNMI_SENSOR_ENTRIES, - sizeof(SK_PNMI_SENSOR), - SK_PNMI_OFF(Sensor) + SK_PNMI_SEN_OFF(SensorDescr), - SK_PNMI_RO, SensorStat, 0}, - {OID_SKGE_SENSOR_TYPE, - SK_PNMI_SENSOR_ENTRIES, - sizeof(SK_PNMI_SENSOR), - SK_PNMI_OFF(Sensor) + SK_PNMI_SEN_OFF(SensorType), - SK_PNMI_RO, SensorStat, 0}, - {OID_SKGE_SENSOR_VALUE, - SK_PNMI_SENSOR_ENTRIES, - sizeof(SK_PNMI_SENSOR), - SK_PNMI_OFF(Sensor) + SK_PNMI_SEN_OFF(SensorValue), - SK_PNMI_RO, SensorStat, 0}, - {OID_SKGE_SENSOR_WAR_THRES_LOW, - SK_PNMI_SENSOR_ENTRIES, - sizeof(SK_PNMI_SENSOR), - SK_PNMI_OFF(Sensor) + SK_PNMI_SEN_OFF(SensorWarningThresholdLow), - SK_PNMI_RO, SensorStat, 0}, - {OID_SKGE_SENSOR_WAR_THRES_UPP, - SK_PNMI_SENSOR_ENTRIES, - sizeof(SK_PNMI_SENSOR), - SK_PNMI_OFF(Sensor) + SK_PNMI_SEN_OFF(SensorWarningThresholdHigh), - SK_PNMI_RO, SensorStat, 0}, - {OID_SKGE_SENSOR_ERR_THRES_LOW, - SK_PNMI_SENSOR_ENTRIES, - sizeof(SK_PNMI_SENSOR), - SK_PNMI_OFF(Sensor) + SK_PNMI_SEN_OFF(SensorErrorThresholdLow), - SK_PNMI_RO, SensorStat, 0}, - {OID_SKGE_SENSOR_ERR_THRES_UPP, - SK_PNMI_SENSOR_ENTRIES, - sizeof(SK_PNMI_SENSOR), - SK_PNMI_OFF(Sensor) + SK_PNMI_SEN_OFF(SensorErrorThresholdHigh), - SK_PNMI_RO, SensorStat, 0}, - {OID_SKGE_SENSOR_STATUS, - SK_PNMI_SENSOR_ENTRIES, - sizeof(SK_PNMI_SENSOR), - SK_PNMI_OFF(Sensor) + SK_PNMI_SEN_OFF(SensorStatus), - SK_PNMI_RO, SensorStat, 0}, - {OID_SKGE_SENSOR_WAR_CTS, - SK_PNMI_SENSOR_ENTRIES, - sizeof(SK_PNMI_SENSOR), - SK_PNMI_OFF(Sensor) + SK_PNMI_SEN_OFF(SensorWarningCts), - SK_PNMI_RO, SensorStat, 0}, - {OID_SKGE_SENSOR_ERR_CTS, - SK_PNMI_SENSOR_ENTRIES, - sizeof(SK_PNMI_SENSOR), - SK_PNMI_OFF(Sensor) + SK_PNMI_SEN_OFF(SensorErrorCts), - SK_PNMI_RO, SensorStat, 0}, - {OID_SKGE_SENSOR_WAR_TIME, - SK_PNMI_SENSOR_ENTRIES, - sizeof(SK_PNMI_SENSOR), - SK_PNMI_OFF(Sensor) + SK_PNMI_SEN_OFF(SensorWarningTimestamp), - SK_PNMI_RO, SensorStat, 0}, - {OID_SKGE_SENSOR_ERR_TIME, - SK_PNMI_SENSOR_ENTRIES, - sizeof(SK_PNMI_SENSOR), - SK_PNMI_OFF(Sensor) + SK_PNMI_SEN_OFF(SensorErrorTimestamp), - SK_PNMI_RO, SensorStat, 0}, - {OID_SKGE_CHKSM_NUMBER, - 1, - 0, - SK_PNMI_MAI_OFF(ChecksumNumber), - SK_PNMI_RO, General, 0}, - {OID_SKGE_CHKSM_RX_OK_CTS, - SKCS_NUM_PROTOCOLS, - sizeof(SK_PNMI_CHECKSUM), - SK_PNMI_OFF(Checksum) + SK_PNMI_CHK_OFF(ChecksumRxOkCts), - SK_PNMI_RO, CsumStat, 0}, - {OID_SKGE_CHKSM_RX_UNABLE_CTS, - SKCS_NUM_PROTOCOLS, - sizeof(SK_PNMI_CHECKSUM), - SK_PNMI_OFF(Checksum) + SK_PNMI_CHK_OFF(ChecksumRxUnableCts), - SK_PNMI_RO, CsumStat, 0}, - {OID_SKGE_CHKSM_RX_ERR_CTS, - SKCS_NUM_PROTOCOLS, - sizeof(SK_PNMI_CHECKSUM), - SK_PNMI_OFF(Checksum) + SK_PNMI_CHK_OFF(ChecksumRxErrCts), - SK_PNMI_RO, CsumStat, 0}, - {OID_SKGE_CHKSM_TX_OK_CTS, - SKCS_NUM_PROTOCOLS, - sizeof(SK_PNMI_CHECKSUM), - SK_PNMI_OFF(Checksum) + SK_PNMI_CHK_OFF(ChecksumTxOkCts), - SK_PNMI_RO, CsumStat, 0}, - {OID_SKGE_CHKSM_TX_UNABLE_CTS, - SKCS_NUM_PROTOCOLS, - sizeof(SK_PNMI_CHECKSUM), - SK_PNMI_OFF(Checksum) + SK_PNMI_CHK_OFF(ChecksumTxUnableCts), - SK_PNMI_RO, CsumStat, 0}, - {OID_SKGE_STAT_TX, - SK_PNMI_MAC_ENTRIES, - sizeof(SK_PNMI_STAT), - SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTxOkCts), - SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX}, - {OID_SKGE_STAT_TX_OCTETS, - SK_PNMI_MAC_ENTRIES, - sizeof(SK_PNMI_STAT), - SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTxOctetsOkCts), - SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX_OCTET}, - {OID_SKGE_STAT_TX_BROADCAST, - SK_PNMI_MAC_ENTRIES, - sizeof(SK_PNMI_STAT), - SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTxBroadcastOkCts), - SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX_BROADCAST}, - {OID_SKGE_STAT_TX_MULTICAST, - SK_PNMI_MAC_ENTRIES, - sizeof(SK_PNMI_STAT), - SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTxMulticastOkCts), - SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX_MULTICAST}, - {OID_SKGE_STAT_TX_UNICAST, - SK_PNMI_MAC_ENTRIES, - sizeof(SK_PNMI_STAT), - SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTxUnicastOkCts), - SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX_UNICAST}, - {OID_SKGE_STAT_TX_LONGFRAMES, - SK_PNMI_MAC_ENTRIES, - sizeof(SK_PNMI_STAT), - SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTxLongFramesCts), - SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX_LONGFRAMES}, - {OID_SKGE_STAT_TX_BURST, - SK_PNMI_MAC_ENTRIES, - sizeof(SK_PNMI_STAT), - SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTxBurstCts), - SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX_BURST}, - {OID_SKGE_STAT_TX_PFLOWC, - SK_PNMI_MAC_ENTRIES, - sizeof(SK_PNMI_STAT), - SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTxPauseMacCtrlCts), - SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX_PMACC}, - {OID_SKGE_STAT_TX_FLOWC, - SK_PNMI_MAC_ENTRIES, - sizeof(SK_PNMI_STAT), - SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTxMacCtrlCts), - SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX_MACC}, - {OID_SKGE_STAT_TX_SINGLE_COL, - SK_PNMI_MAC_ENTRIES, - sizeof(SK_PNMI_STAT), - SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTxSingleCollisionCts), - SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX_SINGLE_COL}, - {OID_SKGE_STAT_TX_MULTI_COL, - SK_PNMI_MAC_ENTRIES, - sizeof(SK_PNMI_STAT), - SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTxMultipleCollisionCts), - SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX_MULTI_COL}, - {OID_SKGE_STAT_TX_EXCESS_COL, - SK_PNMI_MAC_ENTRIES, - sizeof(SK_PNMI_STAT), - SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTxExcessiveCollisionCts), - SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX_EXCESS_COL}, - {OID_SKGE_STAT_TX_LATE_COL, - SK_PNMI_MAC_ENTRIES, - sizeof(SK_PNMI_STAT), - SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTxLateCollisionCts), - SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX_LATE_COL}, - {OID_SKGE_STAT_TX_DEFFERAL, - SK_PNMI_MAC_ENTRIES, - sizeof(SK_PNMI_STAT), - SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTxDeferralCts), - SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX_DEFFERAL}, - {OID_SKGE_STAT_TX_EXCESS_DEF, - SK_PNMI_MAC_ENTRIES, - sizeof(SK_PNMI_STAT), - SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTxExcessiveDeferralCts), - SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX_EXCESS_DEF}, - {OID_SKGE_STAT_TX_UNDERRUN, - SK_PNMI_MAC_ENTRIES, - sizeof(SK_PNMI_STAT), - SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTxFifoUnderrunCts), - SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX_UNDERRUN}, - {OID_SKGE_STAT_TX_CARRIER, - SK_PNMI_MAC_ENTRIES, - sizeof(SK_PNMI_STAT), - SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTxCarrierCts), - SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX_CARRIER}, -/* {OID_SKGE_STAT_TX_UTIL, - SK_PNMI_MAC_ENTRIES, - sizeof(SK_PNMI_STAT), - SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTxUtilization), - SK_PNMI_RO, MacPrivateStat, (SK_U16)(-1)}, */ - {OID_SKGE_STAT_TX_64, - SK_PNMI_MAC_ENTRIES, - sizeof(SK_PNMI_STAT), - SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTx64Cts), - SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX_64}, - {OID_SKGE_STAT_TX_127, - SK_PNMI_MAC_ENTRIES, - sizeof(SK_PNMI_STAT), - SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTx127Cts), - SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX_127}, - {OID_SKGE_STAT_TX_255, - SK_PNMI_MAC_ENTRIES, - sizeof(SK_PNMI_STAT), - SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTx255Cts), - SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX_255}, - {OID_SKGE_STAT_TX_511, - SK_PNMI_MAC_ENTRIES, - sizeof(SK_PNMI_STAT), - SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTx511Cts), - SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX_511}, - {OID_SKGE_STAT_TX_1023, - SK_PNMI_MAC_ENTRIES, - sizeof(SK_PNMI_STAT), - SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTx1023Cts), - SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX_1023}, - {OID_SKGE_STAT_TX_MAX, - SK_PNMI_MAC_ENTRIES, - sizeof(SK_PNMI_STAT), - SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTxMaxCts), - SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX_MAX}, - {OID_SKGE_STAT_TX_SYNC, - SK_PNMI_MAC_ENTRIES, - sizeof(SK_PNMI_STAT), - SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTxSyncCts), - SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX_SYNC}, - {OID_SKGE_STAT_TX_SYNC_OCTETS, - SK_PNMI_MAC_ENTRIES, - sizeof(SK_PNMI_STAT), - SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTxSyncOctetsCts), - SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX_SYNC_OCTET}, - {OID_SKGE_STAT_RX, - SK_PNMI_MAC_ENTRIES, - sizeof(SK_PNMI_STAT), - SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxOkCts), - SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX}, - {OID_SKGE_STAT_RX_OCTETS, - SK_PNMI_MAC_ENTRIES, - sizeof(SK_PNMI_STAT), - SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxOctetsOkCts), - SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_OCTET}, - {OID_SKGE_STAT_RX_BROADCAST, - SK_PNMI_MAC_ENTRIES, - sizeof(SK_PNMI_STAT), - SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxBroadcastOkCts), - SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_BROADCAST}, - {OID_SKGE_STAT_RX_MULTICAST, - SK_PNMI_MAC_ENTRIES, - sizeof(SK_PNMI_STAT), - SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxMulticastOkCts), - SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_MULTICAST}, - {OID_SKGE_STAT_RX_UNICAST, - SK_PNMI_MAC_ENTRIES, - sizeof(SK_PNMI_STAT), - SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxUnicastOkCts), - SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_UNICAST}, - {OID_SKGE_STAT_RX_LONGFRAMES, - SK_PNMI_MAC_ENTRIES, - sizeof(SK_PNMI_STAT), - SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxLongFramesCts), - SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_LONGFRAMES}, - {OID_SKGE_STAT_RX_PFLOWC, - SK_PNMI_MAC_ENTRIES, - sizeof(SK_PNMI_STAT), - SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxPauseMacCtrlCts), - SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_PMACC}, - {OID_SKGE_STAT_RX_FLOWC, - SK_PNMI_MAC_ENTRIES, - sizeof(SK_PNMI_STAT), - SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxMacCtrlCts), - SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_MACC}, - {OID_SKGE_STAT_RX_PFLOWC_ERR, - SK_PNMI_MAC_ENTRIES, - sizeof(SK_PNMI_STAT), - SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxPauseMacCtrlErrorCts), - SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_PMACC_ERR}, - {OID_SKGE_STAT_RX_FLOWC_UNKWN, - SK_PNMI_MAC_ENTRIES, - sizeof(SK_PNMI_STAT), - SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxMacCtrlUnknownCts), - SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_MACC_UNKWN}, - {OID_SKGE_STAT_RX_BURST, - SK_PNMI_MAC_ENTRIES, - sizeof(SK_PNMI_STAT), - SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxBurstCts), - SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_BURST}, - {OID_SKGE_STAT_RX_MISSED, - SK_PNMI_MAC_ENTRIES, - sizeof(SK_PNMI_STAT), - SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxMissedCts), - SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_MISSED}, - {OID_SKGE_STAT_RX_FRAMING, - SK_PNMI_MAC_ENTRIES, - sizeof(SK_PNMI_STAT), - SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxFramingCts), - SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_FRAMING}, - {OID_SKGE_STAT_RX_OVERFLOW, - SK_PNMI_MAC_ENTRIES, - sizeof(SK_PNMI_STAT), - SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxFifoOverflowCts), - SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_OVERFLOW}, - {OID_SKGE_STAT_RX_JABBER, - SK_PNMI_MAC_ENTRIES, - sizeof(SK_PNMI_STAT), - SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxJabberCts), - SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_JABBER}, - {OID_SKGE_STAT_RX_CARRIER, - SK_PNMI_MAC_ENTRIES, - sizeof(SK_PNMI_STAT), - SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxCarrierCts), - SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_CARRIER}, - {OID_SKGE_STAT_RX_IR_LENGTH, - SK_PNMI_MAC_ENTRIES, - sizeof(SK_PNMI_STAT), - SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxIRLengthCts), - SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_IRLENGTH}, - {OID_SKGE_STAT_RX_SYMBOL, - SK_PNMI_MAC_ENTRIES, - sizeof(SK_PNMI_STAT), - SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxSymbolCts), - SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_SYMBOL}, - {OID_SKGE_STAT_RX_SHORTS, - SK_PNMI_MAC_ENTRIES, - sizeof(SK_PNMI_STAT), - SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxShortsCts), - SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_SHORTS}, - {OID_SKGE_STAT_RX_RUNT, - SK_PNMI_MAC_ENTRIES, - sizeof(SK_PNMI_STAT), - SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxRuntCts), - SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_RUNT}, - {OID_SKGE_STAT_RX_CEXT, - SK_PNMI_MAC_ENTRIES, - sizeof(SK_PNMI_STAT), - SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxCextCts), - SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_CEXT}, - {OID_SKGE_STAT_RX_TOO_LONG, - SK_PNMI_MAC_ENTRIES, - sizeof(SK_PNMI_STAT), - SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxTooLongCts), - SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_TOO_LONG}, - {OID_SKGE_STAT_RX_FCS, - SK_PNMI_MAC_ENTRIES, - sizeof(SK_PNMI_STAT), - SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxFcsCts), - SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_FCS}, -/* {OID_SKGE_STAT_RX_UTIL, - SK_PNMI_MAC_ENTRIES, - sizeof(SK_PNMI_STAT), - SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxUtilization), - SK_PNMI_RO, MacPrivateStat, (SK_U16)(-1)}, */ - {OID_SKGE_STAT_RX_64, - SK_PNMI_MAC_ENTRIES, - sizeof(SK_PNMI_STAT), - SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRx64Cts), - SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_64}, - {OID_SKGE_STAT_RX_127, - SK_PNMI_MAC_ENTRIES, - sizeof(SK_PNMI_STAT), - SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRx127Cts), - SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_127}, - {OID_SKGE_STAT_RX_255, - SK_PNMI_MAC_ENTRIES, - sizeof(SK_PNMI_STAT), - SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRx255Cts), - SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_255}, - {OID_SKGE_STAT_RX_511, - SK_PNMI_MAC_ENTRIES, - sizeof(SK_PNMI_STAT), - SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRx511Cts), - SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_511}, - {OID_SKGE_STAT_RX_1023, - SK_PNMI_MAC_ENTRIES, - sizeof(SK_PNMI_STAT), - SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRx1023Cts), - SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_1023}, - {OID_SKGE_STAT_RX_MAX, - SK_PNMI_MAC_ENTRIES, - sizeof(SK_PNMI_STAT), - SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxMaxCts), - SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_MAX}, - {OID_SKGE_PHYS_CUR_ADDR, - SK_PNMI_MAC_ENTRIES, - sizeof(SK_PNMI_CONF), - SK_PNMI_OFF(Conf) + SK_PNMI_CNF_OFF(ConfMacCurrentAddr), - SK_PNMI_RW, Addr, 0}, - {OID_SKGE_PHYS_FAC_ADDR, - SK_PNMI_MAC_ENTRIES, - sizeof(SK_PNMI_CONF), - SK_PNMI_OFF(Conf) + SK_PNMI_CNF_OFF(ConfMacFactoryAddr), - SK_PNMI_RO, Addr, 0}, - {OID_SKGE_PMD, - SK_PNMI_MAC_ENTRIES, - sizeof(SK_PNMI_CONF), - SK_PNMI_OFF(Conf) + SK_PNMI_CNF_OFF(ConfPMD), - SK_PNMI_RO, MacPrivateConf, 0}, - {OID_SKGE_CONNECTOR, - SK_PNMI_MAC_ENTRIES, - sizeof(SK_PNMI_CONF), - SK_PNMI_OFF(Conf) + SK_PNMI_CNF_OFF(ConfConnector), - SK_PNMI_RO, MacPrivateConf, 0}, - {OID_SKGE_PHY_TYPE, - SK_PNMI_MAC_ENTRIES, - sizeof(SK_PNMI_CONF), - SK_PNMI_OFF(Conf) + SK_PNMI_CNF_OFF(ConfPhyType), - SK_PNMI_RO, MacPrivateConf, 0}, -#ifdef SK_PHY_LP_MODE - {OID_SKGE_PHY_LP_MODE, - SK_PNMI_MAC_ENTRIES, - sizeof(SK_PNMI_CONF), - SK_PNMI_OFF(Conf) + SK_PNMI_CNF_OFF(ConfPhyMode), - SK_PNMI_RW, MacPrivateConf, 0}, -#endif - {OID_SKGE_LINK_CAP, - SK_PNMI_MAC_ENTRIES, - sizeof(SK_PNMI_CONF), - SK_PNMI_OFF(Conf) + SK_PNMI_CNF_OFF(ConfLinkCapability), - SK_PNMI_RO, MacPrivateConf, 0}, - {OID_SKGE_LINK_MODE, - SK_PNMI_MAC_ENTRIES, - sizeof(SK_PNMI_CONF), - SK_PNMI_OFF(Conf) + SK_PNMI_CNF_OFF(ConfLinkMode), - SK_PNMI_RW, MacPrivateConf, 0}, - {OID_SKGE_LINK_MODE_STATUS, - SK_PNMI_MAC_ENTRIES, - sizeof(SK_PNMI_CONF), - SK_PNMI_OFF(Conf) + SK_PNMI_CNF_OFF(ConfLinkModeStatus), - SK_PNMI_RO, MacPrivateConf, 0}, - {OID_SKGE_LINK_STATUS, - SK_PNMI_MAC_ENTRIES, - sizeof(SK_PNMI_CONF), - SK_PNMI_OFF(Conf) + SK_PNMI_CNF_OFF(ConfLinkStatus), - SK_PNMI_RO, MacPrivateConf, 0}, - {OID_SKGE_FLOWCTRL_CAP, - SK_PNMI_MAC_ENTRIES, - sizeof(SK_PNMI_CONF), - SK_PNMI_OFF(Conf) + SK_PNMI_CNF_OFF(ConfFlowCtrlCapability), - SK_PNMI_RO, MacPrivateConf, 0}, - {OID_SKGE_FLOWCTRL_MODE, - SK_PNMI_MAC_ENTRIES, - sizeof(SK_PNMI_CONF), - SK_PNMI_OFF(Conf) + SK_PNMI_CNF_OFF(ConfFlowCtrlMode), - SK_PNMI_RW, MacPrivateConf, 0}, - {OID_SKGE_FLOWCTRL_STATUS, - SK_PNMI_MAC_ENTRIES, - sizeof(SK_PNMI_CONF), - SK_PNMI_OFF(Conf) + SK_PNMI_CNF_OFF(ConfFlowCtrlStatus), - SK_PNMI_RO, MacPrivateConf, 0}, - {OID_SKGE_PHY_OPERATION_CAP, - SK_PNMI_MAC_ENTRIES, - sizeof(SK_PNMI_CONF), - SK_PNMI_OFF(Conf) + SK_PNMI_CNF_OFF(ConfPhyOperationCapability), - SK_PNMI_RO, MacPrivateConf, 0}, - {OID_SKGE_PHY_OPERATION_MODE, - SK_PNMI_MAC_ENTRIES, - sizeof(SK_PNMI_CONF), - SK_PNMI_OFF(Conf) + SK_PNMI_CNF_OFF(ConfPhyOperationMode), - SK_PNMI_RW, MacPrivateConf, 0}, - {OID_SKGE_PHY_OPERATION_STATUS, - SK_PNMI_MAC_ENTRIES, - sizeof(SK_PNMI_CONF), - SK_PNMI_OFF(Conf) + SK_PNMI_CNF_OFF(ConfPhyOperationStatus), - SK_PNMI_RO, MacPrivateConf, 0}, - {OID_SKGE_SPEED_CAP, - SK_PNMI_MAC_ENTRIES, - sizeof(SK_PNMI_CONF), - SK_PNMI_OFF(Conf) + SK_PNMI_CNF_OFF(ConfSpeedCapability), - SK_PNMI_RO, MacPrivateConf, 0}, - {OID_SKGE_SPEED_MODE, - SK_PNMI_MAC_ENTRIES, - sizeof(SK_PNMI_CONF), - SK_PNMI_OFF(Conf) + SK_PNMI_CNF_OFF(ConfSpeedMode), - SK_PNMI_RW, MacPrivateConf, 0}, - {OID_SKGE_SPEED_STATUS, - SK_PNMI_MAC_ENTRIES, - sizeof(SK_PNMI_CONF), - SK_PNMI_OFF(Conf) + SK_PNMI_CNF_OFF(ConfSpeedStatus), - SK_PNMI_RO, MacPrivateConf, 0}, - {OID_SKGE_TRAP, - 1, - 0, - SK_PNMI_MAI_OFF(Trap), - SK_PNMI_RO, General, 0}, - {OID_SKGE_TRAP_NUMBER, - 1, - 0, - SK_PNMI_MAI_OFF(TrapNumber), - SK_PNMI_RO, General, 0}, - {OID_SKGE_RLMT_MODE, - 1, - 0, - SK_PNMI_MAI_OFF(RlmtMode), - SK_PNMI_RW, Rlmt, 0}, - {OID_SKGE_RLMT_PORT_NUMBER, - 1, - 0, - SK_PNMI_MAI_OFF(RlmtPortNumber), - SK_PNMI_RO, Rlmt, 0}, - {OID_SKGE_RLMT_PORT_ACTIVE, - 1, - 0, - SK_PNMI_MAI_OFF(RlmtPortActive), - SK_PNMI_RO, Rlmt, 0}, - {OID_SKGE_RLMT_PORT_PREFERRED, - 1, - 0, - SK_PNMI_MAI_OFF(RlmtPortPreferred), - SK_PNMI_RW, Rlmt, 0}, - {OID_SKGE_RLMT_CHANGE_CTS, - 1, - 0, - SK_PNMI_MAI_OFF(RlmtChangeCts), - SK_PNMI_RO, Rlmt, 0}, - {OID_SKGE_RLMT_CHANGE_TIME, - 1, - 0, - SK_PNMI_MAI_OFF(RlmtChangeTime), - SK_PNMI_RO, Rlmt, 0}, - {OID_SKGE_RLMT_CHANGE_ESTIM, - 1, - 0, - SK_PNMI_MAI_OFF(RlmtChangeEstimate), - SK_PNMI_RO, Rlmt, 0}, - {OID_SKGE_RLMT_CHANGE_THRES, - 1, - 0, - SK_PNMI_MAI_OFF(RlmtChangeThreshold), - SK_PNMI_RW, Rlmt, 0}, - {OID_SKGE_RLMT_PORT_INDEX, - SK_PNMI_MAC_ENTRIES, - sizeof(SK_PNMI_RLMT), - SK_PNMI_OFF(Rlmt) + SK_PNMI_RLM_OFF(RlmtIndex), - SK_PNMI_RO, RlmtStat, 0}, - {OID_SKGE_RLMT_STATUS, - SK_PNMI_MAC_ENTRIES, - sizeof(SK_PNMI_RLMT), - SK_PNMI_OFF(Rlmt) + SK_PNMI_RLM_OFF(RlmtStatus), - SK_PNMI_RO, RlmtStat, 0}, - {OID_SKGE_RLMT_TX_HELLO_CTS, - SK_PNMI_MAC_ENTRIES, - sizeof(SK_PNMI_RLMT), - SK_PNMI_OFF(Rlmt) + SK_PNMI_RLM_OFF(RlmtTxHelloCts), - SK_PNMI_RO, RlmtStat, 0}, - {OID_SKGE_RLMT_RX_HELLO_CTS, - SK_PNMI_MAC_ENTRIES, - sizeof(SK_PNMI_RLMT), - SK_PNMI_OFF(Rlmt) + SK_PNMI_RLM_OFF(RlmtRxHelloCts), - SK_PNMI_RO, RlmtStat, 0}, - {OID_SKGE_RLMT_TX_SP_REQ_CTS, - SK_PNMI_MAC_ENTRIES, - sizeof(SK_PNMI_RLMT), - SK_PNMI_OFF(Rlmt) + SK_PNMI_RLM_OFF(RlmtTxSpHelloReqCts), - SK_PNMI_RO, RlmtStat, 0}, - {OID_SKGE_RLMT_RX_SP_CTS, - SK_PNMI_MAC_ENTRIES, - sizeof(SK_PNMI_RLMT), - SK_PNMI_OFF(Rlmt) + SK_PNMI_RLM_OFF(RlmtRxSpHelloCts), - SK_PNMI_RO, RlmtStat, 0}, - {OID_SKGE_RLMT_MONITOR_NUMBER, - 1, - 0, - SK_PNMI_MAI_OFF(RlmtMonitorNumber), - SK_PNMI_RO, General, 0}, - {OID_SKGE_RLMT_MONITOR_INDEX, - SK_PNMI_MONITOR_ENTRIES, - sizeof(SK_PNMI_RLMT_MONITOR), - SK_PNMI_OFF(RlmtMonitor) + SK_PNMI_MON_OFF(RlmtMonitorIndex), - SK_PNMI_RO, Monitor, 0}, - {OID_SKGE_RLMT_MONITOR_ADDR, - SK_PNMI_MONITOR_ENTRIES, - sizeof(SK_PNMI_RLMT_MONITOR), - SK_PNMI_OFF(RlmtMonitor) + SK_PNMI_MON_OFF(RlmtMonitorAddr), - SK_PNMI_RO, Monitor, 0}, - {OID_SKGE_RLMT_MONITOR_ERRS, - SK_PNMI_MONITOR_ENTRIES, - sizeof(SK_PNMI_RLMT_MONITOR), - SK_PNMI_OFF(RlmtMonitor) + SK_PNMI_MON_OFF(RlmtMonitorErrorCts), - SK_PNMI_RO, Monitor, 0}, - {OID_SKGE_RLMT_MONITOR_TIMESTAMP, - SK_PNMI_MONITOR_ENTRIES, - sizeof(SK_PNMI_RLMT_MONITOR), - SK_PNMI_OFF(RlmtMonitor) + SK_PNMI_MON_OFF(RlmtMonitorTimestamp), - SK_PNMI_RO, Monitor, 0}, - {OID_SKGE_RLMT_MONITOR_ADMIN, - SK_PNMI_MONITOR_ENTRIES, - sizeof(SK_PNMI_RLMT_MONITOR), - SK_PNMI_OFF(RlmtMonitor) + SK_PNMI_MON_OFF(RlmtMonitorAdmin), - SK_PNMI_RW, Monitor, 0}, - {OID_SKGE_MTU, - 1, - 0, - SK_PNMI_MAI_OFF(MtuSize), - SK_PNMI_RW, MacPrivateConf, 0}, - {OID_SKGE_VCT_GET, - 0, - 0, - 0, - SK_PNMI_RO, Vct, 0}, - {OID_SKGE_VCT_SET, - 0, - 0, - 0, - SK_PNMI_WO, Vct, 0}, - {OID_SKGE_VCT_STATUS, - 0, - 0, - 0, - SK_PNMI_RO, Vct, 0}, - {OID_SKGE_BOARDLEVEL, - 0, - 0, - 0, - SK_PNMI_RO, General, 0}, -}; - +/***************************************************************************** + * + * Name: skgemib.c + * Project: GEnesis, PCI Gigabit Ethernet Adapter + * Version: $Revision: 2.7 $ + * Date: $Date: 2004/10/26 12:42:18 $ + * Purpose: Private Network Management Interface Management Database + * + ****************************************************************************/ + +/****************************************************************************** + * + * (C)Copyright 1998-2002 SysKonnect GmbH. + * (C)Copyright 2002-2003 Marvell. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * The information in this file is provided "AS IS" without warranty. + * + ******************************************************************************/ + +/* + * PRIVATE OID handler function prototypes + */ +PNMI_STATIC int Addr(SK_AC *pAC, SK_IOC IoC, int action, + SK_U32 Id, char *pBuf, unsigned int *pLen, SK_U32 Instance, + unsigned int TableIndex, SK_U32 NetIndex); +PNMI_STATIC int CsumStat(SK_AC *pAC, SK_IOC IoC, int action, SK_U32 Id, + char *pBuf, unsigned int *pLen, SK_U32 Instance, + unsigned int TableIndex, SK_U32 NetIndex); +PNMI_STATIC int General(SK_AC *pAC, SK_IOC IoC, int action, SK_U32 Id, + char *pBuf, unsigned int *pLen, SK_U32 Instance, + unsigned int TableIndex, SK_U32 NetIndex); +PNMI_STATIC int Mac8023Stat(SK_AC *pAC, SK_IOC IoC, int action, SK_U32 Id, + char *pBuf, unsigned int *pLen, SK_U32 Instance, + unsigned int TableIndex, SK_U32 NetIndex); +PNMI_STATIC int MacPrivateConf(SK_AC *pAC, SK_IOC IoC, int action, SK_U32 Id, + char *pBuf, unsigned int *pLen, SK_U32 Instance, + unsigned int TableIndex, SK_U32 NetIndex); +PNMI_STATIC int MacPrivateStat(SK_AC *pAC, SK_IOC IoC, int action, SK_U32 Id, + char *pBuf, unsigned int *pLen, SK_U32 Instance, + unsigned int TableIndex, SK_U32 NetIndex); +PNMI_STATIC int Monitor(SK_AC *pAC, SK_IOC IoC, int action, + SK_U32 Id, char *pBuf, unsigned int *pLen, SK_U32 Instance, + unsigned int TableIndex, SK_U32 NetIndex); +PNMI_STATIC int OidStruct(SK_AC *pAC, SK_IOC IoC, int action, SK_U32 Id, + char *pBuf, unsigned int *pLen, SK_U32 Instance, + unsigned int TableIndex, SK_U32 NetIndex); +PNMI_STATIC int Perform(SK_AC *pAC, SK_IOC IoC, int action, SK_U32 Id, + char *pBuf, unsigned int* pLen, SK_U32 Instance, + unsigned int TableIndex, SK_U32 NetIndex); +PNMI_STATIC int Rlmt(SK_AC *pAC, SK_IOC IoC, int action, SK_U32 Id, + char *pBuf, unsigned int *pLen, SK_U32 Instance, + unsigned int TableIndex, SK_U32 NetIndex); +PNMI_STATIC int RlmtStat(SK_AC *pAC, SK_IOC IoC, int action, SK_U32 Id, + char *pBuf, unsigned int *pLen, SK_U32 Instance, + unsigned int TableIndex, SK_U32 NetIndex); +PNMI_STATIC int SensorStat(SK_AC *pAC, SK_IOC IoC, int action, SK_U32 Id, + char *pBuf, unsigned int *pLen, SK_U32 Instance, + unsigned int TableIndex, SK_U32 NetIndex); +PNMI_STATIC int Vpd(SK_AC *pAC, SK_IOC IoC, int action, SK_U32 Id, + char *pBuf, unsigned int *pLen, SK_U32 Instance, + unsigned int TableIndex, SK_U32 NetIndex); +PNMI_STATIC int Vct(SK_AC *pAC, SK_IOC IoC, int action, SK_U32 Id, + char *pBuf, unsigned int *pLen, SK_U32 Instance, + unsigned int TableIndex, SK_U32 NetIndex); + +#ifdef SK_POWER_MGMT +PNMI_STATIC int PowerManagement(SK_AC *pAC, SK_IOC IoC, int action, SK_U32 Id, + char *pBuf, unsigned int *pLen, SK_U32 Instance, + unsigned int TableIndex, SK_U32 NetIndex); +#endif /* SK_POWER_MGMT */ + +#ifdef SK_DIAG_SUPPORT +PNMI_STATIC int DiagActions(SK_AC *pAC, SK_IOC IoC, int action, SK_U32 Id, + char *pBuf, unsigned int *pLen, SK_U32 Instance, + unsigned int TableIndex, SK_U32 NetIndex); +#endif /* SK_DIAG_SUPPORT */ + + +/* defines *******************************************************************/ +#define ID_TABLE_SIZE (sizeof(IdTable)/sizeof(IdTable[0])) + + +/* global variables **********************************************************/ + +/* + * Table to correlate OID with handler function and index to + * hardware register stored in StatAddress if applicable. + */ +PNMI_STATIC const SK_PNMI_TAB_ENTRY IdTable[] = { + {OID_GEN_XMIT_OK, + 0, + 0, + 0, + SK_PNMI_RO, Mac8023Stat, SK_PNMI_HTX}, + {OID_GEN_RCV_OK, + 0, + 0, + 0, + SK_PNMI_RO, Mac8023Stat, SK_PNMI_HRX}, + {OID_GEN_XMIT_ERROR, + 0, + 0, + 0, + SK_PNMI_RO, General, 0}, + {OID_GEN_RCV_ERROR, + 0, + 0, + 0, + SK_PNMI_RO, General, 0}, + {OID_GEN_RCV_NO_BUFFER, + 0, + 0, + 0, + SK_PNMI_RO, General, 0}, + {OID_GEN_DIRECTED_FRAMES_XMIT, + 0, + 0, + 0, + SK_PNMI_RO, Mac8023Stat, SK_PNMI_HTX_UNICAST}, + {OID_GEN_MULTICAST_FRAMES_XMIT, + 0, + 0, + 0, + SK_PNMI_RO, Mac8023Stat, SK_PNMI_HTX_MULTICAST}, + {OID_GEN_BROADCAST_FRAMES_XMIT, + 0, + 0, + 0, + SK_PNMI_RO, Mac8023Stat, SK_PNMI_HTX_BROADCAST}, + {OID_GEN_DIRECTED_FRAMES_RCV, + 0, + 0, + 0, + SK_PNMI_RO, Mac8023Stat, SK_PNMI_HRX_UNICAST}, + {OID_GEN_MULTICAST_FRAMES_RCV, + 0, + 0, + 0, + SK_PNMI_RO, Mac8023Stat, SK_PNMI_HRX_MULTICAST}, + {OID_GEN_BROADCAST_FRAMES_RCV, + 0, + 0, + 0, + SK_PNMI_RO, Mac8023Stat, SK_PNMI_HRX_BROADCAST}, + {OID_GEN_RCV_CRC_ERROR, + 0, + 0, + 0, + SK_PNMI_RO, Mac8023Stat, SK_PNMI_HRX_FCS}, + {OID_GEN_TRANSMIT_QUEUE_LENGTH, + 0, + 0, + 0, + SK_PNMI_RO, General, 0}, + {OID_802_3_PERMANENT_ADDRESS, + 0, + 0, + 0, + SK_PNMI_RO, Mac8023Stat, 0}, + {OID_802_3_CURRENT_ADDRESS, + 0, + 0, + 0, + SK_PNMI_RO, Mac8023Stat, 0}, + {OID_802_3_RCV_ERROR_ALIGNMENT, + 0, + 0, + 0, + SK_PNMI_RO, Mac8023Stat, SK_PNMI_HRX_FRAMING}, + {OID_802_3_XMIT_ONE_COLLISION, + 0, + 0, + 0, + SK_PNMI_RO, Mac8023Stat, SK_PNMI_HTX_SINGLE_COL}, + {OID_802_3_XMIT_MORE_COLLISIONS, + 0, + 0, + 0, + SK_PNMI_RO, Mac8023Stat, SK_PNMI_HTX_MULTI_COL}, + {OID_802_3_XMIT_DEFERRED, + 0, + 0, + 0, + SK_PNMI_RO, Mac8023Stat, SK_PNMI_HTX_DEFFERAL}, + {OID_802_3_XMIT_MAX_COLLISIONS, + 0, + 0, + 0, + SK_PNMI_RO, Mac8023Stat, SK_PNMI_HTX_EXCESS_COL}, + {OID_802_3_RCV_OVERRUN, + 0, + 0, + 0, + SK_PNMI_RO, Mac8023Stat, SK_PNMI_HRX_OVERFLOW}, + {OID_802_3_XMIT_UNDERRUN, + 0, + 0, + 0, + SK_PNMI_RO, Mac8023Stat, SK_PNMI_HTX_UNDERRUN}, + {OID_802_3_XMIT_TIMES_CRS_LOST, + 0, + 0, + 0, + SK_PNMI_RO, Mac8023Stat, SK_PNMI_HTX_CARRIER}, + {OID_802_3_XMIT_LATE_COLLISIONS, + 0, + 0, + 0, + SK_PNMI_RO, Mac8023Stat, SK_PNMI_HTX_LATE_COL}, +#ifdef SK_POWER_MGMT + {OID_PNP_CAPABILITIES, + 0, + 0, + 0, + SK_PNMI_RO, PowerManagement, 0}, + {OID_PNP_SET_POWER, + 0, + 0, + 0, + SK_PNMI_WO, PowerManagement, 0}, + {OID_PNP_QUERY_POWER, + 0, + 0, + 0, + SK_PNMI_RO, PowerManagement, 0}, + {OID_PNP_ADD_WAKE_UP_PATTERN, + 0, + 0, + 0, + SK_PNMI_WO, PowerManagement, 0}, + {OID_PNP_REMOVE_WAKE_UP_PATTERN, + 0, + 0, + 0, + SK_PNMI_WO, PowerManagement, 0}, + {OID_PNP_ENABLE_WAKE_UP, + 0, + 0, + 0, + SK_PNMI_RW, PowerManagement, 0}, +#endif /* SK_POWER_MGMT */ +#ifdef SK_DIAG_SUPPORT + {OID_SKGE_DIAG_MODE, + 0, + 0, + 0, + SK_PNMI_RW, DiagActions, 0}, +#endif /* SK_DIAG_SUPPORT */ +#ifdef SK_ASF + {OID_SKGE_ASF, + 0, + 0, + 0, + SK_PNMI_RW, Asf, 0}, + {OID_SKGE_ASF_STORE_CONFIG, + 0, + 0, + 0, + SK_PNMI_RW, Asf, 0}, + {OID_SKGE_ASF_ENA, + 0, + 0, + 0, + SK_PNMI_RW, Asf, 0}, + {OID_SKGE_ASF_RETRANS, + 0, + 0, + 0, + SK_PNMI_RW, Asf, 0}, + {OID_SKGE_ASF_RETRANS_INT, + 0, + 0, + 0, + SK_PNMI_RW, Asf, 0}, + {OID_SKGE_ASF_HB_ENA, + 0, + 0, + 0, + SK_PNMI_RW, Asf, 0}, + {OID_SKGE_ASF_HB_INT, + 0, + 0, + 0, + SK_PNMI_RW, Asf, 0}, + {OID_SKGE_ASF_WD_ENA, + 0, + 0, + 0, + SK_PNMI_RW, Asf, 0}, + {OID_SKGE_ASF_WD_TIME, + 0, + 0, + 0, + SK_PNMI_RW, Asf, 0}, + {OID_SKGE_ASF_IP_SOURCE, + 0, + 0, + 0, + SK_PNMI_RW, Asf, 0}, + {OID_SKGE_ASF_MAC_SOURCE, + 0, + 0, + 0, + SK_PNMI_RW, Asf, 0}, + {OID_SKGE_ASF_IP_DEST, + 0, + 0, + 0, + SK_PNMI_RW, Asf, 0}, + {OID_SKGE_ASF_MAC_DEST, + 0, + 0, + 0, + SK_PNMI_RW, Asf, 0}, + {OID_SKGE_ASF_COMMUNITY_NAME, + 0, + 0, + 0, + SK_PNMI_RW, Asf, 0}, + {OID_SKGE_ASF_RSP_ENA, + 0, + 0, + 0, + SK_PNMI_RW, Asf, 0}, + {OID_SKGE_ASF_RETRANS_COUNT_MIN, + 0, + 0, + 0, + SK_PNMI_RW, Asf, 0}, + {OID_SKGE_ASF_RETRANS_COUNT_MAX, + 0, + 0, + 0, + SK_PNMI_RW, Asf, 0}, + {OID_SKGE_ASF_RETRANS_INT_MIN, + 0, + 0, + 0, + SK_PNMI_RW, Asf, 0}, + {OID_SKGE_ASF_RETRANS_INT_MAX, + 0, + 0, + 0, + SK_PNMI_RW, Asf, 0}, + {OID_SKGE_ASF_HB_INT_MIN, + 0, + 0, + 0, + SK_PNMI_RW, Asf, 0}, + {OID_SKGE_ASF_HB_INT_MAX, + 0, + 0, + 0, + SK_PNMI_RW, Asf, 0}, + {OID_SKGE_ASF_WD_TIME_MIN, + 0, + 0, + 0, + SK_PNMI_RW, Asf, 0}, + {OID_SKGE_ASF_WD_TIME_MAX, + 0, + 0, + 0, + SK_PNMI_RW, Asf, 0}, + {OID_SKGE_ASF_HB_CAP, + 0, + 0, + 0, + SK_PNMI_RW, Asf, 0}, + {OID_SKGE_ASF_WD_TIMER_RES, + 0, + 0, + 0, + SK_PNMI_RW, Asf, 0}, + {OID_SKGE_ASF_GUID, + 0, + 0, + 0, + SK_PNMI_RW, Asf, 0}, + {OID_SKGE_ASF_KEY_OP, + 0, + 0, + 0, + SK_PNMI_RW, Asf, 0}, + {OID_SKGE_ASF_KEY_ADM, + 0, + 0, + 0, + SK_PNMI_RW, Asf, 0}, + {OID_SKGE_ASF_KEY_GEN, + 0, + 0, + 0, + SK_PNMI_RW, Asf, 0}, + {OID_SKGE_ASF_CAP, + 0, + 0, + 0, + SK_PNMI_RW, Asf, 0}, + {OID_SKGE_ASF_PAR_1, + 0, + 0, + 0, + SK_PNMI_RW, Asf, 0}, + {OID_SKGE_ASF_OVERALL_OID, + 0, + 0, + 0, + SK_PNMI_RW, Asf, 0}, + {OID_SKGE_ASF_FWVER_OID, + 0, + 0, + 0, + SK_PNMI_RO, Asf, 0}, + {OID_SKGE_ASF_ACPI_OID, + 0, + 0, + 0, + SK_PNMI_RO, Asf, 0}, + {OID_SKGE_ASF_SMBUS_OID, + 0, + 0, + 0, + SK_PNMI_RO, Asf, 0}, +#endif /* SK_ASF */ + {OID_SKGE_MDB_VERSION, + 1, + 0, + SK_PNMI_MAI_OFF(MgmtDBVersion), + SK_PNMI_RO, General, 0}, + {OID_SKGE_SUPPORTED_LIST, + 0, + 0, + 0, + SK_PNMI_RO, General, 0}, + {OID_SKGE_ALL_DATA, + 0, + 0, + 0, + SK_PNMI_RW, OidStruct, 0}, + {OID_SKGE_VPD_FREE_BYTES, + 1, + 0, + SK_PNMI_MAI_OFF(VpdFreeBytes), + SK_PNMI_RO, Vpd, 0}, + {OID_SKGE_VPD_ENTRIES_LIST, + 1, + 0, + SK_PNMI_MAI_OFF(VpdEntriesList), + SK_PNMI_RO, Vpd, 0}, + {OID_SKGE_VPD_ENTRIES_NUMBER, + 1, + 0, + SK_PNMI_MAI_OFF(VpdEntriesNumber), + SK_PNMI_RO, Vpd, 0}, + {OID_SKGE_VPD_KEY, + SK_PNMI_VPD_ENTRIES, + sizeof(SK_PNMI_VPD), + SK_PNMI_OFF(Vpd) + SK_PNMI_VPD_OFF(VpdKey), + SK_PNMI_RO, Vpd, 0}, + {OID_SKGE_VPD_VALUE, + SK_PNMI_VPD_ENTRIES, + sizeof(SK_PNMI_VPD), + SK_PNMI_OFF(Vpd) + SK_PNMI_VPD_OFF(VpdValue), + SK_PNMI_RO, Vpd, 0}, + {OID_SKGE_VPD_ACCESS, + SK_PNMI_VPD_ENTRIES, + sizeof(SK_PNMI_VPD), + SK_PNMI_OFF(Vpd) + SK_PNMI_VPD_OFF(VpdAccess), + SK_PNMI_RO, Vpd, 0}, + {OID_SKGE_VPD_ACTION, + SK_PNMI_VPD_ENTRIES, + sizeof(SK_PNMI_VPD), + SK_PNMI_OFF(Vpd) + SK_PNMI_VPD_OFF(VpdAction), + SK_PNMI_RW, Vpd, 0}, + {OID_SKGE_PORT_NUMBER, + 1, + 0, + SK_PNMI_MAI_OFF(PortNumber), + SK_PNMI_RO, General, 0}, + {OID_SKGE_DEVICE_TYPE, + 1, + 0, + SK_PNMI_MAI_OFF(DeviceType), + SK_PNMI_RO, General, 0}, + {OID_SKGE_DRIVER_DESCR, + 1, + 0, + SK_PNMI_MAI_OFF(DriverDescr), + SK_PNMI_RO, General, 0}, + {OID_SKGE_DRIVER_VERSION, + 1, + 0, + SK_PNMI_MAI_OFF(DriverVersion), + SK_PNMI_RO, General, 0}, + {OID_SKGE_DRIVER_RELDATE, + 1, + 0, + SK_PNMI_MAI_OFF(DriverReleaseDate), + SK_PNMI_RO, General, 0}, + {OID_SKGE_DRIVER_FILENAME, + 1, + 0, + SK_PNMI_MAI_OFF(DriverFileName), + SK_PNMI_RO, General, 0}, + {OID_SKGE_HW_DESCR, + 1, + 0, + SK_PNMI_MAI_OFF(HwDescr), + SK_PNMI_RO, General, 0}, + {OID_SKGE_HW_VERSION, + 1, + 0, + SK_PNMI_MAI_OFF(HwVersion), + SK_PNMI_RO, General, 0}, + {OID_SKGE_CHIPSET, + 1, + 0, + SK_PNMI_MAI_OFF(Chipset), + SK_PNMI_RO, General, 0}, + {OID_SKGE_CHIPID, + 1, + 0, + SK_PNMI_MAI_OFF(ChipId), + SK_PNMI_RO, General, 0}, + {OID_SKGE_RAMSIZE, + 1, + 0, + SK_PNMI_MAI_OFF(RamSize), + SK_PNMI_RO, General, 0}, + {OID_SKGE_VAUXAVAIL, + 1, + 0, + SK_PNMI_MAI_OFF(VauxAvail), + SK_PNMI_RO, General, 0}, + {OID_SKGE_ACTION, + 1, + 0, + SK_PNMI_MAI_OFF(Action), + SK_PNMI_RW, Perform, 0}, + {OID_SKGE_RESULT, + 1, + 0, + SK_PNMI_MAI_OFF(TestResult), + SK_PNMI_RO, General, 0}, + {OID_SKGE_BUS_TYPE, + 1, + 0, + SK_PNMI_MAI_OFF(BusType), + SK_PNMI_RO, General, 0}, + {OID_SKGE_BUS_SPEED, + 1, + 0, + SK_PNMI_MAI_OFF(BusSpeed), + SK_PNMI_RO, General, 0}, + {OID_SKGE_BUS_WIDTH, + 1, + 0, + SK_PNMI_MAI_OFF(BusWidth), + SK_PNMI_RO, General, 0}, + {OID_SKGE_TX_SW_QUEUE_LEN, + 1, + 0, + SK_PNMI_MAI_OFF(TxSwQueueLen), + SK_PNMI_RO, General, 0}, + {OID_SKGE_TX_SW_QUEUE_MAX, + 1, + 0, + SK_PNMI_MAI_OFF(TxSwQueueMax), + SK_PNMI_RO, General, 0}, + {OID_SKGE_TX_RETRY, + 1, + 0, + SK_PNMI_MAI_OFF(TxRetryCts), + SK_PNMI_RO, General, 0}, + {OID_SKGE_RX_INTR_CTS, + 1, + 0, + SK_PNMI_MAI_OFF(RxIntrCts), + SK_PNMI_RO, General, 0}, + {OID_SKGE_TX_INTR_CTS, + 1, + 0, + SK_PNMI_MAI_OFF(TxIntrCts), + SK_PNMI_RO, General, 0}, + {OID_SKGE_RX_NO_BUF_CTS, + 1, + 0, + SK_PNMI_MAI_OFF(RxNoBufCts), + SK_PNMI_RO, General, 0}, + {OID_SKGE_TX_NO_BUF_CTS, + 1, + 0, + SK_PNMI_MAI_OFF(TxNoBufCts), + SK_PNMI_RO, General, 0}, + {OID_SKGE_TX_USED_DESCR_NO, + 1, + 0, + SK_PNMI_MAI_OFF(TxUsedDescrNo), + SK_PNMI_RO, General, 0}, + {OID_SKGE_RX_DELIVERED_CTS, + 1, + 0, + SK_PNMI_MAI_OFF(RxDeliveredCts), + SK_PNMI_RO, General, 0}, + {OID_SKGE_RX_OCTETS_DELIV_CTS, + 1, + 0, + SK_PNMI_MAI_OFF(RxOctetsDeliveredCts), + SK_PNMI_RO, General, 0}, + {OID_SKGE_RX_HW_ERROR_CTS, + 1, + 0, + SK_PNMI_MAI_OFF(RxHwErrorsCts), + SK_PNMI_RO, General, 0}, + {OID_SKGE_TX_HW_ERROR_CTS, + 1, + 0, + SK_PNMI_MAI_OFF(TxHwErrorsCts), + SK_PNMI_RO, General, 0}, + {OID_SKGE_IN_ERRORS_CTS, + 1, + 0, + SK_PNMI_MAI_OFF(InErrorsCts), + SK_PNMI_RO, General, 0}, + {OID_SKGE_OUT_ERROR_CTS, + 1, + 0, + SK_PNMI_MAI_OFF(OutErrorsCts), + SK_PNMI_RO, General, 0}, + {OID_SKGE_ERR_RECOVERY_CTS, + 1, + 0, + SK_PNMI_MAI_OFF(ErrRecoveryCts), + SK_PNMI_RO, General, 0}, + {OID_SKGE_SYSUPTIME, + 1, + 0, + SK_PNMI_MAI_OFF(SysUpTime), + SK_PNMI_RO, General, 0}, + {OID_SKGE_SENSOR_NUMBER, + 1, + 0, + SK_PNMI_MAI_OFF(SensorNumber), + SK_PNMI_RO, General, 0}, + {OID_SKGE_SENSOR_INDEX, + SK_PNMI_SENSOR_ENTRIES, + sizeof(SK_PNMI_SENSOR), + SK_PNMI_OFF(Sensor) + SK_PNMI_SEN_OFF(SensorIndex), + SK_PNMI_RO, SensorStat, 0}, + {OID_SKGE_SENSOR_DESCR, + SK_PNMI_SENSOR_ENTRIES, + sizeof(SK_PNMI_SENSOR), + SK_PNMI_OFF(Sensor) + SK_PNMI_SEN_OFF(SensorDescr), + SK_PNMI_RO, SensorStat, 0}, + {OID_SKGE_SENSOR_TYPE, + SK_PNMI_SENSOR_ENTRIES, + sizeof(SK_PNMI_SENSOR), + SK_PNMI_OFF(Sensor) + SK_PNMI_SEN_OFF(SensorType), + SK_PNMI_RO, SensorStat, 0}, + {OID_SKGE_SENSOR_VALUE, + SK_PNMI_SENSOR_ENTRIES, + sizeof(SK_PNMI_SENSOR), + SK_PNMI_OFF(Sensor) + SK_PNMI_SEN_OFF(SensorValue), + SK_PNMI_RO, SensorStat, 0}, + {OID_SKGE_SENSOR_WAR_THRES_LOW, + SK_PNMI_SENSOR_ENTRIES, + sizeof(SK_PNMI_SENSOR), + SK_PNMI_OFF(Sensor) + SK_PNMI_SEN_OFF(SensorWarningThresholdLow), + SK_PNMI_RO, SensorStat, 0}, + {OID_SKGE_SENSOR_WAR_THRES_UPP, + SK_PNMI_SENSOR_ENTRIES, + sizeof(SK_PNMI_SENSOR), + SK_PNMI_OFF(Sensor) + SK_PNMI_SEN_OFF(SensorWarningThresholdHigh), + SK_PNMI_RO, SensorStat, 0}, + {OID_SKGE_SENSOR_ERR_THRES_LOW, + SK_PNMI_SENSOR_ENTRIES, + sizeof(SK_PNMI_SENSOR), + SK_PNMI_OFF(Sensor) + SK_PNMI_SEN_OFF(SensorErrorThresholdLow), + SK_PNMI_RO, SensorStat, 0}, + {OID_SKGE_SENSOR_ERR_THRES_UPP, + SK_PNMI_SENSOR_ENTRIES, + sizeof(SK_PNMI_SENSOR), + SK_PNMI_OFF(Sensor) + SK_PNMI_SEN_OFF(SensorErrorThresholdHigh), + SK_PNMI_RO, SensorStat, 0}, + {OID_SKGE_SENSOR_STATUS, + SK_PNMI_SENSOR_ENTRIES, + sizeof(SK_PNMI_SENSOR), + SK_PNMI_OFF(Sensor) + SK_PNMI_SEN_OFF(SensorStatus), + SK_PNMI_RO, SensorStat, 0}, + {OID_SKGE_SENSOR_WAR_CTS, + SK_PNMI_SENSOR_ENTRIES, + sizeof(SK_PNMI_SENSOR), + SK_PNMI_OFF(Sensor) + SK_PNMI_SEN_OFF(SensorWarningCts), + SK_PNMI_RO, SensorStat, 0}, + {OID_SKGE_SENSOR_ERR_CTS, + SK_PNMI_SENSOR_ENTRIES, + sizeof(SK_PNMI_SENSOR), + SK_PNMI_OFF(Sensor) + SK_PNMI_SEN_OFF(SensorErrorCts), + SK_PNMI_RO, SensorStat, 0}, + {OID_SKGE_SENSOR_WAR_TIME, + SK_PNMI_SENSOR_ENTRIES, + sizeof(SK_PNMI_SENSOR), + SK_PNMI_OFF(Sensor) + SK_PNMI_SEN_OFF(SensorWarningTimestamp), + SK_PNMI_RO, SensorStat, 0}, + {OID_SKGE_SENSOR_ERR_TIME, + SK_PNMI_SENSOR_ENTRIES, + sizeof(SK_PNMI_SENSOR), + SK_PNMI_OFF(Sensor) + SK_PNMI_SEN_OFF(SensorErrorTimestamp), + SK_PNMI_RO, SensorStat, 0}, + {OID_SKGE_CHKSM_NUMBER, + 1, + 0, + SK_PNMI_MAI_OFF(ChecksumNumber), + SK_PNMI_RO, General, 0}, + {OID_SKGE_CHKSM_RX_OK_CTS, + SKCS_NUM_PROTOCOLS, + sizeof(SK_PNMI_CHECKSUM), + SK_PNMI_OFF(Checksum) + SK_PNMI_CHK_OFF(ChecksumRxOkCts), + SK_PNMI_RO, CsumStat, 0}, + {OID_SKGE_CHKSM_RX_UNABLE_CTS, + SKCS_NUM_PROTOCOLS, + sizeof(SK_PNMI_CHECKSUM), + SK_PNMI_OFF(Checksum) + SK_PNMI_CHK_OFF(ChecksumRxUnableCts), + SK_PNMI_RO, CsumStat, 0}, + {OID_SKGE_CHKSM_RX_ERR_CTS, + SKCS_NUM_PROTOCOLS, + sizeof(SK_PNMI_CHECKSUM), + SK_PNMI_OFF(Checksum) + SK_PNMI_CHK_OFF(ChecksumRxErrCts), + SK_PNMI_RO, CsumStat, 0}, + {OID_SKGE_CHKSM_TX_OK_CTS, + SKCS_NUM_PROTOCOLS, + sizeof(SK_PNMI_CHECKSUM), + SK_PNMI_OFF(Checksum) + SK_PNMI_CHK_OFF(ChecksumTxOkCts), + SK_PNMI_RO, CsumStat, 0}, + {OID_SKGE_CHKSM_TX_UNABLE_CTS, + SKCS_NUM_PROTOCOLS, + sizeof(SK_PNMI_CHECKSUM), + SK_PNMI_OFF(Checksum) + SK_PNMI_CHK_OFF(ChecksumTxUnableCts), + SK_PNMI_RO, CsumStat, 0}, + {OID_SKGE_STAT_TX, + SK_PNMI_MAC_ENTRIES, + sizeof(SK_PNMI_STAT), + SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTxOkCts), + SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX}, + {OID_SKGE_STAT_TX_OCTETS, + SK_PNMI_MAC_ENTRIES, + sizeof(SK_PNMI_STAT), + SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTxOctetsOkCts), + SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX_OCTET}, + {OID_SKGE_STAT_TX_BROADCAST, + SK_PNMI_MAC_ENTRIES, + sizeof(SK_PNMI_STAT), + SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTxBroadcastOkCts), + SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX_BROADCAST}, + {OID_SKGE_STAT_TX_MULTICAST, + SK_PNMI_MAC_ENTRIES, + sizeof(SK_PNMI_STAT), + SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTxMulticastOkCts), + SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX_MULTICAST}, + {OID_SKGE_STAT_TX_UNICAST, + SK_PNMI_MAC_ENTRIES, + sizeof(SK_PNMI_STAT), + SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTxUnicastOkCts), + SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX_UNICAST}, + {OID_SKGE_STAT_TX_LONGFRAMES, + SK_PNMI_MAC_ENTRIES, + sizeof(SK_PNMI_STAT), + SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTxLongFramesCts), + SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX_LONGFRAMES}, + {OID_SKGE_STAT_TX_BURST, + SK_PNMI_MAC_ENTRIES, + sizeof(SK_PNMI_STAT), + SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTxBurstCts), + SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX_BURST}, + {OID_SKGE_STAT_TX_PFLOWC, + SK_PNMI_MAC_ENTRIES, + sizeof(SK_PNMI_STAT), + SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTxPauseMacCtrlCts), + SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX_PMACC}, + {OID_SKGE_STAT_TX_FLOWC, + SK_PNMI_MAC_ENTRIES, + sizeof(SK_PNMI_STAT), + SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTxMacCtrlCts), + SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX_MACC}, + {OID_SKGE_STAT_TX_SINGLE_COL, + SK_PNMI_MAC_ENTRIES, + sizeof(SK_PNMI_STAT), + SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTxSingleCollisionCts), + SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX_SINGLE_COL}, + {OID_SKGE_STAT_TX_MULTI_COL, + SK_PNMI_MAC_ENTRIES, + sizeof(SK_PNMI_STAT), + SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTxMultipleCollisionCts), + SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX_MULTI_COL}, + {OID_SKGE_STAT_TX_EXCESS_COL, + SK_PNMI_MAC_ENTRIES, + sizeof(SK_PNMI_STAT), + SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTxExcessiveCollisionCts), + SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX_EXCESS_COL}, + {OID_SKGE_STAT_TX_LATE_COL, + SK_PNMI_MAC_ENTRIES, + sizeof(SK_PNMI_STAT), + SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTxLateCollisionCts), + SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX_LATE_COL}, + {OID_SKGE_STAT_TX_DEFFERAL, + SK_PNMI_MAC_ENTRIES, + sizeof(SK_PNMI_STAT), + SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTxDeferralCts), + SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX_DEFFERAL}, + {OID_SKGE_STAT_TX_EXCESS_DEF, + SK_PNMI_MAC_ENTRIES, + sizeof(SK_PNMI_STAT), + SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTxExcessiveDeferralCts), + SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX_EXCESS_DEF}, + {OID_SKGE_STAT_TX_UNDERRUN, + SK_PNMI_MAC_ENTRIES, + sizeof(SK_PNMI_STAT), + SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTxFifoUnderrunCts), + SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX_UNDERRUN}, + {OID_SKGE_STAT_TX_CARRIER, + SK_PNMI_MAC_ENTRIES, + sizeof(SK_PNMI_STAT), + SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTxCarrierCts), + SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX_CARRIER}, +/* {OID_SKGE_STAT_TX_UTIL, + SK_PNMI_MAC_ENTRIES, + sizeof(SK_PNMI_STAT), + SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTxUtilization), + SK_PNMI_RO, MacPrivateStat, (SK_U16)(-1)}, */ + {OID_SKGE_STAT_TX_64, + SK_PNMI_MAC_ENTRIES, + sizeof(SK_PNMI_STAT), + SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTx64Cts), + SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX_64}, + {OID_SKGE_STAT_TX_127, + SK_PNMI_MAC_ENTRIES, + sizeof(SK_PNMI_STAT), + SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTx127Cts), + SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX_127}, + {OID_SKGE_STAT_TX_255, + SK_PNMI_MAC_ENTRIES, + sizeof(SK_PNMI_STAT), + SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTx255Cts), + SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX_255}, + {OID_SKGE_STAT_TX_511, + SK_PNMI_MAC_ENTRIES, + sizeof(SK_PNMI_STAT), + SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTx511Cts), + SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX_511}, + {OID_SKGE_STAT_TX_1023, + SK_PNMI_MAC_ENTRIES, + sizeof(SK_PNMI_STAT), + SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTx1023Cts), + SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX_1023}, + {OID_SKGE_STAT_TX_MAX, + SK_PNMI_MAC_ENTRIES, + sizeof(SK_PNMI_STAT), + SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTxMaxCts), + SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX_MAX}, + {OID_SKGE_STAT_TX_SYNC, + SK_PNMI_MAC_ENTRIES, + sizeof(SK_PNMI_STAT), + SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTxSyncCts), + SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX_SYNC}, + {OID_SKGE_STAT_TX_SYNC_OCTETS, + SK_PNMI_MAC_ENTRIES, + sizeof(SK_PNMI_STAT), + SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatTxSyncOctetsCts), + SK_PNMI_RO, MacPrivateStat, SK_PNMI_HTX_SYNC_OCTET}, + {OID_SKGE_STAT_RX, + SK_PNMI_MAC_ENTRIES, + sizeof(SK_PNMI_STAT), + SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxOkCts), + SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX}, + {OID_SKGE_STAT_RX_OCTETS, + SK_PNMI_MAC_ENTRIES, + sizeof(SK_PNMI_STAT), + SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxOctetsOkCts), + SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_OCTET}, + {OID_SKGE_STAT_RX_BROADCAST, + SK_PNMI_MAC_ENTRIES, + sizeof(SK_PNMI_STAT), + SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxBroadcastOkCts), + SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_BROADCAST}, + {OID_SKGE_STAT_RX_MULTICAST, + SK_PNMI_MAC_ENTRIES, + sizeof(SK_PNMI_STAT), + SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxMulticastOkCts), + SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_MULTICAST}, + {OID_SKGE_STAT_RX_UNICAST, + SK_PNMI_MAC_ENTRIES, + sizeof(SK_PNMI_STAT), + SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxUnicastOkCts), + SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_UNICAST}, + {OID_SKGE_STAT_RX_LONGFRAMES, + SK_PNMI_MAC_ENTRIES, + sizeof(SK_PNMI_STAT), + SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxLongFramesCts), + SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_LONGFRAMES}, + {OID_SKGE_STAT_RX_PFLOWC, + SK_PNMI_MAC_ENTRIES, + sizeof(SK_PNMI_STAT), + SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxPauseMacCtrlCts), + SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_PMACC}, + {OID_SKGE_STAT_RX_FLOWC, + SK_PNMI_MAC_ENTRIES, + sizeof(SK_PNMI_STAT), + SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxMacCtrlCts), + SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_MACC}, + {OID_SKGE_STAT_RX_PFLOWC_ERR, + SK_PNMI_MAC_ENTRIES, + sizeof(SK_PNMI_STAT), + SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxPauseMacCtrlErrorCts), + SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_PMACC_ERR}, + {OID_SKGE_STAT_RX_FLOWC_UNKWN, + SK_PNMI_MAC_ENTRIES, + sizeof(SK_PNMI_STAT), + SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxMacCtrlUnknownCts), + SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_MACC_UNKWN}, + {OID_SKGE_STAT_RX_BURST, + SK_PNMI_MAC_ENTRIES, + sizeof(SK_PNMI_STAT), + SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxBurstCts), + SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_BURST}, + {OID_SKGE_STAT_RX_MISSED, + SK_PNMI_MAC_ENTRIES, + sizeof(SK_PNMI_STAT), + SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxMissedCts), + SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_MISSED}, + {OID_SKGE_STAT_RX_FRAMING, + SK_PNMI_MAC_ENTRIES, + sizeof(SK_PNMI_STAT), + SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxFramingCts), + SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_FRAMING}, + {OID_SKGE_STAT_RX_OVERFLOW, + SK_PNMI_MAC_ENTRIES, + sizeof(SK_PNMI_STAT), + SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxFifoOverflowCts), + SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_OVERFLOW}, + {OID_SKGE_STAT_RX_JABBER, + SK_PNMI_MAC_ENTRIES, + sizeof(SK_PNMI_STAT), + SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxJabberCts), + SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_JABBER}, + {OID_SKGE_STAT_RX_CARRIER, + SK_PNMI_MAC_ENTRIES, + sizeof(SK_PNMI_STAT), + SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxCarrierCts), + SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_CARRIER}, + {OID_SKGE_STAT_RX_IR_LENGTH, + SK_PNMI_MAC_ENTRIES, + sizeof(SK_PNMI_STAT), + SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxIRLengthCts), + SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_IRLENGTH}, + {OID_SKGE_STAT_RX_SYMBOL, + SK_PNMI_MAC_ENTRIES, + sizeof(SK_PNMI_STAT), + SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxSymbolCts), + SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_SYMBOL}, + {OID_SKGE_STAT_RX_SHORTS, + SK_PNMI_MAC_ENTRIES, + sizeof(SK_PNMI_STAT), + SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxShortsCts), + SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_SHORTS}, + {OID_SKGE_STAT_RX_RUNT, + SK_PNMI_MAC_ENTRIES, + sizeof(SK_PNMI_STAT), + SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxRuntCts), + SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_RUNT}, + {OID_SKGE_STAT_RX_CEXT, + SK_PNMI_MAC_ENTRIES, + sizeof(SK_PNMI_STAT), + SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxCextCts), + SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_CEXT}, + {OID_SKGE_STAT_RX_TOO_LONG, + SK_PNMI_MAC_ENTRIES, + sizeof(SK_PNMI_STAT), + SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxTooLongCts), + SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_TOO_LONG}, + {OID_SKGE_STAT_RX_FCS, + SK_PNMI_MAC_ENTRIES, + sizeof(SK_PNMI_STAT), + SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxFcsCts), + SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_FCS}, +/* {OID_SKGE_STAT_RX_UTIL, + SK_PNMI_MAC_ENTRIES, + sizeof(SK_PNMI_STAT), + SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxUtilization), + SK_PNMI_RO, MacPrivateStat, (SK_U16)(-1)}, */ + {OID_SKGE_STAT_RX_64, + SK_PNMI_MAC_ENTRIES, + sizeof(SK_PNMI_STAT), + SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRx64Cts), + SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_64}, + {OID_SKGE_STAT_RX_127, + SK_PNMI_MAC_ENTRIES, + sizeof(SK_PNMI_STAT), + SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRx127Cts), + SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_127}, + {OID_SKGE_STAT_RX_255, + SK_PNMI_MAC_ENTRIES, + sizeof(SK_PNMI_STAT), + SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRx255Cts), + SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_255}, + {OID_SKGE_STAT_RX_511, + SK_PNMI_MAC_ENTRIES, + sizeof(SK_PNMI_STAT), + SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRx511Cts), + SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_511}, + {OID_SKGE_STAT_RX_1023, + SK_PNMI_MAC_ENTRIES, + sizeof(SK_PNMI_STAT), + SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRx1023Cts), + SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_1023}, + {OID_SKGE_STAT_RX_MAX, + SK_PNMI_MAC_ENTRIES, + sizeof(SK_PNMI_STAT), + SK_PNMI_OFF(Stat) + SK_PNMI_STA_OFF(StatRxMaxCts), + SK_PNMI_RO, MacPrivateStat, SK_PNMI_HRX_MAX}, + {OID_SKGE_PHYS_CUR_ADDR, + SK_PNMI_MAC_ENTRIES, + sizeof(SK_PNMI_CONF), + SK_PNMI_OFF(Conf) + SK_PNMI_CNF_OFF(ConfMacCurrentAddr), + SK_PNMI_RW, Addr, 0}, + {OID_SKGE_PHYS_FAC_ADDR, + SK_PNMI_MAC_ENTRIES, + sizeof(SK_PNMI_CONF), + SK_PNMI_OFF(Conf) + SK_PNMI_CNF_OFF(ConfMacFactoryAddr), + SK_PNMI_RO, Addr, 0}, + {OID_SKGE_PMD, + SK_PNMI_MAC_ENTRIES, + sizeof(SK_PNMI_CONF), + SK_PNMI_OFF(Conf) + SK_PNMI_CNF_OFF(ConfPMD), + SK_PNMI_RO, MacPrivateConf, 0}, + {OID_SKGE_CONNECTOR, + SK_PNMI_MAC_ENTRIES, + sizeof(SK_PNMI_CONF), + SK_PNMI_OFF(Conf) + SK_PNMI_CNF_OFF(ConfConnector), + SK_PNMI_RO, MacPrivateConf, 0}, + {OID_SKGE_PHY_TYPE, + SK_PNMI_MAC_ENTRIES, + sizeof(SK_PNMI_CONF), + SK_PNMI_OFF(Conf) + SK_PNMI_CNF_OFF(ConfPhyType), + SK_PNMI_RO, MacPrivateConf, 0}, +#ifdef SK_PHY_LP_MODE + {OID_SKGE_PHY_LP_MODE, + SK_PNMI_MAC_ENTRIES, + sizeof(SK_PNMI_CONF), + SK_PNMI_OFF(Conf) + SK_PNMI_CNF_OFF(ConfPhyMode), + SK_PNMI_RW, MacPrivateConf, 0}, +#endif + {OID_SKGE_LINK_CAP, + SK_PNMI_MAC_ENTRIES, + sizeof(SK_PNMI_CONF), + SK_PNMI_OFF(Conf) + SK_PNMI_CNF_OFF(ConfLinkCapability), + SK_PNMI_RO, MacPrivateConf, 0}, + {OID_SKGE_LINK_MODE, + SK_PNMI_MAC_ENTRIES, + sizeof(SK_PNMI_CONF), + SK_PNMI_OFF(Conf) + SK_PNMI_CNF_OFF(ConfLinkMode), + SK_PNMI_RW, MacPrivateConf, 0}, + {OID_SKGE_LINK_MODE_STATUS, + SK_PNMI_MAC_ENTRIES, + sizeof(SK_PNMI_CONF), + SK_PNMI_OFF(Conf) + SK_PNMI_CNF_OFF(ConfLinkModeStatus), + SK_PNMI_RO, MacPrivateConf, 0}, + {OID_SKGE_LINK_STATUS, + SK_PNMI_MAC_ENTRIES, + sizeof(SK_PNMI_CONF), + SK_PNMI_OFF(Conf) + SK_PNMI_CNF_OFF(ConfLinkStatus), + SK_PNMI_RO, MacPrivateConf, 0}, + {OID_SKGE_FLOWCTRL_CAP, + SK_PNMI_MAC_ENTRIES, + sizeof(SK_PNMI_CONF), + SK_PNMI_OFF(Conf) + SK_PNMI_CNF_OFF(ConfFlowCtrlCapability), + SK_PNMI_RO, MacPrivateConf, 0}, + {OID_SKGE_FLOWCTRL_MODE, + SK_PNMI_MAC_ENTRIES, + sizeof(SK_PNMI_CONF), + SK_PNMI_OFF(Conf) + SK_PNMI_CNF_OFF(ConfFlowCtrlMode), + SK_PNMI_RW, MacPrivateConf, 0}, + {OID_SKGE_FLOWCTRL_STATUS, + SK_PNMI_MAC_ENTRIES, + sizeof(SK_PNMI_CONF), + SK_PNMI_OFF(Conf) + SK_PNMI_CNF_OFF(ConfFlowCtrlStatus), + SK_PNMI_RO, MacPrivateConf, 0}, + {OID_SKGE_PHY_OPERATION_CAP, + SK_PNMI_MAC_ENTRIES, + sizeof(SK_PNMI_CONF), + SK_PNMI_OFF(Conf) + SK_PNMI_CNF_OFF(ConfPhyOperationCapability), + SK_PNMI_RO, MacPrivateConf, 0}, + {OID_SKGE_PHY_OPERATION_MODE, + SK_PNMI_MAC_ENTRIES, + sizeof(SK_PNMI_CONF), + SK_PNMI_OFF(Conf) + SK_PNMI_CNF_OFF(ConfPhyOperationMode), + SK_PNMI_RW, MacPrivateConf, 0}, + {OID_SKGE_PHY_OPERATION_STATUS, + SK_PNMI_MAC_ENTRIES, + sizeof(SK_PNMI_CONF), + SK_PNMI_OFF(Conf) + SK_PNMI_CNF_OFF(ConfPhyOperationStatus), + SK_PNMI_RO, MacPrivateConf, 0}, + {OID_SKGE_SPEED_CAP, + SK_PNMI_MAC_ENTRIES, + sizeof(SK_PNMI_CONF), + SK_PNMI_OFF(Conf) + SK_PNMI_CNF_OFF(ConfSpeedCapability), + SK_PNMI_RO, MacPrivateConf, 0}, + {OID_SKGE_SPEED_MODE, + SK_PNMI_MAC_ENTRIES, + sizeof(SK_PNMI_CONF), + SK_PNMI_OFF(Conf) + SK_PNMI_CNF_OFF(ConfSpeedMode), + SK_PNMI_RW, MacPrivateConf, 0}, + {OID_SKGE_SPEED_STATUS, + SK_PNMI_MAC_ENTRIES, + sizeof(SK_PNMI_CONF), + SK_PNMI_OFF(Conf) + SK_PNMI_CNF_OFF(ConfSpeedStatus), + SK_PNMI_RO, MacPrivateConf, 0}, + {OID_SKGE_TRAP, + 1, + 0, + SK_PNMI_MAI_OFF(Trap), + SK_PNMI_RO, General, 0}, + {OID_SKGE_TRAP_NUMBER, + 1, + 0, + SK_PNMI_MAI_OFF(TrapNumber), + SK_PNMI_RO, General, 0}, + {OID_SKGE_RLMT_MODE, + 1, + 0, + SK_PNMI_MAI_OFF(RlmtMode), + SK_PNMI_RW, Rlmt, 0}, + {OID_SKGE_RLMT_PORT_NUMBER, + 1, + 0, + SK_PNMI_MAI_OFF(RlmtPortNumber), + SK_PNMI_RO, Rlmt, 0}, + {OID_SKGE_RLMT_PORT_ACTIVE, + 1, + 0, + SK_PNMI_MAI_OFF(RlmtPortActive), + SK_PNMI_RO, Rlmt, 0}, + {OID_SKGE_RLMT_PORT_PREFERRED, + 1, + 0, + SK_PNMI_MAI_OFF(RlmtPortPreferred), + SK_PNMI_RW, Rlmt, 0}, + {OID_SKGE_RLMT_CHANGE_CTS, + 1, + 0, + SK_PNMI_MAI_OFF(RlmtChangeCts), + SK_PNMI_RO, Rlmt, 0}, + {OID_SKGE_RLMT_CHANGE_TIME, + 1, + 0, + SK_PNMI_MAI_OFF(RlmtChangeTime), + SK_PNMI_RO, Rlmt, 0}, + {OID_SKGE_RLMT_CHANGE_ESTIM, + 1, + 0, + SK_PNMI_MAI_OFF(RlmtChangeEstimate), + SK_PNMI_RO, Rlmt, 0}, + {OID_SKGE_RLMT_CHANGE_THRES, + 1, + 0, + SK_PNMI_MAI_OFF(RlmtChangeThreshold), + SK_PNMI_RW, Rlmt, 0}, + {OID_SKGE_RLMT_PORT_INDEX, + SK_PNMI_MAC_ENTRIES, + sizeof(SK_PNMI_RLMT), + SK_PNMI_OFF(Rlmt) + SK_PNMI_RLM_OFF(RlmtIndex), + SK_PNMI_RO, RlmtStat, 0}, + {OID_SKGE_RLMT_STATUS, + SK_PNMI_MAC_ENTRIES, + sizeof(SK_PNMI_RLMT), + SK_PNMI_OFF(Rlmt) + SK_PNMI_RLM_OFF(RlmtStatus), + SK_PNMI_RO, RlmtStat, 0}, + {OID_SKGE_RLMT_TX_HELLO_CTS, + SK_PNMI_MAC_ENTRIES, + sizeof(SK_PNMI_RLMT), + SK_PNMI_OFF(Rlmt) + SK_PNMI_RLM_OFF(RlmtTxHelloCts), + SK_PNMI_RO, RlmtStat, 0}, + {OID_SKGE_RLMT_RX_HELLO_CTS, + SK_PNMI_MAC_ENTRIES, + sizeof(SK_PNMI_RLMT), + SK_PNMI_OFF(Rlmt) + SK_PNMI_RLM_OFF(RlmtRxHelloCts), + SK_PNMI_RO, RlmtStat, 0}, + {OID_SKGE_RLMT_TX_SP_REQ_CTS, + SK_PNMI_MAC_ENTRIES, + sizeof(SK_PNMI_RLMT), + SK_PNMI_OFF(Rlmt) + SK_PNMI_RLM_OFF(RlmtTxSpHelloReqCts), + SK_PNMI_RO, RlmtStat, 0}, + {OID_SKGE_RLMT_RX_SP_CTS, + SK_PNMI_MAC_ENTRIES, + sizeof(SK_PNMI_RLMT), + SK_PNMI_OFF(Rlmt) + SK_PNMI_RLM_OFF(RlmtRxSpHelloCts), + SK_PNMI_RO, RlmtStat, 0}, + {OID_SKGE_RLMT_MONITOR_NUMBER, + 1, + 0, + SK_PNMI_MAI_OFF(RlmtMonitorNumber), + SK_PNMI_RO, General, 0}, + {OID_SKGE_RLMT_MONITOR_INDEX, + SK_PNMI_MONITOR_ENTRIES, + sizeof(SK_PNMI_RLMT_MONITOR), + SK_PNMI_OFF(RlmtMonitor) + SK_PNMI_MON_OFF(RlmtMonitorIndex), + SK_PNMI_RO, Monitor, 0}, + {OID_SKGE_RLMT_MONITOR_ADDR, + SK_PNMI_MONITOR_ENTRIES, + sizeof(SK_PNMI_RLMT_MONITOR), + SK_PNMI_OFF(RlmtMonitor) + SK_PNMI_MON_OFF(RlmtMonitorAddr), + SK_PNMI_RO, Monitor, 0}, + {OID_SKGE_RLMT_MONITOR_ERRS, + SK_PNMI_MONITOR_ENTRIES, + sizeof(SK_PNMI_RLMT_MONITOR), + SK_PNMI_OFF(RlmtMonitor) + SK_PNMI_MON_OFF(RlmtMonitorErrorCts), + SK_PNMI_RO, Monitor, 0}, + {OID_SKGE_RLMT_MONITOR_TIMESTAMP, + SK_PNMI_MONITOR_ENTRIES, + sizeof(SK_PNMI_RLMT_MONITOR), + SK_PNMI_OFF(RlmtMonitor) + SK_PNMI_MON_OFF(RlmtMonitorTimestamp), + SK_PNMI_RO, Monitor, 0}, + {OID_SKGE_RLMT_MONITOR_ADMIN, + SK_PNMI_MONITOR_ENTRIES, + sizeof(SK_PNMI_RLMT_MONITOR), + SK_PNMI_OFF(RlmtMonitor) + SK_PNMI_MON_OFF(RlmtMonitorAdmin), + SK_PNMI_RW, Monitor, 0}, + {OID_SKGE_MTU, + 1, + 0, + SK_PNMI_MAI_OFF(MtuSize), + SK_PNMI_RW, MacPrivateConf, 0}, + {OID_SKGE_VCT_GET, + 0, + 0, + 0, + SK_PNMI_RO, Vct, 0}, + {OID_SKGE_VCT_SET, + 0, + 0, + 0, + SK_PNMI_WO, Vct, 0}, + {OID_SKGE_VCT_STATUS, + 0, + 0, + 0, + SK_PNMI_RO, Vct, 0}, + {OID_SKGE_VCT_CAPABILITIES, + 0, + 0, + 0, + SK_PNMI_RO, Vct, 0}, + {OID_SKGE_BOARDLEVEL, + 0, + 0, + 0, + SK_PNMI_RO, General, 0}, +}; + diff -urN linux-2.4.32-600/drivers/net/sk98lin/skgepnmi.c linux-2.4.32-600-sk98_831/drivers/net/sk98lin/skgepnmi.c --- linux-2.4.32-600/drivers/net/sk98lin/skgepnmi.c Sat Mar 20 10:08:19 2004 +++ linux-2.4.32-600-sk98_831/drivers/net/sk98lin/skgepnmi.c Sun Feb 26 11:13:02 2006 @@ -1,8356 +1,8351 @@ -/***************************************************************************** - * - * Name: skgepnmi.c - * Project: GEnesis, PCI Gigabit Ethernet Adapter - * Purpose: Private Network Management Interface - * - ****************************************************************************/ - -/****************************************************************************** - * - * (C)Copyright 1998-2002 SysKonnect GmbH. - * (C)Copyright 2002-2003 Marvell. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * The information in this file is provided "AS IS" without warranty. - * - ******************************************************************************/ - -#ifndef _lint -static const char SysKonnectFileId[] = - "@(#) $Id: skgepnmi.c,v 1.111 2003/09/15 13:35:35 tschilli Exp $ (C) Marvell."; -#endif /* !_lint */ - -#include "h/skdrv1st.h" -#include "h/sktypes.h" -#include "h/xmac_ii.h" -#include "h/skdebug.h" -#include "h/skqueue.h" -#include "h/skgepnmi.h" -#include "h/skgesirq.h" -#include "h/skcsum.h" -#include "h/skvpd.h" -#include "h/skgehw.h" -#include "h/skgeinit.h" -#include "h/skdrv2nd.h" -#include "h/skgepnm2.h" -#ifdef SK_POWER_MGMT -#include "h/skgepmgt.h" -#endif -/* defines *******************************************************************/ - -#ifndef DEBUG -#define PNMI_STATIC static -#else /* DEBUG */ -#define PNMI_STATIC -#endif /* DEBUG */ - -/* - * Public Function prototypes - */ -int SkPnmiInit(SK_AC *pAC, SK_IOC IoC, int level); -int SkPnmiGetVar(SK_AC *pAC, SK_IOC IoC, SK_U32 Id, void *pBuf, - unsigned int *pLen, SK_U32 Instance, SK_U32 NetIndex); -int SkPnmiPreSetVar(SK_AC *pAC, SK_IOC IoC, SK_U32 Id, void *pBuf, - unsigned int *pLen, SK_U32 Instance, SK_U32 NetIndex); -int SkPnmiSetVar(SK_AC *pAC, SK_IOC IoC, SK_U32 Id, void *pBuf, - unsigned int *pLen, SK_U32 Instance, SK_U32 NetIndex); -int SkPnmiGetStruct(SK_AC *pAC, SK_IOC IoC, void *pBuf, - unsigned int *pLen, SK_U32 NetIndex); -int SkPnmiPreSetStruct(SK_AC *pAC, SK_IOC IoC, void *pBuf, - unsigned int *pLen, SK_U32 NetIndex); -int SkPnmiSetStruct(SK_AC *pAC, SK_IOC IoC, void *pBuf, - unsigned int *pLen, SK_U32 NetIndex); -int SkPnmiEvent(SK_AC *pAC, SK_IOC IoC, SK_U32 Event, SK_EVPARA Param); -int SkPnmiGenIoctl(SK_AC *pAC, SK_IOC IoC, void * pBuf, - unsigned int * pLen, SK_U32 NetIndex); - - -/* - * Private Function prototypes - */ - -PNMI_STATIC SK_U8 CalculateLinkModeStatus(SK_AC *pAC, SK_IOC IoC, unsigned int - PhysPortIndex); -PNMI_STATIC SK_U8 CalculateLinkStatus(SK_AC *pAC, SK_IOC IoC, unsigned int - PhysPortIndex); -PNMI_STATIC void CopyMac(char *pDst, SK_MAC_ADDR *pMac); -PNMI_STATIC void CopyTrapQueue(SK_AC *pAC, char *pDstBuf); -PNMI_STATIC SK_U64 GetPhysStatVal(SK_AC *pAC, SK_IOC IoC, - unsigned int PhysPortIndex, unsigned int StatIndex); -PNMI_STATIC SK_U64 GetStatVal(SK_AC *pAC, SK_IOC IoC, unsigned int LogPortIndex, - unsigned int StatIndex, SK_U32 NetIndex); -PNMI_STATIC char* GetTrapEntry(SK_AC *pAC, SK_U32 TrapId, unsigned int Size); -PNMI_STATIC void GetTrapQueueLen(SK_AC *pAC, unsigned int *pLen, - unsigned int *pEntries); -PNMI_STATIC int GetVpdKeyArr(SK_AC *pAC, SK_IOC IoC, char *pKeyArr, - unsigned int KeyArrLen, unsigned int *pKeyNo); -PNMI_STATIC int LookupId(SK_U32 Id); -PNMI_STATIC int MacUpdate(SK_AC *pAC, SK_IOC IoC, unsigned int FirstMac, - unsigned int LastMac); -PNMI_STATIC int PnmiStruct(SK_AC *pAC, SK_IOC IoC, int Action, char *pBuf, - unsigned int *pLen, SK_U32 NetIndex); -PNMI_STATIC int PnmiVar(SK_AC *pAC, SK_IOC IoC, int Action, SK_U32 Id, - char *pBuf, unsigned int *pLen, SK_U32 Instance, SK_U32 NetIndex); -PNMI_STATIC void QueueRlmtNewMacTrap(SK_AC *pAC, unsigned int ActiveMac); -PNMI_STATIC void QueueRlmtPortTrap(SK_AC *pAC, SK_U32 TrapId, - unsigned int PortIndex); -PNMI_STATIC void QueueSensorTrap(SK_AC *pAC, SK_U32 TrapId, - unsigned int SensorIndex); -PNMI_STATIC void QueueSimpleTrap(SK_AC *pAC, SK_U32 TrapId); -PNMI_STATIC void ResetCounter(SK_AC *pAC, SK_IOC IoC, SK_U32 NetIndex); -PNMI_STATIC int RlmtUpdate(SK_AC *pAC, SK_IOC IoC, SK_U32 NetIndex); -PNMI_STATIC int SirqUpdate(SK_AC *pAC, SK_IOC IoC); -PNMI_STATIC void VirtualConf(SK_AC *pAC, SK_IOC IoC, SK_U32 Id, char *pBuf); -PNMI_STATIC int Vct(SK_AC *pAC, SK_IOC IoC, int Action, SK_U32 Id, char *pBuf, - unsigned int *pLen, SK_U32 Instance, unsigned int TableIndex, SK_U32 NetIndex); -PNMI_STATIC void CheckVctStatus(SK_AC *, SK_IOC, char *, SK_U32, SK_U32); - -/* - * Table to correlate OID with handler function and index to - * hardware register stored in StatAddress if applicable. - */ -#include "skgemib.c" - -/* global variables **********************************************************/ - -/* - * Overflow status register bit table and corresponding counter - * dependent on MAC type - the number relates to the size of overflow - * mask returned by the pFnMacOverflow function - */ -PNMI_STATIC const SK_U16 StatOvrflwBit[][SK_PNMI_MAC_TYPES] = { -/* Bit0 */ { SK_PNMI_HTX, SK_PNMI_HTX_UNICAST}, -/* Bit1 */ { SK_PNMI_HTX_OCTETHIGH, SK_PNMI_HTX_BROADCAST}, -/* Bit2 */ { SK_PNMI_HTX_OCTETLOW, SK_PNMI_HTX_PMACC}, -/* Bit3 */ { SK_PNMI_HTX_BROADCAST, SK_PNMI_HTX_MULTICAST}, -/* Bit4 */ { SK_PNMI_HTX_MULTICAST, SK_PNMI_HTX_OCTETLOW}, -/* Bit5 */ { SK_PNMI_HTX_UNICAST, SK_PNMI_HTX_OCTETHIGH}, -/* Bit6 */ { SK_PNMI_HTX_LONGFRAMES, SK_PNMI_HTX_64}, -/* Bit7 */ { SK_PNMI_HTX_BURST, SK_PNMI_HTX_127}, -/* Bit8 */ { SK_PNMI_HTX_PMACC, SK_PNMI_HTX_255}, -/* Bit9 */ { SK_PNMI_HTX_MACC, SK_PNMI_HTX_511}, -/* Bit10 */ { SK_PNMI_HTX_SINGLE_COL, SK_PNMI_HTX_1023}, -/* Bit11 */ { SK_PNMI_HTX_MULTI_COL, SK_PNMI_HTX_MAX}, -/* Bit12 */ { SK_PNMI_HTX_EXCESS_COL, SK_PNMI_HTX_LONGFRAMES}, -/* Bit13 */ { SK_PNMI_HTX_LATE_COL, SK_PNMI_HTX_RESERVED}, -/* Bit14 */ { SK_PNMI_HTX_DEFFERAL, SK_PNMI_HTX_COL}, -/* Bit15 */ { SK_PNMI_HTX_EXCESS_DEF, SK_PNMI_HTX_LATE_COL}, -/* Bit16 */ { SK_PNMI_HTX_UNDERRUN, SK_PNMI_HTX_EXCESS_COL}, -/* Bit17 */ { SK_PNMI_HTX_CARRIER, SK_PNMI_HTX_MULTI_COL}, -/* Bit18 */ { SK_PNMI_HTX_UTILUNDER, SK_PNMI_HTX_SINGLE_COL}, -/* Bit19 */ { SK_PNMI_HTX_UTILOVER, SK_PNMI_HTX_UNDERRUN}, -/* Bit20 */ { SK_PNMI_HTX_64, SK_PNMI_HTX_RESERVED}, -/* Bit21 */ { SK_PNMI_HTX_127, SK_PNMI_HTX_RESERVED}, -/* Bit22 */ { SK_PNMI_HTX_255, SK_PNMI_HTX_RESERVED}, -/* Bit23 */ { SK_PNMI_HTX_511, SK_PNMI_HTX_RESERVED}, -/* Bit24 */ { SK_PNMI_HTX_1023, SK_PNMI_HTX_RESERVED}, -/* Bit25 */ { SK_PNMI_HTX_MAX, SK_PNMI_HTX_RESERVED}, -/* Bit26 */ { SK_PNMI_HTX_RESERVED, SK_PNMI_HTX_RESERVED}, -/* Bit27 */ { SK_PNMI_HTX_RESERVED, SK_PNMI_HTX_RESERVED}, -/* Bit28 */ { SK_PNMI_HTX_RESERVED, SK_PNMI_HTX_RESERVED}, -/* Bit29 */ { SK_PNMI_HTX_RESERVED, SK_PNMI_HTX_RESERVED}, -/* Bit30 */ { SK_PNMI_HTX_RESERVED, SK_PNMI_HTX_RESERVED}, -/* Bit31 */ { SK_PNMI_HTX_RESERVED, SK_PNMI_HTX_RESERVED}, -/* Bit32 */ { SK_PNMI_HRX, SK_PNMI_HRX_UNICAST}, -/* Bit33 */ { SK_PNMI_HRX_OCTETHIGH, SK_PNMI_HRX_BROADCAST}, -/* Bit34 */ { SK_PNMI_HRX_OCTETLOW, SK_PNMI_HRX_PMACC}, -/* Bit35 */ { SK_PNMI_HRX_BROADCAST, SK_PNMI_HRX_MULTICAST}, -/* Bit36 */ { SK_PNMI_HRX_MULTICAST, SK_PNMI_HRX_FCS}, -/* Bit37 */ { SK_PNMI_HRX_UNICAST, SK_PNMI_HRX_RESERVED}, -/* Bit38 */ { SK_PNMI_HRX_PMACC, SK_PNMI_HRX_OCTETLOW}, -/* Bit39 */ { SK_PNMI_HRX_MACC, SK_PNMI_HRX_OCTETHIGH}, -/* Bit40 */ { SK_PNMI_HRX_PMACC_ERR, SK_PNMI_HRX_BADOCTETLOW}, -/* Bit41 */ { SK_PNMI_HRX_MACC_UNKWN, SK_PNMI_HRX_BADOCTETHIGH}, -/* Bit42 */ { SK_PNMI_HRX_BURST, SK_PNMI_HRX_UNDERSIZE}, -/* Bit43 */ { SK_PNMI_HRX_MISSED, SK_PNMI_HRX_RUNT}, -/* Bit44 */ { SK_PNMI_HRX_FRAMING, SK_PNMI_HRX_64}, -/* Bit45 */ { SK_PNMI_HRX_OVERFLOW, SK_PNMI_HRX_127}, -/* Bit46 */ { SK_PNMI_HRX_JABBER, SK_PNMI_HRX_255}, -/* Bit47 */ { SK_PNMI_HRX_CARRIER, SK_PNMI_HRX_511}, -/* Bit48 */ { SK_PNMI_HRX_IRLENGTH, SK_PNMI_HRX_1023}, -/* Bit49 */ { SK_PNMI_HRX_SYMBOL, SK_PNMI_HRX_MAX}, -/* Bit50 */ { SK_PNMI_HRX_SHORTS, SK_PNMI_HRX_LONGFRAMES}, -/* Bit51 */ { SK_PNMI_HRX_RUNT, SK_PNMI_HRX_TOO_LONG}, -/* Bit52 */ { SK_PNMI_HRX_TOO_LONG, SK_PNMI_HRX_JABBER}, -/* Bit53 */ { SK_PNMI_HRX_FCS, SK_PNMI_HRX_RESERVED}, -/* Bit54 */ { SK_PNMI_HRX_RESERVED, SK_PNMI_HRX_OVERFLOW}, -/* Bit55 */ { SK_PNMI_HRX_CEXT, SK_PNMI_HRX_RESERVED}, -/* Bit56 */ { SK_PNMI_HRX_UTILUNDER, SK_PNMI_HRX_RESERVED}, -/* Bit57 */ { SK_PNMI_HRX_UTILOVER, SK_PNMI_HRX_RESERVED}, -/* Bit58 */ { SK_PNMI_HRX_64, SK_PNMI_HRX_RESERVED}, -/* Bit59 */ { SK_PNMI_HRX_127, SK_PNMI_HRX_RESERVED}, -/* Bit60 */ { SK_PNMI_HRX_255, SK_PNMI_HRX_RESERVED}, -/* Bit61 */ { SK_PNMI_HRX_511, SK_PNMI_HRX_RESERVED}, -/* Bit62 */ { SK_PNMI_HRX_1023, SK_PNMI_HRX_RESERVED}, -/* Bit63 */ { SK_PNMI_HRX_MAX, SK_PNMI_HRX_RESERVED} -}; - -/* - * Table for hardware register saving on resets and port switches - */ -PNMI_STATIC const SK_PNMI_STATADDR StatAddr[SK_PNMI_MAX_IDX][SK_PNMI_MAC_TYPES] = { - /* SK_PNMI_HTX */ - {{XM_TXF_OK, SK_TRUE}, {0, SK_FALSE}}, - /* SK_PNMI_HTX_OCTETHIGH */ - {{XM_TXO_OK_HI, SK_TRUE}, {GM_TXO_OK_HI, SK_TRUE}}, - /* SK_PNMI_HTX_OCTETLOW */ - {{XM_TXO_OK_LO, SK_FALSE}, {GM_TXO_OK_LO, SK_FALSE}}, - /* SK_PNMI_HTX_BROADCAST */ - {{XM_TXF_BC_OK, SK_TRUE}, {GM_TXF_BC_OK, SK_TRUE}}, - /* SK_PNMI_HTX_MULTICAST */ - {{XM_TXF_MC_OK, SK_TRUE}, {GM_TXF_MC_OK, SK_TRUE}}, - /* SK_PNMI_HTX_UNICAST */ - {{XM_TXF_UC_OK, SK_TRUE}, {GM_TXF_UC_OK, SK_TRUE}}, - /* SK_PNMI_HTX_BURST */ - {{XM_TXE_BURST, SK_TRUE}, {0, SK_FALSE}}, - /* SK_PNMI_HTX_PMACC */ - {{XM_TXF_MPAUSE, SK_TRUE}, {GM_TXF_MPAUSE, SK_TRUE}}, - /* SK_PNMI_HTX_MACC */ - {{XM_TXF_MCTRL, SK_TRUE}, {0, SK_FALSE}}, - /* SK_PNMI_HTX_COL */ - {{0, SK_FALSE}, {GM_TXF_COL, SK_TRUE}}, - /* SK_PNMI_HTX_SINGLE_COL */ - {{XM_TXF_SNG_COL, SK_TRUE}, {GM_TXF_SNG_COL, SK_TRUE}}, - /* SK_PNMI_HTX_MULTI_COL */ - {{XM_TXF_MUL_COL, SK_TRUE}, {GM_TXF_MUL_COL, SK_TRUE}}, - /* SK_PNMI_HTX_EXCESS_COL */ - {{XM_TXF_ABO_COL, SK_TRUE}, {GM_TXF_ABO_COL, SK_TRUE}}, - /* SK_PNMI_HTX_LATE_COL */ - {{XM_TXF_LAT_COL, SK_TRUE}, {GM_TXF_LAT_COL, SK_TRUE}}, - /* SK_PNMI_HTX_DEFFERAL */ - {{XM_TXF_DEF, SK_TRUE}, {0, SK_FALSE}}, - /* SK_PNMI_HTX_EXCESS_DEF */ - {{XM_TXF_EX_DEF, SK_TRUE}, {0, SK_FALSE}}, - /* SK_PNMI_HTX_UNDERRUN */ - {{XM_TXE_FIFO_UR, SK_TRUE}, {GM_TXE_FIFO_UR, SK_TRUE}}, - /* SK_PNMI_HTX_CARRIER */ - {{XM_TXE_CS_ERR, SK_TRUE}, {0, SK_FALSE}}, - /* SK_PNMI_HTX_UTILUNDER */ - {{0, SK_FALSE}, {0, SK_FALSE}}, - /* SK_PNMI_HTX_UTILOVER */ - {{0, SK_FALSE}, {0, SK_FALSE}}, - /* SK_PNMI_HTX_64 */ - {{XM_TXF_64B, SK_TRUE}, {GM_TXF_64B, SK_TRUE}}, - /* SK_PNMI_HTX_127 */ - {{XM_TXF_127B, SK_TRUE}, {GM_TXF_127B, SK_TRUE}}, - /* SK_PNMI_HTX_255 */ - {{XM_TXF_255B, SK_TRUE}, {GM_TXF_255B, SK_TRUE}}, - /* SK_PNMI_HTX_511 */ - {{XM_TXF_511B, SK_TRUE}, {GM_TXF_511B, SK_TRUE}}, - /* SK_PNMI_HTX_1023 */ - {{XM_TXF_1023B, SK_TRUE}, {GM_TXF_1023B, SK_TRUE}}, - /* SK_PNMI_HTX_MAX */ - {{XM_TXF_MAX_SZ, SK_TRUE}, {GM_TXF_1518B, SK_TRUE}}, - /* SK_PNMI_HTX_LONGFRAMES */ - {{XM_TXF_LONG, SK_TRUE}, {GM_TXF_MAX_SZ, SK_TRUE}}, - /* SK_PNMI_HTX_SYNC */ - {{0, SK_FALSE}, {0, SK_FALSE}}, - /* SK_PNMI_HTX_SYNC_OCTET */ - {{0, SK_FALSE}, {0, SK_FALSE}}, - /* SK_PNMI_HTX_RESERVED */ - {{0, SK_FALSE}, {0, SK_FALSE}}, - /* SK_PNMI_HRX */ - {{XM_RXF_OK, SK_TRUE}, {0, SK_FALSE}}, - /* SK_PNMI_HRX_OCTETHIGH */ - {{XM_RXO_OK_HI, SK_TRUE}, {GM_RXO_OK_HI, SK_TRUE}}, - /* SK_PNMI_HRX_OCTETLOW */ - {{XM_RXO_OK_LO, SK_FALSE}, {GM_RXO_OK_LO, SK_FALSE}}, - /* SK_PNMI_HRX_BADOCTETHIGH */ - {{0, SK_FALSE}, {GM_RXO_ERR_HI, SK_TRUE}}, - /* SK_PNMI_HRX_BADOCTETLOW */ - {{0, SK_FALSE}, {GM_RXO_ERR_LO, SK_TRUE}}, - /* SK_PNMI_HRX_BROADCAST */ - {{XM_RXF_BC_OK, SK_TRUE}, {GM_RXF_BC_OK, SK_TRUE}}, - /* SK_PNMI_HRX_MULTICAST */ - {{XM_RXF_MC_OK, SK_TRUE}, {GM_RXF_MC_OK, SK_TRUE}}, - /* SK_PNMI_HRX_UNICAST */ - {{XM_RXF_UC_OK, SK_TRUE}, {GM_RXF_UC_OK, SK_TRUE}}, - /* SK_PNMI_HRX_PMACC */ - {{XM_RXF_MPAUSE, SK_TRUE}, {GM_RXF_MPAUSE, SK_TRUE}}, - /* SK_PNMI_HRX_MACC */ - {{XM_RXF_MCTRL, SK_TRUE}, {0, SK_FALSE}}, - /* SK_PNMI_HRX_PMACC_ERR */ - {{XM_RXF_INV_MP, SK_TRUE}, {0, SK_FALSE}}, - /* SK_PNMI_HRX_MACC_UNKWN */ - {{XM_RXF_INV_MOC, SK_TRUE}, {0, SK_FALSE}}, - /* SK_PNMI_HRX_BURST */ - {{XM_RXE_BURST, SK_TRUE}, {0, SK_FALSE}}, - /* SK_PNMI_HRX_MISSED */ - {{XM_RXE_FMISS, SK_TRUE}, {0, SK_FALSE}}, - /* SK_PNMI_HRX_FRAMING */ - {{XM_RXF_FRA_ERR, SK_TRUE}, {0, SK_FALSE}}, - /* SK_PNMI_HRX_UNDERSIZE */ - {{0, SK_FALSE}, {GM_RXF_SHT, SK_TRUE}}, - /* SK_PNMI_HRX_OVERFLOW */ - {{XM_RXE_FIFO_OV, SK_TRUE}, {GM_RXE_FIFO_OV, SK_TRUE}}, - /* SK_PNMI_HRX_JABBER */ - {{XM_RXF_JAB_PKT, SK_TRUE}, {GM_RXF_JAB_PKT, SK_TRUE}}, - /* SK_PNMI_HRX_CARRIER */ - {{XM_RXE_CAR_ERR, SK_TRUE}, {0, SK_FALSE}}, - /* SK_PNMI_HRX_IRLENGTH */ - {{XM_RXF_LEN_ERR, SK_TRUE}, {0, SK_FALSE}}, - /* SK_PNMI_HRX_SYMBOL */ - {{XM_RXE_SYM_ERR, SK_TRUE}, {0, SK_FALSE}}, - /* SK_PNMI_HRX_SHORTS */ - {{XM_RXE_SHT_ERR, SK_TRUE}, {0, SK_FALSE}}, - /* SK_PNMI_HRX_RUNT */ - {{XM_RXE_RUNT, SK_TRUE}, {GM_RXE_FRAG, SK_TRUE}}, - /* SK_PNMI_HRX_TOO_LONG */ - {{XM_RXF_LNG_ERR, SK_TRUE}, {GM_RXF_LNG_ERR, SK_TRUE}}, - /* SK_PNMI_HRX_FCS */ - {{XM_RXF_FCS_ERR, SK_TRUE}, {GM_RXF_FCS_ERR, SK_TRUE}}, - /* SK_PNMI_HRX_CEXT */ - {{XM_RXF_CEX_ERR, SK_TRUE}, {0, SK_FALSE}}, - /* SK_PNMI_HRX_UTILUNDER */ - {{0, SK_FALSE}, {0, SK_FALSE}}, - /* SK_PNMI_HRX_UTILOVER */ - {{0, SK_FALSE}, {0, SK_FALSE}}, - /* SK_PNMI_HRX_64 */ - {{XM_RXF_64B, SK_TRUE}, {GM_RXF_64B, SK_TRUE}}, - /* SK_PNMI_HRX_127 */ - {{XM_RXF_127B, SK_TRUE}, {GM_RXF_127B, SK_TRUE}}, - /* SK_PNMI_HRX_255 */ - {{XM_RXF_255B, SK_TRUE}, {GM_RXF_255B, SK_TRUE}}, - /* SK_PNMI_HRX_511 */ - {{XM_RXF_511B, SK_TRUE}, {GM_RXF_511B, SK_TRUE}}, - /* SK_PNMI_HRX_1023 */ - {{XM_RXF_1023B, SK_TRUE}, {GM_RXF_1023B, SK_TRUE}}, - /* SK_PNMI_HRX_MAX */ - {{XM_RXF_MAX_SZ, SK_TRUE}, {GM_RXF_1518B, SK_TRUE}}, - /* SK_PNMI_HRX_LONGFRAMES */ - {{0, SK_FALSE}, {GM_RXF_MAX_SZ, SK_TRUE}}, - /* SK_PNMI_HRX_RESERVED */ - {{0, SK_FALSE}, {0, SK_FALSE}} -}; - - -/***************************************************************************** - * - * Public functions - * - */ - -/***************************************************************************** - * - * SkPnmiInit - Init function of PNMI - * - * Description: - * SK_INIT_DATA: Initialises the data structures - * SK_INIT_IO: Resets the XMAC statistics, determines the device and - * connector type. - * SK_INIT_RUN: Starts a timer event for port switch per hour - * calculation. - * - * Returns: - * Always 0 - */ -int SkPnmiInit( -SK_AC *pAC, /* Pointer to adapter context */ -SK_IOC IoC, /* IO context handle */ -int Level) /* Initialization level */ -{ - unsigned int PortMax; /* Number of ports */ - unsigned int PortIndex; /* Current port index in loop */ - SK_U16 Val16; /* Multiple purpose 16 bit variable */ - SK_U8 Val8; /* Mulitple purpose 8 bit variable */ - SK_EVPARA EventParam; /* Event struct for timer event */ - SK_PNMI_VCT *pVctBackupData; - - - SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL, - ("PNMI: SkPnmiInit: Called, level=%d\n", Level)); - - switch (Level) { - - case SK_INIT_DATA: - SK_MEMSET((char *)&pAC->Pnmi, 0, sizeof(pAC->Pnmi)); - pAC->Pnmi.TrapBufFree = SK_PNMI_TRAP_QUEUE_LEN; - pAC->Pnmi.StartUpTime = SK_PNMI_HUNDREDS_SEC(SkOsGetTime(pAC)); - pAC->Pnmi.RlmtChangeThreshold = SK_PNMI_DEF_RLMT_CHG_THRES; - for (PortIndex = 0; PortIndex < SK_MAX_MACS; PortIndex ++) { - - pAC->Pnmi.Port[PortIndex].ActiveFlag = SK_FALSE; - pAC->Pnmi.DualNetActiveFlag = SK_FALSE; - } - -#ifdef SK_PNMI_CHECK - if (SK_PNMI_MAX_IDX != SK_PNMI_CNT_NO) { - - SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR049, SK_PNMI_ERR049MSG); - - SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_INIT | SK_DBGCAT_FATAL, - ("CounterOffset struct size (%d) differs from" - "SK_PNMI_MAX_IDX (%d)\n", - SK_PNMI_CNT_NO, SK_PNMI_MAX_IDX)); - } - - if (SK_PNMI_MAX_IDX != - (sizeof(StatAddr) / (sizeof(SK_PNMI_STATADDR) * SK_PNMI_MAC_TYPES))) { - - SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR050, SK_PNMI_ERR050MSG); - - SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_INIT | SK_DBGCAT_FATAL, - ("StatAddr table size (%d) differs from " - "SK_PNMI_MAX_IDX (%d)\n", - (sizeof(StatAddr) / - (sizeof(SK_PNMI_STATADDR) * SK_PNMI_MAC_TYPES)), - SK_PNMI_MAX_IDX)); - } -#endif /* SK_PNMI_CHECK */ - break; - - case SK_INIT_IO: - /* - * Reset MAC counters - */ - PortMax = pAC->GIni.GIMacsFound; - - for (PortIndex = 0; PortIndex < PortMax; PortIndex ++) { - - pAC->GIni.GIFunc.pFnMacResetCounter(pAC, IoC, PortIndex); - } - - /* Initialize DSP variables for Vct() to 0xff => Never written! */ - for (PortIndex = 0; PortIndex < PortMax; PortIndex ++) { - pAC->GIni.GP[PortIndex].PCableLen = 0xff; - pVctBackupData = &pAC->Pnmi.VctBackup[PortIndex]; - pVctBackupData->PCableLen = 0xff; - } - - /* - * Get pci bus speed - */ - SK_IN16(IoC, B0_CTST, &Val16); - if ((Val16 & CS_BUS_CLOCK) == 0) { - - pAC->Pnmi.PciBusSpeed = 33; - } - else { - pAC->Pnmi.PciBusSpeed = 66; - } - - /* - * Get pci bus width - */ - SK_IN16(IoC, B0_CTST, &Val16); - if ((Val16 & CS_BUS_SLOT_SZ) == 0) { - - pAC->Pnmi.PciBusWidth = 32; - } - else { - pAC->Pnmi.PciBusWidth = 64; - } - - /* - * Get chipset - */ - switch (pAC->GIni.GIChipId) { - case CHIP_ID_GENESIS: - pAC->Pnmi.Chipset = SK_PNMI_CHIPSET_XMAC; - break; - - case CHIP_ID_YUKON: - pAC->Pnmi.Chipset = SK_PNMI_CHIPSET_YUKON; - break; - - default: - break; - } - - /* - * Get PMD and DeviceType - */ - SK_IN8(IoC, B2_PMD_TYP, &Val8); - switch (Val8) { - case 'S': - pAC->Pnmi.PMD = 3; - if (pAC->GIni.GIMacsFound > 1) { - - pAC->Pnmi.DeviceType = 0x00020002; - } - else { - pAC->Pnmi.DeviceType = 0x00020001; - } - break; - - case 'L': - pAC->Pnmi.PMD = 2; - if (pAC->GIni.GIMacsFound > 1) { - - pAC->Pnmi.DeviceType = 0x00020004; - } - else { - pAC->Pnmi.DeviceType = 0x00020003; - } - break; - - case 'C': - pAC->Pnmi.PMD = 4; - if (pAC->GIni.GIMacsFound > 1) { - - pAC->Pnmi.DeviceType = 0x00020006; - } - else { - pAC->Pnmi.DeviceType = 0x00020005; - } - break; - - case 'T': - pAC->Pnmi.PMD = 5; - if (pAC->GIni.GIMacsFound > 1) { - - pAC->Pnmi.DeviceType = 0x00020008; - } - else { - pAC->Pnmi.DeviceType = 0x00020007; - } - break; - - default : - pAC->Pnmi.PMD = 1; - pAC->Pnmi.DeviceType = 0; - break; - } - - /* - * Get connector - */ - SK_IN8(IoC, B2_CONN_TYP, &Val8); - switch (Val8) { - case 'C': - pAC->Pnmi.Connector = 2; - break; - - case 'D': - pAC->Pnmi.Connector = 3; - break; - - case 'F': - pAC->Pnmi.Connector = 4; - break; - - case 'J': - pAC->Pnmi.Connector = 5; - break; - - case 'V': - pAC->Pnmi.Connector = 6; - break; - - default: - pAC->Pnmi.Connector = 1; - break; - } - break; - - case SK_INIT_RUN: - /* - * Start timer for RLMT change counter - */ - SK_MEMSET((char *)&EventParam, 0, sizeof(EventParam)); - SkTimerStart(pAC, IoC, &pAC->Pnmi.RlmtChangeEstimate.EstTimer, - 28125000, SKGE_PNMI, SK_PNMI_EVT_CHG_EST_TIMER, - EventParam); - break; - - default: - break; /* Nothing todo */ - } - - return (0); -} - -/***************************************************************************** - * - * SkPnmiGetVar - Retrieves the value of a single OID - * - * Description: - * Calls a general sub-function for all this stuff. If the instance - * -1 is passed, the values of all instances are returned in an - * array of values. - * - * Returns: - * SK_PNMI_ERR_OK The request was successfully performed - * SK_PNMI_ERR_GENERAL A general severe internal error occured - * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to take - * the data. - * SK_PNMI_ERR_UNKNOWN_OID The requested OID is unknown - * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't - * exist (e.g. port instance 3 on a two port - * adapter. - */ -int SkPnmiGetVar( -SK_AC *pAC, /* Pointer to adapter context */ -SK_IOC IoC, /* IO context handle */ -SK_U32 Id, /* Object ID that is to be processed */ -void *pBuf, /* Buffer to which the management data will be copied */ -unsigned int *pLen, /* On call: buffer length. On return: used buffer */ -SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */ -SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */ -{ - SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL, - ("PNMI: SkPnmiGetVar: Called, Id=0x%x, BufLen=%d, Instance=%d, NetIndex=%d\n", - Id, *pLen, Instance, NetIndex)); - - return (PnmiVar(pAC, IoC, SK_PNMI_GET, Id, (char *)pBuf, pLen, - Instance, NetIndex)); -} - -/***************************************************************************** - * - * SkPnmiPreSetVar - Presets the value of a single OID - * - * Description: - * Calls a general sub-function for all this stuff. The preset does - * the same as a set, but returns just before finally setting the - * new value. This is usefull to check if a set might be successfull. - * If the instance -1 is passed, an array of values is supposed and - * all instances of the OID will be set. - * - * Returns: - * SK_PNMI_ERR_OK The request was successfully performed. - * SK_PNMI_ERR_GENERAL A general severe internal error occured. - * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain - * the correct data (e.g. a 32bit value is - * needed, but a 16 bit value was passed). - * SK_PNMI_ERR_BAD_VALUE The passed value is not in the valid - * value range. - * SK_PNMI_ERR_READ_ONLY The OID is read-only and cannot be set. - * SK_PNMI_ERR_UNKNOWN_OID The requested OID is unknown. - * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't - * exist (e.g. port instance 3 on a two port - * adapter. - */ -int SkPnmiPreSetVar( -SK_AC *pAC, /* Pointer to adapter context */ -SK_IOC IoC, /* IO context handle */ -SK_U32 Id, /* Object ID that is to be processed */ -void *pBuf, /* Buffer to which the management data will be copied */ -unsigned int *pLen, /* Total length of management data */ -SK_U32 Instance, /* Instance (1..n) that is to be set or -1 */ -SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */ -{ - SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL, - ("PNMI: SkPnmiPreSetVar: Called, Id=0x%x, BufLen=%d, Instance=%d, NetIndex=%d\n", - Id, *pLen, Instance, NetIndex)); - - - return (PnmiVar(pAC, IoC, SK_PNMI_PRESET, Id, (char *)pBuf, pLen, - Instance, NetIndex)); -} - -/***************************************************************************** - * - * SkPnmiSetVar - Sets the value of a single OID - * - * Description: - * Calls a general sub-function for all this stuff. The preset does - * the same as a set, but returns just before finally setting the - * new value. This is usefull to check if a set might be successfull. - * If the instance -1 is passed, an array of values is supposed and - * all instances of the OID will be set. - * - * Returns: - * SK_PNMI_ERR_OK The request was successfully performed. - * SK_PNMI_ERR_GENERAL A general severe internal error occured. - * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain - * the correct data (e.g. a 32bit value is - * needed, but a 16 bit value was passed). - * SK_PNMI_ERR_BAD_VALUE The passed value is not in the valid - * value range. - * SK_PNMI_ERR_READ_ONLY The OID is read-only and cannot be set. - * SK_PNMI_ERR_UNKNOWN_OID The requested OID is unknown. - * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't - * exist (e.g. port instance 3 on a two port - * adapter. - */ -int SkPnmiSetVar( -SK_AC *pAC, /* Pointer to adapter context */ -SK_IOC IoC, /* IO context handle */ -SK_U32 Id, /* Object ID that is to be processed */ -void *pBuf, /* Buffer to which the management data will be copied */ -unsigned int *pLen, /* Total length of management data */ -SK_U32 Instance, /* Instance (1..n) that is to be set or -1 */ -SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */ -{ - SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL, - ("PNMI: SkPnmiSetVar: Called, Id=0x%x, BufLen=%d, Instance=%d, NetIndex=%d\n", - Id, *pLen, Instance, NetIndex)); - - return (PnmiVar(pAC, IoC, SK_PNMI_SET, Id, (char *)pBuf, pLen, - Instance, NetIndex)); -} - -/***************************************************************************** - * - * SkPnmiGetStruct - Retrieves the management database in SK_PNMI_STRUCT_DATA - * - * Description: - * Runs through the IdTable, queries the single OIDs and stores the - * returned data into the management database structure - * SK_PNMI_STRUCT_DATA. The offset of the OID in the structure - * is stored in the IdTable. The return value of the function will also - * be stored in SK_PNMI_STRUCT_DATA if the passed buffer has the - * minimum size of SK_PNMI_MIN_STRUCT_SIZE. - * - * Returns: - * SK_PNMI_ERR_OK The request was successfully performed - * SK_PNMI_ERR_GENERAL A general severe internal error occured - * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to take - * the data. - * SK_PNMI_ERR_UNKNOWN_NET The requested NetIndex doesn't exist - */ -int SkPnmiGetStruct( -SK_AC *pAC, /* Pointer to adapter context */ -SK_IOC IoC, /* IO context handle */ -void *pBuf, /* Buffer to which the management data will be copied. */ -unsigned int *pLen, /* Length of buffer */ -SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */ -{ - int Ret; - unsigned int TableIndex; - unsigned int DstOffset; - unsigned int InstanceNo; - unsigned int InstanceCnt; - SK_U32 Instance; - unsigned int TmpLen; - char KeyArr[SK_PNMI_VPD_ENTRIES][SK_PNMI_VPD_KEY_SIZE]; - - - SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL, - ("PNMI: SkPnmiGetStruct: Called, BufLen=%d, NetIndex=%d\n", - *pLen, NetIndex)); - - if (*pLen < SK_PNMI_STRUCT_SIZE) { - - if (*pLen >= SK_PNMI_MIN_STRUCT_SIZE) { - - SK_PNMI_SET_STAT(pBuf, SK_PNMI_ERR_TOO_SHORT, - (SK_U32)(-1)); - } - - *pLen = SK_PNMI_STRUCT_SIZE; - return (SK_PNMI_ERR_TOO_SHORT); - } - - /* - * Check NetIndex - */ - if (NetIndex >= pAC->Rlmt.NumNets) { - return (SK_PNMI_ERR_UNKNOWN_NET); - } - - /* Update statistic */ - SK_PNMI_CHECKFLAGS("SkPnmiGetStruct: On call"); - - if ((Ret = MacUpdate(pAC, IoC, 0, pAC->GIni.GIMacsFound - 1)) != - SK_PNMI_ERR_OK) { - - SK_PNMI_SET_STAT(pBuf, Ret, (SK_U32)(-1)); - *pLen = SK_PNMI_MIN_STRUCT_SIZE; - return (Ret); - } - - if ((Ret = RlmtUpdate(pAC, IoC, NetIndex)) != SK_PNMI_ERR_OK) { - - SK_PNMI_SET_STAT(pBuf, Ret, (SK_U32)(-1)); - *pLen = SK_PNMI_MIN_STRUCT_SIZE; - return (Ret); - } - - if ((Ret = SirqUpdate(pAC, IoC)) != SK_PNMI_ERR_OK) { - - SK_PNMI_SET_STAT(pBuf, Ret, (SK_U32)(-1)); - *pLen = SK_PNMI_MIN_STRUCT_SIZE; - return (Ret); - } - - /* - * Increment semaphores to indicate that an update was - * already done - */ - pAC->Pnmi.MacUpdatedFlag ++; - pAC->Pnmi.RlmtUpdatedFlag ++; - pAC->Pnmi.SirqUpdatedFlag ++; - - /* Get vpd keys for instance calculation */ - Ret = GetVpdKeyArr(pAC, IoC, &KeyArr[0][0], sizeof(KeyArr), &TmpLen); - if (Ret != SK_PNMI_ERR_OK) { - - pAC->Pnmi.MacUpdatedFlag --; - pAC->Pnmi.RlmtUpdatedFlag --; - pAC->Pnmi.SirqUpdatedFlag --; - - SK_PNMI_CHECKFLAGS("SkPnmiGetStruct: On return"); - SK_PNMI_SET_STAT(pBuf, Ret, (SK_U32)(-1)); - *pLen = SK_PNMI_MIN_STRUCT_SIZE; - return (SK_PNMI_ERR_GENERAL); - } - - /* Retrieve values */ - SK_MEMSET((char *)pBuf, 0, SK_PNMI_STRUCT_SIZE); - for (TableIndex = 0; TableIndex < ID_TABLE_SIZE; TableIndex ++) { - - InstanceNo = IdTable[TableIndex].InstanceNo; - for (InstanceCnt = 1; InstanceCnt <= InstanceNo; - InstanceCnt ++) { - - DstOffset = IdTable[TableIndex].Offset + - (InstanceCnt - 1) * - IdTable[TableIndex].StructSize; - - /* - * For the VPD the instance is not an index number - * but the key itself. Determin with the instance - * counter the VPD key to be used. - */ - if (IdTable[TableIndex].Id == OID_SKGE_VPD_KEY || - IdTable[TableIndex].Id == OID_SKGE_VPD_VALUE || - IdTable[TableIndex].Id == OID_SKGE_VPD_ACCESS || - IdTable[TableIndex].Id == OID_SKGE_VPD_ACTION) { - - SK_STRNCPY((char *)&Instance, KeyArr[InstanceCnt - 1], 4); - } - else { - Instance = (SK_U32)InstanceCnt; - } - - TmpLen = *pLen - DstOffset; - Ret = IdTable[TableIndex].Func(pAC, IoC, SK_PNMI_GET, - IdTable[TableIndex].Id, (char *)pBuf + - DstOffset, &TmpLen, Instance, TableIndex, NetIndex); - - /* - * An unknown instance error means that we reached - * the last instance of that variable. Proceed with - * the next OID in the table and ignore the return - * code. - */ - if (Ret == SK_PNMI_ERR_UNKNOWN_INST) { - - break; - } - - if (Ret != SK_PNMI_ERR_OK) { - - pAC->Pnmi.MacUpdatedFlag --; - pAC->Pnmi.RlmtUpdatedFlag --; - pAC->Pnmi.SirqUpdatedFlag --; - - SK_PNMI_CHECKFLAGS("SkPnmiGetStruct: On return"); - SK_PNMI_SET_STAT(pBuf, Ret, DstOffset); - *pLen = SK_PNMI_MIN_STRUCT_SIZE; - return (Ret); - } - } - } - - pAC->Pnmi.MacUpdatedFlag --; - pAC->Pnmi.RlmtUpdatedFlag --; - pAC->Pnmi.SirqUpdatedFlag --; - - *pLen = SK_PNMI_STRUCT_SIZE; - SK_PNMI_CHECKFLAGS("SkPnmiGetStruct: On return"); - SK_PNMI_SET_STAT(pBuf, SK_PNMI_ERR_OK, (SK_U32)(-1)); - return (SK_PNMI_ERR_OK); -} - -/***************************************************************************** - * - * SkPnmiPreSetStruct - Presets the management database in SK_PNMI_STRUCT_DATA - * - * Description: - * Calls a general sub-function for all this set stuff. The preset does - * the same as a set, but returns just before finally setting the - * new value. This is usefull to check if a set might be successfull. - * The sub-function runs through the IdTable, checks which OIDs are able - * to set, and calls the handler function of the OID to perform the - * preset. The return value of the function will also be stored in - * SK_PNMI_STRUCT_DATA if the passed buffer has the minimum size of - * SK_PNMI_MIN_STRUCT_SIZE. - * - * Returns: - * SK_PNMI_ERR_OK The request was successfully performed. - * SK_PNMI_ERR_GENERAL A general severe internal error occured. - * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain - * the correct data (e.g. a 32bit value is - * needed, but a 16 bit value was passed). - * SK_PNMI_ERR_BAD_VALUE The passed value is not in the valid - * value range. - */ -int SkPnmiPreSetStruct( -SK_AC *pAC, /* Pointer to adapter context */ -SK_IOC IoC, /* IO context handle */ -void *pBuf, /* Buffer which contains the data to be set */ -unsigned int *pLen, /* Length of buffer */ -SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */ -{ - SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL, - ("PNMI: SkPnmiPreSetStruct: Called, BufLen=%d, NetIndex=%d\n", - *pLen, NetIndex)); - - return (PnmiStruct(pAC, IoC, SK_PNMI_PRESET, (char *)pBuf, - pLen, NetIndex)); -} - -/***************************************************************************** - * - * SkPnmiSetStruct - Sets the management database in SK_PNMI_STRUCT_DATA - * - * Description: - * Calls a general sub-function for all this set stuff. The return value - * of the function will also be stored in SK_PNMI_STRUCT_DATA if the - * passed buffer has the minimum size of SK_PNMI_MIN_STRUCT_SIZE. - * The sub-function runs through the IdTable, checks which OIDs are able - * to set, and calls the handler function of the OID to perform the - * set. The return value of the function will also be stored in - * SK_PNMI_STRUCT_DATA if the passed buffer has the minimum size of - * SK_PNMI_MIN_STRUCT_SIZE. - * - * Returns: - * SK_PNMI_ERR_OK The request was successfully performed. - * SK_PNMI_ERR_GENERAL A general severe internal error occured. - * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain - * the correct data (e.g. a 32bit value is - * needed, but a 16 bit value was passed). - * SK_PNMI_ERR_BAD_VALUE The passed value is not in the valid - * value range. - */ -int SkPnmiSetStruct( -SK_AC *pAC, /* Pointer to adapter context */ -SK_IOC IoC, /* IO context handle */ -void *pBuf, /* Buffer which contains the data to be set */ -unsigned int *pLen, /* Length of buffer */ -SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */ -{ - SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL, - ("PNMI: SkPnmiSetStruct: Called, BufLen=%d, NetIndex=%d\n", - *pLen, NetIndex)); - - return (PnmiStruct(pAC, IoC, SK_PNMI_SET, (char *)pBuf, - pLen, NetIndex)); -} - -/***************************************************************************** - * - * SkPnmiEvent - Event handler - * - * Description: - * Handles the following events: - * SK_PNMI_EVT_SIRQ_OVERFLOW When a hardware counter overflows an - * interrupt will be generated which is - * first handled by SIRQ which generates a - * this event. The event increments the - * upper 32 bit of the 64 bit counter. - * SK_PNMI_EVT_SEN_XXX The event is generated by the I2C module - * when a sensor reports a warning or - * error. The event will store a trap - * message in the trap buffer. - * SK_PNMI_EVT_CHG_EST_TIMER The timer event was initiated by this - * module and is used to calculate the - * port switches per hour. - * SK_PNMI_EVT_CLEAR_COUNTER The event clears all counters and - * timestamps. - * SK_PNMI_EVT_XMAC_RESET The event is generated by the driver - * before a hard reset of the XMAC is - * performed. All counters will be saved - * and added to the hardware counter - * values after reset to grant continuous - * counter values. - * SK_PNMI_EVT_RLMT_PORT_UP Generated by RLMT to notify that a port - * went logically up. A trap message will - * be stored to the trap buffer. - * SK_PNMI_EVT_RLMT_PORT_DOWN Generated by RLMT to notify that a port - * went logically down. A trap message will - * be stored to the trap buffer. - * SK_PNMI_EVT_RLMT_SEGMENTATION Generated by RLMT to notify that two - * spanning tree root bridges were - * detected. A trap message will be stored - * to the trap buffer. - * SK_PNMI_EVT_RLMT_ACTIVE_DOWN Notifies PNMI that an active port went - * down. PNMI will not further add the - * statistic values to the virtual port. - * SK_PNMI_EVT_RLMT_ACTIVE_UP Notifies PNMI that a port went up and - * is now an active port. PNMI will now - * add the statistic data of this port to - * the virtual port. - * SK_PNMI_EVT_RLMT_SET_NETS Notifies PNMI about the net mode. The first parameter - * contains the number of nets. 1 means single net, 2 means - * dual net. The second parameter is -1 - * - * Returns: - * Always 0 - */ -int SkPnmiEvent( -SK_AC *pAC, /* Pointer to adapter context */ -SK_IOC IoC, /* IO context handle */ -SK_U32 Event, /* Event-Id */ -SK_EVPARA Param) /* Event dependent parameter */ -{ - unsigned int PhysPortIndex; - unsigned int MaxNetNumber; - int CounterIndex; - int Ret; - SK_U16 MacStatus; - SK_U64 OverflowStatus; - SK_U64 Mask; - int MacType; - SK_U64 Value; - SK_U32 Val32; - SK_U16 Register; - SK_EVPARA EventParam; - SK_U64 NewestValue; - SK_U64 OldestValue; - SK_U64 Delta; - SK_PNMI_ESTIMATE *pEst; - SK_U32 NetIndex; - SK_GEPORT *pPrt; - SK_PNMI_VCT *pVctBackupData; - SK_U32 RetCode; - int i; - SK_U32 CableLength; - - -#ifdef DEBUG - if (Event != SK_PNMI_EVT_XMAC_RESET) { - - SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL, - ("PNMI: SkPnmiEvent: Called, Event=0x%x, Param=0x%x\n", - (unsigned int)Event, (unsigned int)Param.Para64)); - } -#endif /* DEBUG */ - SK_PNMI_CHECKFLAGS("SkPnmiEvent: On call"); - - MacType = pAC->GIni.GIMacType; - - switch (Event) { - - case SK_PNMI_EVT_SIRQ_OVERFLOW: - PhysPortIndex = (int)Param.Para32[0]; - MacStatus = (SK_U16)Param.Para32[1]; -#ifdef DEBUG - if (PhysPortIndex >= SK_MAX_MACS) { - - SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL, - ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_SIRQ_OVERFLOW parameter" - " wrong, PhysPortIndex=0x%x\n", - PhysPortIndex)); - return (0); - } -#endif /* DEBUG */ - OverflowStatus = 0; - - /* - * Check which source caused an overflow interrupt. - */ - if ((pAC->GIni.GIFunc.pFnMacOverflow(pAC, IoC, PhysPortIndex, - MacStatus, &OverflowStatus) != 0) || - (OverflowStatus == 0)) { - - SK_PNMI_CHECKFLAGS("SkPnmiEvent: On return"); - return (0); - } - - /* - * Check the overflow status register and increment - * the upper dword of corresponding counter. - */ - for (CounterIndex = 0; CounterIndex < sizeof(Mask) * 8; - CounterIndex ++) { - - Mask = (SK_U64)1 << CounterIndex; - if ((OverflowStatus & Mask) == 0) { - - continue; - } - - switch (StatOvrflwBit[CounterIndex][MacType]) { - - case SK_PNMI_HTX_UTILUNDER: - case SK_PNMI_HTX_UTILOVER: - if (MacType == SK_MAC_XMAC) { - XM_IN16(IoC, PhysPortIndex, XM_TX_CMD, &Register); - Register |= XM_TX_SAM_LINE; - XM_OUT16(IoC, PhysPortIndex, XM_TX_CMD, Register); - } - break; - - case SK_PNMI_HRX_UTILUNDER: - case SK_PNMI_HRX_UTILOVER: - if (MacType == SK_MAC_XMAC) { - XM_IN16(IoC, PhysPortIndex, XM_RX_CMD, &Register); - Register |= XM_RX_SAM_LINE; - XM_OUT16(IoC, PhysPortIndex, XM_RX_CMD, Register); - } - break; - - case SK_PNMI_HTX_OCTETHIGH: - case SK_PNMI_HTX_OCTETLOW: - case SK_PNMI_HTX_RESERVED: - case SK_PNMI_HRX_OCTETHIGH: - case SK_PNMI_HRX_OCTETLOW: - case SK_PNMI_HRX_IRLENGTH: - case SK_PNMI_HRX_RESERVED: - - /* - * the following counters aren't be handled (id > 63) - */ - case SK_PNMI_HTX_SYNC: - case SK_PNMI_HTX_SYNC_OCTET: - break; - - case SK_PNMI_HRX_LONGFRAMES: - if (MacType == SK_MAC_GMAC) { - pAC->Pnmi.Port[PhysPortIndex]. - CounterHigh[CounterIndex] ++; - } - break; - - default: - pAC->Pnmi.Port[PhysPortIndex]. - CounterHigh[CounterIndex] ++; - } - } - break; - - case SK_PNMI_EVT_SEN_WAR_LOW: -#ifdef DEBUG - if ((unsigned int)Param.Para64 >= (unsigned int)pAC->I2c.MaxSens) { - - SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL, - ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_SEN_WAR_LOW parameter wrong, SensorIndex=%d\n", - (unsigned int)Param.Para64)); - return (0); - } -#endif /* DEBUG */ - - /* - * Store a trap message in the trap buffer and generate - * an event for user space applications with the - * SK_DRIVER_SENDEVENT macro. - */ - QueueSensorTrap(pAC, OID_SKGE_TRAP_SEN_WAR_LOW, - (unsigned int)Param.Para64); - (void)SK_DRIVER_SENDEVENT(pAC, IoC); - break; - - case SK_PNMI_EVT_SEN_WAR_UPP: -#ifdef DEBUG - if ((unsigned int)Param.Para64 >= (unsigned int)pAC->I2c.MaxSens) { - - SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL, - ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_SEN_WAR_UPP parameter wrong, SensorIndex=%d\n", - (unsigned int)Param.Para64)); - return (0); - } -#endif /* DEBUG */ - - /* - * Store a trap message in the trap buffer and generate - * an event for user space applications with the - * SK_DRIVER_SENDEVENT macro. - */ - QueueSensorTrap(pAC, OID_SKGE_TRAP_SEN_WAR_UPP, - (unsigned int)Param.Para64); - (void)SK_DRIVER_SENDEVENT(pAC, IoC); - break; - - case SK_PNMI_EVT_SEN_ERR_LOW: -#ifdef DEBUG - if ((unsigned int)Param.Para64 >= (unsigned int)pAC->I2c.MaxSens) { - - SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL, - ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_SEN_ERR_LOW parameter wrong, SensorIndex=%d\n", - (unsigned int)Param.Para64)); - return (0); - } -#endif /* DEBUG */ - - /* - * Store a trap message in the trap buffer and generate - * an event for user space applications with the - * SK_DRIVER_SENDEVENT macro. - */ - QueueSensorTrap(pAC, OID_SKGE_TRAP_SEN_ERR_LOW, - (unsigned int)Param.Para64); - (void)SK_DRIVER_SENDEVENT(pAC, IoC); - break; - - case SK_PNMI_EVT_SEN_ERR_UPP: -#ifdef DEBUG - if ((unsigned int)Param.Para64 >= (unsigned int)pAC->I2c.MaxSens) { - - SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL, - ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_SEN_ERR_UPP parameter wrong, SensorIndex=%d\n", - (unsigned int)Param.Para64)); - return (0); - } -#endif /* DEBUG */ - - /* - * Store a trap message in the trap buffer and generate - * an event for user space applications with the - * SK_DRIVER_SENDEVENT macro. - */ - QueueSensorTrap(pAC, OID_SKGE_TRAP_SEN_ERR_UPP, - (unsigned int)Param.Para64); - (void)SK_DRIVER_SENDEVENT(pAC, IoC); - break; - - case SK_PNMI_EVT_CHG_EST_TIMER: - /* - * Calculate port switch average on a per hour basis - * Time interval for check : 28125 ms - * Number of values for average : 8 - * - * Be careful in changing these values, on change check - * - typedef of SK_PNMI_ESTIMATE (Size of EstValue - * array one less than value number) - * - Timer initialization SkTimerStart() in SkPnmiInit - * - Delta value below must be multiplicated with - * power of 2 - * - */ - pEst = &pAC->Pnmi.RlmtChangeEstimate; - CounterIndex = pEst->EstValueIndex + 1; - if (CounterIndex == 7) { - - CounterIndex = 0; - } - pEst->EstValueIndex = CounterIndex; - - NewestValue = pAC->Pnmi.RlmtChangeCts; - OldestValue = pEst->EstValue[CounterIndex]; - pEst->EstValue[CounterIndex] = NewestValue; - - /* - * Calculate average. Delta stores the number of - * port switches per 28125 * 8 = 225000 ms - */ - if (NewestValue >= OldestValue) { - - Delta = NewestValue - OldestValue; - } - else { - /* Overflow situation */ - Delta = (SK_U64)(0 - OldestValue) + NewestValue; - } - - /* - * Extrapolate delta to port switches per hour. - * Estimate = Delta * (3600000 / 225000) - * = Delta * 16 - * = Delta << 4 - */ - pAC->Pnmi.RlmtChangeEstimate.Estimate = Delta << 4; - - /* - * Check if threshold is exceeded. If the threshold is - * permanently exceeded every 28125 ms an event will be - * generated to remind the user of this condition. - */ - if ((pAC->Pnmi.RlmtChangeThreshold != 0) && - (pAC->Pnmi.RlmtChangeEstimate.Estimate >= - pAC->Pnmi.RlmtChangeThreshold)) { - - QueueSimpleTrap(pAC, OID_SKGE_TRAP_RLMT_CHANGE_THRES); - (void)SK_DRIVER_SENDEVENT(pAC, IoC); - } - - SK_MEMSET((char *)&EventParam, 0, sizeof(EventParam)); - SkTimerStart(pAC, IoC, &pAC->Pnmi.RlmtChangeEstimate.EstTimer, - 28125000, SKGE_PNMI, SK_PNMI_EVT_CHG_EST_TIMER, - EventParam); - break; - - case SK_PNMI_EVT_CLEAR_COUNTER: - /* - * Param.Para32[0] contains the NetIndex (0 ..1). - * Param.Para32[1] is reserved, contains -1. - */ - NetIndex = (SK_U32)Param.Para32[0]; - -#ifdef DEBUG - if (NetIndex >= pAC->Rlmt.NumNets) { - - SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL, - ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_CLEAR_COUNTER parameter wrong, NetIndex=%d\n", - NetIndex)); - - return (0); - } -#endif /* DEBUG */ - - /* - * Set all counters and timestamps to zero. - * The according NetIndex is required as a - * parameter of the event. - */ - ResetCounter(pAC, IoC, NetIndex); - break; - - case SK_PNMI_EVT_XMAC_RESET: - /* - * To grant continuous counter values store the current - * XMAC statistic values to the entries 1..n of the - * CounterOffset array. XMAC Errata #2 - */ -#ifdef DEBUG - if ((unsigned int)Param.Para64 >= SK_MAX_MACS) { - - SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL, - ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_XMAC_RESET parameter wrong, PhysPortIndex=%d\n", - (unsigned int)Param.Para64)); - return (0); - } -#endif - PhysPortIndex = (unsigned int)Param.Para64; - - /* - * Update XMAC statistic to get fresh values - */ - Ret = MacUpdate(pAC, IoC, 0, pAC->GIni.GIMacsFound - 1); - if (Ret != SK_PNMI_ERR_OK) { - - SK_PNMI_CHECKFLAGS("SkPnmiEvent: On return"); - return (0); - } - /* - * Increment semaphore to indicate that an update was - * already done - */ - pAC->Pnmi.MacUpdatedFlag ++; - - for (CounterIndex = 0; CounterIndex < SK_PNMI_MAX_IDX; - CounterIndex ++) { - - if (!StatAddr[CounterIndex][MacType].GetOffset) { - - continue; - } - - pAC->Pnmi.Port[PhysPortIndex].CounterOffset[CounterIndex] = - GetPhysStatVal(pAC, IoC, PhysPortIndex, CounterIndex); - - pAC->Pnmi.Port[PhysPortIndex].CounterHigh[CounterIndex] = 0; - } - - pAC->Pnmi.MacUpdatedFlag --; - break; - - case SK_PNMI_EVT_RLMT_PORT_UP: - PhysPortIndex = (unsigned int)Param.Para32[0]; -#ifdef DEBUG - if (PhysPortIndex >= SK_MAX_MACS) { - - SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL, - ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_RLMT_PORT_UP parameter" - " wrong, PhysPortIndex=%d\n", PhysPortIndex)); - - return (0); - } -#endif /* DEBUG */ - - /* - * Store a trap message in the trap buffer and generate an event for - * user space applications with the SK_DRIVER_SENDEVENT macro. - */ - QueueRlmtPortTrap(pAC, OID_SKGE_TRAP_RLMT_PORT_UP, PhysPortIndex); - (void)SK_DRIVER_SENDEVENT(pAC, IoC); - - /* Bugfix for XMAC errata (#10620)*/ - if (MacType == SK_MAC_XMAC) { - /* Add incremental difference to offset (#10620)*/ - (void)pAC->GIni.GIFunc.pFnMacStatistic(pAC, IoC, PhysPortIndex, - XM_RXE_SHT_ERR, &Val32); - - Value = (((SK_U64)pAC->Pnmi.Port[PhysPortIndex]. - CounterHigh[SK_PNMI_HRX_SHORTS] << 32) | (SK_U64)Val32); - pAC->Pnmi.Port[PhysPortIndex].CounterOffset[SK_PNMI_HRX_SHORTS] += - Value - pAC->Pnmi.Port[PhysPortIndex].RxShortZeroMark; - } - - /* Tell VctStatus() that a link was up meanwhile. */ - pAC->Pnmi.VctStatus[PhysPortIndex] |= SK_PNMI_VCT_LINK; - break; - - case SK_PNMI_EVT_RLMT_PORT_DOWN: - PhysPortIndex = (unsigned int)Param.Para32[0]; - -#ifdef DEBUG - if (PhysPortIndex >= SK_MAX_MACS) { - - SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL, - ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_RLMT_PORT_DOWN parameter" - " wrong, PhysPortIndex=%d\n", PhysPortIndex)); - - return (0); - } -#endif /* DEBUG */ - - /* - * Store a trap message in the trap buffer and generate an event for - * user space applications with the SK_DRIVER_SENDEVENT macro. - */ - QueueRlmtPortTrap(pAC, OID_SKGE_TRAP_RLMT_PORT_DOWN, PhysPortIndex); - (void)SK_DRIVER_SENDEVENT(pAC, IoC); - - /* Bugfix #10620 - get zero level for incremental difference */ - if (MacType == SK_MAC_XMAC) { - - (void)pAC->GIni.GIFunc.pFnMacStatistic(pAC, IoC, PhysPortIndex, - XM_RXE_SHT_ERR, &Val32); - - pAC->Pnmi.Port[PhysPortIndex].RxShortZeroMark = - (((SK_U64)pAC->Pnmi.Port[PhysPortIndex]. - CounterHigh[SK_PNMI_HRX_SHORTS] << 32) | (SK_U64)Val32); - } - break; - - case SK_PNMI_EVT_RLMT_ACTIVE_DOWN: - PhysPortIndex = (unsigned int)Param.Para32[0]; - NetIndex = (SK_U32)Param.Para32[1]; - -#ifdef DEBUG - if (PhysPortIndex >= SK_MAX_MACS) { - - SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL, - ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_RLMT_ACTIVE_DOWN parameter too high, PhysPort=%d\n", - PhysPortIndex)); - } - - if (NetIndex >= pAC->Rlmt.NumNets) { - - SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL, - ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_RLMT_ACTIVE_DOWN parameter too high, NetIndex=%d\n", - NetIndex)); - } -#endif /* DEBUG */ - - /* - * For now, ignore event if NetIndex != 0. - */ - if (Param.Para32[1] != 0) { - - return (0); - } - - /* - * Nothing to do if port is already inactive - */ - if (!pAC->Pnmi.Port[PhysPortIndex].ActiveFlag) { - - return (0); - } - - /* - * Update statistic counters to calculate new offset for the virtual - * port and increment semaphore to indicate that an update was already - * done. - */ - if (MacUpdate(pAC, IoC, 0, pAC->GIni.GIMacsFound - 1) != - SK_PNMI_ERR_OK) { - - SK_PNMI_CHECKFLAGS("SkPnmiEvent: On return"); - return (0); - } - pAC->Pnmi.MacUpdatedFlag ++; - - /* - * Calculate new counter offset for virtual port to grant continous - * counting on port switches. The virtual port consists of all currently - * active ports. The port down event indicates that a port is removed - * from the virtual port. Therefore add the counter value of the removed - * port to the CounterOffset for the virtual port to grant the same - * counter value. - */ - for (CounterIndex = 0; CounterIndex < SK_PNMI_MAX_IDX; - CounterIndex ++) { - - if (!StatAddr[CounterIndex][MacType].GetOffset) { - - continue; - } - - Value = GetPhysStatVal(pAC, IoC, PhysPortIndex, CounterIndex); - - pAC->Pnmi.VirtualCounterOffset[CounterIndex] += Value; - } - - /* - * Set port to inactive - */ - pAC->Pnmi.Port[PhysPortIndex].ActiveFlag = SK_FALSE; - - pAC->Pnmi.MacUpdatedFlag --; - break; - - case SK_PNMI_EVT_RLMT_ACTIVE_UP: - PhysPortIndex = (unsigned int)Param.Para32[0]; - NetIndex = (SK_U32)Param.Para32[1]; - -#ifdef DEBUG - if (PhysPortIndex >= SK_MAX_MACS) { - - SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL, - ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_RLMT_ACTIVE_UP parameter too high, PhysPort=%d\n", - PhysPortIndex)); - } - - if (NetIndex >= pAC->Rlmt.NumNets) { - - SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL, - ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_RLMT_ACTIVE_UP parameter too high, NetIndex=%d\n", - NetIndex)); - } -#endif /* DEBUG */ - - /* - * For now, ignore event if NetIndex != 0. - */ - if (Param.Para32[1] != 0) { - - return (0); - } - - /* - * Nothing to do if port is already active - */ - if (pAC->Pnmi.Port[PhysPortIndex].ActiveFlag) { - - return (0); - } - - /* - * Statistic maintenance - */ - pAC->Pnmi.RlmtChangeCts ++; - pAC->Pnmi.RlmtChangeTime = SK_PNMI_HUNDREDS_SEC(SkOsGetTime(pAC)); - - /* - * Store a trap message in the trap buffer and generate an event for - * user space applications with the SK_DRIVER_SENDEVENT macro. - */ - QueueRlmtNewMacTrap(pAC, PhysPortIndex); - (void)SK_DRIVER_SENDEVENT(pAC, IoC); - - /* - * Update statistic counters to calculate new offset for the virtual - * port and increment semaphore to indicate that an update was - * already done. - */ - if (MacUpdate(pAC, IoC, 0, pAC->GIni.GIMacsFound - 1) != - SK_PNMI_ERR_OK) { - - SK_PNMI_CHECKFLAGS("SkPnmiEvent: On return"); - return (0); - } - pAC->Pnmi.MacUpdatedFlag ++; - - /* - * Calculate new counter offset for virtual port to grant continous - * counting on port switches. A new port is added to the virtual port. - * Therefore substract the counter value of the new port from the - * CounterOffset for the virtual port to grant the same value. - */ - for (CounterIndex = 0; CounterIndex < SK_PNMI_MAX_IDX; - CounterIndex ++) { - - if (!StatAddr[CounterIndex][MacType].GetOffset) { - - continue; - } - - Value = GetPhysStatVal(pAC, IoC, PhysPortIndex, CounterIndex); - - pAC->Pnmi.VirtualCounterOffset[CounterIndex] -= Value; - } - - /* Set port to active */ - pAC->Pnmi.Port[PhysPortIndex].ActiveFlag = SK_TRUE; - - pAC->Pnmi.MacUpdatedFlag --; - break; - - case SK_PNMI_EVT_RLMT_SEGMENTATION: - /* - * Para.Para32[0] contains the NetIndex. - */ - - /* - * Store a trap message in the trap buffer and generate an event for - * user space applications with the SK_DRIVER_SENDEVENT macro. - */ - QueueSimpleTrap(pAC, OID_SKGE_TRAP_RLMT_SEGMENTATION); - (void)SK_DRIVER_SENDEVENT(pAC, IoC); - break; - - case SK_PNMI_EVT_RLMT_SET_NETS: - /* - * Param.Para32[0] contains the number of Nets. - * Param.Para32[1] is reserved, contains -1. - */ - /* - * Check number of nets - */ - MaxNetNumber = pAC->GIni.GIMacsFound; - if (((unsigned int)Param.Para32[0] < 1) - || ((unsigned int)Param.Para32[0] > MaxNetNumber)) { - return (SK_PNMI_ERR_UNKNOWN_NET); - } - - if ((unsigned int)Param.Para32[0] == 1) { /* single net mode */ - pAC->Pnmi.DualNetActiveFlag = SK_FALSE; - } - else { /* dual net mode */ - pAC->Pnmi.DualNetActiveFlag = SK_TRUE; - } - break; - - case SK_PNMI_EVT_VCT_RESET: - PhysPortIndex = Param.Para32[0]; - pPrt = &pAC->GIni.GP[PhysPortIndex]; - pVctBackupData = &pAC->Pnmi.VctBackup[PhysPortIndex]; - - if (pAC->Pnmi.VctStatus[PhysPortIndex] & SK_PNMI_VCT_PENDING) { - RetCode = SkGmCableDiagStatus(pAC, IoC, PhysPortIndex, SK_FALSE); - if (RetCode == 2) { - /* - * VCT test is still running. - * Start VCT timer counter again. - */ - SK_MEMSET((char *) &Param, 0, sizeof(Param)); - Param.Para32[0] = PhysPortIndex; - Param.Para32[1] = -1; - SkTimerStart(pAC, IoC, - &pAC->Pnmi.VctTimeout[PhysPortIndex].VctTimer, - 4000000, SKGE_PNMI, SK_PNMI_EVT_VCT_RESET, Param); - break; - } - pAC->Pnmi.VctStatus[PhysPortIndex] &= ~SK_PNMI_VCT_PENDING; - pAC->Pnmi.VctStatus[PhysPortIndex] |= - (SK_PNMI_VCT_NEW_VCT_DATA | SK_PNMI_VCT_TEST_DONE); - - /* Copy results for later use to PNMI struct. */ - for (i = 0; i < 4; i++) { - if (pPrt->PMdiPairSts[i] == SK_PNMI_VCT_NORMAL_CABLE) { - if ((pPrt->PMdiPairLen[i] > 35) && - (pPrt->PMdiPairLen[i] < 0xff)) { - pPrt->PMdiPairSts[i] = SK_PNMI_VCT_IMPEDANCE_MISMATCH; - } - } - if ((pPrt->PMdiPairLen[i] > 35) && - (pPrt->PMdiPairLen[i] != 0xff)) { - CableLength = 1000 * - (((175 * pPrt->PMdiPairLen[i]) / 210) - 28); - } - else { - CableLength = 0; - } - pVctBackupData->PMdiPairLen[i] = CableLength; - pVctBackupData->PMdiPairSts[i] = pPrt->PMdiPairSts[i]; - } - - Param.Para32[0] = PhysPortIndex; - Param.Para32[1] = -1; - SkEventQueue(pAC, SKGE_DRV, SK_DRV_PORT_RESET, Param); - SkEventDispatcher(pAC, IoC); - } - - break; - - default: - break; - } - - SK_PNMI_CHECKFLAGS("SkPnmiEvent: On return"); - return (0); -} - - -/****************************************************************************** - * - * Private functions - * - */ - -/***************************************************************************** - * - * PnmiVar - Gets, presets, and sets single OIDs - * - * Description: - * Looks up the requested OID, calls the corresponding handler - * function, and passes the parameters with the get, preset, or - * set command. The function is called by SkGePnmiGetVar, - * SkGePnmiPreSetVar, or SkGePnmiSetVar. - * - * Returns: - * SK_PNMI_ERR_XXX. For details have a look at the description of the - * calling functions. - * SK_PNMI_ERR_UNKNOWN_NET The requested NetIndex doesn't exist - */ -PNMI_STATIC int PnmiVar( -SK_AC *pAC, /* Pointer to adapter context */ -SK_IOC IoC, /* IO context handle */ -int Action, /* GET/PRESET/SET action */ -SK_U32 Id, /* Object ID that is to be processed */ -char *pBuf, /* Buffer used for the management data transfer */ -unsigned int *pLen, /* Total length of pBuf management data */ -SK_U32 Instance, /* Instance (1..n) that is to be set or -1 */ -SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */ -{ - unsigned int TableIndex; - int Ret; - - - if ((TableIndex = LookupId(Id)) == (unsigned int)(-1)) { - - *pLen = 0; - return (SK_PNMI_ERR_UNKNOWN_OID); - } - - /* Check NetIndex */ - if (NetIndex >= pAC->Rlmt.NumNets) { - return (SK_PNMI_ERR_UNKNOWN_NET); - } - - SK_PNMI_CHECKFLAGS("PnmiVar: On call"); - - Ret = IdTable[TableIndex].Func(pAC, IoC, Action, Id, pBuf, pLen, - Instance, TableIndex, NetIndex); - - SK_PNMI_CHECKFLAGS("PnmiVar: On return"); - - return (Ret); -} - -/***************************************************************************** - * - * PnmiStruct - Presets and Sets data in structure SK_PNMI_STRUCT_DATA - * - * Description: - * The return value of the function will also be stored in - * SK_PNMI_STRUCT_DATA if the passed buffer has the minimum size of - * SK_PNMI_MIN_STRUCT_SIZE. The sub-function runs through the IdTable, - * checks which OIDs are able to set, and calls the handler function of - * the OID to perform the set. The return value of the function will - * also be stored in SK_PNMI_STRUCT_DATA if the passed buffer has the - * minimum size of SK_PNMI_MIN_STRUCT_SIZE. The function is called - * by SkGePnmiPreSetStruct and SkGePnmiSetStruct. - * - * Returns: - * SK_PNMI_ERR_XXX. The codes are described in the calling functions. - * SK_PNMI_ERR_UNKNOWN_NET The requested NetIndex doesn't exist - */ -PNMI_STATIC int PnmiStruct( -SK_AC *pAC, /* Pointer to adapter context */ -SK_IOC IoC, /* IO context handle */ -int Action, /* PRESET/SET action to be performed */ -char *pBuf, /* Buffer used for the management data transfer */ -unsigned int *pLen, /* Length of pBuf management data buffer */ -SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */ -{ - int Ret; - unsigned int TableIndex; - unsigned int DstOffset; - unsigned int Len; - unsigned int InstanceNo; - unsigned int InstanceCnt; - SK_U32 Instance; - SK_U32 Id; - - - /* Check if the passed buffer has the right size */ - if (*pLen < SK_PNMI_STRUCT_SIZE) { - - /* Check if we can return the error within the buffer */ - if (*pLen >= SK_PNMI_MIN_STRUCT_SIZE) { - - SK_PNMI_SET_STAT(pBuf, SK_PNMI_ERR_TOO_SHORT, - (SK_U32)(-1)); - } - - *pLen = SK_PNMI_STRUCT_SIZE; - return (SK_PNMI_ERR_TOO_SHORT); - } - - /* Check NetIndex */ - if (NetIndex >= pAC->Rlmt.NumNets) { - return (SK_PNMI_ERR_UNKNOWN_NET); - } - - SK_PNMI_CHECKFLAGS("PnmiStruct: On call"); - - /* - * Update the values of RLMT and SIRQ and increment semaphores to - * indicate that an update was already done. - */ - if ((Ret = RlmtUpdate(pAC, IoC, NetIndex)) != SK_PNMI_ERR_OK) { - - SK_PNMI_SET_STAT(pBuf, Ret, (SK_U32)(-1)); - *pLen = SK_PNMI_MIN_STRUCT_SIZE; - return (Ret); - } - - if ((Ret = SirqUpdate(pAC, IoC)) != SK_PNMI_ERR_OK) { - - SK_PNMI_SET_STAT(pBuf, Ret, (SK_U32)(-1)); - *pLen = SK_PNMI_MIN_STRUCT_SIZE; - return (Ret); - } - - pAC->Pnmi.RlmtUpdatedFlag ++; - pAC->Pnmi.SirqUpdatedFlag ++; - - /* Preset/Set values */ - for (TableIndex = 0; TableIndex < ID_TABLE_SIZE; TableIndex ++) { - - if ((IdTable[TableIndex].Access != SK_PNMI_RW) && - (IdTable[TableIndex].Access != SK_PNMI_WO)) { - - continue; - } - - InstanceNo = IdTable[TableIndex].InstanceNo; - Id = IdTable[TableIndex].Id; - - for (InstanceCnt = 1; InstanceCnt <= InstanceNo; - InstanceCnt ++) { - - DstOffset = IdTable[TableIndex].Offset + - (InstanceCnt - 1) * - IdTable[TableIndex].StructSize; - - /* - * Because VPD multiple instance variables are - * not setable we do not need to evaluate VPD - * instances. Have a look to VPD instance - * calculation in SkPnmiGetStruct(). - */ - Instance = (SK_U32)InstanceCnt; - - /* - * Evaluate needed buffer length - */ - Len = 0; - Ret = IdTable[TableIndex].Func(pAC, IoC, - SK_PNMI_GET, IdTable[TableIndex].Id, - NULL, &Len, Instance, TableIndex, NetIndex); - - if (Ret == SK_PNMI_ERR_UNKNOWN_INST) { - - break; - } - if (Ret != SK_PNMI_ERR_TOO_SHORT) { - - pAC->Pnmi.RlmtUpdatedFlag --; - pAC->Pnmi.SirqUpdatedFlag --; - - SK_PNMI_CHECKFLAGS("PnmiStruct: On return"); - SK_PNMI_SET_STAT(pBuf, - SK_PNMI_ERR_GENERAL, DstOffset); - *pLen = SK_PNMI_MIN_STRUCT_SIZE; - return (SK_PNMI_ERR_GENERAL); - } - if (Id == OID_SKGE_VPD_ACTION) { - - switch (*(pBuf + DstOffset)) { - - case SK_PNMI_VPD_CREATE: - Len = 3 + *(pBuf + DstOffset + 3); - break; - - case SK_PNMI_VPD_DELETE: - Len = 3; - break; - - default: - Len = 1; - break; - } - } - - /* Call the OID handler function */ - Ret = IdTable[TableIndex].Func(pAC, IoC, Action, - IdTable[TableIndex].Id, pBuf + DstOffset, - &Len, Instance, TableIndex, NetIndex); - - if (Ret != SK_PNMI_ERR_OK) { - - pAC->Pnmi.RlmtUpdatedFlag --; - pAC->Pnmi.SirqUpdatedFlag --; - - SK_PNMI_CHECKFLAGS("PnmiStruct: On return"); - SK_PNMI_SET_STAT(pBuf, SK_PNMI_ERR_BAD_VALUE, - DstOffset); - *pLen = SK_PNMI_MIN_STRUCT_SIZE; - return (SK_PNMI_ERR_BAD_VALUE); - } - } - } - - pAC->Pnmi.RlmtUpdatedFlag --; - pAC->Pnmi.SirqUpdatedFlag --; - - SK_PNMI_CHECKFLAGS("PnmiStruct: On return"); - SK_PNMI_SET_STAT(pBuf, SK_PNMI_ERR_OK, (SK_U32)(-1)); - return (SK_PNMI_ERR_OK); -} - -/***************************************************************************** - * - * LookupId - Lookup an OID in the IdTable - * - * Description: - * Scans the IdTable to find the table entry of an OID. - * - * Returns: - * The table index or -1 if not found. - */ -PNMI_STATIC int LookupId( -SK_U32 Id) /* Object identifier to be searched */ -{ - int i; - - for (i = 0; i < ID_TABLE_SIZE; i++) { - - if (IdTable[i].Id == Id) { - - return i; - } - } - - return (-1); -} - -/***************************************************************************** - * - * OidStruct - Handler of OID_SKGE_ALL_DATA - * - * Description: - * This OID performs a Get/Preset/SetStruct call and returns all data - * in a SK_PNMI_STRUCT_DATA structure. - * - * Returns: - * SK_PNMI_ERR_OK The request was successfully performed. - * SK_PNMI_ERR_GENERAL A general severe internal error occured. - * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain - * the correct data (e.g. a 32bit value is - * needed, but a 16 bit value was passed). - * SK_PNMI_ERR_BAD_VALUE The passed value is not in the valid - * value range. - * SK_PNMI_ERR_READ_ONLY The OID is read-only and cannot be set. - * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't - * exist (e.g. port instance 3 on a two port - * adapter. - */ -PNMI_STATIC int OidStruct( -SK_AC *pAC, /* Pointer to adapter context */ -SK_IOC IoC, /* IO context handle */ -int Action, /* GET/PRESET/SET action */ -SK_U32 Id, /* Object ID that is to be processed */ -char *pBuf, /* Buffer used for the management data transfer */ -unsigned int *pLen, /* On call: pBuf buffer length. On return: used buffer */ -SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */ -unsigned int TableIndex, /* Index to the Id table */ -SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */ -{ - if (Id != OID_SKGE_ALL_DATA) { - - SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR003, - SK_PNMI_ERR003MSG); - - *pLen = 0; - return (SK_PNMI_ERR_GENERAL); - } - - /* - * Check instance. We only handle single instance variables - */ - if (Instance != (SK_U32)(-1) && Instance != 1) { - - *pLen = 0; - return (SK_PNMI_ERR_UNKNOWN_INST); - } - - switch (Action) { - - case SK_PNMI_GET: - return (SkPnmiGetStruct(pAC, IoC, pBuf, pLen, NetIndex)); - - case SK_PNMI_PRESET: - return (SkPnmiPreSetStruct(pAC, IoC, pBuf, pLen, NetIndex)); - - case SK_PNMI_SET: - return (SkPnmiSetStruct(pAC, IoC, pBuf, pLen, NetIndex)); - } - - SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR004, SK_PNMI_ERR004MSG); - - *pLen = 0; - return (SK_PNMI_ERR_GENERAL); -} - -/***************************************************************************** - * - * Perform - OID handler of OID_SKGE_ACTION - * - * Description: - * None. - * - * Returns: - * SK_PNMI_ERR_OK The request was successfully performed. - * SK_PNMI_ERR_GENERAL A general severe internal error occured. - * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain - * the correct data (e.g. a 32bit value is - * needed, but a 16 bit value was passed). - * SK_PNMI_ERR_BAD_VALUE The passed value is not in the valid - * value range. - * SK_PNMI_ERR_READ_ONLY The OID is read-only and cannot be set. - * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't - * exist (e.g. port instance 3 on a two port - * adapter. - */ -PNMI_STATIC int Perform( -SK_AC *pAC, /* Pointer to adapter context */ -SK_IOC IoC, /* IO context handle */ -int Action, /* GET/PRESET/SET action */ -SK_U32 Id, /* Object ID that is to be processed */ -char *pBuf, /* Buffer used for the management data transfer */ -unsigned int *pLen, /* On call: pBuf buffer length. On return: used buffer */ -SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */ -unsigned int TableIndex, /* Index to the Id table */ -SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */ -{ - int Ret; - SK_U32 ActionOp; - - - /* - * Check instance. We only handle single instance variables - */ - if (Instance != (SK_U32)(-1) && Instance != 1) { - - *pLen = 0; - return (SK_PNMI_ERR_UNKNOWN_INST); - } - - if (*pLen < sizeof(SK_U32)) { - - *pLen = sizeof(SK_U32); - return (SK_PNMI_ERR_TOO_SHORT); - } - - /* Check if a get should be performed */ - if (Action == SK_PNMI_GET) { - - /* A get is easy. We always return the same value */ - ActionOp = (SK_U32)SK_PNMI_ACT_IDLE; - SK_PNMI_STORE_U32(pBuf, ActionOp); - *pLen = sizeof(SK_U32); - - return (SK_PNMI_ERR_OK); - } - - /* Continue with PRESET/SET action */ - if (*pLen > sizeof(SK_U32)) { - - return (SK_PNMI_ERR_BAD_VALUE); - } - - /* Check if the command is a known one */ - SK_PNMI_READ_U32(pBuf, ActionOp); - if (*pLen > sizeof(SK_U32) || - (ActionOp != SK_PNMI_ACT_IDLE && - ActionOp != SK_PNMI_ACT_RESET && - ActionOp != SK_PNMI_ACT_SELFTEST && - ActionOp != SK_PNMI_ACT_RESETCNT)) { - - *pLen = 0; - return (SK_PNMI_ERR_BAD_VALUE); - } - - /* A preset ends here */ - if (Action == SK_PNMI_PRESET) { - - return (SK_PNMI_ERR_OK); - } - - switch (ActionOp) { - - case SK_PNMI_ACT_IDLE: - /* Nothing to do */ - break; - - case SK_PNMI_ACT_RESET: - /* - * Perform a driver reset or something that comes near - * to this. - */ - Ret = SK_DRIVER_RESET(pAC, IoC); - if (Ret != 0) { - - SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR005, - SK_PNMI_ERR005MSG); - - return (SK_PNMI_ERR_GENERAL); - } - break; - - case SK_PNMI_ACT_SELFTEST: - /* - * Perform a driver selftest or something similar to this. - * Currently this feature is not used and will probably - * implemented in another way. - */ - Ret = SK_DRIVER_SELFTEST(pAC, IoC); - pAC->Pnmi.TestResult = Ret; - break; - - case SK_PNMI_ACT_RESETCNT: - /* Set all counters and timestamps to zero */ - ResetCounter(pAC, IoC, NetIndex); - break; - - default: - SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR006, - SK_PNMI_ERR006MSG); - - return (SK_PNMI_ERR_GENERAL); - } - - return (SK_PNMI_ERR_OK); -} - -/***************************************************************************** - * - * Mac8023Stat - OID handler of OID_GEN_XXX and OID_802_3_XXX - * - * Description: - * Retrieves the statistic values of the virtual port (logical - * index 0). Only special OIDs of NDIS are handled which consist - * of a 32 bit instead of a 64 bit value. The OIDs are public - * because perhaps some other platform can use them too. - * - * Returns: - * SK_PNMI_ERR_OK The request was successfully performed. - * SK_PNMI_ERR_GENERAL A general severe internal error occured. - * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain - * the correct data (e.g. a 32bit value is - * needed, but a 16 bit value was passed). - * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't - * exist (e.g. port instance 3 on a two port - * adapter. - */ -PNMI_STATIC int Mac8023Stat( -SK_AC *pAC, /* Pointer to adapter context */ -SK_IOC IoC, /* IO context handle */ -int Action, /* GET/PRESET/SET action */ -SK_U32 Id, /* Object ID that is to be processed */ -char *pBuf, /* Buffer used for the management data transfer */ -unsigned int *pLen, /* On call: pBuf buffer length. On return: used buffer */ -SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */ -unsigned int TableIndex, /* Index to the Id table */ -SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */ -{ - int Ret; - SK_U64 StatVal; - SK_U32 StatVal32; - SK_BOOL Is64BitReq = SK_FALSE; - - /* - * Only the active Mac is returned - */ - if (Instance != (SK_U32)(-1) && Instance != 1) { - - *pLen = 0; - return (SK_PNMI_ERR_UNKNOWN_INST); - } - - /* - * Check action type - */ - if (Action != SK_PNMI_GET) { - - *pLen = 0; - return (SK_PNMI_ERR_READ_ONLY); - } - - /* Check length */ - switch (Id) { - - case OID_802_3_PERMANENT_ADDRESS: - case OID_802_3_CURRENT_ADDRESS: - if (*pLen < sizeof(SK_MAC_ADDR)) { - - *pLen = sizeof(SK_MAC_ADDR); - return (SK_PNMI_ERR_TOO_SHORT); - } - break; - - default: -#ifndef SK_NDIS_64BIT_CTR - if (*pLen < sizeof(SK_U32)) { - *pLen = sizeof(SK_U32); - return (SK_PNMI_ERR_TOO_SHORT); - } - -#else /* SK_NDIS_64BIT_CTR */ - - /* for compatibility, at least 32bit are required for OID */ - if (*pLen < sizeof(SK_U32)) { - /* - * but indicate handling for 64bit values, - * if insufficient space is provided - */ - *pLen = sizeof(SK_U64); - return (SK_PNMI_ERR_TOO_SHORT); - } - - Is64BitReq = (*pLen < sizeof(SK_U64)) ? SK_FALSE : SK_TRUE; -#endif /* SK_NDIS_64BIT_CTR */ - break; - } - - /* - * Update all statistics, because we retrieve virtual MAC, which - * consists of multiple physical statistics and increment semaphore - * to indicate that an update was already done. - */ - Ret = MacUpdate(pAC, IoC, 0, pAC->GIni.GIMacsFound - 1); - if ( Ret != SK_PNMI_ERR_OK) { - - *pLen = 0; - return (Ret); - } - pAC->Pnmi.MacUpdatedFlag ++; - - /* - * Get value (MAC Index 0 identifies the virtual MAC) - */ - switch (Id) { - - case OID_802_3_PERMANENT_ADDRESS: - CopyMac(pBuf, &pAC->Addr.Net[NetIndex].PermanentMacAddress); - *pLen = sizeof(SK_MAC_ADDR); - break; - - case OID_802_3_CURRENT_ADDRESS: - CopyMac(pBuf, &pAC->Addr.Net[NetIndex].CurrentMacAddress); - *pLen = sizeof(SK_MAC_ADDR); - break; - - default: - StatVal = GetStatVal(pAC, IoC, 0, IdTable[TableIndex].Param, NetIndex); - - /* by default 32bit values are evaluated */ - if (!Is64BitReq) { - StatVal32 = (SK_U32)StatVal; - SK_PNMI_STORE_U32(pBuf, StatVal32); - *pLen = sizeof(SK_U32); - } - else { - SK_PNMI_STORE_U64(pBuf, StatVal); - *pLen = sizeof(SK_U64); - } - break; - } - - pAC->Pnmi.MacUpdatedFlag --; - - return (SK_PNMI_ERR_OK); -} - -/***************************************************************************** - * - * MacPrivateStat - OID handler function of OID_SKGE_STAT_XXX - * - * Description: - * Retrieves the MAC statistic data. - * - * Returns: - * SK_PNMI_ERR_OK The request was successfully performed. - * SK_PNMI_ERR_GENERAL A general severe internal error occured. - * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain - * the correct data (e.g. a 32bit value is - * needed, but a 16 bit value was passed). - * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't - * exist (e.g. port instance 3 on a two port - * adapter. - */ -PNMI_STATIC int MacPrivateStat( -SK_AC *pAC, /* Pointer to adapter context */ -SK_IOC IoC, /* IO context handle */ -int Action, /* GET/PRESET/SET action */ -SK_U32 Id, /* Object ID that is to be processed */ -char *pBuf, /* Buffer used for the management data transfer */ -unsigned int *pLen, /* On call: pBuf buffer length. On return: used buffer */ -SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */ -unsigned int TableIndex, /* Index to the Id table */ -SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */ -{ - unsigned int LogPortMax; - unsigned int LogPortIndex; - unsigned int PhysPortMax; - unsigned int Limit; - unsigned int Offset; - int MacType; - int Ret; - SK_U64 StatVal; - - - - /* Calculate instance if wished. MAC index 0 is the virtual MAC */ - PhysPortMax = pAC->GIni.GIMacsFound; - LogPortMax = SK_PNMI_PORT_PHYS2LOG(PhysPortMax); - - MacType = pAC->GIni.GIMacType; - - if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { /* Dual net mode */ - LogPortMax--; - } - - if ((Instance != (SK_U32)(-1))) { /* Only one specific instance is queried */ - /* Check instance range */ - if ((Instance < 1) || (Instance > LogPortMax)) { - - *pLen = 0; - return (SK_PNMI_ERR_UNKNOWN_INST); - } - LogPortIndex = SK_PNMI_PORT_INST2LOG(Instance); - Limit = LogPortIndex + 1; - } - - else { /* Instance == (SK_U32)(-1), get all Instances of that OID */ - - LogPortIndex = 0; - Limit = LogPortMax; - } - - /* Check action */ - if (Action != SK_PNMI_GET) { - - *pLen = 0; - return (SK_PNMI_ERR_READ_ONLY); - } - - /* Check length */ - if (*pLen < (Limit - LogPortIndex) * sizeof(SK_U64)) { - - *pLen = (Limit - LogPortIndex) * sizeof(SK_U64); - return (SK_PNMI_ERR_TOO_SHORT); - } - - /* - * Update MAC statistic and increment semaphore to indicate that - * an update was already done. - */ - Ret = MacUpdate(pAC, IoC, 0, pAC->GIni.GIMacsFound - 1); - if (Ret != SK_PNMI_ERR_OK) { - - *pLen = 0; - return (Ret); - } - pAC->Pnmi.MacUpdatedFlag ++; - - /* Get value */ - Offset = 0; - for (; LogPortIndex < Limit; LogPortIndex ++) { - - switch (Id) { - -/* XXX not yet implemented due to XMAC problems - case OID_SKGE_STAT_TX_UTIL: - return (SK_PNMI_ERR_GENERAL); -*/ -/* XXX not yet implemented due to XMAC problems - case OID_SKGE_STAT_RX_UTIL: - return (SK_PNMI_ERR_GENERAL); -*/ - case OID_SKGE_STAT_RX: - if (MacType == SK_MAC_GMAC) { - StatVal = - GetStatVal(pAC, IoC, LogPortIndex, - SK_PNMI_HRX_BROADCAST, NetIndex) + - GetStatVal(pAC, IoC, LogPortIndex, - SK_PNMI_HRX_MULTICAST, NetIndex) + - GetStatVal(pAC, IoC, LogPortIndex, - SK_PNMI_HRX_UNICAST, NetIndex) + - GetStatVal(pAC, IoC, LogPortIndex, - SK_PNMI_HRX_UNDERSIZE, NetIndex); - } - else { - StatVal = GetStatVal(pAC, IoC, LogPortIndex, - IdTable[TableIndex].Param, NetIndex); - } - break; - - case OID_SKGE_STAT_TX: - if (MacType == SK_MAC_GMAC) { - StatVal = - GetStatVal(pAC, IoC, LogPortIndex, - SK_PNMI_HTX_BROADCAST, NetIndex) + - GetStatVal(pAC, IoC, LogPortIndex, - SK_PNMI_HTX_MULTICAST, NetIndex) + - GetStatVal(pAC, IoC, LogPortIndex, - SK_PNMI_HTX_UNICAST, NetIndex); - } - else { - StatVal = GetStatVal(pAC, IoC, LogPortIndex, - IdTable[TableIndex].Param, NetIndex); - } - break; - - default: - StatVal = GetStatVal(pAC, IoC, LogPortIndex, - IdTable[TableIndex].Param, NetIndex); - } - SK_PNMI_STORE_U64(pBuf + Offset, StatVal); - - Offset += sizeof(SK_U64); - } - *pLen = Offset; - - pAC->Pnmi.MacUpdatedFlag --; - - return (SK_PNMI_ERR_OK); -} - -/***************************************************************************** - * - * Addr - OID handler function of OID_SKGE_PHYS_CUR_ADDR and _FAC_ADDR - * - * Description: - * Get/Presets/Sets the current and factory MAC address. The MAC - * address of the virtual port, which is reported to the OS, may - * not be changed, but the physical ones. A set to the virtual port - * will be ignored. No error should be reported because otherwise - * a multiple instance set (-1) would always fail. - * - * Returns: - * SK_PNMI_ERR_OK The request was successfully performed. - * SK_PNMI_ERR_GENERAL A general severe internal error occured. - * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain - * the correct data (e.g. a 32bit value is - * needed, but a 16 bit value was passed). - * SK_PNMI_ERR_BAD_VALUE The passed value is not in the valid - * value range. - * SK_PNMI_ERR_READ_ONLY The OID is read-only and cannot be set. - * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't - * exist (e.g. port instance 3 on a two port - * adapter. - */ -PNMI_STATIC int Addr( -SK_AC *pAC, /* Pointer to adapter context */ -SK_IOC IoC, /* IO context handle */ -int Action, /* GET/PRESET/SET action */ -SK_U32 Id, /* Object ID that is to be processed */ -char *pBuf, /* Buffer used for the management data transfer */ -unsigned int *pLen, /* On call: pBuf buffer length. On return: used buffer */ -SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */ -unsigned int TableIndex, /* Index to the Id table */ -SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */ -{ - int Ret; - unsigned int LogPortMax; - unsigned int PhysPortMax; - unsigned int LogPortIndex; - unsigned int PhysPortIndex; - unsigned int Limit; - unsigned int Offset = 0; - - /* - * Calculate instance if wished. MAC index 0 is the virtual - * MAC. - */ - PhysPortMax = pAC->GIni.GIMacsFound; - LogPortMax = SK_PNMI_PORT_PHYS2LOG(PhysPortMax); - - if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { /* Dual net mode */ - LogPortMax--; - } - - if ((Instance != (SK_U32)(-1))) { /* Only one specific instance is queried */ - /* Check instance range */ - if ((Instance < 1) || (Instance > LogPortMax)) { - - *pLen = 0; - return (SK_PNMI_ERR_UNKNOWN_INST); - } - LogPortIndex = SK_PNMI_PORT_INST2LOG(Instance); - Limit = LogPortIndex + 1; - } - else { /* Instance == (SK_U32)(-1), get all Instances of that OID */ - - LogPortIndex = 0; - Limit = LogPortMax; - } - - /* - * Perform Action - */ - if (Action == SK_PNMI_GET) { - - /* Check length */ - if (*pLen < (Limit - LogPortIndex) * 6) { - - *pLen = (Limit - LogPortIndex) * 6; - return (SK_PNMI_ERR_TOO_SHORT); - } - - /* - * Get value - */ - for (; LogPortIndex < Limit; LogPortIndex ++) { - - switch (Id) { - - case OID_SKGE_PHYS_CUR_ADDR: - if (LogPortIndex == 0) { - CopyMac(pBuf + Offset, &pAC->Addr.Net[NetIndex].CurrentMacAddress); - } - else { - PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(pAC, LogPortIndex); - - CopyMac(pBuf + Offset, - &pAC->Addr.Port[PhysPortIndex].CurrentMacAddress); - } - Offset += 6; - break; - - case OID_SKGE_PHYS_FAC_ADDR: - if (LogPortIndex == 0) { - CopyMac(pBuf + Offset, - &pAC->Addr.Net[NetIndex].PermanentMacAddress); - } - else { - PhysPortIndex = SK_PNMI_PORT_LOG2PHYS( - pAC, LogPortIndex); - - CopyMac(pBuf + Offset, - &pAC->Addr.Port[PhysPortIndex].PermanentMacAddress); - } - Offset += 6; - break; - - default: - SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR008, - SK_PNMI_ERR008MSG); - - *pLen = 0; - return (SK_PNMI_ERR_GENERAL); - } - } - - *pLen = Offset; - } - else { - /* - * The logical MAC address may not be changed only - * the physical ones - */ - if (Id == OID_SKGE_PHYS_FAC_ADDR) { - - *pLen = 0; - return (SK_PNMI_ERR_READ_ONLY); - } - - /* - * Only the current address may be changed - */ - if (Id != OID_SKGE_PHYS_CUR_ADDR) { - - SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR009, - SK_PNMI_ERR009MSG); - - *pLen = 0; - return (SK_PNMI_ERR_GENERAL); - } - - /* Check length */ - if (*pLen < (Limit - LogPortIndex) * 6) { - - *pLen = (Limit - LogPortIndex) * 6; - return (SK_PNMI_ERR_TOO_SHORT); - } - if (*pLen > (Limit - LogPortIndex) * 6) { - - *pLen = 0; - return (SK_PNMI_ERR_BAD_VALUE); - } - - /* - * Check Action - */ - if (Action == SK_PNMI_PRESET) { - - *pLen = 0; - return (SK_PNMI_ERR_OK); - } - - /* - * Set OID_SKGE_MAC_CUR_ADDR - */ - for (; LogPortIndex < Limit; LogPortIndex ++, Offset += 6) { - - /* - * A set to virtual port and set of broadcast - * address will be ignored - */ - if (LogPortIndex == 0 || SK_MEMCMP(pBuf + Offset, - "\xff\xff\xff\xff\xff\xff", 6) == 0) { - - continue; - } - - PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(pAC, - LogPortIndex); - - Ret = SkAddrOverride(pAC, IoC, PhysPortIndex, - (SK_MAC_ADDR *)(pBuf + Offset), - (LogPortIndex == 0 ? SK_ADDR_VIRTUAL_ADDRESS : - SK_ADDR_PHYSICAL_ADDRESS)); - if (Ret != SK_ADDR_OVERRIDE_SUCCESS) { - - return (SK_PNMI_ERR_GENERAL); - } - } - *pLen = Offset; - } - - return (SK_PNMI_ERR_OK); -} - -/***************************************************************************** - * - * CsumStat - OID handler function of OID_SKGE_CHKSM_XXX - * - * Description: - * Retrieves the statistic values of the CSUM module. The CSUM data - * structure must be available in the SK_AC even if the CSUM module - * is not included, because PNMI reads the statistic data from the - * CSUM part of SK_AC directly. - * - * Returns: - * SK_PNMI_ERR_OK The request was successfully performed. - * SK_PNMI_ERR_GENERAL A general severe internal error occured. - * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain - * the correct data (e.g. a 32bit value is - * needed, but a 16 bit value was passed). - * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't - * exist (e.g. port instance 3 on a two port - * adapter. - */ -PNMI_STATIC int CsumStat( -SK_AC *pAC, /* Pointer to adapter context */ -SK_IOC IoC, /* IO context handle */ -int Action, /* GET/PRESET/SET action */ -SK_U32 Id, /* Object ID that is to be processed */ -char *pBuf, /* Buffer used for the management data transfer */ -unsigned int *pLen, /* On call: pBuf buffer length. On return: used buffer */ -SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */ -unsigned int TableIndex, /* Index to the Id table */ -SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */ -{ - unsigned int Index; - unsigned int Limit; - unsigned int Offset = 0; - SK_U64 StatVal; - - - /* - * Calculate instance if wished - */ - if (Instance != (SK_U32)(-1)) { - - if ((Instance < 1) || (Instance > SKCS_NUM_PROTOCOLS)) { - - *pLen = 0; - return (SK_PNMI_ERR_UNKNOWN_INST); - } - Index = (unsigned int)Instance - 1; - Limit = Index + 1; - } - else { - Index = 0; - Limit = SKCS_NUM_PROTOCOLS; - } - - /* - * Check action - */ - if (Action != SK_PNMI_GET) { - - *pLen = 0; - return (SK_PNMI_ERR_READ_ONLY); - } - - /* Check length */ - if (*pLen < (Limit - Index) * sizeof(SK_U64)) { - - *pLen = (Limit - Index) * sizeof(SK_U64); - return (SK_PNMI_ERR_TOO_SHORT); - } - - /* - * Get value - */ - for (; Index < Limit; Index ++) { - - switch (Id) { - - case OID_SKGE_CHKSM_RX_OK_CTS: - StatVal = pAC->Csum.ProtoStats[NetIndex][Index].RxOkCts; - break; - - case OID_SKGE_CHKSM_RX_UNABLE_CTS: - StatVal = pAC->Csum.ProtoStats[NetIndex][Index].RxUnableCts; - break; - - case OID_SKGE_CHKSM_RX_ERR_CTS: - StatVal = pAC->Csum.ProtoStats[NetIndex][Index].RxErrCts; - break; - - case OID_SKGE_CHKSM_TX_OK_CTS: - StatVal = pAC->Csum.ProtoStats[NetIndex][Index].TxOkCts; - break; - - case OID_SKGE_CHKSM_TX_UNABLE_CTS: - StatVal = pAC->Csum.ProtoStats[NetIndex][Index].TxUnableCts; - break; - - default: - SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR010, - SK_PNMI_ERR010MSG); - - *pLen = 0; - return (SK_PNMI_ERR_GENERAL); - } - - SK_PNMI_STORE_U64(pBuf + Offset, StatVal); - Offset += sizeof(SK_U64); - } - - /* - * Store used buffer space - */ - *pLen = Offset; - - return (SK_PNMI_ERR_OK); -} - -/***************************************************************************** - * - * SensorStat - OID handler function of OID_SKGE_SENSOR_XXX - * - * Description: - * Retrieves the statistic values of the I2C module, which handles - * the temperature and voltage sensors. - * - * Returns: - * SK_PNMI_ERR_OK The request was successfully performed. - * SK_PNMI_ERR_GENERAL A general severe internal error occured. - * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain - * the correct data (e.g. a 32bit value is - * needed, but a 16 bit value was passed). - * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't - * exist (e.g. port instance 3 on a two port - * adapter. - */ -PNMI_STATIC int SensorStat( -SK_AC *pAC, /* Pointer to adapter context */ -SK_IOC IoC, /* IO context handle */ -int Action, /* GET/PRESET/SET action */ -SK_U32 Id, /* Object ID that is to be processed */ -char *pBuf, /* Buffer used for the management data transfer */ -unsigned int *pLen, /* On call: pBuf buffer length. On return: used buffer */ -SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */ -unsigned int TableIndex, /* Index to the Id table */ -SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */ -{ - unsigned int i; - unsigned int Index; - unsigned int Limit; - unsigned int Offset; - unsigned int Len; - SK_U32 Val32; - SK_U64 Val64; - - - /* - * Calculate instance if wished - */ - if ((Instance != (SK_U32)(-1))) { - - if ((Instance < 1) || (Instance > (SK_U32)pAC->I2c.MaxSens)) { - - *pLen = 0; - return (SK_PNMI_ERR_UNKNOWN_INST); - } - - Index = (unsigned int)Instance -1; - Limit = (unsigned int)Instance; - } - else { - Index = 0; - Limit = (unsigned int) pAC->I2c.MaxSens; - } - - /* - * Check action - */ - if (Action != SK_PNMI_GET) { - - *pLen = 0; - return (SK_PNMI_ERR_READ_ONLY); - } - - /* Check length */ - switch (Id) { - - case OID_SKGE_SENSOR_VALUE: - case OID_SKGE_SENSOR_WAR_THRES_LOW: - case OID_SKGE_SENSOR_WAR_THRES_UPP: - case OID_SKGE_SENSOR_ERR_THRES_LOW: - case OID_SKGE_SENSOR_ERR_THRES_UPP: - if (*pLen < (Limit - Index) * sizeof(SK_U32)) { - - *pLen = (Limit - Index) * sizeof(SK_U32); - return (SK_PNMI_ERR_TOO_SHORT); - } - break; - - case OID_SKGE_SENSOR_DESCR: - for (Offset = 0, i = Index; i < Limit; i ++) { - - Len = (unsigned int) - SK_STRLEN(pAC->I2c.SenTable[i].SenDesc) + 1; - if (Len >= SK_PNMI_STRINGLEN2) { - - SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR011, - SK_PNMI_ERR011MSG); - - *pLen = 0; - return (SK_PNMI_ERR_GENERAL); - } - Offset += Len; - } - if (*pLen < Offset) { - - *pLen = Offset; - return (SK_PNMI_ERR_TOO_SHORT); - } - break; - - case OID_SKGE_SENSOR_INDEX: - case OID_SKGE_SENSOR_TYPE: - case OID_SKGE_SENSOR_STATUS: - if (*pLen < Limit - Index) { - - *pLen = Limit - Index; - return (SK_PNMI_ERR_TOO_SHORT); - } - break; - - case OID_SKGE_SENSOR_WAR_CTS: - case OID_SKGE_SENSOR_WAR_TIME: - case OID_SKGE_SENSOR_ERR_CTS: - case OID_SKGE_SENSOR_ERR_TIME: - if (*pLen < (Limit - Index) * sizeof(SK_U64)) { - - *pLen = (Limit - Index) * sizeof(SK_U64); - return (SK_PNMI_ERR_TOO_SHORT); - } - break; - - default: - SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR012, - SK_PNMI_ERR012MSG); - - *pLen = 0; - return (SK_PNMI_ERR_GENERAL); - - } - - /* - * Get value - */ - for (Offset = 0; Index < Limit; Index ++) { - - switch (Id) { - - case OID_SKGE_SENSOR_INDEX: - *(pBuf + Offset) = (char)Index; - Offset += sizeof(char); - break; - - case OID_SKGE_SENSOR_DESCR: - Len = SK_STRLEN(pAC->I2c.SenTable[Index].SenDesc); - SK_MEMCPY(pBuf + Offset + 1, - pAC->I2c.SenTable[Index].SenDesc, Len); - *(pBuf + Offset) = (char)Len; - Offset += Len + 1; - break; - - case OID_SKGE_SENSOR_TYPE: - *(pBuf + Offset) = - (char)pAC->I2c.SenTable[Index].SenType; - Offset += sizeof(char); - break; - - case OID_SKGE_SENSOR_VALUE: - Val32 = (SK_U32)pAC->I2c.SenTable[Index].SenValue; - SK_PNMI_STORE_U32(pBuf + Offset, Val32); - Offset += sizeof(SK_U32); - break; - - case OID_SKGE_SENSOR_WAR_THRES_LOW: - Val32 = (SK_U32)pAC->I2c.SenTable[Index]. - SenThreWarnLow; - SK_PNMI_STORE_U32(pBuf + Offset, Val32); - Offset += sizeof(SK_U32); - break; - - case OID_SKGE_SENSOR_WAR_THRES_UPP: - Val32 = (SK_U32)pAC->I2c.SenTable[Index]. - SenThreWarnHigh; - SK_PNMI_STORE_U32(pBuf + Offset, Val32); - Offset += sizeof(SK_U32); - break; - - case OID_SKGE_SENSOR_ERR_THRES_LOW: - Val32 = (SK_U32)pAC->I2c.SenTable[Index]. - SenThreErrLow; - SK_PNMI_STORE_U32(pBuf + Offset, Val32); - Offset += sizeof(SK_U32); - break; - - case OID_SKGE_SENSOR_ERR_THRES_UPP: - Val32 = pAC->I2c.SenTable[Index].SenThreErrHigh; - SK_PNMI_STORE_U32(pBuf + Offset, Val32); - Offset += sizeof(SK_U32); - break; - - case OID_SKGE_SENSOR_STATUS: - *(pBuf + Offset) = - (char)pAC->I2c.SenTable[Index].SenErrFlag; - Offset += sizeof(char); - break; - - case OID_SKGE_SENSOR_WAR_CTS: - Val64 = pAC->I2c.SenTable[Index].SenWarnCts; - SK_PNMI_STORE_U64(pBuf + Offset, Val64); - Offset += sizeof(SK_U64); - break; - - case OID_SKGE_SENSOR_ERR_CTS: - Val64 = pAC->I2c.SenTable[Index].SenErrCts; - SK_PNMI_STORE_U64(pBuf + Offset, Val64); - Offset += sizeof(SK_U64); - break; - - case OID_SKGE_SENSOR_WAR_TIME: - Val64 = SK_PNMI_HUNDREDS_SEC(pAC->I2c.SenTable[Index]. - SenBegWarnTS); - SK_PNMI_STORE_U64(pBuf + Offset, Val64); - Offset += sizeof(SK_U64); - break; - - case OID_SKGE_SENSOR_ERR_TIME: - Val64 = SK_PNMI_HUNDREDS_SEC(pAC->I2c.SenTable[Index]. - SenBegErrTS); - SK_PNMI_STORE_U64(pBuf + Offset, Val64); - Offset += sizeof(SK_U64); - break; - - default: - SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_ERR, - ("SensorStat: Unknown OID should be handled before")); - - return (SK_PNMI_ERR_GENERAL); - } - } - - /* - * Store used buffer space - */ - *pLen = Offset; - - return (SK_PNMI_ERR_OK); -} - -/***************************************************************************** - * - * Vpd - OID handler function of OID_SKGE_VPD_XXX - * - * Description: - * Get/preset/set of VPD data. As instance the name of a VPD key - * can be passed. The Instance parameter is a SK_U32 and can be - * used as a string buffer for the VPD key, because their maximum - * length is 4 byte. - * - * Returns: - * SK_PNMI_ERR_OK The request was successfully performed. - * SK_PNMI_ERR_GENERAL A general severe internal error occured. - * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain - * the correct data (e.g. a 32bit value is - * needed, but a 16 bit value was passed). - * SK_PNMI_ERR_BAD_VALUE The passed value is not in the valid - * value range. - * SK_PNMI_ERR_READ_ONLY The OID is read-only and cannot be set. - * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't - * exist (e.g. port instance 3 on a two port - * adapter. - */ -PNMI_STATIC int Vpd( -SK_AC *pAC, /* Pointer to adapter context */ -SK_IOC IoC, /* IO context handle */ -int Action, /* GET/PRESET/SET action */ -SK_U32 Id, /* Object ID that is to be processed */ -char *pBuf, /* Buffer used for the management data transfer */ -unsigned int *pLen, /* On call: pBuf buffer length. On return: used buffer */ -SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */ -unsigned int TableIndex, /* Index to the Id table */ -SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */ -{ - SK_VPD_STATUS *pVpdStatus; - unsigned int BufLen; - char Buf[256]; - char KeyArr[SK_PNMI_VPD_ENTRIES][SK_PNMI_VPD_KEY_SIZE]; - char KeyStr[SK_PNMI_VPD_KEY_SIZE]; - unsigned int KeyNo; - unsigned int Offset; - unsigned int Index; - unsigned int FirstIndex; - unsigned int LastIndex; - unsigned int Len; - int Ret; - SK_U32 Val32; - - /* - * Get array of all currently stored VPD keys - */ - Ret = GetVpdKeyArr(pAC, IoC, &KeyArr[0][0], sizeof(KeyArr), &KeyNo); - if (Ret != SK_PNMI_ERR_OK) { - *pLen = 0; - return (Ret); - } - - /* - * If instance is not -1, try to find the requested VPD key for - * the multiple instance variables. The other OIDs as for example - * OID VPD_ACTION are single instance variables and must be - * handled separatly. - */ - FirstIndex = 0; - LastIndex = KeyNo; - - if ((Instance != (SK_U32)(-1))) { - - if (Id == OID_SKGE_VPD_KEY || Id == OID_SKGE_VPD_VALUE || - Id == OID_SKGE_VPD_ACCESS) { - - SK_STRNCPY(KeyStr, (char *)&Instance, 4); - KeyStr[4] = 0; - - for (Index = 0; Index < KeyNo; Index ++) { - - if (SK_STRCMP(KeyStr, KeyArr[Index]) == 0) { - FirstIndex = Index; - LastIndex = Index+1; - break; - } - } - if (Index == KeyNo) { - - *pLen = 0; - return (SK_PNMI_ERR_UNKNOWN_INST); - } - } - else if (Instance != 1) { - - *pLen = 0; - return (SK_PNMI_ERR_UNKNOWN_INST); - } - } - - /* - * Get value, if a query should be performed - */ - if (Action == SK_PNMI_GET) { - - switch (Id) { - - case OID_SKGE_VPD_FREE_BYTES: - /* Check length of buffer */ - if (*pLen < sizeof(SK_U32)) { - - *pLen = sizeof(SK_U32); - return (SK_PNMI_ERR_TOO_SHORT); - } - /* Get number of free bytes */ - pVpdStatus = VpdStat(pAC, IoC); - if (pVpdStatus == NULL) { - - SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR017, - SK_PNMI_ERR017MSG); - - *pLen = 0; - return (SK_PNMI_ERR_GENERAL); - } - if ((pVpdStatus->vpd_status & VPD_VALID) == 0) { - - SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR018, - SK_PNMI_ERR018MSG); - - *pLen = 0; - return (SK_PNMI_ERR_GENERAL); - } - - Val32 = (SK_U32)pVpdStatus->vpd_free_rw; - SK_PNMI_STORE_U32(pBuf, Val32); - *pLen = sizeof(SK_U32); - break; - - case OID_SKGE_VPD_ENTRIES_LIST: - /* Check length */ - for (Len = 0, Index = 0; Index < KeyNo; Index ++) { - - Len += SK_STRLEN(KeyArr[Index]) + 1; - } - if (*pLen < Len) { - - *pLen = Len; - return (SK_PNMI_ERR_TOO_SHORT); - } - - /* Get value */ - *(pBuf) = (char)Len - 1; - for (Offset = 1, Index = 0; Index < KeyNo; Index ++) { - - Len = SK_STRLEN(KeyArr[Index]); - SK_MEMCPY(pBuf + Offset, KeyArr[Index], Len); - - Offset += Len; - - if (Index < KeyNo - 1) { - - *(pBuf + Offset) = ' '; - Offset ++; - } - } - *pLen = Offset; - break; - - case OID_SKGE_VPD_ENTRIES_NUMBER: - /* Check length */ - if (*pLen < sizeof(SK_U32)) { - - *pLen = sizeof(SK_U32); - return (SK_PNMI_ERR_TOO_SHORT); - } - - Val32 = (SK_U32)KeyNo; - SK_PNMI_STORE_U32(pBuf, Val32); - *pLen = sizeof(SK_U32); - break; - - case OID_SKGE_VPD_KEY: - /* Check buffer length, if it is large enough */ - for (Len = 0, Index = FirstIndex; - Index < LastIndex; Index ++) { - - Len += SK_STRLEN(KeyArr[Index]) + 1; - } - if (*pLen < Len) { - - *pLen = Len; - return (SK_PNMI_ERR_TOO_SHORT); - } - - /* - * Get the key to an intermediate buffer, because - * we have to prepend a length byte. - */ - for (Offset = 0, Index = FirstIndex; - Index < LastIndex; Index ++) { - - Len = SK_STRLEN(KeyArr[Index]); - - *(pBuf + Offset) = (char)Len; - SK_MEMCPY(pBuf + Offset + 1, KeyArr[Index], - Len); - Offset += Len + 1; - } - *pLen = Offset; - break; - - case OID_SKGE_VPD_VALUE: - /* Check the buffer length if it is large enough */ - for (Offset = 0, Index = FirstIndex; - Index < LastIndex; Index ++) { - - BufLen = 256; - if (VpdRead(pAC, IoC, KeyArr[Index], Buf, - (int *)&BufLen) > 0 || - BufLen >= SK_PNMI_VPD_DATALEN) { - - SK_ERR_LOG(pAC, SK_ERRCL_SW, - SK_PNMI_ERR021, - SK_PNMI_ERR021MSG); - - return (SK_PNMI_ERR_GENERAL); - } - Offset += BufLen + 1; - } - if (*pLen < Offset) { - - *pLen = Offset; - return (SK_PNMI_ERR_TOO_SHORT); - } - - /* - * Get the value to an intermediate buffer, because - * we have to prepend a length byte. - */ - for (Offset = 0, Index = FirstIndex; - Index < LastIndex; Index ++) { - - BufLen = 256; - if (VpdRead(pAC, IoC, KeyArr[Index], Buf, - (int *)&BufLen) > 0 || - BufLen >= SK_PNMI_VPD_DATALEN) { - - SK_ERR_LOG(pAC, SK_ERRCL_SW, - SK_PNMI_ERR022, - SK_PNMI_ERR022MSG); - - *pLen = 0; - return (SK_PNMI_ERR_GENERAL); - } - - *(pBuf + Offset) = (char)BufLen; - SK_MEMCPY(pBuf + Offset + 1, Buf, BufLen); - Offset += BufLen + 1; - } - *pLen = Offset; - break; - - case OID_SKGE_VPD_ACCESS: - if (*pLen < LastIndex - FirstIndex) { - - *pLen = LastIndex - FirstIndex; - return (SK_PNMI_ERR_TOO_SHORT); - } - - for (Offset = 0, Index = FirstIndex; - Index < LastIndex; Index ++) { - - if (VpdMayWrite(KeyArr[Index])) { - - *(pBuf + Offset) = SK_PNMI_VPD_RW; - } - else { - *(pBuf + Offset) = SK_PNMI_VPD_RO; - } - Offset ++; - } - *pLen = Offset; - break; - - case OID_SKGE_VPD_ACTION: - Offset = LastIndex - FirstIndex; - if (*pLen < Offset) { - - *pLen = Offset; - return (SK_PNMI_ERR_TOO_SHORT); - } - SK_MEMSET(pBuf, 0, Offset); - *pLen = Offset; - break; - - default: - SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR023, - SK_PNMI_ERR023MSG); - - *pLen = 0; - return (SK_PNMI_ERR_GENERAL); - } - } - else { - /* The only OID which can be set is VPD_ACTION */ - if (Id != OID_SKGE_VPD_ACTION) { - - if (Id == OID_SKGE_VPD_FREE_BYTES || - Id == OID_SKGE_VPD_ENTRIES_LIST || - Id == OID_SKGE_VPD_ENTRIES_NUMBER || - Id == OID_SKGE_VPD_KEY || - Id == OID_SKGE_VPD_VALUE || - Id == OID_SKGE_VPD_ACCESS) { - - *pLen = 0; - return (SK_PNMI_ERR_READ_ONLY); - } - - SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR024, - SK_PNMI_ERR024MSG); - - *pLen = 0; - return (SK_PNMI_ERR_GENERAL); - } - - /* - * From this point we handle VPD_ACTION. Check the buffer - * length. It should at least have the size of one byte. - */ - if (*pLen < 1) { - - *pLen = 1; - return (SK_PNMI_ERR_TOO_SHORT); - } - - /* - * The first byte contains the VPD action type we should - * perform. - */ - switch (*pBuf) { - - case SK_PNMI_VPD_IGNORE: - /* Nothing to do */ - break; - - case SK_PNMI_VPD_CREATE: - /* - * We have to create a new VPD entry or we modify - * an existing one. Check first the buffer length. - */ - if (*pLen < 4) { - - *pLen = 4; - return (SK_PNMI_ERR_TOO_SHORT); - } - KeyStr[0] = pBuf[1]; - KeyStr[1] = pBuf[2]; - KeyStr[2] = 0; - - /* - * Is the entry writable or does it belong to the - * read-only area? - */ - if (!VpdMayWrite(KeyStr)) { - - *pLen = 0; - return (SK_PNMI_ERR_BAD_VALUE); - } - - Offset = (int)pBuf[3] & 0xFF; - - SK_MEMCPY(Buf, pBuf + 4, Offset); - Buf[Offset] = 0; - - /* A preset ends here */ - if (Action == SK_PNMI_PRESET) { - - return (SK_PNMI_ERR_OK); - } - - /* Write the new entry or modify an existing one */ - Ret = VpdWrite(pAC, IoC, KeyStr, Buf); - if (Ret == SK_PNMI_VPD_NOWRITE ) { - - *pLen = 0; - return (SK_PNMI_ERR_BAD_VALUE); - } - else if (Ret != SK_PNMI_VPD_OK) { - - SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR025, - SK_PNMI_ERR025MSG); - - *pLen = 0; - return (SK_PNMI_ERR_GENERAL); - } - - /* - * Perform an update of the VPD data. This is - * not mandantory, but just to be sure. - */ - Ret = VpdUpdate(pAC, IoC); - if (Ret != SK_PNMI_VPD_OK) { - - SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR026, - SK_PNMI_ERR026MSG); - - *pLen = 0; - return (SK_PNMI_ERR_GENERAL); - } - break; - - case SK_PNMI_VPD_DELETE: - /* Check if the buffer size is plausible */ - if (*pLen < 3) { - - *pLen = 3; - return (SK_PNMI_ERR_TOO_SHORT); - } - if (*pLen > 3) { - - *pLen = 0; - return (SK_PNMI_ERR_BAD_VALUE); - } - KeyStr[0] = pBuf[1]; - KeyStr[1] = pBuf[2]; - KeyStr[2] = 0; - - /* Find the passed key in the array */ - for (Index = 0; Index < KeyNo; Index ++) { - - if (SK_STRCMP(KeyStr, KeyArr[Index]) == 0) { - - break; - } - } - /* - * If we cannot find the key it is wrong, so we - * return an appropriate error value. - */ - if (Index == KeyNo) { - - *pLen = 0; - return (SK_PNMI_ERR_BAD_VALUE); - } - - if (Action == SK_PNMI_PRESET) { - - return (SK_PNMI_ERR_OK); - } - - /* Ok, you wanted it and you will get it */ - Ret = VpdDelete(pAC, IoC, KeyStr); - if (Ret != SK_PNMI_VPD_OK) { - - SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR027, - SK_PNMI_ERR027MSG); - - *pLen = 0; - return (SK_PNMI_ERR_GENERAL); - } - - /* - * Perform an update of the VPD data. This is - * not mandantory, but just to be sure. - */ - Ret = VpdUpdate(pAC, IoC); - if (Ret != SK_PNMI_VPD_OK) { - - SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR028, - SK_PNMI_ERR028MSG); - - *pLen = 0; - return (SK_PNMI_ERR_GENERAL); - } - break; - - default: - *pLen = 0; - return (SK_PNMI_ERR_BAD_VALUE); - } - } - - return (SK_PNMI_ERR_OK); -} - -/***************************************************************************** - * - * General - OID handler function of various single instance OIDs - * - * Description: - * The code is simple. No description necessary. - * - * Returns: - * SK_PNMI_ERR_OK The request was successfully performed. - * SK_PNMI_ERR_GENERAL A general severe internal error occured. - * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain - * the correct data (e.g. a 32bit value is - * needed, but a 16 bit value was passed). - * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't - * exist (e.g. port instance 3 on a two port - * adapter. - */ -PNMI_STATIC int General( -SK_AC *pAC, /* Pointer to adapter context */ -SK_IOC IoC, /* IO context handle */ -int Action, /* GET/PRESET/SET action */ -SK_U32 Id, /* Object ID that is to be processed */ -char *pBuf, /* Buffer used for the management data transfer */ -unsigned int *pLen, /* On call: buffer length. On return: used buffer */ -SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */ -unsigned int TableIndex, /* Index to the Id table */ -SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */ -{ - int Ret; - unsigned int Index; - unsigned int Len; - unsigned int Offset; - unsigned int Val; - SK_U8 Val8; - SK_U16 Val16; - SK_U32 Val32; - SK_U64 Val64; - SK_U64 Val64RxHwErrs = 0; - SK_U64 Val64TxHwErrs = 0; - SK_BOOL Is64BitReq = SK_FALSE; - char Buf[256]; - int MacType; - - /* - * Check instance. We only handle single instance variables. - */ - if (Instance != (SK_U32)(-1) && Instance != 1) { - - *pLen = 0; - return (SK_PNMI_ERR_UNKNOWN_INST); - } - - /* - * Check action. We only allow get requests. - */ - if (Action != SK_PNMI_GET) { - - *pLen = 0; - return (SK_PNMI_ERR_READ_ONLY); - } - - MacType = pAC->GIni.GIMacType; - - /* - * Check length for the various supported OIDs - */ - switch (Id) { - - case OID_GEN_XMIT_ERROR: - case OID_GEN_RCV_ERROR: - case OID_GEN_RCV_NO_BUFFER: -#ifndef SK_NDIS_64BIT_CTR - if (*pLen < sizeof(SK_U32)) { - *pLen = sizeof(SK_U32); - return (SK_PNMI_ERR_TOO_SHORT); - } - -#else /* SK_NDIS_64BIT_CTR */ - - /* - * for compatibility, at least 32bit are required for oid - */ - if (*pLen < sizeof(SK_U32)) { - /* - * but indicate handling for 64bit values, - * if insufficient space is provided - */ - *pLen = sizeof(SK_U64); - return (SK_PNMI_ERR_TOO_SHORT); - } - - Is64BitReq = (*pLen < sizeof(SK_U64)) ? SK_FALSE : SK_TRUE; -#endif /* SK_NDIS_64BIT_CTR */ - break; - - case OID_SKGE_PORT_NUMBER: - case OID_SKGE_DEVICE_TYPE: - case OID_SKGE_RESULT: - case OID_SKGE_RLMT_MONITOR_NUMBER: - case OID_GEN_TRANSMIT_QUEUE_LENGTH: - case OID_SKGE_TRAP_NUMBER: - case OID_SKGE_MDB_VERSION: - case OID_SKGE_BOARDLEVEL: - case OID_SKGE_CHIPID: - case OID_SKGE_RAMSIZE: - if (*pLen < sizeof(SK_U32)) { - - *pLen = sizeof(SK_U32); - return (SK_PNMI_ERR_TOO_SHORT); - } - break; - - case OID_SKGE_CHIPSET: - if (*pLen < sizeof(SK_U16)) { - - *pLen = sizeof(SK_U16); - return (SK_PNMI_ERR_TOO_SHORT); - } - break; - - case OID_SKGE_BUS_TYPE: - case OID_SKGE_BUS_SPEED: - case OID_SKGE_BUS_WIDTH: - case OID_SKGE_SENSOR_NUMBER: - case OID_SKGE_CHKSM_NUMBER: - case OID_SKGE_VAUXAVAIL: - if (*pLen < sizeof(SK_U8)) { - - *pLen = sizeof(SK_U8); - return (SK_PNMI_ERR_TOO_SHORT); - } - break; - - case OID_SKGE_TX_SW_QUEUE_LEN: - case OID_SKGE_TX_SW_QUEUE_MAX: - case OID_SKGE_TX_RETRY: - case OID_SKGE_RX_INTR_CTS: - case OID_SKGE_TX_INTR_CTS: - case OID_SKGE_RX_NO_BUF_CTS: - case OID_SKGE_TX_NO_BUF_CTS: - case OID_SKGE_TX_USED_DESCR_NO: - case OID_SKGE_RX_DELIVERED_CTS: - case OID_SKGE_RX_OCTETS_DELIV_CTS: - case OID_SKGE_RX_HW_ERROR_CTS: - case OID_SKGE_TX_HW_ERROR_CTS: - case OID_SKGE_IN_ERRORS_CTS: - case OID_SKGE_OUT_ERROR_CTS: - case OID_SKGE_ERR_RECOVERY_CTS: - case OID_SKGE_SYSUPTIME: - if (*pLen < sizeof(SK_U64)) { - - *pLen = sizeof(SK_U64); - return (SK_PNMI_ERR_TOO_SHORT); - } - break; - - default: - /* Checked later */ - break; - } - - /* Update statistic */ - if (Id == OID_SKGE_RX_HW_ERROR_CTS || - Id == OID_SKGE_TX_HW_ERROR_CTS || - Id == OID_SKGE_IN_ERRORS_CTS || - Id == OID_SKGE_OUT_ERROR_CTS || - Id == OID_GEN_XMIT_ERROR || - Id == OID_GEN_RCV_ERROR) { - - /* Force the XMAC to update its statistic counters and - * Increment semaphore to indicate that an update was - * already done. - */ - Ret = MacUpdate(pAC, IoC, 0, pAC->GIni.GIMacsFound - 1); - if (Ret != SK_PNMI_ERR_OK) { - - *pLen = 0; - return (Ret); - } - pAC->Pnmi.MacUpdatedFlag ++; - - /* - * Some OIDs consist of multiple hardware counters. Those - * values which are contained in all of them will be added - * now. - */ - switch (Id) { - - case OID_SKGE_RX_HW_ERROR_CTS: - case OID_SKGE_IN_ERRORS_CTS: - case OID_GEN_RCV_ERROR: - Val64RxHwErrs = - GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_MISSED, NetIndex) + - GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_FRAMING, NetIndex) + - GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_OVERFLOW, NetIndex) + - GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_JABBER, NetIndex) + - GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_CARRIER, NetIndex) + - GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_IRLENGTH, NetIndex) + - GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_SYMBOL, NetIndex) + - GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_SHORTS, NetIndex) + - GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_RUNT, NetIndex) + - GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_TOO_LONG, NetIndex) + - GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_FCS, NetIndex) + - GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_CEXT, NetIndex); - break; - - case OID_SKGE_TX_HW_ERROR_CTS: - case OID_SKGE_OUT_ERROR_CTS: - case OID_GEN_XMIT_ERROR: - Val64TxHwErrs = - GetStatVal(pAC, IoC, 0, SK_PNMI_HTX_EXCESS_COL, NetIndex) + - GetStatVal(pAC, IoC, 0, SK_PNMI_HTX_LATE_COL, NetIndex) + - GetStatVal(pAC, IoC, 0, SK_PNMI_HTX_UNDERRUN, NetIndex) + - GetStatVal(pAC, IoC, 0, SK_PNMI_HTX_CARRIER, NetIndex); - break; - } - } - - /* - * Retrieve value - */ - switch (Id) { - - case OID_SKGE_SUPPORTED_LIST: - Len = ID_TABLE_SIZE * sizeof(SK_U32); - if (*pLen < Len) { - - *pLen = Len; - return (SK_PNMI_ERR_TOO_SHORT); - } - for (Offset = 0, Index = 0; Offset < Len; - Offset += sizeof(SK_U32), Index ++) { - - Val32 = (SK_U32)IdTable[Index].Id; - SK_PNMI_STORE_U32(pBuf + Offset, Val32); - } - *pLen = Len; - break; - - case OID_SKGE_BOARDLEVEL: - Val32 = (SK_U32)pAC->GIni.GILevel; - SK_PNMI_STORE_U32(pBuf, Val32); - *pLen = sizeof(SK_U32); - break; - - case OID_SKGE_PORT_NUMBER: - Val32 = (SK_U32)pAC->GIni.GIMacsFound; - SK_PNMI_STORE_U32(pBuf, Val32); - *pLen = sizeof(SK_U32); - break; - - case OID_SKGE_DEVICE_TYPE: - Val32 = (SK_U32)pAC->Pnmi.DeviceType; - SK_PNMI_STORE_U32(pBuf, Val32); - *pLen = sizeof(SK_U32); - break; - - case OID_SKGE_DRIVER_DESCR: - if (pAC->Pnmi.pDriverDescription == NULL) { - - SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR007, - SK_PNMI_ERR007MSG); - - *pLen = 0; - return (SK_PNMI_ERR_GENERAL); - } - - Len = SK_STRLEN(pAC->Pnmi.pDriverDescription) + 1; - if (Len > SK_PNMI_STRINGLEN1) { - - SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR029, - SK_PNMI_ERR029MSG); - - *pLen = 0; - return (SK_PNMI_ERR_GENERAL); - } - - if (*pLen < Len) { - - *pLen = Len; - return (SK_PNMI_ERR_TOO_SHORT); - } - *pBuf = (char)(Len - 1); - SK_MEMCPY(pBuf + 1, pAC->Pnmi.pDriverDescription, Len - 1); - *pLen = Len; - break; - - case OID_SKGE_DRIVER_VERSION: - if (pAC->Pnmi.pDriverVersion == NULL) { - - SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR030, - SK_PNMI_ERR030MSG); - - *pLen = 0; - return (SK_PNMI_ERR_GENERAL); - } - - Len = SK_STRLEN(pAC->Pnmi.pDriverVersion) + 1; - if (Len > SK_PNMI_STRINGLEN1) { - - SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR031, - SK_PNMI_ERR031MSG); - - *pLen = 0; - return (SK_PNMI_ERR_GENERAL); - } - - if (*pLen < Len) { - - *pLen = Len; - return (SK_PNMI_ERR_TOO_SHORT); - } - *pBuf = (char)(Len - 1); - SK_MEMCPY(pBuf + 1, pAC->Pnmi.pDriverVersion, Len - 1); - *pLen = Len; - break; - - case OID_SKGE_DRIVER_RELDATE: - if (pAC->Pnmi.pDriverReleaseDate == NULL) { - - SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR030, - SK_PNMI_ERR053MSG); - - *pLen = 0; - return (SK_PNMI_ERR_GENERAL); - } - - Len = SK_STRLEN(pAC->Pnmi.pDriverReleaseDate) + 1; - if (Len > SK_PNMI_STRINGLEN1) { - - SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR031, - SK_PNMI_ERR054MSG); - - *pLen = 0; - return (SK_PNMI_ERR_GENERAL); - } - - if (*pLen < Len) { - - *pLen = Len; - return (SK_PNMI_ERR_TOO_SHORT); - } - *pBuf = (char)(Len - 1); - SK_MEMCPY(pBuf + 1, pAC->Pnmi.pDriverReleaseDate, Len - 1); - *pLen = Len; - break; - - case OID_SKGE_DRIVER_FILENAME: - if (pAC->Pnmi.pDriverFileName == NULL) { - - SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR030, - SK_PNMI_ERR055MSG); - - *pLen = 0; - return (SK_PNMI_ERR_GENERAL); - } - - Len = SK_STRLEN(pAC->Pnmi.pDriverFileName) + 1; - if (Len > SK_PNMI_STRINGLEN1) { - - SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR031, - SK_PNMI_ERR056MSG); - - *pLen = 0; - return (SK_PNMI_ERR_GENERAL); - } - - if (*pLen < Len) { - - *pLen = Len; - return (SK_PNMI_ERR_TOO_SHORT); - } - *pBuf = (char)(Len - 1); - SK_MEMCPY(pBuf + 1, pAC->Pnmi.pDriverFileName, Len - 1); - *pLen = Len; - break; - - case OID_SKGE_HW_DESCR: - /* - * The hardware description is located in the VPD. This - * query may move to the initialisation routine. But - * the VPD data is cached and therefore a call here - * will not make much difference. - */ - Len = 256; - if (VpdRead(pAC, IoC, VPD_NAME, Buf, (int *)&Len) > 0) { - - SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR032, - SK_PNMI_ERR032MSG); - - *pLen = 0; - return (SK_PNMI_ERR_GENERAL); - } - Len ++; - if (Len > SK_PNMI_STRINGLEN1) { - - SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR033, - SK_PNMI_ERR033MSG); - - *pLen = 0; - return (SK_PNMI_ERR_GENERAL); - } - if (*pLen < Len) { - - *pLen = Len; - return (SK_PNMI_ERR_TOO_SHORT); - } - *pBuf = (char)(Len - 1); - SK_MEMCPY(pBuf + 1, Buf, Len - 1); - *pLen = Len; - break; - - case OID_SKGE_HW_VERSION: - /* Oh, I love to do some string manipulation */ - if (*pLen < 5) { - - *pLen = 5; - return (SK_PNMI_ERR_TOO_SHORT); - } - Val8 = (SK_U8)pAC->GIni.GIPciHwRev; - pBuf[0] = 4; - pBuf[1] = 'v'; - pBuf[2] = (char)(0x30 | ((Val8 >> 4) & 0x0F)); - pBuf[3] = '.'; - pBuf[4] = (char)(0x30 | (Val8 & 0x0F)); - *pLen = 5; - break; - - case OID_SKGE_CHIPSET: - Val16 = pAC->Pnmi.Chipset; - SK_PNMI_STORE_U16(pBuf, Val16); - *pLen = sizeof(SK_U16); - break; - - case OID_SKGE_CHIPID: - Val32 = pAC->GIni.GIChipId; - SK_PNMI_STORE_U32(pBuf, Val32); - *pLen = sizeof(SK_U32); - break; - - case OID_SKGE_RAMSIZE: - Val32 = pAC->GIni.GIRamSize; - SK_PNMI_STORE_U32(pBuf, Val32); - *pLen = sizeof(SK_U32); - break; - - case OID_SKGE_VAUXAVAIL: - *pBuf = (char) pAC->GIni.GIVauxAvail; - *pLen = sizeof(char); - break; - - case OID_SKGE_BUS_TYPE: - *pBuf = (char) SK_PNMI_BUS_PCI; - *pLen = sizeof(char); - break; - - case OID_SKGE_BUS_SPEED: - *pBuf = pAC->Pnmi.PciBusSpeed; - *pLen = sizeof(char); - break; - - case OID_SKGE_BUS_WIDTH: - *pBuf = pAC->Pnmi.PciBusWidth; - *pLen = sizeof(char); - break; - - case OID_SKGE_RESULT: - Val32 = pAC->Pnmi.TestResult; - SK_PNMI_STORE_U32(pBuf, Val32); - *pLen = sizeof(SK_U32); - break; - - case OID_SKGE_SENSOR_NUMBER: - *pBuf = (char)pAC->I2c.MaxSens; - *pLen = sizeof(char); - break; - - case OID_SKGE_CHKSM_NUMBER: - *pBuf = SKCS_NUM_PROTOCOLS; - *pLen = sizeof(char); - break; - - case OID_SKGE_TRAP_NUMBER: - GetTrapQueueLen(pAC, &Len, &Val); - Val32 = (SK_U32)Val; - SK_PNMI_STORE_U32(pBuf, Val32); - *pLen = sizeof(SK_U32); - break; - - case OID_SKGE_TRAP: - GetTrapQueueLen(pAC, &Len, &Val); - if (*pLen < Len) { - - *pLen = Len; - return (SK_PNMI_ERR_TOO_SHORT); - } - CopyTrapQueue(pAC, pBuf); - *pLen = Len; - break; - - case OID_SKGE_RLMT_MONITOR_NUMBER: -/* XXX Not yet implemented by RLMT therefore we return zero elements */ - Val32 = 0; - SK_PNMI_STORE_U32(pBuf, Val32); - *pLen = sizeof(SK_U32); - break; - - case OID_SKGE_TX_SW_QUEUE_LEN: - /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */ - if (MacType == SK_MAC_XMAC) { - /* Dual net mode */ - if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { - Val64 = pAC->Pnmi.BufPort[NetIndex].TxSwQueueLen; - } - /* Single net mode */ - else { - Val64 = pAC->Pnmi.BufPort[0].TxSwQueueLen + - pAC->Pnmi.BufPort[1].TxSwQueueLen; - } - } - else { - /* Dual net mode */ - if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { - Val64 = pAC->Pnmi.Port[NetIndex].TxSwQueueLen; - } - /* Single net mode */ - else { - Val64 = pAC->Pnmi.Port[0].TxSwQueueLen + - pAC->Pnmi.Port[1].TxSwQueueLen; - } - } - SK_PNMI_STORE_U64(pBuf, Val64); - *pLen = sizeof(SK_U64); - break; - - - case OID_SKGE_TX_SW_QUEUE_MAX: - /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */ - if (MacType == SK_MAC_XMAC) { - /* Dual net mode */ - if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { - Val64 = pAC->Pnmi.BufPort[NetIndex].TxSwQueueMax; - } - /* Single net mode */ - else { - Val64 = pAC->Pnmi.BufPort[0].TxSwQueueMax + - pAC->Pnmi.BufPort[1].TxSwQueueMax; - } - } - else { - /* Dual net mode */ - if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { - Val64 = pAC->Pnmi.Port[NetIndex].TxSwQueueMax; - } - /* Single net mode */ - else { - Val64 = pAC->Pnmi.Port[0].TxSwQueueMax + - pAC->Pnmi.Port[1].TxSwQueueMax; - } - } - SK_PNMI_STORE_U64(pBuf, Val64); - *pLen = sizeof(SK_U64); - break; - - case OID_SKGE_TX_RETRY: - /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */ - if (MacType == SK_MAC_XMAC) { - /* Dual net mode */ - if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { - Val64 = pAC->Pnmi.BufPort[NetIndex].TxRetryCts; - } - /* Single net mode */ - else { - Val64 = pAC->Pnmi.BufPort[0].TxRetryCts + - pAC->Pnmi.BufPort[1].TxRetryCts; - } - } - else { - /* Dual net mode */ - if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { - Val64 = pAC->Pnmi.Port[NetIndex].TxRetryCts; - } - /* Single net mode */ - else { - Val64 = pAC->Pnmi.Port[0].TxRetryCts + - pAC->Pnmi.Port[1].TxRetryCts; - } - } - SK_PNMI_STORE_U64(pBuf, Val64); - *pLen = sizeof(SK_U64); - break; - - case OID_SKGE_RX_INTR_CTS: - /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */ - if (MacType == SK_MAC_XMAC) { - /* Dual net mode */ - if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { - Val64 = pAC->Pnmi.BufPort[NetIndex].RxIntrCts; - } - /* Single net mode */ - else { - Val64 = pAC->Pnmi.BufPort[0].RxIntrCts + - pAC->Pnmi.BufPort[1].RxIntrCts; - } - } - else { - /* Dual net mode */ - if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { - Val64 = pAC->Pnmi.Port[NetIndex].RxIntrCts; - } - /* Single net mode */ - else { - Val64 = pAC->Pnmi.Port[0].RxIntrCts + - pAC->Pnmi.Port[1].RxIntrCts; - } - } - SK_PNMI_STORE_U64(pBuf, Val64); - *pLen = sizeof(SK_U64); - break; - - case OID_SKGE_TX_INTR_CTS: - /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */ - if (MacType == SK_MAC_XMAC) { - /* Dual net mode */ - if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { - Val64 = pAC->Pnmi.BufPort[NetIndex].TxIntrCts; - } - /* Single net mode */ - else { - Val64 = pAC->Pnmi.BufPort[0].TxIntrCts + - pAC->Pnmi.BufPort[1].TxIntrCts; - } - } - else { - /* Dual net mode */ - if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { - Val64 = pAC->Pnmi.Port[NetIndex].TxIntrCts; - } - /* Single net mode */ - else { - Val64 = pAC->Pnmi.Port[0].TxIntrCts + - pAC->Pnmi.Port[1].TxIntrCts; - } - } - SK_PNMI_STORE_U64(pBuf, Val64); - *pLen = sizeof(SK_U64); - break; - - case OID_SKGE_RX_NO_BUF_CTS: - /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */ - if (MacType == SK_MAC_XMAC) { - /* Dual net mode */ - if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { - Val64 = pAC->Pnmi.BufPort[NetIndex].RxNoBufCts; - } - /* Single net mode */ - else { - Val64 = pAC->Pnmi.BufPort[0].RxNoBufCts + - pAC->Pnmi.BufPort[1].RxNoBufCts; - } - } - else { - /* Dual net mode */ - if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { - Val64 = pAC->Pnmi.Port[NetIndex].RxNoBufCts; - } - /* Single net mode */ - else { - Val64 = pAC->Pnmi.Port[0].RxNoBufCts + - pAC->Pnmi.Port[1].RxNoBufCts; - } - } - SK_PNMI_STORE_U64(pBuf, Val64); - *pLen = sizeof(SK_U64); - break; - - case OID_SKGE_TX_NO_BUF_CTS: - /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */ - if (MacType == SK_MAC_XMAC) { - /* Dual net mode */ - if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { - Val64 = pAC->Pnmi.BufPort[NetIndex].TxNoBufCts; - } - /* Single net mode */ - else { - Val64 = pAC->Pnmi.BufPort[0].TxNoBufCts + - pAC->Pnmi.BufPort[1].TxNoBufCts; - } - } - else { - /* Dual net mode */ - if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { - Val64 = pAC->Pnmi.Port[NetIndex].TxNoBufCts; - } - /* Single net mode */ - else { - Val64 = pAC->Pnmi.Port[0].TxNoBufCts + - pAC->Pnmi.Port[1].TxNoBufCts; - } - } - SK_PNMI_STORE_U64(pBuf, Val64); - *pLen = sizeof(SK_U64); - break; - - case OID_SKGE_TX_USED_DESCR_NO: - /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */ - if (MacType == SK_MAC_XMAC) { - /* Dual net mode */ - if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { - Val64 = pAC->Pnmi.BufPort[NetIndex].TxUsedDescrNo; - } - /* Single net mode */ - else { - Val64 = pAC->Pnmi.BufPort[0].TxUsedDescrNo + - pAC->Pnmi.BufPort[1].TxUsedDescrNo; - } - } - else { - /* Dual net mode */ - if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { - Val64 = pAC->Pnmi.Port[NetIndex].TxUsedDescrNo; - } - /* Single net mode */ - else { - Val64 = pAC->Pnmi.Port[0].TxUsedDescrNo + - pAC->Pnmi.Port[1].TxUsedDescrNo; - } - } - SK_PNMI_STORE_U64(pBuf, Val64); - *pLen = sizeof(SK_U64); - break; - - case OID_SKGE_RX_DELIVERED_CTS: - /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */ - if (MacType == SK_MAC_XMAC) { - /* Dual net mode */ - if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { - Val64 = pAC->Pnmi.BufPort[NetIndex].RxDeliveredCts; - } - /* Single net mode */ - else { - Val64 = pAC->Pnmi.BufPort[0].RxDeliveredCts + - pAC->Pnmi.BufPort[1].RxDeliveredCts; - } - } - else { - /* Dual net mode */ - if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { - Val64 = pAC->Pnmi.Port[NetIndex].RxDeliveredCts; - } - /* Single net mode */ - else { - Val64 = pAC->Pnmi.Port[0].RxDeliveredCts + - pAC->Pnmi.Port[1].RxDeliveredCts; - } - } - SK_PNMI_STORE_U64(pBuf, Val64); - *pLen = sizeof(SK_U64); - break; - - case OID_SKGE_RX_OCTETS_DELIV_CTS: - /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */ - if (MacType == SK_MAC_XMAC) { - /* Dual net mode */ - if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { - Val64 = pAC->Pnmi.BufPort[NetIndex].RxOctetsDeliveredCts; - } - /* Single net mode */ - else { - Val64 = pAC->Pnmi.BufPort[0].RxOctetsDeliveredCts + - pAC->Pnmi.BufPort[1].RxOctetsDeliveredCts; - } - } - else { - /* Dual net mode */ - if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { - Val64 = pAC->Pnmi.Port[NetIndex].RxOctetsDeliveredCts; - } - /* Single net mode */ - else { - Val64 = pAC->Pnmi.Port[0].RxOctetsDeliveredCts + - pAC->Pnmi.Port[1].RxOctetsDeliveredCts; - } - } - SK_PNMI_STORE_U64(pBuf, Val64); - *pLen = sizeof(SK_U64); - break; - - case OID_SKGE_RX_HW_ERROR_CTS: - SK_PNMI_STORE_U64(pBuf, Val64RxHwErrs); - *pLen = sizeof(SK_U64); - break; - - case OID_SKGE_TX_HW_ERROR_CTS: - SK_PNMI_STORE_U64(pBuf, Val64TxHwErrs); - *pLen = sizeof(SK_U64); - break; - - case OID_SKGE_IN_ERRORS_CTS: - /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */ - if (MacType == SK_MAC_XMAC) { - /* Dual net mode */ - if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { - Val64 = Val64RxHwErrs + pAC->Pnmi.BufPort[NetIndex].RxNoBufCts; - } - /* Single net mode */ - else { - Val64 = Val64RxHwErrs + - pAC->Pnmi.BufPort[0].RxNoBufCts + - pAC->Pnmi.BufPort[1].RxNoBufCts; - } - } - else { - /* Dual net mode */ - if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { - Val64 = Val64RxHwErrs + pAC->Pnmi.Port[NetIndex].RxNoBufCts; - } - /* Single net mode */ - else { - Val64 = Val64RxHwErrs + - pAC->Pnmi.Port[0].RxNoBufCts + - pAC->Pnmi.Port[1].RxNoBufCts; - } - } - SK_PNMI_STORE_U64(pBuf, Val64); - *pLen = sizeof(SK_U64); - break; - - case OID_SKGE_OUT_ERROR_CTS: - /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */ - if (MacType == SK_MAC_XMAC) { - /* Dual net mode */ - if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { - Val64 = Val64TxHwErrs + pAC->Pnmi.BufPort[NetIndex].TxNoBufCts; - } - /* Single net mode */ - else { - Val64 = Val64TxHwErrs + - pAC->Pnmi.BufPort[0].TxNoBufCts + - pAC->Pnmi.BufPort[1].TxNoBufCts; - } - } - else { - /* Dual net mode */ - if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { - Val64 = Val64TxHwErrs + pAC->Pnmi.Port[NetIndex].TxNoBufCts; - } - /* Single net mode */ - else { - Val64 = Val64TxHwErrs + - pAC->Pnmi.Port[0].TxNoBufCts + - pAC->Pnmi.Port[1].TxNoBufCts; - } - } - SK_PNMI_STORE_U64(pBuf, Val64); - *pLen = sizeof(SK_U64); - break; - - case OID_SKGE_ERR_RECOVERY_CTS: - /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */ - if (MacType == SK_MAC_XMAC) { - /* Dual net mode */ - if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { - Val64 = pAC->Pnmi.BufPort[NetIndex].ErrRecoveryCts; - } - /* Single net mode */ - else { - Val64 = pAC->Pnmi.BufPort[0].ErrRecoveryCts + - pAC->Pnmi.BufPort[1].ErrRecoveryCts; - } - } - else { - /* Dual net mode */ - if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { - Val64 = pAC->Pnmi.Port[NetIndex].ErrRecoveryCts; - } - /* Single net mode */ - else { - Val64 = pAC->Pnmi.Port[0].ErrRecoveryCts + - pAC->Pnmi.Port[1].ErrRecoveryCts; - } - } - SK_PNMI_STORE_U64(pBuf, Val64); - *pLen = sizeof(SK_U64); - break; - - case OID_SKGE_SYSUPTIME: - Val64 = SK_PNMI_HUNDREDS_SEC(SkOsGetTime(pAC)); - Val64 -= pAC->Pnmi.StartUpTime; - SK_PNMI_STORE_U64(pBuf, Val64); - *pLen = sizeof(SK_U64); - break; - - case OID_SKGE_MDB_VERSION: - Val32 = SK_PNMI_MDB_VERSION; - SK_PNMI_STORE_U32(pBuf, Val32); - *pLen = sizeof(SK_U32); - break; - - case OID_GEN_RCV_ERROR: - /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */ - if (MacType == SK_MAC_XMAC) { - Val64 = Val64RxHwErrs + pAC->Pnmi.BufPort[NetIndex].RxNoBufCts; - } - else { - Val64 = Val64RxHwErrs + pAC->Pnmi.Port[NetIndex].RxNoBufCts; - } - - /* - * by default 32bit values are evaluated - */ - if (!Is64BitReq) { - Val32 = (SK_U32)Val64; - SK_PNMI_STORE_U32(pBuf, Val32); - *pLen = sizeof(SK_U32); - } - else { - SK_PNMI_STORE_U64(pBuf, Val64); - *pLen = sizeof(SK_U64); - } - break; - - case OID_GEN_XMIT_ERROR: - /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */ - if (MacType == SK_MAC_XMAC) { - Val64 = Val64TxHwErrs + pAC->Pnmi.BufPort[NetIndex].TxNoBufCts; - } - else { - Val64 = Val64TxHwErrs + pAC->Pnmi.Port[NetIndex].TxNoBufCts; - } - - /* - * by default 32bit values are evaluated - */ - if (!Is64BitReq) { - Val32 = (SK_U32)Val64; - SK_PNMI_STORE_U32(pBuf, Val32); - *pLen = sizeof(SK_U32); - } - else { - SK_PNMI_STORE_U64(pBuf, Val64); - *pLen = sizeof(SK_U64); - } - break; - - case OID_GEN_RCV_NO_BUFFER: - /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */ - if (MacType == SK_MAC_XMAC) { - Val64 = pAC->Pnmi.BufPort[NetIndex].RxNoBufCts; - } - else { - Val64 = pAC->Pnmi.Port[NetIndex].RxNoBufCts; - } - - /* - * by default 32bit values are evaluated - */ - if (!Is64BitReq) { - Val32 = (SK_U32)Val64; - SK_PNMI_STORE_U32(pBuf, Val32); - *pLen = sizeof(SK_U32); - } - else { - SK_PNMI_STORE_U64(pBuf, Val64); - *pLen = sizeof(SK_U64); - } - break; - - case OID_GEN_TRANSMIT_QUEUE_LENGTH: - Val32 = (SK_U32)pAC->Pnmi.Port[NetIndex].TxSwQueueLen; - SK_PNMI_STORE_U32(pBuf, Val32); - *pLen = sizeof(SK_U32); - break; - - default: - SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR034, - SK_PNMI_ERR034MSG); - - *pLen = 0; - return (SK_PNMI_ERR_GENERAL); - } - - if (Id == OID_SKGE_RX_HW_ERROR_CTS || - Id == OID_SKGE_TX_HW_ERROR_CTS || - Id == OID_SKGE_IN_ERRORS_CTS || - Id == OID_SKGE_OUT_ERROR_CTS || - Id == OID_GEN_XMIT_ERROR || - Id == OID_GEN_RCV_ERROR) { - - pAC->Pnmi.MacUpdatedFlag --; - } - - return (SK_PNMI_ERR_OK); -} - -/***************************************************************************** - * - * Rlmt - OID handler function of OID_SKGE_RLMT_XXX single instance. - * - * Description: - * Get/Presets/Sets the RLMT OIDs. - * - * Returns: - * SK_PNMI_ERR_OK The request was successfully performed. - * SK_PNMI_ERR_GENERAL A general severe internal error occured. - * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain - * the correct data (e.g. a 32bit value is - * needed, but a 16 bit value was passed). - * SK_PNMI_ERR_BAD_VALUE The passed value is not in the valid - * value range. - * SK_PNMI_ERR_READ_ONLY The OID is read-only and cannot be set. - * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't - * exist (e.g. port instance 3 on a two port - * adapter. - */ -PNMI_STATIC int Rlmt( -SK_AC *pAC, /* Pointer to adapter context */ -SK_IOC IoC, /* IO context handle */ -int Action, /* GET/PRESET/SET action */ -SK_U32 Id, /* Object ID that is to be processed */ -char *pBuf, /* Buffer used for the management data transfer */ -unsigned int *pLen, /* On call: pBuf buffer length. On return: used buffer */ -SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */ -unsigned int TableIndex, /* Index to the Id table */ -SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */ -{ - int Ret; - unsigned int PhysPortIndex; - unsigned int PhysPortMax; - SK_EVPARA EventParam; - SK_U32 Val32; - SK_U64 Val64; - - - /* - * Check instance. Only single instance OIDs are allowed here. - */ - if (Instance != (SK_U32)(-1) && Instance != 1) { - - *pLen = 0; - return (SK_PNMI_ERR_UNKNOWN_INST); - } - - /* - * Perform the requested action. - */ - if (Action == SK_PNMI_GET) { - - /* - * Check if the buffer length is large enough. - */ - - switch (Id) { - - case OID_SKGE_RLMT_MODE: - case OID_SKGE_RLMT_PORT_ACTIVE: - case OID_SKGE_RLMT_PORT_PREFERRED: - if (*pLen < sizeof(SK_U8)) { - - *pLen = sizeof(SK_U8); - return (SK_PNMI_ERR_TOO_SHORT); - } - break; - - case OID_SKGE_RLMT_PORT_NUMBER: - if (*pLen < sizeof(SK_U32)) { - - *pLen = sizeof(SK_U32); - return (SK_PNMI_ERR_TOO_SHORT); - } - break; - - case OID_SKGE_RLMT_CHANGE_CTS: - case OID_SKGE_RLMT_CHANGE_TIME: - case OID_SKGE_RLMT_CHANGE_ESTIM: - case OID_SKGE_RLMT_CHANGE_THRES: - if (*pLen < sizeof(SK_U64)) { - - *pLen = sizeof(SK_U64); - return (SK_PNMI_ERR_TOO_SHORT); - } - break; - - default: - SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR035, - SK_PNMI_ERR035MSG); - - *pLen = 0; - return (SK_PNMI_ERR_GENERAL); - } - - /* - * Update RLMT statistic and increment semaphores to indicate - * that an update was already done. Maybe RLMT will hold its - * statistic always up to date some time. Then we can - * remove this type of call. - */ - if ((Ret = RlmtUpdate(pAC, IoC, NetIndex)) != SK_PNMI_ERR_OK) { - - *pLen = 0; - return (Ret); - } - pAC->Pnmi.RlmtUpdatedFlag ++; - - /* - * Retrieve Value - */ - switch (Id) { - - case OID_SKGE_RLMT_MODE: - *pBuf = (char)pAC->Rlmt.Net[0].RlmtMode; - *pLen = sizeof(char); - break; - - case OID_SKGE_RLMT_PORT_NUMBER: - Val32 = (SK_U32)pAC->GIni.GIMacsFound; - SK_PNMI_STORE_U32(pBuf, Val32); - *pLen = sizeof(SK_U32); - break; - - case OID_SKGE_RLMT_PORT_ACTIVE: - *pBuf = 0; - /* - * If multiple ports may become active this OID - * doesn't make sense any more. A new variable in - * the port structure should be created. However, - * for this variable the first active port is - * returned. - */ - PhysPortMax = pAC->GIni.GIMacsFound; - - for (PhysPortIndex = 0; PhysPortIndex < PhysPortMax; - PhysPortIndex ++) { - - if (pAC->Pnmi.Port[PhysPortIndex].ActiveFlag) { - - *pBuf = (char)SK_PNMI_PORT_PHYS2LOG(PhysPortIndex); - break; - } - } - *pLen = sizeof(char); - break; - - case OID_SKGE_RLMT_PORT_PREFERRED: - *pBuf = (char)SK_PNMI_PORT_PHYS2LOG(pAC->Rlmt.Net[NetIndex].Preference); - *pLen = sizeof(char); - break; - - case OID_SKGE_RLMT_CHANGE_CTS: - Val64 = pAC->Pnmi.RlmtChangeCts; - SK_PNMI_STORE_U64(pBuf, Val64); - *pLen = sizeof(SK_U64); - break; - - case OID_SKGE_RLMT_CHANGE_TIME: - Val64 = pAC->Pnmi.RlmtChangeTime; - SK_PNMI_STORE_U64(pBuf, Val64); - *pLen = sizeof(SK_U64); - break; - - case OID_SKGE_RLMT_CHANGE_ESTIM: - Val64 = pAC->Pnmi.RlmtChangeEstimate.Estimate; - SK_PNMI_STORE_U64(pBuf, Val64); - *pLen = sizeof(SK_U64); - break; - - case OID_SKGE_RLMT_CHANGE_THRES: - Val64 = pAC->Pnmi.RlmtChangeThreshold; - SK_PNMI_STORE_U64(pBuf, Val64); - *pLen = sizeof(SK_U64); - break; - - default: - SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_ERR, - ("Rlmt: Unknown OID should be handled before")); - - pAC->Pnmi.RlmtUpdatedFlag --; - *pLen = 0; - return (SK_PNMI_ERR_GENERAL); - } - - pAC->Pnmi.RlmtUpdatedFlag --; - } - else { - /* Perform a preset or set */ - switch (Id) { - - case OID_SKGE_RLMT_MODE: - /* Check if the buffer length is plausible */ - if (*pLen < sizeof(char)) { - - *pLen = sizeof(char); - return (SK_PNMI_ERR_TOO_SHORT); - } - /* Check if the value range is correct */ - if (*pLen != sizeof(char) || - (*pBuf & SK_PNMI_RLMT_MODE_CHK_LINK) == 0 || - *(SK_U8 *)pBuf > 15) { - - *pLen = 0; - return (SK_PNMI_ERR_BAD_VALUE); - } - /* The preset ends here */ - if (Action == SK_PNMI_PRESET) { - - *pLen = 0; - return (SK_PNMI_ERR_OK); - } - /* Send an event to RLMT to change the mode */ - SK_MEMSET((char *)&EventParam, 0, sizeof(EventParam)); - EventParam.Para32[0] |= (SK_U32)(*pBuf); - EventParam.Para32[1] = 0; - if (SkRlmtEvent(pAC, IoC, SK_RLMT_MODE_CHANGE, - EventParam) > 0) { - - SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR037, - SK_PNMI_ERR037MSG); - - *pLen = 0; - return (SK_PNMI_ERR_GENERAL); - } - break; - - case OID_SKGE_RLMT_PORT_PREFERRED: - /* Check if the buffer length is plausible */ - if (*pLen < sizeof(char)) { - - *pLen = sizeof(char); - return (SK_PNMI_ERR_TOO_SHORT); - } - /* Check if the value range is correct */ - if (*pLen != sizeof(char) || *(SK_U8 *)pBuf > - (SK_U8)pAC->GIni.GIMacsFound) { - - *pLen = 0; - return (SK_PNMI_ERR_BAD_VALUE); - } - /* The preset ends here */ - if (Action == SK_PNMI_PRESET) { - - *pLen = 0; - return (SK_PNMI_ERR_OK); - } - - /* - * Send an event to RLMT change the preferred port. - * A param of -1 means automatic mode. RLMT will - * make the decision which is the preferred port. - */ - SK_MEMSET((char *)&EventParam, 0, sizeof(EventParam)); - EventParam.Para32[0] = (SK_U32)(*pBuf) - 1; - EventParam.Para32[1] = NetIndex; - if (SkRlmtEvent(pAC, IoC, SK_RLMT_PREFPORT_CHANGE, - EventParam) > 0) { - - SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR038, - SK_PNMI_ERR038MSG); - - *pLen = 0; - return (SK_PNMI_ERR_GENERAL); - } - break; - - case OID_SKGE_RLMT_CHANGE_THRES: - /* Check if the buffer length is plausible */ - if (*pLen < sizeof(SK_U64)) { - - *pLen = sizeof(SK_U64); - return (SK_PNMI_ERR_TOO_SHORT); - } - /* - * There are not many restrictions to the - * value range. - */ - if (*pLen != sizeof(SK_U64)) { - - *pLen = 0; - return (SK_PNMI_ERR_BAD_VALUE); - } - /* A preset ends here */ - if (Action == SK_PNMI_PRESET) { - - *pLen = 0; - return (SK_PNMI_ERR_OK); - } - /* - * Store the new threshold, which will be taken - * on the next timer event. - */ - SK_PNMI_READ_U64(pBuf, Val64); - pAC->Pnmi.RlmtChangeThreshold = Val64; - break; - - default: - /* The other OIDs are not be able for set */ - *pLen = 0; - return (SK_PNMI_ERR_READ_ONLY); - } - } - - return (SK_PNMI_ERR_OK); -} - -/***************************************************************************** - * - * RlmtStat - OID handler function of OID_SKGE_RLMT_XXX multiple instance. - * - * Description: - * Performs get requests on multiple instance variables. - * - * Returns: - * SK_PNMI_ERR_OK The request was successfully performed. - * SK_PNMI_ERR_GENERAL A general severe internal error occured. - * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain - * the correct data (e.g. a 32bit value is - * needed, but a 16 bit value was passed). - * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't - * exist (e.g. port instance 3 on a two port - * adapter. - */ -PNMI_STATIC int RlmtStat( -SK_AC *pAC, /* Pointer to adapter context */ -SK_IOC IoC, /* IO context handle */ -int Action, /* GET/PRESET/SET action */ -SK_U32 Id, /* Object ID that is to be processed */ -char *pBuf, /* Buffer used for the management data transfer */ -unsigned int *pLen, /* On call: pBuf buffer length. On return: used buffer */ -SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */ -unsigned int TableIndex, /* Index to the Id table */ -SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */ -{ - unsigned int PhysPortMax; - unsigned int PhysPortIndex; - unsigned int Limit; - unsigned int Offset; - int Ret; - SK_U32 Val32; - SK_U64 Val64; - - /* - * Calculate the port indexes from the instance. - */ - PhysPortMax = pAC->GIni.GIMacsFound; - - if ((Instance != (SK_U32)(-1))) { - /* Check instance range */ - if ((Instance < 1) || (Instance > PhysPortMax)) { - - *pLen = 0; - return (SK_PNMI_ERR_UNKNOWN_INST); - } - - /* Single net mode */ - PhysPortIndex = Instance - 1; - - /* Dual net mode */ - if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { - PhysPortIndex = NetIndex; - } - - /* Both net modes */ - Limit = PhysPortIndex + 1; - } - else { - /* Single net mode */ - PhysPortIndex = 0; - Limit = PhysPortMax; - - /* Dual net mode */ - if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { - PhysPortIndex = NetIndex; - Limit = PhysPortIndex + 1; - } - } - - /* - * Currently only get requests are allowed. - */ - if (Action != SK_PNMI_GET) { - - *pLen = 0; - return (SK_PNMI_ERR_READ_ONLY); - } - - /* - * Check if the buffer length is large enough. - */ - switch (Id) { - - case OID_SKGE_RLMT_PORT_INDEX: - case OID_SKGE_RLMT_STATUS: - if (*pLen < (Limit - PhysPortIndex) * sizeof(SK_U32)) { - - *pLen = (Limit - PhysPortIndex) * sizeof(SK_U32); - return (SK_PNMI_ERR_TOO_SHORT); - } - break; - - case OID_SKGE_RLMT_TX_HELLO_CTS: - case OID_SKGE_RLMT_RX_HELLO_CTS: - case OID_SKGE_RLMT_TX_SP_REQ_CTS: - case OID_SKGE_RLMT_RX_SP_CTS: - if (*pLen < (Limit - PhysPortIndex) * sizeof(SK_U64)) { - - *pLen = (Limit - PhysPortIndex) * sizeof(SK_U64); - return (SK_PNMI_ERR_TOO_SHORT); - } - break; - - default: - SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR039, - SK_PNMI_ERR039MSG); - - *pLen = 0; - return (SK_PNMI_ERR_GENERAL); - - } - - /* - * Update statistic and increment semaphores to indicate that - * an update was already done. - */ - if ((Ret = RlmtUpdate(pAC, IoC, NetIndex)) != SK_PNMI_ERR_OK) { - - *pLen = 0; - return (Ret); - } - pAC->Pnmi.RlmtUpdatedFlag ++; - - /* - * Get value - */ - Offset = 0; - for (; PhysPortIndex < Limit; PhysPortIndex ++) { - - switch (Id) { - - case OID_SKGE_RLMT_PORT_INDEX: - Val32 = PhysPortIndex; - SK_PNMI_STORE_U32(pBuf + Offset, Val32); - Offset += sizeof(SK_U32); - break; - - case OID_SKGE_RLMT_STATUS: - if (pAC->Rlmt.Port[PhysPortIndex].PortState == - SK_RLMT_PS_INIT || - pAC->Rlmt.Port[PhysPortIndex].PortState == - SK_RLMT_PS_DOWN) { - - Val32 = SK_PNMI_RLMT_STATUS_ERROR; - } - else if (pAC->Pnmi.Port[PhysPortIndex].ActiveFlag) { - - Val32 = SK_PNMI_RLMT_STATUS_ACTIVE; - } - else { - Val32 = SK_PNMI_RLMT_STATUS_STANDBY; - } - SK_PNMI_STORE_U32(pBuf + Offset, Val32); - Offset += sizeof(SK_U32); - break; - - case OID_SKGE_RLMT_TX_HELLO_CTS: - Val64 = pAC->Rlmt.Port[PhysPortIndex].TxHelloCts; - SK_PNMI_STORE_U64(pBuf + Offset, Val64); - Offset += sizeof(SK_U64); - break; - - case OID_SKGE_RLMT_RX_HELLO_CTS: - Val64 = pAC->Rlmt.Port[PhysPortIndex].RxHelloCts; - SK_PNMI_STORE_U64(pBuf + Offset, Val64); - Offset += sizeof(SK_U64); - break; - - case OID_SKGE_RLMT_TX_SP_REQ_CTS: - Val64 = pAC->Rlmt.Port[PhysPortIndex].TxSpHelloReqCts; - SK_PNMI_STORE_U64(pBuf + Offset, Val64); - Offset += sizeof(SK_U64); - break; - - case OID_SKGE_RLMT_RX_SP_CTS: - Val64 = pAC->Rlmt.Port[PhysPortIndex].RxSpHelloCts; - SK_PNMI_STORE_U64(pBuf + Offset, Val64); - Offset += sizeof(SK_U64); - break; - - default: - SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_ERR, - ("RlmtStat: Unknown OID should be errored before")); - - pAC->Pnmi.RlmtUpdatedFlag --; - *pLen = 0; - return (SK_PNMI_ERR_GENERAL); - } - } - *pLen = Offset; - - pAC->Pnmi.RlmtUpdatedFlag --; - - return (SK_PNMI_ERR_OK); -} - -/***************************************************************************** - * - * MacPrivateConf - OID handler function of OIDs concerning the configuration - * - * Description: - * Get/Presets/Sets the OIDs concerning the configuration. - * - * Returns: - * SK_PNMI_ERR_OK The request was successfully performed. - * SK_PNMI_ERR_GENERAL A general severe internal error occured. - * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain - * the correct data (e.g. a 32bit value is - * needed, but a 16 bit value was passed). - * SK_PNMI_ERR_BAD_VALUE The passed value is not in the valid - * value range. - * SK_PNMI_ERR_READ_ONLY The OID is read-only and cannot be set. - * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't - * exist (e.g. port instance 3 on a two port - * adapter. - */ -PNMI_STATIC int MacPrivateConf( -SK_AC *pAC, /* Pointer to adapter context */ -SK_IOC IoC, /* IO context handle */ -int Action, /* GET/PRESET/SET action */ -SK_U32 Id, /* Object ID that is to be processed */ -char *pBuf, /* Buffer used for the management data transfer */ -unsigned int *pLen, /* On call: pBuf buffer length. On return: used buffer */ -SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */ -unsigned int TableIndex, /* Index to the Id table */ -SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */ -{ - unsigned int PhysPortMax; - unsigned int PhysPortIndex; - unsigned int LogPortMax; - unsigned int LogPortIndex; - unsigned int Limit; - unsigned int Offset; - char Val8; - char *pBufPtr; - int Ret; - SK_EVPARA EventParam; - SK_U32 Val32; - - /* - * Calculate instance if wished. MAC index 0 is the virtual MAC. - */ - PhysPortMax = pAC->GIni.GIMacsFound; - LogPortMax = SK_PNMI_PORT_PHYS2LOG(PhysPortMax); - - if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { /* Dual net mode */ - LogPortMax--; - } - - if ((Instance != (SK_U32)(-1))) { /* Only one specific instance is queried */ - /* Check instance range */ - if ((Instance < 1) || (Instance > LogPortMax)) { - - *pLen = 0; - return (SK_PNMI_ERR_UNKNOWN_INST); - } - LogPortIndex = SK_PNMI_PORT_INST2LOG(Instance); - Limit = LogPortIndex + 1; - } - - else { /* Instance == (SK_U32)(-1), get all Instances of that OID */ - - LogPortIndex = 0; - Limit = LogPortMax; - } - - /* - * Perform action - */ - if (Action == SK_PNMI_GET) { - - /* Check length */ - switch (Id) { - - case OID_SKGE_PMD: - case OID_SKGE_CONNECTOR: - case OID_SKGE_LINK_CAP: - case OID_SKGE_LINK_MODE: - case OID_SKGE_LINK_MODE_STATUS: - case OID_SKGE_LINK_STATUS: - case OID_SKGE_FLOWCTRL_CAP: - case OID_SKGE_FLOWCTRL_MODE: - case OID_SKGE_FLOWCTRL_STATUS: - case OID_SKGE_PHY_OPERATION_CAP: - case OID_SKGE_PHY_OPERATION_MODE: - case OID_SKGE_PHY_OPERATION_STATUS: - case OID_SKGE_SPEED_CAP: - case OID_SKGE_SPEED_MODE: - case OID_SKGE_SPEED_STATUS: -#ifdef SK_PHY_LP_MODE - case OID_SKGE_PHY_LP_MODE: -#endif - if (*pLen < (Limit - LogPortIndex) * sizeof(SK_U8)) { - - *pLen = (Limit - LogPortIndex) * sizeof(SK_U8); - return (SK_PNMI_ERR_TOO_SHORT); - } - break; - - case OID_SKGE_MTU: - case OID_SKGE_PHY_TYPE: - if (*pLen < (Limit - LogPortIndex) * sizeof(SK_U32)) { - - *pLen = (Limit - LogPortIndex) * sizeof(SK_U32); - return (SK_PNMI_ERR_TOO_SHORT); - } - break; - - default: - SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR041, - SK_PNMI_ERR041MSG); - *pLen = 0; - return (SK_PNMI_ERR_GENERAL); - } - - /* - * Update statistic and increment semaphore to indicate - * that an update was already done. - */ - if ((Ret = SirqUpdate(pAC, IoC)) != SK_PNMI_ERR_OK) { - - *pLen = 0; - return (Ret); - } - pAC->Pnmi.SirqUpdatedFlag ++; - - /* - * Get value - */ - Offset = 0; - for (; LogPortIndex < Limit; LogPortIndex ++) { - - pBufPtr = pBuf + Offset; - - switch (Id) { - - case OID_SKGE_PMD: - *pBufPtr = pAC->Pnmi.PMD; - Offset += sizeof(char); - break; - - case OID_SKGE_CONNECTOR: - *pBufPtr = pAC->Pnmi.Connector; - Offset += sizeof(char); - break; - - case OID_SKGE_PHY_TYPE: - if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */ - if (LogPortIndex == 0) { - continue; - } - else { - /* Get value for physical ports */ - PhysPortIndex = SK_PNMI_PORT_LOG2PHYS( - pAC, LogPortIndex); - Val32 = pAC->GIni.GP[PhysPortIndex].PhyType; - SK_PNMI_STORE_U32(pBufPtr, Val32); - } - } - else { /* DualNetMode */ - - Val32 = pAC->GIni.GP[NetIndex].PhyType; - SK_PNMI_STORE_U32(pBufPtr, Val32); - } - Offset += sizeof(SK_U32); - break; - -#ifdef SK_PHY_LP_MODE - case OID_SKGE_PHY_LP_MODE: - if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */ - if (LogPortIndex == 0) { - continue; - } - else { - /* Get value for physical ports */ - PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(pAC, LogPortIndex); - Val8 = (SK_U8) pAC->GIni.GP[PhysPortIndex].PPhyPowerState; - *pBufPtr = Val8; - } - } - else { /* DualNetMode */ - - Val8 = (SK_U8) pAC->GIni.GP[PhysPortIndex].PPhyPowerState; - *pBufPtr = Val8; - } - Offset += sizeof(SK_U8); - break; -#endif - - case OID_SKGE_LINK_CAP: - if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */ - if (LogPortIndex == 0) { - /* Get value for virtual port */ - VirtualConf(pAC, IoC, Id, pBufPtr); - } - else { - /* Get value for physical ports */ - PhysPortIndex = SK_PNMI_PORT_LOG2PHYS( - pAC, LogPortIndex); - - *pBufPtr = pAC->GIni.GP[PhysPortIndex].PLinkCap; - } - } - else { /* DualNetMode */ - - *pBufPtr = pAC->GIni.GP[NetIndex].PLinkCap; - } - Offset += sizeof(char); - break; - - case OID_SKGE_LINK_MODE: - if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */ - if (LogPortIndex == 0) { - /* Get value for virtual port */ - VirtualConf(pAC, IoC, Id, pBufPtr); - } - else { - /* Get value for physical ports */ - PhysPortIndex = SK_PNMI_PORT_LOG2PHYS( - pAC, LogPortIndex); - - *pBufPtr = pAC->GIni.GP[PhysPortIndex].PLinkModeConf; - } - } - else { /* DualNetMode */ - - *pBufPtr = pAC->GIni.GP[NetIndex].PLinkModeConf; - } - Offset += sizeof(char); - break; - - case OID_SKGE_LINK_MODE_STATUS: - if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */ - if (LogPortIndex == 0) { - /* Get value for virtual port */ - VirtualConf(pAC, IoC, Id, pBufPtr); - } - else { - /* Get value for physical port */ - PhysPortIndex = SK_PNMI_PORT_LOG2PHYS( - pAC, LogPortIndex); - - *pBufPtr = - CalculateLinkModeStatus(pAC, IoC, PhysPortIndex); - } - } - else { /* DualNetMode */ - - *pBufPtr = CalculateLinkModeStatus(pAC, IoC, NetIndex); - } - Offset += sizeof(char); - break; - - case OID_SKGE_LINK_STATUS: - if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */ - if (LogPortIndex == 0) { - /* Get value for virtual port */ - VirtualConf(pAC, IoC, Id, pBufPtr); - } - else { - /* Get value for physical ports */ - PhysPortIndex = SK_PNMI_PORT_LOG2PHYS( - pAC, LogPortIndex); - - *pBufPtr = CalculateLinkStatus(pAC, IoC, PhysPortIndex); - } - } - else { /* DualNetMode */ - - *pBufPtr = CalculateLinkStatus(pAC, IoC, NetIndex); - } - Offset += sizeof(char); - break; - - case OID_SKGE_FLOWCTRL_CAP: - if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */ - if (LogPortIndex == 0) { - /* Get value for virtual port */ - VirtualConf(pAC, IoC, Id, pBufPtr); - } - else { - /* Get value for physical ports */ - PhysPortIndex = SK_PNMI_PORT_LOG2PHYS( - pAC, LogPortIndex); - - *pBufPtr = pAC->GIni.GP[PhysPortIndex].PFlowCtrlCap; - } - } - else { /* DualNetMode */ - - *pBufPtr = pAC->GIni.GP[NetIndex].PFlowCtrlCap; - } - Offset += sizeof(char); - break; - - case OID_SKGE_FLOWCTRL_MODE: - if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */ - if (LogPortIndex == 0) { - /* Get value for virtual port */ - VirtualConf(pAC, IoC, Id, pBufPtr); - } - else { - /* Get value for physical port */ - PhysPortIndex = SK_PNMI_PORT_LOG2PHYS( - pAC, LogPortIndex); - - *pBufPtr = pAC->GIni.GP[PhysPortIndex].PFlowCtrlMode; - } - } - else { /* DualNetMode */ - - *pBufPtr = pAC->GIni.GP[NetIndex].PFlowCtrlMode; - } - Offset += sizeof(char); - break; - - case OID_SKGE_FLOWCTRL_STATUS: - if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */ - if (LogPortIndex == 0) { - /* Get value for virtual port */ - VirtualConf(pAC, IoC, Id, pBufPtr); - } - else { - /* Get value for physical port */ - PhysPortIndex = SK_PNMI_PORT_LOG2PHYS( - pAC, LogPortIndex); - - *pBufPtr = pAC->GIni.GP[PhysPortIndex].PFlowCtrlStatus; - } - } - else { /* DualNetMode */ - - *pBufPtr = pAC->GIni.GP[NetIndex].PFlowCtrlStatus; - } - Offset += sizeof(char); - break; - - case OID_SKGE_PHY_OPERATION_CAP: - if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */ - if (LogPortIndex == 0) { - /* Get value for virtual port */ - VirtualConf(pAC, IoC, Id, pBufPtr); - } - else { - /* Get value for physical ports */ - PhysPortIndex = SK_PNMI_PORT_LOG2PHYS( - pAC, LogPortIndex); - - *pBufPtr = pAC->GIni.GP[PhysPortIndex].PMSCap; - } - } - else { /* DualNetMode */ - - *pBufPtr = pAC->GIni.GP[NetIndex].PMSCap; - } - Offset += sizeof(char); - break; - - case OID_SKGE_PHY_OPERATION_MODE: - if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */ - if (LogPortIndex == 0) { - /* Get value for virtual port */ - VirtualConf(pAC, IoC, Id, pBufPtr); - } - else { - /* Get value for physical port */ - PhysPortIndex = SK_PNMI_PORT_LOG2PHYS( - pAC, LogPortIndex); - - *pBufPtr = pAC->GIni.GP[PhysPortIndex].PMSMode; - } - } - else { /* DualNetMode */ - - *pBufPtr = pAC->GIni.GP[NetIndex].PMSMode; - } - Offset += sizeof(char); - break; - - case OID_SKGE_PHY_OPERATION_STATUS: - if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */ - if (LogPortIndex == 0) { - /* Get value for virtual port */ - VirtualConf(pAC, IoC, Id, pBufPtr); - } - else { - /* Get value for physical port */ - PhysPortIndex = SK_PNMI_PORT_LOG2PHYS( - pAC, LogPortIndex); - - *pBufPtr = pAC->GIni.GP[PhysPortIndex].PMSStatus; - } - } - else { - - *pBufPtr = pAC->GIni.GP[NetIndex].PMSStatus; - } - Offset += sizeof(char); - break; - - case OID_SKGE_SPEED_CAP: - if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */ - if (LogPortIndex == 0) { - /* Get value for virtual port */ - VirtualConf(pAC, IoC, Id, pBufPtr); - } - else { - /* Get value for physical ports */ - PhysPortIndex = SK_PNMI_PORT_LOG2PHYS( - pAC, LogPortIndex); - - *pBufPtr = pAC->GIni.GP[PhysPortIndex].PLinkSpeedCap; - } - } - else { /* DualNetMode */ - - *pBufPtr = pAC->GIni.GP[NetIndex].PLinkSpeedCap; - } - Offset += sizeof(char); - break; - - case OID_SKGE_SPEED_MODE: - if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */ - if (LogPortIndex == 0) { - /* Get value for virtual port */ - VirtualConf(pAC, IoC, Id, pBufPtr); - } - else { - /* Get value for physical port */ - PhysPortIndex = SK_PNMI_PORT_LOG2PHYS( - pAC, LogPortIndex); - - *pBufPtr = pAC->GIni.GP[PhysPortIndex].PLinkSpeed; - } - } - else { /* DualNetMode */ - - *pBufPtr = pAC->GIni.GP[NetIndex].PLinkSpeed; - } - Offset += sizeof(char); - break; - - case OID_SKGE_SPEED_STATUS: - if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */ - if (LogPortIndex == 0) { - /* Get value for virtual port */ - VirtualConf(pAC, IoC, Id, pBufPtr); - } - else { - /* Get value for physical port */ - PhysPortIndex = SK_PNMI_PORT_LOG2PHYS( - pAC, LogPortIndex); - - *pBufPtr = pAC->GIni.GP[PhysPortIndex].PLinkSpeedUsed; - } - } - else { /* DualNetMode */ - - *pBufPtr = pAC->GIni.GP[NetIndex].PLinkSpeedUsed; - } - Offset += sizeof(char); - break; - - case OID_SKGE_MTU: - Val32 = SK_DRIVER_GET_MTU(pAC, IoC, NetIndex); - SK_PNMI_STORE_U32(pBufPtr, Val32); - Offset += sizeof(SK_U32); - break; - - default: - SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_ERR, - ("MacPrivateConf: Unknown OID should be handled before")); - - pAC->Pnmi.SirqUpdatedFlag --; - return (SK_PNMI_ERR_GENERAL); - } - } - *pLen = Offset; - pAC->Pnmi.SirqUpdatedFlag --; - - return (SK_PNMI_ERR_OK); - } - - /* - * From here SET or PRESET action. Check if the passed - * buffer length is plausible. - */ - switch (Id) { - - case OID_SKGE_LINK_MODE: - case OID_SKGE_FLOWCTRL_MODE: - case OID_SKGE_PHY_OPERATION_MODE: - case OID_SKGE_SPEED_MODE: - if (*pLen < Limit - LogPortIndex) { - - *pLen = Limit - LogPortIndex; - return (SK_PNMI_ERR_TOO_SHORT); - } - if (*pLen != Limit - LogPortIndex) { - - *pLen = 0; - return (SK_PNMI_ERR_BAD_VALUE); - } - break; - -#ifdef SK_PHY_LP_MODE - case OID_SKGE_PHY_LP_MODE: - if (*pLen < Limit - LogPortIndex) { - - *pLen = Limit - LogPortIndex; - return (SK_PNMI_ERR_TOO_SHORT); - } - break; -#endif - - case OID_SKGE_MTU: - if (*pLen < sizeof(SK_U32)) { - - *pLen = sizeof(SK_U32); - return (SK_PNMI_ERR_TOO_SHORT); - } - if (*pLen != sizeof(SK_U32)) { - - *pLen = 0; - return (SK_PNMI_ERR_BAD_VALUE); - } - break; - - default: - *pLen = 0; - return (SK_PNMI_ERR_READ_ONLY); - } - - /* - * Perform preset or set - */ - Offset = 0; - for (; LogPortIndex < Limit; LogPortIndex ++) { - - switch (Id) { - - case OID_SKGE_LINK_MODE: - /* Check the value range */ - Val8 = *(pBuf + Offset); - if (Val8 == 0) { - - Offset += sizeof(char); - break; - } - if (Val8 < SK_LMODE_HALF || - (LogPortIndex != 0 && Val8 > SK_LMODE_AUTOSENSE) || - (LogPortIndex == 0 && Val8 > SK_LMODE_INDETERMINATED)) { - - *pLen = 0; - return (SK_PNMI_ERR_BAD_VALUE); - } - - /* The preset ends here */ - if (Action == SK_PNMI_PRESET) { - - return (SK_PNMI_ERR_OK); - } - - if (LogPortIndex == 0) { - - /* - * The virtual port consists of all currently - * active ports. Find them and send an event - * with the new link mode to SIRQ. - */ - for (PhysPortIndex = 0; - PhysPortIndex < PhysPortMax; - PhysPortIndex ++) { - - if (!pAC->Pnmi.Port[PhysPortIndex]. - ActiveFlag) { - - continue; - } - - EventParam.Para32[0] = PhysPortIndex; - EventParam.Para32[1] = (SK_U32)Val8; - if (SkGeSirqEvent(pAC, IoC, - SK_HWEV_SET_LMODE, - EventParam) > 0) { - - SK_ERR_LOG(pAC, SK_ERRCL_SW, - SK_PNMI_ERR043, - SK_PNMI_ERR043MSG); - - *pLen = 0; - return (SK_PNMI_ERR_GENERAL); - } - } - } - else { - /* - * Send an event with the new link mode to - * the SIRQ module. - */ - EventParam.Para32[0] = SK_PNMI_PORT_LOG2PHYS( - pAC, LogPortIndex); - EventParam.Para32[1] = (SK_U32)Val8; - if (SkGeSirqEvent(pAC, IoC, SK_HWEV_SET_LMODE, - EventParam) > 0) { - - SK_ERR_LOG(pAC, SK_ERRCL_SW, - SK_PNMI_ERR043, - SK_PNMI_ERR043MSG); - - *pLen = 0; - return (SK_PNMI_ERR_GENERAL); - } - } - Offset += sizeof(char); - break; - - case OID_SKGE_FLOWCTRL_MODE: - /* Check the value range */ - Val8 = *(pBuf + Offset); - if (Val8 == 0) { - - Offset += sizeof(char); - break; - } - if (Val8 < SK_FLOW_MODE_NONE || - (LogPortIndex != 0 && Val8 > SK_FLOW_MODE_SYM_OR_REM) || - (LogPortIndex == 0 && Val8 > SK_FLOW_MODE_INDETERMINATED)) { - - *pLen = 0; - return (SK_PNMI_ERR_BAD_VALUE); - } - - /* The preset ends here */ - if (Action == SK_PNMI_PRESET) { - - return (SK_PNMI_ERR_OK); - } - - if (LogPortIndex == 0) { - - /* - * The virtual port consists of all currently - * active ports. Find them and send an event - * with the new flow control mode to SIRQ. - */ - for (PhysPortIndex = 0; - PhysPortIndex < PhysPortMax; - PhysPortIndex ++) { - - if (!pAC->Pnmi.Port[PhysPortIndex]. - ActiveFlag) { - - continue; - } - - EventParam.Para32[0] = PhysPortIndex; - EventParam.Para32[1] = (SK_U32)Val8; - if (SkGeSirqEvent(pAC, IoC, - SK_HWEV_SET_FLOWMODE, - EventParam) > 0) { - - SK_ERR_LOG(pAC, SK_ERRCL_SW, - SK_PNMI_ERR044, - SK_PNMI_ERR044MSG); - - *pLen = 0; - return (SK_PNMI_ERR_GENERAL); - } - } - } - else { - /* - * Send an event with the new flow control - * mode to the SIRQ module. - */ - EventParam.Para32[0] = SK_PNMI_PORT_LOG2PHYS( - pAC, LogPortIndex); - EventParam.Para32[1] = (SK_U32)Val8; - if (SkGeSirqEvent(pAC, IoC, - SK_HWEV_SET_FLOWMODE, EventParam) - > 0) { - - SK_ERR_LOG(pAC, SK_ERRCL_SW, - SK_PNMI_ERR044, - SK_PNMI_ERR044MSG); - - *pLen = 0; - return (SK_PNMI_ERR_GENERAL); - } - } - Offset += sizeof(char); - break; - - case OID_SKGE_PHY_OPERATION_MODE : - /* Check the value range */ - Val8 = *(pBuf + Offset); - if (Val8 == 0) { - /* mode of this port remains unchanged */ - Offset += sizeof(char); - break; - } - if (Val8 < SK_MS_MODE_AUTO || - (LogPortIndex != 0 && Val8 > SK_MS_MODE_SLAVE) || - (LogPortIndex == 0 && Val8 > SK_MS_MODE_INDETERMINATED)) { - - *pLen = 0; - return (SK_PNMI_ERR_BAD_VALUE); - } - - /* The preset ends here */ - if (Action == SK_PNMI_PRESET) { - - return (SK_PNMI_ERR_OK); - } - - if (LogPortIndex == 0) { - - /* - * The virtual port consists of all currently - * active ports. Find them and send an event - * with new master/slave (role) mode to SIRQ. - */ - for (PhysPortIndex = 0; - PhysPortIndex < PhysPortMax; - PhysPortIndex ++) { - - if (!pAC->Pnmi.Port[PhysPortIndex]. - ActiveFlag) { - - continue; - } - - EventParam.Para32[0] = PhysPortIndex; - EventParam.Para32[1] = (SK_U32)Val8; - if (SkGeSirqEvent(pAC, IoC, - SK_HWEV_SET_ROLE, - EventParam) > 0) { - - SK_ERR_LOG(pAC, SK_ERRCL_SW, - SK_PNMI_ERR042, - SK_PNMI_ERR042MSG); - - *pLen = 0; - return (SK_PNMI_ERR_GENERAL); - } - } - } - else { - /* - * Send an event with the new master/slave - * (role) mode to the SIRQ module. - */ - EventParam.Para32[0] = SK_PNMI_PORT_LOG2PHYS( - pAC, LogPortIndex); - EventParam.Para32[1] = (SK_U32)Val8; - if (SkGeSirqEvent(pAC, IoC, - SK_HWEV_SET_ROLE, EventParam) > 0) { - - SK_ERR_LOG(pAC, SK_ERRCL_SW, - SK_PNMI_ERR042, - SK_PNMI_ERR042MSG); - - *pLen = 0; - return (SK_PNMI_ERR_GENERAL); - } - } - - Offset += sizeof(char); - break; - - case OID_SKGE_SPEED_MODE: - /* Check the value range */ - Val8 = *(pBuf + Offset); - if (Val8 == 0) { - - Offset += sizeof(char); - break; - } - if (Val8 < (SK_LSPEED_AUTO) || - (LogPortIndex != 0 && Val8 > (SK_LSPEED_1000MBPS)) || - (LogPortIndex == 0 && Val8 > (SK_LSPEED_INDETERMINATED))) { - - *pLen = 0; - return (SK_PNMI_ERR_BAD_VALUE); - } - - /* The preset ends here */ - if (Action == SK_PNMI_PRESET) { - - return (SK_PNMI_ERR_OK); - } - - if (LogPortIndex == 0) { - - /* - * The virtual port consists of all currently - * active ports. Find them and send an event - * with the new flow control mode to SIRQ. - */ - for (PhysPortIndex = 0; - PhysPortIndex < PhysPortMax; - PhysPortIndex ++) { - - if (!pAC->Pnmi.Port[PhysPortIndex].ActiveFlag) { - - continue; - } - - EventParam.Para32[0] = PhysPortIndex; - EventParam.Para32[1] = (SK_U32)Val8; - if (SkGeSirqEvent(pAC, IoC, - SK_HWEV_SET_SPEED, - EventParam) > 0) { - - SK_ERR_LOG(pAC, SK_ERRCL_SW, - SK_PNMI_ERR045, - SK_PNMI_ERR045MSG); - - *pLen = 0; - return (SK_PNMI_ERR_GENERAL); - } - } - } - else { - /* - * Send an event with the new flow control - * mode to the SIRQ module. - */ - EventParam.Para32[0] = SK_PNMI_PORT_LOG2PHYS( - pAC, LogPortIndex); - EventParam.Para32[1] = (SK_U32)Val8; - if (SkGeSirqEvent(pAC, IoC, - SK_HWEV_SET_SPEED, - EventParam) > 0) { - - SK_ERR_LOG(pAC, SK_ERRCL_SW, - SK_PNMI_ERR045, - SK_PNMI_ERR045MSG); - - *pLen = 0; - return (SK_PNMI_ERR_GENERAL); - } - } - Offset += sizeof(char); - break; - - case OID_SKGE_MTU : - /* Check the value range */ - Val32 = *(SK_U32*)(pBuf + Offset); - if (Val32 == 0) { - /* mtu of this port remains unchanged */ - Offset += sizeof(SK_U32); - break; - } - if (SK_DRIVER_PRESET_MTU(pAC, IoC, NetIndex, Val32) != 0) { - *pLen = 0; - return (SK_PNMI_ERR_BAD_VALUE); - } - - /* The preset ends here */ - if (Action == SK_PNMI_PRESET) { - return (SK_PNMI_ERR_OK); - } - - if (SK_DRIVER_SET_MTU(pAC, IoC, NetIndex, Val32) != 0) { - return (SK_PNMI_ERR_GENERAL); - } - - Offset += sizeof(SK_U32); - break; - -#ifdef SK_PHY_LP_MODE - case OID_SKGE_PHY_LP_MODE: - /* The preset ends here */ - if (Action == SK_PNMI_PRESET) { - - return (SK_PNMI_ERR_OK); - } - - if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */ - if (LogPortIndex == 0) { - Offset = 0; - continue; - } - else { - /* Set value for physical ports */ - PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(pAC, LogPortIndex); - - switch (*(pBuf + Offset)) { - case 0: - /* If LowPowerMode is active, we can leave it. */ - if (pAC->GIni.GP[PhysPortIndex].PPhyPowerState) { - - Val32 = SkGmLeaveLowPowerMode(pAC, IoC, PhysPortIndex); - - if (pAC->GIni.GP[PhysPortIndex].PPhyPowerState < 3) { - - SkDrvInitAdapter(pAC); - } - break; - } - else { - *pLen = 0; - return (SK_PNMI_ERR_GENERAL); - } - case 1: - case 2: - case 3: - case 4: - /* If no LowPowerMode is active, we can enter it. */ - if (!pAC->GIni.GP[PhysPortIndex].PPhyPowerState) { - - if ((*(pBuf + Offset)) < 3) { - - SkDrvDeInitAdapter(pAC); - } - - Val32 = SkGmEnterLowPowerMode(pAC, IoC, PhysPortIndex, *pBuf); - break; - } - else { - *pLen = 0; - return (SK_PNMI_ERR_GENERAL); - } - default: - *pLen = 0; - return (SK_PNMI_ERR_BAD_VALUE); - } - } - } - else { /* DualNetMode */ - - switch (*(pBuf + Offset)) { - case 0: - /* If we are in a LowPowerMode, we can leave it. */ - if (pAC->GIni.GP[PhysPortIndex].PPhyPowerState) { - - Val32 = SkGmLeaveLowPowerMode(pAC, IoC, PhysPortIndex); - - if (pAC->GIni.GP[PhysPortIndex].PPhyPowerState < 3) { - - SkDrvInitAdapter(pAC); - } - break; - } - else { - *pLen = 0; - return (SK_PNMI_ERR_GENERAL); - } - - case 1: - case 2: - case 3: - case 4: - /* If we are not already in LowPowerMode, we can enter it. */ - if (!pAC->GIni.GP[PhysPortIndex].PPhyPowerState) { - - if ((*(pBuf + Offset)) < 3) { - - SkDrvDeInitAdapter(pAC); - } - else { - - Val32 = SkGmEnterLowPowerMode(pAC, IoC, PhysPortIndex, *pBuf); - } - break; - } - else { - *pLen = 0; - return (SK_PNMI_ERR_GENERAL); - } - - default: - *pLen = 0; - return (SK_PNMI_ERR_BAD_VALUE); - } - } - Offset += sizeof(SK_U8); - break; -#endif - - default: - SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_ERR, - ("MacPrivateConf: Unknown OID should be handled before set")); - - *pLen = 0; - return (SK_PNMI_ERR_GENERAL); - } - } - - return (SK_PNMI_ERR_OK); -} - -/***************************************************************************** - * - * Monitor - OID handler function for RLMT_MONITOR_XXX - * - * Description: - * Because RLMT currently does not support the monitoring of - * remote adapter cards, we return always an empty table. - * - * Returns: - * SK_PNMI_ERR_OK The request was successfully performed. - * SK_PNMI_ERR_GENERAL A general severe internal error occured. - * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain - * the correct data (e.g. a 32bit value is - * needed, but a 16 bit value was passed). - * SK_PNMI_ERR_BAD_VALUE The passed value is not in the valid - * value range. - * SK_PNMI_ERR_READ_ONLY The OID is read-only and cannot be set. - * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't - * exist (e.g. port instance 3 on a two port - * adapter. - */ -PNMI_STATIC int Monitor( -SK_AC *pAC, /* Pointer to adapter context */ -SK_IOC IoC, /* IO context handle */ -int Action, /* GET/PRESET/SET action */ -SK_U32 Id, /* Object ID that is to be processed */ -char *pBuf, /* Buffer used for the management data transfer */ -unsigned int *pLen, /* On call: pBuf buffer length. On return: used buffer */ -SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */ -unsigned int TableIndex, /* Index to the Id table */ -SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */ -{ - unsigned int Index; - unsigned int Limit; - unsigned int Offset; - unsigned int Entries; - - - /* - * Calculate instance if wished. - */ - /* XXX Not yet implemented. Return always an empty table. */ - Entries = 0; - - if ((Instance != (SK_U32)(-1))) { - - if ((Instance < 1) || (Instance > Entries)) { - - *pLen = 0; - return (SK_PNMI_ERR_UNKNOWN_INST); - } - - Index = (unsigned int)Instance - 1; - Limit = (unsigned int)Instance; - } - else { - Index = 0; - Limit = Entries; - } - - /* - * Get/Set value - */ - if (Action == SK_PNMI_GET) { - - for (Offset=0; Index < Limit; Index ++) { - - switch (Id) { - - case OID_SKGE_RLMT_MONITOR_INDEX: - case OID_SKGE_RLMT_MONITOR_ADDR: - case OID_SKGE_RLMT_MONITOR_ERRS: - case OID_SKGE_RLMT_MONITOR_TIMESTAMP: - case OID_SKGE_RLMT_MONITOR_ADMIN: - break; - - default: - SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR046, - SK_PNMI_ERR046MSG); - - *pLen = 0; - return (SK_PNMI_ERR_GENERAL); - } - } - *pLen = Offset; - } - else { - /* Only MONITOR_ADMIN can be set */ - if (Id != OID_SKGE_RLMT_MONITOR_ADMIN) { - - *pLen = 0; - return (SK_PNMI_ERR_READ_ONLY); - } - - /* Check if the length is plausible */ - if (*pLen < (Limit - Index)) { - - return (SK_PNMI_ERR_TOO_SHORT); - } - /* Okay, we have a wide value range */ - if (*pLen != (Limit - Index)) { - - *pLen = 0; - return (SK_PNMI_ERR_BAD_VALUE); - } -/* - for (Offset=0; Index < Limit; Index ++) { - } -*/ -/* - * XXX Not yet implemented. Return always BAD_VALUE, because the table - * is empty. - */ - *pLen = 0; - return (SK_PNMI_ERR_BAD_VALUE); - } - - return (SK_PNMI_ERR_OK); -} - -/***************************************************************************** - * - * VirtualConf - Calculates the values of configuration OIDs for virtual port - * - * Description: - * We handle here the get of the configuration group OIDs, which are - * a little bit complicated. The virtual port consists of all currently - * active physical ports. If multiple ports are active and configured - * differently we get in some trouble to return a single value. So we - * get the value of the first active port and compare it with that of - * the other active ports. If they are not the same, we return a value - * that indicates that the state is indeterminated. - * - * Returns: - * Nothing - */ -PNMI_STATIC void VirtualConf( -SK_AC *pAC, /* Pointer to adapter context */ -SK_IOC IoC, /* IO context handle */ -SK_U32 Id, /* Object ID that is to be processed */ -char *pBuf) /* Buffer used for the management data transfer */ -{ - unsigned int PhysPortMax; - unsigned int PhysPortIndex; - SK_U8 Val8; - SK_U32 Val32; - SK_BOOL PortActiveFlag; - SK_GEPORT *pPrt; - - *pBuf = 0; - PortActiveFlag = SK_FALSE; - PhysPortMax = pAC->GIni.GIMacsFound; - - for (PhysPortIndex = 0; PhysPortIndex < PhysPortMax; - PhysPortIndex ++) { - - pPrt = &pAC->GIni.GP[PhysPortIndex]; - - /* Check if the physical port is active */ - if (!pAC->Pnmi.Port[PhysPortIndex].ActiveFlag) { - - continue; - } - - PortActiveFlag = SK_TRUE; - - switch (Id) { - - case OID_SKGE_PHY_TYPE: - /* Check if it is the first active port */ - if (*pBuf == 0) { - Val32 = pPrt->PhyType; - SK_PNMI_STORE_U32(pBuf, Val32); - continue; - } - - case OID_SKGE_LINK_CAP: - - /* - * Different capabilities should not happen, but - * in the case of the cases OR them all together. - * From a curious point of view the virtual port - * is capable of all found capabilities. - */ - *pBuf |= pPrt->PLinkCap; - break; - - case OID_SKGE_LINK_MODE: - /* Check if it is the first active port */ - if (*pBuf == 0) { - - *pBuf = pPrt->PLinkModeConf; - continue; - } - - /* - * If we find an active port with a different link - * mode than the first one we return a value that - * indicates that the link mode is indeterminated. - */ - if (*pBuf != pPrt->PLinkModeConf) { - - *pBuf = SK_LMODE_INDETERMINATED; - } - break; - - case OID_SKGE_LINK_MODE_STATUS: - /* Get the link mode of the physical port */ - Val8 = CalculateLinkModeStatus(pAC, IoC, PhysPortIndex); - - /* Check if it is the first active port */ - if (*pBuf == 0) { - - *pBuf = Val8; - continue; - } - - /* - * If we find an active port with a different link - * mode status than the first one we return a value - * that indicates that the link mode status is - * indeterminated. - */ - if (*pBuf != Val8) { - - *pBuf = SK_LMODE_STAT_INDETERMINATED; - } - break; - - case OID_SKGE_LINK_STATUS: - /* Get the link status of the physical port */ - Val8 = CalculateLinkStatus(pAC, IoC, PhysPortIndex); - - /* Check if it is the first active port */ - if (*pBuf == 0) { - - *pBuf = Val8; - continue; - } - - /* - * If we find an active port with a different link - * status than the first one, we return a value - * that indicates that the link status is - * indeterminated. - */ - if (*pBuf != Val8) { - - *pBuf = SK_PNMI_RLMT_LSTAT_INDETERMINATED; - } - break; - - case OID_SKGE_FLOWCTRL_CAP: - /* Check if it is the first active port */ - if (*pBuf == 0) { - - *pBuf = pPrt->PFlowCtrlCap; - continue; - } - - /* - * From a curious point of view the virtual port - * is capable of all found capabilities. - */ - *pBuf |= pPrt->PFlowCtrlCap; - break; - - case OID_SKGE_FLOWCTRL_MODE: - /* Check if it is the first active port */ - if (*pBuf == 0) { - - *pBuf = pPrt->PFlowCtrlMode; - continue; - } - - /* - * If we find an active port with a different flow - * control mode than the first one, we return a value - * that indicates that the mode is indeterminated. - */ - if (*pBuf != pPrt->PFlowCtrlMode) { - - *pBuf = SK_FLOW_MODE_INDETERMINATED; - } - break; - - case OID_SKGE_FLOWCTRL_STATUS: - /* Check if it is the first active port */ - if (*pBuf == 0) { - - *pBuf = pPrt->PFlowCtrlStatus; - continue; - } - - /* - * If we find an active port with a different flow - * control status than the first one, we return a - * value that indicates that the status is - * indeterminated. - */ - if (*pBuf != pPrt->PFlowCtrlStatus) { - - *pBuf = SK_FLOW_STAT_INDETERMINATED; - } - break; - - case OID_SKGE_PHY_OPERATION_CAP: - /* Check if it is the first active port */ - if (*pBuf == 0) { - - *pBuf = pPrt->PMSCap; - continue; - } - - /* - * From a curious point of view the virtual port - * is capable of all found capabilities. - */ - *pBuf |= pPrt->PMSCap; - break; - - case OID_SKGE_PHY_OPERATION_MODE: - /* Check if it is the first active port */ - if (*pBuf == 0) { - - *pBuf = pPrt->PMSMode; - continue; - } - - /* - * If we find an active port with a different master/ - * slave mode than the first one, we return a value - * that indicates that the mode is indeterminated. - */ - if (*pBuf != pPrt->PMSMode) { - - *pBuf = SK_MS_MODE_INDETERMINATED; - } - break; - - case OID_SKGE_PHY_OPERATION_STATUS: - /* Check if it is the first active port */ - if (*pBuf == 0) { - - *pBuf = pPrt->PMSStatus; - continue; - } - - /* - * If we find an active port with a different master/ - * slave status than the first one, we return a - * value that indicates that the status is - * indeterminated. - */ - if (*pBuf != pPrt->PMSStatus) { - - *pBuf = SK_MS_STAT_INDETERMINATED; - } - break; - - case OID_SKGE_SPEED_MODE: - /* Check if it is the first active port */ - if (*pBuf == 0) { - - *pBuf = pPrt->PLinkSpeed; - continue; - } - - /* - * If we find an active port with a different flow - * control mode than the first one, we return a value - * that indicates that the mode is indeterminated. - */ - if (*pBuf != pPrt->PLinkSpeed) { - - *pBuf = SK_LSPEED_INDETERMINATED; - } - break; - - case OID_SKGE_SPEED_STATUS: - /* Check if it is the first active port */ - if (*pBuf == 0) { - - *pBuf = pPrt->PLinkSpeedUsed; - continue; - } - - /* - * If we find an active port with a different flow - * control status than the first one, we return a - * value that indicates that the status is - * indeterminated. - */ - if (*pBuf != pPrt->PLinkSpeedUsed) { - - *pBuf = SK_LSPEED_STAT_INDETERMINATED; - } - break; - } - } - - /* - * If no port is active return an indeterminated answer - */ - if (!PortActiveFlag) { - - switch (Id) { - - case OID_SKGE_LINK_CAP: - *pBuf = SK_LMODE_CAP_INDETERMINATED; - break; - - case OID_SKGE_LINK_MODE: - *pBuf = SK_LMODE_INDETERMINATED; - break; - - case OID_SKGE_LINK_MODE_STATUS: - *pBuf = SK_LMODE_STAT_INDETERMINATED; - break; - - case OID_SKGE_LINK_STATUS: - *pBuf = SK_PNMI_RLMT_LSTAT_INDETERMINATED; - break; - - case OID_SKGE_FLOWCTRL_CAP: - case OID_SKGE_FLOWCTRL_MODE: - *pBuf = SK_FLOW_MODE_INDETERMINATED; - break; - - case OID_SKGE_FLOWCTRL_STATUS: - *pBuf = SK_FLOW_STAT_INDETERMINATED; - break; - - case OID_SKGE_PHY_OPERATION_CAP: - *pBuf = SK_MS_CAP_INDETERMINATED; - break; - - case OID_SKGE_PHY_OPERATION_MODE: - *pBuf = SK_MS_MODE_INDETERMINATED; - break; - - case OID_SKGE_PHY_OPERATION_STATUS: - *pBuf = SK_MS_STAT_INDETERMINATED; - break; - case OID_SKGE_SPEED_CAP: - *pBuf = SK_LSPEED_CAP_INDETERMINATED; - break; - - case OID_SKGE_SPEED_MODE: - *pBuf = SK_LSPEED_INDETERMINATED; - break; - - case OID_SKGE_SPEED_STATUS: - *pBuf = SK_LSPEED_STAT_INDETERMINATED; - break; - } - } -} - -/***************************************************************************** - * - * CalculateLinkStatus - Determins the link status of a physical port - * - * Description: - * Determins the link status the following way: - * LSTAT_PHY_DOWN: Link is down - * LSTAT_AUTONEG: Auto-negotiation failed - * LSTAT_LOG_DOWN: Link is up but RLMT did not yet put the port - * logically up. - * LSTAT_LOG_UP: RLMT marked the port as up - * - * Returns: - * Link status of physical port - */ -PNMI_STATIC SK_U8 CalculateLinkStatus( -SK_AC *pAC, /* Pointer to adapter context */ -SK_IOC IoC, /* IO context handle */ -unsigned int PhysPortIndex) /* Physical port index */ -{ - SK_U8 Result; - - if (!pAC->GIni.GP[PhysPortIndex].PHWLinkUp) { - - Result = SK_PNMI_RLMT_LSTAT_PHY_DOWN; - } - else if (pAC->GIni.GP[PhysPortIndex].PAutoNegFail > 0) { - - Result = SK_PNMI_RLMT_LSTAT_AUTONEG; - } - else if (!pAC->Rlmt.Port[PhysPortIndex].PortDown) { - - Result = SK_PNMI_RLMT_LSTAT_LOG_UP; - } - else { - Result = SK_PNMI_RLMT_LSTAT_LOG_DOWN; - } - - return (Result); -} - -/***************************************************************************** - * - * CalculateLinkModeStatus - Determins the link mode status of a phys. port - * - * Description: - * The COMMON module only tells us if the mode is half or full duplex. - * But in the decade of auto sensing it is usefull for the user to - * know if the mode was negotiated or forced. Therefore we have a - * look to the mode, which was last used by the negotiation process. - * - * Returns: - * The link mode status - */ -PNMI_STATIC SK_U8 CalculateLinkModeStatus( -SK_AC *pAC, /* Pointer to adapter context */ -SK_IOC IoC, /* IO context handle */ -unsigned int PhysPortIndex) /* Physical port index */ -{ - SK_U8 Result; - - /* Get the current mode, which can be full or half duplex */ - Result = pAC->GIni.GP[PhysPortIndex].PLinkModeStatus; - - /* Check if no valid mode could be found (link is down) */ - if (Result < SK_LMODE_STAT_HALF) { - - Result = SK_LMODE_STAT_UNKNOWN; - } - else if (pAC->GIni.GP[PhysPortIndex].PLinkMode >= SK_LMODE_AUTOHALF) { - - /* - * Auto-negotiation was used to bring up the link. Change - * the already found duplex status that it indicates - * auto-negotiation was involved. - */ - if (Result == SK_LMODE_STAT_HALF) { - - Result = SK_LMODE_STAT_AUTOHALF; - } - else if (Result == SK_LMODE_STAT_FULL) { - - Result = SK_LMODE_STAT_AUTOFULL; - } - } - - return (Result); -} - -/***************************************************************************** - * - * GetVpdKeyArr - Obtain an array of VPD keys - * - * Description: - * Read the VPD keys and build an array of VPD keys, which are - * easy to access. - * - * Returns: - * SK_PNMI_ERR_OK Task successfully performed. - * SK_PNMI_ERR_GENERAL Something went wrong. - */ -PNMI_STATIC int GetVpdKeyArr( -SK_AC *pAC, /* Pointer to adapter context */ -SK_IOC IoC, /* IO context handle */ -char *pKeyArr, /* Ptr KeyArray */ -unsigned int KeyArrLen, /* Length of array in bytes */ -unsigned int *pKeyNo) /* Number of keys */ -{ - unsigned int BufKeysLen = SK_PNMI_VPD_BUFSIZE; - char BufKeys[SK_PNMI_VPD_BUFSIZE]; - unsigned int StartOffset; - unsigned int Offset; - int Index; - int Ret; - - - SK_MEMSET(pKeyArr, 0, KeyArrLen); - - /* - * Get VPD key list - */ - Ret = VpdKeys(pAC, IoC, (char *)&BufKeys, (int *)&BufKeysLen, - (int *)pKeyNo); - if (Ret > 0) { - - SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR014, - SK_PNMI_ERR014MSG); - - return (SK_PNMI_ERR_GENERAL); - } - /* If no keys are available return now */ - if (*pKeyNo == 0 || BufKeysLen == 0) { - - return (SK_PNMI_ERR_OK); - } - /* - * If the key list is too long for us trunc it and give a - * errorlog notification. This case should not happen because - * the maximum number of keys is limited due to RAM limitations - */ - if (*pKeyNo > SK_PNMI_VPD_ENTRIES) { - - SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR015, - SK_PNMI_ERR015MSG); - - *pKeyNo = SK_PNMI_VPD_ENTRIES; - } - - /* - * Now build an array of fixed string length size and copy - * the keys together. - */ - for (Index = 0, StartOffset = 0, Offset = 0; Offset < BufKeysLen; - Offset ++) { - - if (BufKeys[Offset] != 0) { - - continue; - } - - if (Offset - StartOffset > SK_PNMI_VPD_KEY_SIZE) { - - SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR016, - SK_PNMI_ERR016MSG); - return (SK_PNMI_ERR_GENERAL); - } - - SK_STRNCPY(pKeyArr + Index * SK_PNMI_VPD_KEY_SIZE, - &BufKeys[StartOffset], SK_PNMI_VPD_KEY_SIZE); - - Index ++; - StartOffset = Offset + 1; - } - - /* Last key not zero terminated? Get it anyway */ - if (StartOffset < Offset) { - - SK_STRNCPY(pKeyArr + Index * SK_PNMI_VPD_KEY_SIZE, - &BufKeys[StartOffset], SK_PNMI_VPD_KEY_SIZE); - } - - return (SK_PNMI_ERR_OK); -} - -/***************************************************************************** - * - * SirqUpdate - Let the SIRQ update its internal values - * - * Description: - * Just to be sure that the SIRQ module holds its internal data - * structures up to date, we send an update event before we make - * any access. - * - * Returns: - * SK_PNMI_ERR_OK Task successfully performed. - * SK_PNMI_ERR_GENERAL Something went wrong. - */ -PNMI_STATIC int SirqUpdate( -SK_AC *pAC, /* Pointer to adapter context */ -SK_IOC IoC) /* IO context handle */ -{ - SK_EVPARA EventParam; - - - /* Was the module already updated during the current PNMI call? */ - if (pAC->Pnmi.SirqUpdatedFlag > 0) { - - return (SK_PNMI_ERR_OK); - } - - /* Send an synchronuous update event to the module */ - SK_MEMSET((char *)&EventParam, 0, sizeof(EventParam)); - if (SkGeSirqEvent(pAC, IoC, SK_HWEV_UPDATE_STAT, EventParam) > 0) { - - SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR047, - SK_PNMI_ERR047MSG); - - return (SK_PNMI_ERR_GENERAL); - } - - return (SK_PNMI_ERR_OK); -} - -/***************************************************************************** - * - * RlmtUpdate - Let the RLMT update its internal values - * - * Description: - * Just to be sure that the RLMT module holds its internal data - * structures up to date, we send an update event before we make - * any access. - * - * Returns: - * SK_PNMI_ERR_OK Task successfully performed. - * SK_PNMI_ERR_GENERAL Something went wrong. - */ -PNMI_STATIC int RlmtUpdate( -SK_AC *pAC, /* Pointer to adapter context */ -SK_IOC IoC, /* IO context handle */ -SK_U32 NetIndex) /* NetIndex (0..n), in single net mode allways zero */ -{ - SK_EVPARA EventParam; - - - /* Was the module already updated during the current PNMI call? */ - if (pAC->Pnmi.RlmtUpdatedFlag > 0) { - - return (SK_PNMI_ERR_OK); - } - - /* Send an synchronuous update event to the module */ - SK_MEMSET((char *)&EventParam, 0, sizeof(EventParam)); - EventParam.Para32[0] = NetIndex; - EventParam.Para32[1] = (SK_U32)-1; - if (SkRlmtEvent(pAC, IoC, SK_RLMT_STATS_UPDATE, EventParam) > 0) { - - SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR048, - SK_PNMI_ERR048MSG); - - return (SK_PNMI_ERR_GENERAL); - } - - return (SK_PNMI_ERR_OK); -} - -/***************************************************************************** - * - * MacUpdate - Force the XMAC to output the current statistic - * - * Description: - * The XMAC holds its statistic internally. To obtain the current - * values we must send a command so that the statistic data will - * be written to a predefined memory area on the adapter. - * - * Returns: - * SK_PNMI_ERR_OK Task successfully performed. - * SK_PNMI_ERR_GENERAL Something went wrong. - */ -PNMI_STATIC int MacUpdate( -SK_AC *pAC, /* Pointer to adapter context */ -SK_IOC IoC, /* IO context handle */ -unsigned int FirstMac, /* Index of the first Mac to be updated */ -unsigned int LastMac) /* Index of the last Mac to be updated */ -{ - unsigned int MacIndex; - - /* - * Were the statistics already updated during the - * current PNMI call? - */ - if (pAC->Pnmi.MacUpdatedFlag > 0) { - - return (SK_PNMI_ERR_OK); - } - - /* Send an update command to all MACs specified */ - for (MacIndex = FirstMac; MacIndex <= LastMac; MacIndex ++) { - - /* - * 2002-09-13 pweber: Freeze the current SW counters. - * (That should be done as close as - * possible to the update of the - * HW counters) - */ - if (pAC->GIni.GIMacType == SK_MAC_XMAC) { - pAC->Pnmi.BufPort[MacIndex] = pAC->Pnmi.Port[MacIndex]; - } - - /* 2002-09-13 pweber: Update the HW counter */ - if (pAC->GIni.GIFunc.pFnMacUpdateStats(pAC, IoC, MacIndex) != 0) { - - return (SK_PNMI_ERR_GENERAL); - } - } - - return (SK_PNMI_ERR_OK); -} - -/***************************************************************************** - * - * GetStatVal - Retrieve an XMAC statistic counter - * - * Description: - * Retrieves the statistic counter of a virtual or physical port. The - * virtual port is identified by the index 0. It consists of all - * currently active ports. To obtain the counter value for this port - * we must add the statistic counter of all active ports. To grant - * continuous counter values for the virtual port even when port - * switches occur we must additionally add a delta value, which was - * calculated during a SK_PNMI_EVT_RLMT_ACTIVE_UP event. - * - * Returns: - * Requested statistic value - */ -PNMI_STATIC SK_U64 GetStatVal( -SK_AC *pAC, /* Pointer to adapter context */ -SK_IOC IoC, /* IO context handle */ -unsigned int LogPortIndex, /* Index of the logical Port to be processed */ -unsigned int StatIndex, /* Index to statistic value */ -SK_U32 NetIndex) /* NetIndex (0..n), in single net mode allways zero */ -{ - unsigned int PhysPortIndex; - unsigned int PhysPortMax; - SK_U64 Val = 0; - - - if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { /* Dual net mode */ - - PhysPortIndex = NetIndex; - - Val = GetPhysStatVal(pAC, IoC, PhysPortIndex, StatIndex); - } - else { /* Single Net mode */ - - if (LogPortIndex == 0) { - - PhysPortMax = pAC->GIni.GIMacsFound; - - /* Add counter of all active ports */ - for (PhysPortIndex = 0; PhysPortIndex < PhysPortMax; - PhysPortIndex ++) { - - if (pAC->Pnmi.Port[PhysPortIndex].ActiveFlag) { - - Val += GetPhysStatVal(pAC, IoC, PhysPortIndex, StatIndex); - } - } - - /* Correct value because of port switches */ - Val += pAC->Pnmi.VirtualCounterOffset[StatIndex]; - } - else { - /* Get counter value of physical port */ - PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(pAC, LogPortIndex); - - Val = GetPhysStatVal(pAC, IoC, PhysPortIndex, StatIndex); - } - } - return (Val); -} - -/***************************************************************************** - * - * GetPhysStatVal - Get counter value for physical port - * - * Description: - * Builds a 64bit counter value. Except for the octet counters - * the lower 32bit are counted in hardware and the upper 32bit - * in software by monitoring counter overflow interrupts in the - * event handler. To grant continous counter values during XMAC - * resets (caused by a workaround) we must add a delta value. - * The delta was calculated in the event handler when a - * SK_PNMI_EVT_XMAC_RESET was received. - * - * Returns: - * Counter value - */ -PNMI_STATIC SK_U64 GetPhysStatVal( -SK_AC *pAC, /* Pointer to adapter context */ -SK_IOC IoC, /* IO context handle */ -unsigned int PhysPortIndex, /* Index of the logical Port to be processed */ -unsigned int StatIndex) /* Index to statistic value */ -{ - SK_U64 Val = 0; - SK_U32 LowVal = 0; - SK_U32 HighVal = 0; - SK_U16 Word; - int MacType; - unsigned int HelpIndex; - SK_GEPORT *pPrt; - - SK_PNMI_PORT *pPnmiPrt; - SK_GEMACFUNC *pFnMac; - - pPrt = &pAC->GIni.GP[PhysPortIndex]; - - MacType = pAC->GIni.GIMacType; - - /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */ - if (MacType == SK_MAC_XMAC) { - pPnmiPrt = &pAC->Pnmi.BufPort[PhysPortIndex]; - } - else { - pPnmiPrt = &pAC->Pnmi.Port[PhysPortIndex]; - } - - pFnMac = &pAC->GIni.GIFunc; - - switch (StatIndex) { - case SK_PNMI_HTX: - if (MacType == SK_MAC_GMAC) { - (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex, - StatAddr[SK_PNMI_HTX_BROADCAST][MacType].Reg, - &LowVal); - (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex, - StatAddr[SK_PNMI_HTX_MULTICAST][MacType].Reg, - &HighVal); - LowVal += HighVal; - (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex, - StatAddr[SK_PNMI_HTX_UNICAST][MacType].Reg, - &HighVal); - LowVal += HighVal; - } - else { - (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex, - StatAddr[StatIndex][MacType].Reg, - &LowVal); - } - HighVal = pPnmiPrt->CounterHigh[StatIndex]; - break; - - case SK_PNMI_HRX: - if (MacType == SK_MAC_GMAC) { - (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex, - StatAddr[SK_PNMI_HRX_BROADCAST][MacType].Reg, - &LowVal); - (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex, - StatAddr[SK_PNMI_HRX_MULTICAST][MacType].Reg, - &HighVal); - LowVal += HighVal; - (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex, - StatAddr[SK_PNMI_HRX_UNICAST][MacType].Reg, - &HighVal); - LowVal += HighVal; - } - else { - (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex, - StatAddr[StatIndex][MacType].Reg, - &LowVal); - } - HighVal = pPnmiPrt->CounterHigh[StatIndex]; - break; - - case SK_PNMI_HTX_OCTET: - case SK_PNMI_HRX_OCTET: - (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex, - StatAddr[StatIndex][MacType].Reg, - &HighVal); - (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex, - StatAddr[StatIndex + 1][MacType].Reg, - &LowVal); - break; - - case SK_PNMI_HTX_BURST: - case SK_PNMI_HTX_EXCESS_DEF: - case SK_PNMI_HTX_CARRIER: - /* Not supported by GMAC */ - if (MacType == SK_MAC_GMAC) { - return (Val); - } - - (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex, - StatAddr[StatIndex][MacType].Reg, - &LowVal); - HighVal = pPnmiPrt->CounterHigh[StatIndex]; - break; - - case SK_PNMI_HTX_MACC: - /* GMAC only supports PAUSE MAC control frames */ - if (MacType == SK_MAC_GMAC) { - HelpIndex = SK_PNMI_HTX_PMACC; - } - else { - HelpIndex = StatIndex; - } - - (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex, - StatAddr[HelpIndex][MacType].Reg, - &LowVal); - - HighVal = pPnmiPrt->CounterHigh[StatIndex]; - break; - - case SK_PNMI_HTX_COL: - case SK_PNMI_HRX_UNDERSIZE: - /* Not supported by XMAC */ - if (MacType == SK_MAC_XMAC) { - return (Val); - } - - (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex, - StatAddr[StatIndex][MacType].Reg, - &LowVal); - HighVal = pPnmiPrt->CounterHigh[StatIndex]; - break; - - case SK_PNMI_HTX_DEFFERAL: - /* Not supported by GMAC */ - if (MacType == SK_MAC_GMAC) { - return (Val); - } - - /* - * XMAC counts frames with deferred transmission - * even in full-duplex mode. - * - * In full-duplex mode the counter remains constant! - */ - if ((pPrt->PLinkModeStatus == SK_LMODE_STAT_AUTOFULL) || - (pPrt->PLinkModeStatus == SK_LMODE_STAT_FULL)) { - - LowVal = 0; - HighVal = 0; - } - else { - /* Otherwise get contents of hardware register */ - (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex, - StatAddr[StatIndex][MacType].Reg, - &LowVal); - HighVal = pPnmiPrt->CounterHigh[StatIndex]; - } - break; - - case SK_PNMI_HRX_BADOCTET: - /* Not supported by XMAC */ - if (MacType == SK_MAC_XMAC) { - return (Val); - } - - (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex, - StatAddr[StatIndex][MacType].Reg, - &HighVal); - (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex, - StatAddr[StatIndex + 1][MacType].Reg, - &LowVal); - break; - - case SK_PNMI_HTX_OCTETLOW: - case SK_PNMI_HRX_OCTETLOW: - case SK_PNMI_HRX_BADOCTETLOW: - return (Val); - - case SK_PNMI_HRX_LONGFRAMES: - /* For XMAC the SW counter is managed by PNMI */ - if (MacType == SK_MAC_XMAC) { - return (pPnmiPrt->StatRxLongFrameCts); - } - - (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex, - StatAddr[StatIndex][MacType].Reg, - &LowVal); - HighVal = pPnmiPrt->CounterHigh[StatIndex]; - break; - - case SK_PNMI_HRX_TOO_LONG: - (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex, - StatAddr[StatIndex][MacType].Reg, - &LowVal); - HighVal = pPnmiPrt->CounterHigh[StatIndex]; - - Val = (((SK_U64)HighVal << 32) | (SK_U64)LowVal); - - if (MacType == SK_MAC_GMAC) { - /* For GMAC the SW counter is additionally managed by PNMI */ - Val += pPnmiPrt->StatRxFrameTooLongCts; - } - else { - /* - * Frames longer than IEEE 802.3 frame max size are counted - * by XMAC in frame_too_long counter even reception of long - * frames was enabled and the frame was correct. - * So correct the value by subtracting RxLongFrame counter. - */ - Val -= pPnmiPrt->StatRxLongFrameCts; - } - - LowVal = (SK_U32)Val; - HighVal = (SK_U32)(Val >> 32); - break; - - case SK_PNMI_HRX_SHORTS: - /* Not supported by GMAC */ - if (MacType == SK_MAC_GMAC) { - /* GM_RXE_FRAG?? */ - return (Val); - } - - /* - * XMAC counts short frame errors even if link down (#10620) - * - * If link-down the counter remains constant - */ - if (pPrt->PLinkModeStatus != SK_LMODE_STAT_UNKNOWN) { - - /* Otherwise get incremental difference */ - (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex, - StatAddr[StatIndex][MacType].Reg, - &LowVal); - HighVal = pPnmiPrt->CounterHigh[StatIndex]; - - Val = (((SK_U64)HighVal << 32) | (SK_U64)LowVal); - Val -= pPnmiPrt->RxShortZeroMark; - - LowVal = (SK_U32)Val; - HighVal = (SK_U32)(Val >> 32); - } - break; - - case SK_PNMI_HRX_MACC: - case SK_PNMI_HRX_MACC_UNKWN: - case SK_PNMI_HRX_BURST: - case SK_PNMI_HRX_MISSED: - case SK_PNMI_HRX_FRAMING: - case SK_PNMI_HRX_CARRIER: - case SK_PNMI_HRX_IRLENGTH: - case SK_PNMI_HRX_SYMBOL: - case SK_PNMI_HRX_CEXT: - /* Not supported by GMAC */ - if (MacType == SK_MAC_GMAC) { - return (Val); - } - - (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex, - StatAddr[StatIndex][MacType].Reg, - &LowVal); - HighVal = pPnmiPrt->CounterHigh[StatIndex]; - break; - - case SK_PNMI_HRX_PMACC_ERR: - /* For GMAC the SW counter is managed by PNMI */ - if (MacType == SK_MAC_GMAC) { - return (pPnmiPrt->StatRxPMaccErr); - } - - (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex, - StatAddr[StatIndex][MacType].Reg, - &LowVal); - HighVal = pPnmiPrt->CounterHigh[StatIndex]; - break; - - /* SW counter managed by PNMI */ - case SK_PNMI_HTX_SYNC: - LowVal = (SK_U32)pPnmiPrt->StatSyncCts; - HighVal = (SK_U32)(pPnmiPrt->StatSyncCts >> 32); - break; - - /* SW counter managed by PNMI */ - case SK_PNMI_HTX_SYNC_OCTET: - LowVal = (SK_U32)pPnmiPrt->StatSyncOctetsCts; - HighVal = (SK_U32)(pPnmiPrt->StatSyncOctetsCts >> 32); - break; - - case SK_PNMI_HRX_FCS: - /* - * Broadcom filters FCS errors and counts it in - * Receive Error Counter register - */ - if (pPrt->PhyType == SK_PHY_BCOM) { - /* do not read while not initialized (PHY_READ hangs!)*/ - if (pPrt->PState != SK_PRT_RESET) { - SkXmPhyRead(pAC, IoC, PhysPortIndex, PHY_BCOM_RE_CTR, &Word); - - LowVal = Word; - } - HighVal = pPnmiPrt->CounterHigh[StatIndex]; - } - else { - (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex, - StatAddr[StatIndex][MacType].Reg, - &LowVal); - HighVal = pPnmiPrt->CounterHigh[StatIndex]; - } - break; - - default: - (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex, - StatAddr[StatIndex][MacType].Reg, - &LowVal); - HighVal = pPnmiPrt->CounterHigh[StatIndex]; - break; - } - - Val = (((SK_U64)HighVal << 32) | (SK_U64)LowVal); - - /* Correct value because of possible XMAC reset. XMAC Errata #2 */ - Val += pPnmiPrt->CounterOffset[StatIndex]; - - return (Val); -} - -/***************************************************************************** - * - * ResetCounter - Set all counters and timestamps to zero - * - * Description: - * Notifies other common modules which store statistic data to - * reset their counters and finally reset our own counters. - * - * Returns: - * Nothing - */ -PNMI_STATIC void ResetCounter( -SK_AC *pAC, /* Pointer to adapter context */ -SK_IOC IoC, /* IO context handle */ -SK_U32 NetIndex) -{ - unsigned int PhysPortIndex; - SK_EVPARA EventParam; - - - SK_MEMSET((char *)&EventParam, 0, sizeof(EventParam)); - - /* Notify sensor module */ - SkEventQueue(pAC, SKGE_I2C, SK_I2CEV_CLEAR, EventParam); - - /* Notify RLMT module */ - EventParam.Para32[0] = NetIndex; - EventParam.Para32[1] = (SK_U32)-1; - SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_STATS_CLEAR, EventParam); - EventParam.Para32[1] = 0; - - /* Notify SIRQ module */ - SkEventQueue(pAC, SKGE_HWAC, SK_HWEV_CLEAR_STAT, EventParam); - - /* Notify CSUM module */ -#ifdef SK_USE_CSUM - EventParam.Para32[0] = NetIndex; - EventParam.Para32[1] = (SK_U32)-1; - SkEventQueue(pAC, SKGE_CSUM, SK_CSUM_EVENT_CLEAR_PROTO_STATS, - EventParam); -#endif /* SK_USE_CSUM */ - - /* Clear XMAC statistic */ - for (PhysPortIndex = 0; PhysPortIndex < - (unsigned int)pAC->GIni.GIMacsFound; PhysPortIndex ++) { - - (void)pAC->GIni.GIFunc.pFnMacResetCounter(pAC, IoC, PhysPortIndex); - - SK_MEMSET((char *)&pAC->Pnmi.Port[PhysPortIndex].CounterHigh, - 0, sizeof(pAC->Pnmi.Port[PhysPortIndex].CounterHigh)); - SK_MEMSET((char *)&pAC->Pnmi.Port[PhysPortIndex]. - CounterOffset, 0, sizeof(pAC->Pnmi.Port[ - PhysPortIndex].CounterOffset)); - SK_MEMSET((char *)&pAC->Pnmi.Port[PhysPortIndex].StatSyncCts, - 0, sizeof(pAC->Pnmi.Port[PhysPortIndex].StatSyncCts)); - SK_MEMSET((char *)&pAC->Pnmi.Port[PhysPortIndex]. - StatSyncOctetsCts, 0, sizeof(pAC->Pnmi.Port[ - PhysPortIndex].StatSyncOctetsCts)); - SK_MEMSET((char *)&pAC->Pnmi.Port[PhysPortIndex]. - StatRxLongFrameCts, 0, sizeof(pAC->Pnmi.Port[ - PhysPortIndex].StatRxLongFrameCts)); - SK_MEMSET((char *)&pAC->Pnmi.Port[PhysPortIndex]. - StatRxFrameTooLongCts, 0, sizeof(pAC->Pnmi.Port[ - PhysPortIndex].StatRxFrameTooLongCts)); - SK_MEMSET((char *)&pAC->Pnmi.Port[PhysPortIndex]. - StatRxPMaccErr, 0, sizeof(pAC->Pnmi.Port[ - PhysPortIndex].StatRxPMaccErr)); - } - - /* - * Clear local statistics - */ - SK_MEMSET((char *)&pAC->Pnmi.VirtualCounterOffset, 0, - sizeof(pAC->Pnmi.VirtualCounterOffset)); - pAC->Pnmi.RlmtChangeCts = 0; - pAC->Pnmi.RlmtChangeTime = 0; - SK_MEMSET((char *)&pAC->Pnmi.RlmtChangeEstimate.EstValue[0], 0, - sizeof(pAC->Pnmi.RlmtChangeEstimate.EstValue)); - pAC->Pnmi.RlmtChangeEstimate.EstValueIndex = 0; - pAC->Pnmi.RlmtChangeEstimate.Estimate = 0; - pAC->Pnmi.Port[NetIndex].TxSwQueueMax = 0; - pAC->Pnmi.Port[NetIndex].TxRetryCts = 0; - pAC->Pnmi.Port[NetIndex].RxIntrCts = 0; - pAC->Pnmi.Port[NetIndex].TxIntrCts = 0; - pAC->Pnmi.Port[NetIndex].RxNoBufCts = 0; - pAC->Pnmi.Port[NetIndex].TxNoBufCts = 0; - pAC->Pnmi.Port[NetIndex].TxUsedDescrNo = 0; - pAC->Pnmi.Port[NetIndex].RxDeliveredCts = 0; - pAC->Pnmi.Port[NetIndex].RxOctetsDeliveredCts = 0; - pAC->Pnmi.Port[NetIndex].ErrRecoveryCts = 0; -} - -/***************************************************************************** - * - * GetTrapEntry - Get an entry in the trap buffer - * - * Description: - * The trap buffer stores various events. A user application somehow - * gets notified that an event occured and retrieves the trap buffer - * contens (or simply polls the buffer). The buffer is organized as - * a ring which stores the newest traps at the beginning. The oldest - * traps are overwritten by the newest ones. Each trap entry has a - * unique number, so that applications may detect new trap entries. - * - * Returns: - * A pointer to the trap entry - */ -PNMI_STATIC char* GetTrapEntry( -SK_AC *pAC, /* Pointer to adapter context */ -SK_U32 TrapId, /* SNMP ID of the trap */ -unsigned int Size) /* Space needed for trap entry */ -{ - unsigned int BufPad = pAC->Pnmi.TrapBufPad; - unsigned int BufFree = pAC->Pnmi.TrapBufFree; - unsigned int Beg = pAC->Pnmi.TrapQueueBeg; - unsigned int End = pAC->Pnmi.TrapQueueEnd; - char *pBuf = &pAC->Pnmi.TrapBuf[0]; - int Wrap; - unsigned int NeededSpace; - unsigned int EntrySize; - SK_U32 Val32; - SK_U64 Val64; - - - /* Last byte of entry will get a copy of the entry length */ - Size ++; - - /* - * Calculate needed buffer space */ - if (Beg >= Size) { - - NeededSpace = Size; - Wrap = SK_FALSE; - } - else { - NeededSpace = Beg + Size; - Wrap = SK_TRUE; - } - - /* - * Check if enough buffer space is provided. Otherwise - * free some entries. Leave one byte space between begin - * and end of buffer to make it possible to detect whether - * the buffer is full or empty - */ - while (BufFree < NeededSpace + 1) { - - if (End == 0) { - - End = SK_PNMI_TRAP_QUEUE_LEN; - } - - EntrySize = (unsigned int)*((unsigned char *)pBuf + End - 1); - BufFree += EntrySize; - End -= EntrySize; -#ifdef DEBUG - SK_MEMSET(pBuf + End, (char)(-1), EntrySize); -#endif /* DEBUG */ - if (End == BufPad) { -#ifdef DEBUG - SK_MEMSET(pBuf, (char)(-1), End); -#endif /* DEBUG */ - BufFree += End; - End = 0; - BufPad = 0; - } - } - - /* - * Insert new entry as first entry. Newest entries are - * stored at the beginning of the queue. - */ - if (Wrap) { - - BufPad = Beg; - Beg = SK_PNMI_TRAP_QUEUE_LEN - Size; - } - else { - Beg = Beg - Size; - } - BufFree -= NeededSpace; - - /* Save the current offsets */ - pAC->Pnmi.TrapQueueBeg = Beg; - pAC->Pnmi.TrapQueueEnd = End; - pAC->Pnmi.TrapBufPad = BufPad; - pAC->Pnmi.TrapBufFree = BufFree; - - /* Initialize the trap entry */ - *(pBuf + Beg + Size - 1) = (char)Size; - *(pBuf + Beg) = (char)Size; - Val32 = (pAC->Pnmi.TrapUnique) ++; - SK_PNMI_STORE_U32(pBuf + Beg + 1, Val32); - SK_PNMI_STORE_U32(pBuf + Beg + 1 + sizeof(SK_U32), TrapId); - Val64 = SK_PNMI_HUNDREDS_SEC(SkOsGetTime(pAC)); - SK_PNMI_STORE_U64(pBuf + Beg + 1 + 2 * sizeof(SK_U32), Val64); - - return (pBuf + Beg); -} - -/***************************************************************************** - * - * CopyTrapQueue - Copies the trap buffer for the TRAP OID - * - * Description: - * On a query of the TRAP OID the trap buffer contents will be - * copied continuously to the request buffer, which must be large - * enough. No length check is performed. - * - * Returns: - * Nothing - */ -PNMI_STATIC void CopyTrapQueue( -SK_AC *pAC, /* Pointer to adapter context */ -char *pDstBuf) /* Buffer to which the queued traps will be copied */ -{ - unsigned int BufPad = pAC->Pnmi.TrapBufPad; - unsigned int Trap = pAC->Pnmi.TrapQueueBeg; - unsigned int End = pAC->Pnmi.TrapQueueEnd; - char *pBuf = &pAC->Pnmi.TrapBuf[0]; - unsigned int Len; - unsigned int DstOff = 0; - - - while (Trap != End) { - - Len = (unsigned int)*(pBuf + Trap); - - /* - * Last byte containing a copy of the length will - * not be copied. - */ - *(pDstBuf + DstOff) = (char)(Len - 1); - SK_MEMCPY(pDstBuf + DstOff + 1, pBuf + Trap + 1, Len - 2); - DstOff += Len - 1; - - Trap += Len; - if (Trap == SK_PNMI_TRAP_QUEUE_LEN) { - - Trap = BufPad; - } - } -} - -/***************************************************************************** - * - * GetTrapQueueLen - Get the length of the trap buffer - * - * Description: - * Evaluates the number of currently stored traps and the needed - * buffer size to retrieve them. - * - * Returns: - * Nothing - */ -PNMI_STATIC void GetTrapQueueLen( -SK_AC *pAC, /* Pointer to adapter context */ -unsigned int *pLen, /* Length in Bytes of all queued traps */ -unsigned int *pEntries) /* Returns number of trapes stored in queue */ -{ - unsigned int BufPad = pAC->Pnmi.TrapBufPad; - unsigned int Trap = pAC->Pnmi.TrapQueueBeg; - unsigned int End = pAC->Pnmi.TrapQueueEnd; - char *pBuf = &pAC->Pnmi.TrapBuf[0]; - unsigned int Len; - unsigned int Entries = 0; - unsigned int TotalLen = 0; - - - while (Trap != End) { - - Len = (unsigned int)*(pBuf + Trap); - TotalLen += Len - 1; - Entries ++; - - Trap += Len; - if (Trap == SK_PNMI_TRAP_QUEUE_LEN) { - - Trap = BufPad; - } - } - - *pEntries = Entries; - *pLen = TotalLen; -} - -/***************************************************************************** - * - * QueueSimpleTrap - Store a simple trap to the trap buffer - * - * Description: - * A simple trap is a trap with now additional data. It consists - * simply of a trap code. - * - * Returns: - * Nothing - */ -PNMI_STATIC void QueueSimpleTrap( -SK_AC *pAC, /* Pointer to adapter context */ -SK_U32 TrapId) /* Type of sensor trap */ -{ - GetTrapEntry(pAC, TrapId, SK_PNMI_TRAP_SIMPLE_LEN); -} - -/***************************************************************************** - * - * QueueSensorTrap - Stores a sensor trap in the trap buffer - * - * Description: - * Gets an entry in the trap buffer and fills it with sensor related - * data. - * - * Returns: - * Nothing - */ -PNMI_STATIC void QueueSensorTrap( -SK_AC *pAC, /* Pointer to adapter context */ -SK_U32 TrapId, /* Type of sensor trap */ -unsigned int SensorIndex) /* Index of sensor which caused the trap */ -{ - char *pBuf; - unsigned int Offset; - unsigned int DescrLen; - SK_U32 Val32; - - - /* Get trap buffer entry */ - DescrLen = SK_STRLEN(pAC->I2c.SenTable[SensorIndex].SenDesc); - pBuf = GetTrapEntry(pAC, TrapId, - SK_PNMI_TRAP_SENSOR_LEN_BASE + DescrLen); - Offset = SK_PNMI_TRAP_SIMPLE_LEN; - - /* Store additionally sensor trap related data */ - Val32 = OID_SKGE_SENSOR_INDEX; - SK_PNMI_STORE_U32(pBuf + Offset, Val32); - *(pBuf + Offset + 4) = 4; - Val32 = (SK_U32)SensorIndex; - SK_PNMI_STORE_U32(pBuf + Offset + 5, Val32); - Offset += 9; - - Val32 = (SK_U32)OID_SKGE_SENSOR_DESCR; - SK_PNMI_STORE_U32(pBuf + Offset, Val32); - *(pBuf + Offset + 4) = (char)DescrLen; - SK_MEMCPY(pBuf + Offset + 5, pAC->I2c.SenTable[SensorIndex].SenDesc, - DescrLen); - Offset += DescrLen + 5; - - Val32 = OID_SKGE_SENSOR_TYPE; - SK_PNMI_STORE_U32(pBuf + Offset, Val32); - *(pBuf + Offset + 4) = 1; - *(pBuf + Offset + 5) = (char)pAC->I2c.SenTable[SensorIndex].SenType; - Offset += 6; - - Val32 = OID_SKGE_SENSOR_VALUE; - SK_PNMI_STORE_U32(pBuf + Offset, Val32); - *(pBuf + Offset + 4) = 4; - Val32 = (SK_U32)pAC->I2c.SenTable[SensorIndex].SenValue; - SK_PNMI_STORE_U32(pBuf + Offset + 5, Val32); -} - -/***************************************************************************** - * - * QueueRlmtNewMacTrap - Store a port switch trap in the trap buffer - * - * Description: - * Nothing further to explain. - * - * Returns: - * Nothing - */ -PNMI_STATIC void QueueRlmtNewMacTrap( -SK_AC *pAC, /* Pointer to adapter context */ -unsigned int ActiveMac) /* Index (0..n) of the currently active port */ -{ - char *pBuf; - SK_U32 Val32; - - - pBuf = GetTrapEntry(pAC, OID_SKGE_TRAP_RLMT_CHANGE_PORT, - SK_PNMI_TRAP_RLMT_CHANGE_LEN); - - Val32 = OID_SKGE_RLMT_PORT_ACTIVE; - SK_PNMI_STORE_U32(pBuf + SK_PNMI_TRAP_SIMPLE_LEN, Val32); - *(pBuf + SK_PNMI_TRAP_SIMPLE_LEN + 4) = 1; - *(pBuf + SK_PNMI_TRAP_SIMPLE_LEN + 5) = (char)ActiveMac; -} - -/***************************************************************************** - * - * QueueRlmtPortTrap - Store port related RLMT trap to trap buffer - * - * Description: - * Nothing further to explain. - * - * Returns: - * Nothing - */ -PNMI_STATIC void QueueRlmtPortTrap( -SK_AC *pAC, /* Pointer to adapter context */ -SK_U32 TrapId, /* Type of RLMT port trap */ -unsigned int PortIndex) /* Index of the port, which changed its state */ -{ - char *pBuf; - SK_U32 Val32; - - - pBuf = GetTrapEntry(pAC, TrapId, SK_PNMI_TRAP_RLMT_PORT_LEN); - - Val32 = OID_SKGE_RLMT_PORT_INDEX; - SK_PNMI_STORE_U32(pBuf + SK_PNMI_TRAP_SIMPLE_LEN, Val32); - *(pBuf + SK_PNMI_TRAP_SIMPLE_LEN + 4) = 1; - *(pBuf + SK_PNMI_TRAP_SIMPLE_LEN + 5) = (char)PortIndex; -} - -/***************************************************************************** - * - * CopyMac - Copies a MAC address - * - * Description: - * Nothing further to explain. - * - * Returns: - * Nothing - */ -PNMI_STATIC void CopyMac( -char *pDst, /* Pointer to destination buffer */ -SK_MAC_ADDR *pMac) /* Pointer of Source */ -{ - int i; - - - for (i = 0; i < sizeof(SK_MAC_ADDR); i ++) { - - *(pDst + i) = pMac->a[i]; - } -} - -#ifdef SK_POWER_MGMT -/***************************************************************************** - * - * PowerManagement - OID handler function of PowerManagement OIDs - * - * Description: - * The code is simple. No description necessary. - * - * Returns: - * SK_PNMI_ERR_OK The request was successfully performed. - * SK_PNMI_ERR_GENERAL A general severe internal error occured. - * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain - * the correct data (e.g. a 32bit value is - * needed, but a 16 bit value was passed). - * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't - * exist (e.g. port instance 3 on a two port - * adapter. - */ - -PNMI_STATIC int PowerManagement( -SK_AC *pAC, /* Pointer to adapter context */ -SK_IOC IoC, /* IO context handle */ -int Action, /* Get/PreSet/Set action */ -SK_U32 Id, /* Object ID that is to be processed */ -char *pBuf, /* Buffer to which to mgmt data will be retrieved */ -unsigned int *pLen, /* On call: buffer length. On return: used buffer */ -SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */ -unsigned int TableIndex, /* Index to the Id table */ -SK_U32 NetIndex) /* NetIndex (0..n), in single net mode allways zero */ -{ - - SK_U32 RetCode = SK_PNMI_ERR_GENERAL; - - /* - * Check instance. We only handle single instance variables - */ - if (Instance != (SK_U32)(-1) && Instance != 1) { - - *pLen = 0; - return (SK_PNMI_ERR_UNKNOWN_INST); - } - - - /* Check length */ - switch (Id) { - - case OID_PNP_CAPABILITIES: - if (*pLen < sizeof(SK_PNP_CAPABILITIES)) { - - *pLen = sizeof(SK_PNP_CAPABILITIES); - return (SK_PNMI_ERR_TOO_SHORT); - } - break; - - case OID_PNP_SET_POWER: - case OID_PNP_QUERY_POWER: - if (*pLen < sizeof(SK_DEVICE_POWER_STATE)) - { - *pLen = sizeof(SK_DEVICE_POWER_STATE); - return (SK_PNMI_ERR_TOO_SHORT); - } - break; - - case OID_PNP_ADD_WAKE_UP_PATTERN: - case OID_PNP_REMOVE_WAKE_UP_PATTERN: - if (*pLen < sizeof(SK_PM_PACKET_PATTERN)) { - - *pLen = sizeof(SK_PM_PACKET_PATTERN); - return (SK_PNMI_ERR_TOO_SHORT); - } - break; - - case OID_PNP_ENABLE_WAKE_UP: - if (*pLen < sizeof(SK_U32)) { - - *pLen = sizeof(SK_U32); - return (SK_PNMI_ERR_TOO_SHORT); - } - break; - } - - /* - * Perform action - */ - if (Action == SK_PNMI_GET) { - - /* - * Get value - */ - switch (Id) { - - case OID_PNP_CAPABILITIES: - RetCode = SkPowerQueryPnPCapabilities(pAC, IoC, pBuf, pLen); - break; - - case OID_PNP_QUERY_POWER: - /* The Windows DDK describes: An OID_PNP_QUERY_POWER requests - the miniport to indicate whether it can transition its NIC - to the low-power state. - A miniport driver must always return NDIS_STATUS_SUCCESS - to a query of OID_PNP_QUERY_POWER. */ - *pLen = sizeof(SK_DEVICE_POWER_STATE);; - RetCode = SK_PNMI_ERR_OK; - break; - - /* NDIS handles these OIDs as write-only. - * So in case of get action the buffer with written length = 0 - * is returned - */ - case OID_PNP_SET_POWER: - case OID_PNP_ADD_WAKE_UP_PATTERN: - case OID_PNP_REMOVE_WAKE_UP_PATTERN: - *pLen = 0; - RetCode = SK_PNMI_ERR_NOT_SUPPORTED; - break; - - case OID_PNP_ENABLE_WAKE_UP: - RetCode = SkPowerGetEnableWakeUp(pAC, IoC, pBuf, pLen); - break; - - default: - RetCode = SK_PNMI_ERR_GENERAL; - break; - } - - return (RetCode); - } - - - /* - * Perform preset or set - */ - - /* POWER module does not support PRESET action */ - if (Action == SK_PNMI_PRESET) { - return (SK_PNMI_ERR_OK); - } - - switch (Id) { - case OID_PNP_SET_POWER: - RetCode = SkPowerSetPower(pAC, IoC, pBuf, pLen); - break; - - case OID_PNP_ADD_WAKE_UP_PATTERN: - RetCode = SkPowerAddWakeUpPattern(pAC, IoC, pBuf, pLen); - break; - - case OID_PNP_REMOVE_WAKE_UP_PATTERN: - RetCode = SkPowerRemoveWakeUpPattern(pAC, IoC, pBuf, pLen); - break; - - case OID_PNP_ENABLE_WAKE_UP: - RetCode = SkPowerSetEnableWakeUp(pAC, IoC, pBuf, pLen); - break; - - default: - RetCode = SK_PNMI_ERR_READ_ONLY; - } - - return (RetCode); -} -#endif /* SK_POWER_MGMT */ - -#ifdef SK_DIAG_SUPPORT -/***************************************************************************** - * - * DiagActions - OID handler function of Diagnostic driver - * - * Description: - * The code is simple. No description necessary. - * - * Returns: - * SK_PNMI_ERR_OK The request was successfully performed. - * SK_PNMI_ERR_GENERAL A general severe internal error occured. - * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain - * the correct data (e.g. a 32bit value is - * needed, but a 16 bit value was passed). - * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't - * exist (e.g. port instance 3 on a two port - * adapter. - */ - -PNMI_STATIC int DiagActions( -SK_AC *pAC, /* Pointer to adapter context */ -SK_IOC IoC, /* IO context handle */ -int Action, /* GET/PRESET/SET action */ -SK_U32 Id, /* Object ID that is to be processed */ -char *pBuf, /* Buffer used for the management data transfer */ -unsigned int *pLen, /* On call: pBuf buffer length. On return: used buffer */ -SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */ -unsigned int TableIndex, /* Index to the Id table */ -SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */ -{ - - SK_U32 DiagStatus; - SK_U32 RetCode = SK_PNMI_ERR_GENERAL; - - /* - * Check instance. We only handle single instance variables. - */ - if (Instance != (SK_U32)(-1) && Instance != 1) { - - *pLen = 0; - return (SK_PNMI_ERR_UNKNOWN_INST); - } - - /* - * Check length. - */ - switch (Id) { - - case OID_SKGE_DIAG_MODE: - if (*pLen < sizeof(SK_U32)) { - - *pLen = sizeof(SK_U32); - return (SK_PNMI_ERR_TOO_SHORT); - } - break; - - default: - SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR040, SK_PNMI_ERR040MSG); - *pLen = 0; - return (SK_PNMI_ERR_GENERAL); - } - - /* Perform action. */ - - /* GET value. */ - if (Action == SK_PNMI_GET) { - - switch (Id) { - - case OID_SKGE_DIAG_MODE: - DiagStatus = pAC->Pnmi.DiagAttached; - SK_PNMI_STORE_U32(pBuf, DiagStatus); - *pLen = sizeof(SK_U32); - RetCode = SK_PNMI_ERR_OK; - break; - - default: - *pLen = 0; - RetCode = SK_PNMI_ERR_GENERAL; - break; - } - return (RetCode); - } - - /* From here SET or PRESET value. */ - - /* PRESET value is not supported. */ - if (Action == SK_PNMI_PRESET) { - return (SK_PNMI_ERR_OK); - } - - /* SET value. */ - switch (Id) { - case OID_SKGE_DIAG_MODE: - - /* Handle the SET. */ - switch (*pBuf) { - - /* Attach the DIAG to this adapter. */ - case SK_DIAG_ATTACHED: - /* Check if we come from running */ - if (pAC->Pnmi.DiagAttached == SK_DIAG_RUNNING) { - - RetCode = SkDrvLeaveDiagMode(pAC); - - } - else if (pAC->Pnmi.DiagAttached == SK_DIAG_IDLE) { - - RetCode = SK_PNMI_ERR_OK; - } - - else { - - RetCode = SK_PNMI_ERR_GENERAL; - - } - - if (RetCode == SK_PNMI_ERR_OK) { - - pAC->Pnmi.DiagAttached = SK_DIAG_ATTACHED; - } - break; - - /* Enter the DIAG mode in the driver. */ - case SK_DIAG_RUNNING: - RetCode = SK_PNMI_ERR_OK; - - /* - * If DiagAttached is set, we can tell the driver - * to enter the DIAG mode. - */ - if (pAC->Pnmi.DiagAttached == SK_DIAG_ATTACHED) { - /* If DiagMode is not active, we can enter it. */ - if (!pAC->DiagModeActive) { - - RetCode = SkDrvEnterDiagMode(pAC); - } - else { - - RetCode = SK_PNMI_ERR_GENERAL; - } - } - else { - - RetCode = SK_PNMI_ERR_GENERAL; - } - - if (RetCode == SK_PNMI_ERR_OK) { - - pAC->Pnmi.DiagAttached = SK_DIAG_RUNNING; - } - break; - - case SK_DIAG_IDLE: - /* Check if we come from running */ - if (pAC->Pnmi.DiagAttached == SK_DIAG_RUNNING) { - - RetCode = SkDrvLeaveDiagMode(pAC); - - } - else if (pAC->Pnmi.DiagAttached == SK_DIAG_ATTACHED) { - - RetCode = SK_PNMI_ERR_OK; - } - - else { - - RetCode = SK_PNMI_ERR_GENERAL; - - } - - if (RetCode == SK_PNMI_ERR_OK) { - - pAC->Pnmi.DiagAttached = SK_DIAG_IDLE; - } - break; - - default: - RetCode = SK_PNMI_ERR_BAD_VALUE; - break; - } - break; - - default: - RetCode = SK_PNMI_ERR_GENERAL; - } - - if (RetCode == SK_PNMI_ERR_OK) { - *pLen = sizeof(SK_U32); - } - else { - - *pLen = 0; - } - return (RetCode); -} -#endif /* SK_DIAG_SUPPORT */ - -/***************************************************************************** - * - * Vct - OID handler function of OIDs - * - * Description: - * The code is simple. No description necessary. - * - * Returns: - * SK_PNMI_ERR_OK The request was performed successfully. - * SK_PNMI_ERR_GENERAL A general severe internal error occured. - * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain - * the correct data (e.g. a 32bit value is - * needed, but a 16 bit value was passed). - * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't - * exist (e.g. port instance 3 on a two port - * adapter). - * SK_PNMI_ERR_READ_ONLY Only the Get action is allowed. - * - */ - -PNMI_STATIC int Vct( -SK_AC *pAC, /* Pointer to adapter context */ -SK_IOC IoC, /* IO context handle */ -int Action, /* GET/PRESET/SET action */ -SK_U32 Id, /* Object ID that is to be processed */ -char *pBuf, /* Buffer used for the management data transfer */ -unsigned int *pLen, /* On call: pBuf buffer length. On return: used buffer */ -SK_U32 Instance, /* Instance (-1,2..n) that is to be queried */ -unsigned int TableIndex, /* Index to the Id table */ -SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */ -{ - SK_GEPORT *pPrt; - SK_PNMI_VCT *pVctBackupData; - SK_U32 LogPortMax; - SK_U32 PhysPortMax; - SK_U32 PhysPortIndex; - SK_U32 Limit; - SK_U32 Offset; - SK_BOOL Link; - SK_U32 RetCode = SK_PNMI_ERR_GENERAL; - int i; - SK_EVPARA Para; - SK_U32 CableLength; - - /* - * Calculate the port indexes from the instance. - */ - PhysPortMax = pAC->GIni.GIMacsFound; - LogPortMax = SK_PNMI_PORT_PHYS2LOG(PhysPortMax); - - /* Dual net mode? */ - if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { - LogPortMax--; - } - - if ((Instance != (SK_U32) (-1))) { - /* Check instance range. */ - if ((Instance < 2) || (Instance > LogPortMax)) { - *pLen = 0; - return (SK_PNMI_ERR_UNKNOWN_INST); - } - - if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { - PhysPortIndex = NetIndex; - } - else { - PhysPortIndex = Instance - 2; - } - Limit = PhysPortIndex + 1; - } - else { - /* - * Instance == (SK_U32) (-1), get all Instances of that OID. - * - * Not implemented yet. May be used in future releases. - */ - PhysPortIndex = 0; - Limit = PhysPortMax; - } - - pPrt = &pAC->GIni.GP[PhysPortIndex]; - if (pPrt->PHWLinkUp) { - Link = SK_TRUE; - } - else { - Link = SK_FALSE; - } - - /* Check MAC type */ - if (pPrt->PhyType != SK_PHY_MARV_COPPER) { - *pLen = 0; - return (SK_PNMI_ERR_GENERAL); - } - - /* Initialize backup data pointer. */ - pVctBackupData = &pAC->Pnmi.VctBackup[PhysPortIndex]; - - /* Check action type */ - if (Action == SK_PNMI_GET) { - /* Check length */ - switch (Id) { - - case OID_SKGE_VCT_GET: - if (*pLen < (Limit - PhysPortIndex) * sizeof(SK_PNMI_VCT)) { - *pLen = (Limit - PhysPortIndex) * sizeof(SK_PNMI_VCT); - return (SK_PNMI_ERR_TOO_SHORT); - } - break; - - case OID_SKGE_VCT_STATUS: - if (*pLen < (Limit - PhysPortIndex) * sizeof(SK_U8)) { - *pLen = (Limit - PhysPortIndex) * sizeof(SK_U8); - return (SK_PNMI_ERR_TOO_SHORT); - } - break; - - default: - *pLen = 0; - return (SK_PNMI_ERR_GENERAL); - } - - /* Get value */ - Offset = 0; - for (; PhysPortIndex < Limit; PhysPortIndex++) { - switch (Id) { - - case OID_SKGE_VCT_GET: - if ((Link == SK_FALSE) && - (pAC->Pnmi.VctStatus[PhysPortIndex] & SK_PNMI_VCT_PENDING)) { - RetCode = SkGmCableDiagStatus(pAC, IoC, PhysPortIndex, SK_FALSE); - if (RetCode == 0) { - pAC->Pnmi.VctStatus[PhysPortIndex] &= ~SK_PNMI_VCT_PENDING; - pAC->Pnmi.VctStatus[PhysPortIndex] |= - (SK_PNMI_VCT_NEW_VCT_DATA | SK_PNMI_VCT_TEST_DONE); - - /* Copy results for later use to PNMI struct. */ - for (i = 0; i < 4; i++) { - if (pPrt->PMdiPairSts[i] == SK_PNMI_VCT_NORMAL_CABLE) { - if ((pPrt->PMdiPairLen[i] > 35) && (pPrt->PMdiPairLen[i] < 0xff)) { - pPrt->PMdiPairSts[i] = SK_PNMI_VCT_IMPEDANCE_MISMATCH; - } - } - if ((pPrt->PMdiPairLen[i] > 35) && (pPrt->PMdiPairLen[i] != 0xff)) { - CableLength = 1000 * (((175 * pPrt->PMdiPairLen[i]) / 210) - 28); - } - else { - CableLength = 0; - } - pVctBackupData->PMdiPairLen[i] = CableLength; - pVctBackupData->PMdiPairSts[i] = pPrt->PMdiPairSts[i]; - } - - Para.Para32[0] = PhysPortIndex; - Para.Para32[1] = -1; - SkEventQueue(pAC, SKGE_DRV, SK_DRV_PORT_RESET, Para); - SkEventDispatcher(pAC, IoC); - } - else { - ; /* VCT test is running. */ - } - } - - /* Get all results. */ - CheckVctStatus(pAC, IoC, pBuf, Offset, PhysPortIndex); - Offset += sizeof(SK_U8); - *(pBuf + Offset) = pPrt->PCableLen; - Offset += sizeof(SK_U8); - for (i = 0; i < 4; i++) { - SK_PNMI_STORE_U32((pBuf + Offset), pVctBackupData->PMdiPairLen[i]); - Offset += sizeof(SK_U32); - } - for (i = 0; i < 4; i++) { - *(pBuf + Offset) = pVctBackupData->PMdiPairSts[i]; - Offset += sizeof(SK_U8); - } - - RetCode = SK_PNMI_ERR_OK; - break; - - case OID_SKGE_VCT_STATUS: - CheckVctStatus(pAC, IoC, pBuf, Offset, PhysPortIndex); - Offset += sizeof(SK_U8); - RetCode = SK_PNMI_ERR_OK; - break; - - default: - *pLen = 0; - return (SK_PNMI_ERR_GENERAL); - } - } /* for */ - *pLen = Offset; - return (RetCode); - - } /* if SK_PNMI_GET */ - - /* - * From here SET or PRESET action. Check if the passed - * buffer length is plausible. - */ - - /* Check length */ - switch (Id) { - case OID_SKGE_VCT_SET: - if (*pLen < (Limit - PhysPortIndex) * sizeof(SK_U32)) { - *pLen = (Limit - PhysPortIndex) * sizeof(SK_U32); - return (SK_PNMI_ERR_TOO_SHORT); - } - break; - - default: - *pLen = 0; - return (SK_PNMI_ERR_GENERAL); - } - - /* - * Perform preset or set. - */ - - /* VCT does not support PRESET action. */ - if (Action == SK_PNMI_PRESET) { - return (SK_PNMI_ERR_OK); - } - - Offset = 0; - for (; PhysPortIndex < Limit; PhysPortIndex++) { - switch (Id) { - case OID_SKGE_VCT_SET: /* Start VCT test. */ - if (Link == SK_FALSE) { - SkGeStopPort(pAC, IoC, PhysPortIndex, SK_STOP_ALL, SK_SOFT_RST); - - RetCode = SkGmCableDiagStatus(pAC, IoC, PhysPortIndex, SK_TRUE); - if (RetCode == 0) { /* RetCode: 0 => Start! */ - pAC->Pnmi.VctStatus[PhysPortIndex] |= SK_PNMI_VCT_PENDING; - pAC->Pnmi.VctStatus[PhysPortIndex] &= ~SK_PNMI_VCT_NEW_VCT_DATA; - pAC->Pnmi.VctStatus[PhysPortIndex] &= ~SK_PNMI_VCT_LINK; - - /* - * Start VCT timer counter. - */ - SK_MEMSET((char *) &Para, 0, sizeof(Para)); - Para.Para32[0] = PhysPortIndex; - Para.Para32[1] = -1; - SkTimerStart(pAC, IoC, &pAC->Pnmi.VctTimeout[PhysPortIndex].VctTimer, - 4000000, SKGE_PNMI, SK_PNMI_EVT_VCT_RESET, Para); - SK_PNMI_STORE_U32((pBuf + Offset), RetCode); - RetCode = SK_PNMI_ERR_OK; - } - else { /* RetCode: 2 => Running! */ - SK_PNMI_STORE_U32((pBuf + Offset), RetCode); - RetCode = SK_PNMI_ERR_OK; - } - } - else { /* RetCode: 4 => Link! */ - RetCode = 4; - SK_PNMI_STORE_U32((pBuf + Offset), RetCode); - RetCode = SK_PNMI_ERR_OK; - } - Offset += sizeof(SK_U32); - break; - - default: - *pLen = 0; - return (SK_PNMI_ERR_GENERAL); - } - } /* for */ - *pLen = Offset; - return (RetCode); - -} /* Vct */ - - -PNMI_STATIC void CheckVctStatus( -SK_AC *pAC, -SK_IOC IoC, -char *pBuf, -SK_U32 Offset, -SK_U32 PhysPortIndex) -{ - SK_GEPORT *pPrt; - SK_PNMI_VCT *pVctData; - SK_U32 RetCode; - - pPrt = &pAC->GIni.GP[PhysPortIndex]; - - pVctData = (SK_PNMI_VCT *) (pBuf + Offset); - pVctData->VctStatus = SK_PNMI_VCT_NONE; - - if (!pPrt->PHWLinkUp) { - - /* Was a VCT test ever made before? */ - if (pAC->Pnmi.VctStatus[PhysPortIndex] & SK_PNMI_VCT_TEST_DONE) { - if ((pAC->Pnmi.VctStatus[PhysPortIndex] & SK_PNMI_VCT_LINK)) { - pVctData->VctStatus |= SK_PNMI_VCT_OLD_VCT_DATA; - } - else { - pVctData->VctStatus |= SK_PNMI_VCT_NEW_VCT_DATA; - } - } - - /* Check VCT test status. */ - RetCode = SkGmCableDiagStatus(pAC,IoC, PhysPortIndex, SK_FALSE); - if (RetCode == 2) { /* VCT test is running. */ - pVctData->VctStatus |= SK_PNMI_VCT_RUNNING; - } - else { /* VCT data was copied to pAC here. Check PENDING state. */ - if (pAC->Pnmi.VctStatus[PhysPortIndex] & SK_PNMI_VCT_PENDING) { - pVctData->VctStatus |= SK_PNMI_VCT_NEW_VCT_DATA; - } - } - - if (pPrt->PCableLen != 0xff) { /* Old DSP value. */ - pVctData->VctStatus |= SK_PNMI_VCT_OLD_DSP_DATA; - } - } - else { - - /* Was a VCT test ever made before? */ - if (pAC->Pnmi.VctStatus[PhysPortIndex] & SK_PNMI_VCT_TEST_DONE) { - pVctData->VctStatus &= ~SK_PNMI_VCT_NEW_VCT_DATA; - pVctData->VctStatus |= SK_PNMI_VCT_OLD_VCT_DATA; - } - - /* DSP only valid in 100/1000 modes. */ - if (pAC->GIni.GP[PhysPortIndex].PLinkSpeedUsed != - SK_LSPEED_STAT_10MBPS) { - pVctData->VctStatus |= SK_PNMI_VCT_NEW_DSP_DATA; - } - } -} /* CheckVctStatus */ - - -/***************************************************************************** - * - * SkPnmiGenIoctl - Handles new generic PNMI IOCTL, calls the needed - * PNMI function depending on the subcommand and - * returns all data belonging to the complete database - * or OID request. - * - * Description: - * Looks up the requested subcommand, calls the corresponding handler - * function and passes all required parameters to it. - * The function is called by the driver. It is needed to handle the new - * generic PNMI IOCTL. This IOCTL is given to the driver and contains both - * the OID and a subcommand to decide what kind of request has to be done. - * - * Returns: - * SK_PNMI_ERR_OK The request was successfully performed - * SK_PNMI_ERR_GENERAL A general severe internal error occured - * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to take - * the data. - * SK_PNMI_ERR_UNKNOWN_OID The requested OID is unknown - * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't - * exist (e.g. port instance 3 on a two port - * adapter. - */ -int SkPnmiGenIoctl( -SK_AC *pAC, /* Pointer to adapter context struct */ -SK_IOC IoC, /* I/O context */ -void *pBuf, /* Buffer used for the management data transfer */ -unsigned int *pLen, /* Length of buffer */ -SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */ -{ -SK_I32 Mode; /* Store value of subcommand. */ -SK_U32 Oid; /* Store value of OID. */ -int ReturnCode; /* Store return value to show status of PNMI action. */ -int HeaderLength; /* Length of desired action plus OID. */ - - ReturnCode = SK_PNMI_ERR_GENERAL; - - SK_MEMCPY(&Mode, pBuf, sizeof(SK_I32)); - SK_MEMCPY(&Oid, (char *) pBuf + sizeof(SK_I32), sizeof(SK_U32)); - HeaderLength = sizeof(SK_I32) + sizeof(SK_U32); - *pLen = *pLen - HeaderLength; - SK_MEMCPY((char *) pBuf + sizeof(SK_I32), (char *) pBuf + HeaderLength, *pLen); - - switch(Mode) { - case SK_GET_SINGLE_VAR: - ReturnCode = SkPnmiGetVar(pAC, IoC, Oid, - (char *) pBuf + sizeof(SK_I32), pLen, - ((SK_U32) (-1)), NetIndex); - SK_PNMI_STORE_U32(pBuf, ReturnCode); - *pLen = *pLen + sizeof(SK_I32); - break; - case SK_PRESET_SINGLE_VAR: - ReturnCode = SkPnmiPreSetVar(pAC, IoC, Oid, - (char *) pBuf + sizeof(SK_I32), pLen, - ((SK_U32) (-1)), NetIndex); - SK_PNMI_STORE_U32(pBuf, ReturnCode); - *pLen = *pLen + sizeof(SK_I32); - break; - case SK_SET_SINGLE_VAR: - ReturnCode = SkPnmiSetVar(pAC, IoC, Oid, - (char *) pBuf + sizeof(SK_I32), pLen, - ((SK_U32) (-1)), NetIndex); - SK_PNMI_STORE_U32(pBuf, ReturnCode); - *pLen = *pLen + sizeof(SK_I32); - break; - case SK_GET_FULL_MIB: - ReturnCode = SkPnmiGetStruct(pAC, IoC, pBuf, pLen, NetIndex); - break; - case SK_PRESET_FULL_MIB: - ReturnCode = SkPnmiPreSetStruct(pAC, IoC, pBuf, pLen, NetIndex); - break; - case SK_SET_FULL_MIB: - ReturnCode = SkPnmiSetStruct(pAC, IoC, pBuf, pLen, NetIndex); - break; - default: - break; - } - - return (ReturnCode); - -} /* SkGeIocGen */ +/***************************************************************************** + * + * Name: skgepnmi.c + * Project: Gigabit Ethernet Adapters, PNMI-Module + * Version: $Revision: 2.24 $ + * Date: $Date: 2005/10/21 09:54:35 $ + * Purpose: Private Network Management Interface + * + ****************************************************************************/ + +/****************************************************************************** + * + * (C)Copyright 1998-2002 SysKonnect GmbH. + * (C)Copyright 2002-2003 Marvell. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * The information in this file is provided "AS IS" without warranty. + * + ******************************************************************************/ + +#if (defined(DEBUG) || ((!defined(LINT)) && (!defined(SK_SLIM)))) +static const char SysKonnectFileId[] = + "@(#) $Id: skgepnmi.c,v 2.24 2005/10/21 09:54:35 mkunz Exp $ (C) Marvell."; +#endif + +#include "h/skdrv1st.h" +#include "h/sktypes.h" +#include "h/xmac_ii.h" +#include "h/skdebug.h" +#include "h/skqueue.h" +#include "h/skgepnmi.h" +#include "h/skgesirq.h" +#include "h/skcsum.h" +#include "h/skvpd.h" +#include "h/skgehw.h" +#include "h/sky2le.h" +#include "h/skgeinit.h" +#include "h/skdrv2nd.h" +#include "h/skgepnm2.h" +#ifdef SK_POWER_MGMT +#include "h/skgepmgt.h" +#endif /* SK_POWER_MGMT */ + +/* defines *******************************************************************/ + +#ifndef DEBUG +#define PNMI_STATIC static +#else /* DEBUG */ +#define PNMI_STATIC +#endif /* DEBUG */ + +/* + * Public Function prototypes + */ +int SkPnmiInit(SK_AC *pAC, SK_IOC IoC, int level); +int SkPnmiGetVar(SK_AC *pAC, SK_IOC IoC, SK_U32 Id, void *pBuf, + unsigned int *pLen, SK_U32 Instance, SK_U32 NetIndex); +int SkPnmiPreSetVar(SK_AC *pAC, SK_IOC IoC, SK_U32 Id, void *pBuf, + unsigned int *pLen, SK_U32 Instance, SK_U32 NetIndex); +int SkPnmiSetVar(SK_AC *pAC, SK_IOC IoC, SK_U32 Id, void *pBuf, + unsigned int *pLen, SK_U32 Instance, SK_U32 NetIndex); +int SkPnmiGetStruct(SK_AC *pAC, SK_IOC IoC, void *pBuf, + unsigned int *pLen, SK_U32 NetIndex); +int SkPnmiPreSetStruct(SK_AC *pAC, SK_IOC IoC, void *pBuf, + unsigned int *pLen, SK_U32 NetIndex); +int SkPnmiSetStruct(SK_AC *pAC, SK_IOC IoC, void *pBuf, + unsigned int *pLen, SK_U32 NetIndex); +int SkPnmiEvent(SK_AC *pAC, SK_IOC IoC, SK_U32 Event, SK_EVPARA Param); +int SkPnmiGenIoctl(SK_AC *pAC, SK_IOC IoC, void * pBuf, + unsigned int * pLen, SK_U32 NetIndex); + +/* + * Private Function prototypes + */ + +PNMI_STATIC SK_U8 CalculateLinkModeStatus(SK_AC *pAC, SK_IOC IoC, unsigned int + PhysPortIndex); +PNMI_STATIC SK_U8 CalculateLinkStatus(SK_AC *pAC, SK_IOC IoC, unsigned int + PhysPortIndex); +PNMI_STATIC void CopyMac(char *pDst, SK_MAC_ADDR *pMac); +PNMI_STATIC void CopyTrapQueue(SK_AC *pAC, char *pDstBuf); +PNMI_STATIC SK_U64 GetPhysStatVal(SK_AC *pAC, SK_IOC IoC, + unsigned int PhysPortIndex, unsigned int StatIndex); +PNMI_STATIC SK_U64 GetStatVal(SK_AC *pAC, SK_IOC IoC, unsigned int LogPortIndex, + unsigned int StatIndex, SK_U32 NetIndex); +PNMI_STATIC char* GetTrapEntry(SK_AC *pAC, SK_U32 TrapId, unsigned int Size); +PNMI_STATIC void GetTrapQueueLen(SK_AC *pAC, unsigned int *pLen, + unsigned int *pEntries); +PNMI_STATIC int GetVpdKeyArr(SK_AC *pAC, SK_IOC IoC, char *pKeyArr, + unsigned int KeyArrLen, unsigned int *pKeyNo); +PNMI_STATIC int LookupId(SK_U32 Id); +PNMI_STATIC int MacUpdate(SK_AC *pAC, SK_IOC IoC, unsigned int FirstMac, + unsigned int LastMac); +PNMI_STATIC int PnmiStruct(SK_AC *pAC, SK_IOC IoC, int Action, char *pBuf, + unsigned int *pLen, SK_U32 NetIndex); +PNMI_STATIC int PnmiVar(SK_AC *pAC, SK_IOC IoC, int Action, SK_U32 Id, + char *pBuf, unsigned int *pLen, SK_U32 Instance, SK_U32 NetIndex); +PNMI_STATIC void QueueRlmtNewMacTrap(SK_AC *pAC, unsigned int ActiveMac); +PNMI_STATIC void QueueRlmtPortTrap(SK_AC *pAC, SK_U32 TrapId, + unsigned int PortIndex); +PNMI_STATIC void QueueSensorTrap(SK_AC *pAC, SK_U32 TrapId, + unsigned int SensorIndex); +PNMI_STATIC void QueueSimpleTrap(SK_AC *pAC, SK_U32 TrapId); +PNMI_STATIC void ResetCounter(SK_AC *pAC, SK_IOC IoC, SK_U32 NetIndex); +PNMI_STATIC int RlmtUpdate(SK_AC *pAC, SK_IOC IoC, SK_U32 NetIndex); +PNMI_STATIC int SirqUpdate(SK_AC *pAC, SK_IOC IoC); +PNMI_STATIC void VirtualConf(SK_AC *pAC, SK_IOC IoC, SK_U32 Id, char *pBuf); +PNMI_STATIC int Vct(SK_AC *pAC, SK_IOC IoC, int Action, SK_U32 Id, char *pBuf, + unsigned int *pLen, SK_U32 Instance, unsigned int TableIndex, SK_U32 NetIndex); +PNMI_STATIC void CheckVctStatus(SK_AC *, SK_IOC, char *, SK_U32, SK_U32); +PNMI_STATIC void VctGetResults(SK_AC *, SK_IOC, SK_U32); +#ifdef SK_ASF +PNMI_STATIC int Asf(SK_AC *pAC, SK_IOC IoC, int action, SK_U32 Id, + char *pBuf, unsigned int *pLen, SK_U32 Instance, + unsigned int TableIndex, SK_U32 NetIndex); +#endif /* SK_ASF */ + +/* + * Table to correlate OID with handler function and index to + * hardware register stored in StatAddress if applicable. + */ +#include "skgemib.c" + +/* global variables **********************************************************/ + +/* + * Overflow status register bit table and corresponding counter + * dependent on MAC type - the number relates to the size of overflow + * mask returned by the pFnMacOverflow function + */ +PNMI_STATIC const SK_U16 StatOvrflwBit[][SK_PNMI_MAC_TYPES] = { +/* Bit0 */ { SK_PNMI_HTX, SK_PNMI_HTX_UNICAST}, +/* Bit1 */ { SK_PNMI_HTX_OCTETHIGH, SK_PNMI_HTX_BROADCAST}, +/* Bit2 */ { SK_PNMI_HTX_OCTETLOW, SK_PNMI_HTX_PMACC}, +/* Bit3 */ { SK_PNMI_HTX_BROADCAST, SK_PNMI_HTX_MULTICAST}, +/* Bit4 */ { SK_PNMI_HTX_MULTICAST, SK_PNMI_HTX_OCTETLOW}, +/* Bit5 */ { SK_PNMI_HTX_UNICAST, SK_PNMI_HTX_OCTETHIGH}, +/* Bit6 */ { SK_PNMI_HTX_LONGFRAMES, SK_PNMI_HTX_64}, +/* Bit7 */ { SK_PNMI_HTX_BURST, SK_PNMI_HTX_127}, +/* Bit8 */ { SK_PNMI_HTX_PMACC, SK_PNMI_HTX_255}, +/* Bit9 */ { SK_PNMI_HTX_MACC, SK_PNMI_HTX_511}, +/* Bit10 */ { SK_PNMI_HTX_SINGLE_COL, SK_PNMI_HTX_1023}, +/* Bit11 */ { SK_PNMI_HTX_MULTI_COL, SK_PNMI_HTX_MAX}, +/* Bit12 */ { SK_PNMI_HTX_EXCESS_COL, SK_PNMI_HTX_LONGFRAMES}, +/* Bit13 */ { SK_PNMI_HTX_LATE_COL, SK_PNMI_HTX_RESERVED}, +/* Bit14 */ { SK_PNMI_HTX_DEFFERAL, SK_PNMI_HTX_COL}, +/* Bit15 */ { SK_PNMI_HTX_EXCESS_DEF, SK_PNMI_HTX_LATE_COL}, +/* Bit16 */ { SK_PNMI_HTX_UNDERRUN, SK_PNMI_HTX_EXCESS_COL}, +/* Bit17 */ { SK_PNMI_HTX_CARRIER, SK_PNMI_HTX_MULTI_COL}, +/* Bit18 */ { SK_PNMI_HTX_UTILUNDER, SK_PNMI_HTX_SINGLE_COL}, +/* Bit19 */ { SK_PNMI_HTX_UTILOVER, SK_PNMI_HTX_UNDERRUN}, +/* Bit20 */ { SK_PNMI_HTX_64, SK_PNMI_HTX_RESERVED}, +/* Bit21 */ { SK_PNMI_HTX_127, SK_PNMI_HTX_RESERVED}, +/* Bit22 */ { SK_PNMI_HTX_255, SK_PNMI_HTX_RESERVED}, +/* Bit23 */ { SK_PNMI_HTX_511, SK_PNMI_HTX_RESERVED}, +/* Bit24 */ { SK_PNMI_HTX_1023, SK_PNMI_HTX_RESERVED}, +/* Bit25 */ { SK_PNMI_HTX_MAX, SK_PNMI_HTX_RESERVED}, +/* Bit26 */ { SK_PNMI_HTX_RESERVED, SK_PNMI_HTX_RESERVED}, +/* Bit27 */ { SK_PNMI_HTX_RESERVED, SK_PNMI_HTX_RESERVED}, +/* Bit28 */ { SK_PNMI_HTX_RESERVED, SK_PNMI_HTX_RESERVED}, +/* Bit29 */ { SK_PNMI_HTX_RESERVED, SK_PNMI_HTX_RESERVED}, +/* Bit30 */ { SK_PNMI_HTX_RESERVED, SK_PNMI_HTX_RESERVED}, +/* Bit31 */ { SK_PNMI_HTX_RESERVED, SK_PNMI_HTX_RESERVED}, +/* Bit32 */ { SK_PNMI_HRX, SK_PNMI_HRX_UNICAST}, +/* Bit33 */ { SK_PNMI_HRX_OCTETHIGH, SK_PNMI_HRX_BROADCAST}, +/* Bit34 */ { SK_PNMI_HRX_OCTETLOW, SK_PNMI_HRX_PMACC}, +/* Bit35 */ { SK_PNMI_HRX_BROADCAST, SK_PNMI_HRX_MULTICAST}, +/* Bit36 */ { SK_PNMI_HRX_MULTICAST, SK_PNMI_HRX_FCS}, +/* Bit37 */ { SK_PNMI_HRX_UNICAST, SK_PNMI_HRX_RESERVED}, +/* Bit38 */ { SK_PNMI_HRX_PMACC, SK_PNMI_HRX_OCTETLOW}, +/* Bit39 */ { SK_PNMI_HRX_MACC, SK_PNMI_HRX_OCTETHIGH}, +/* Bit40 */ { SK_PNMI_HRX_PMACC_ERR, SK_PNMI_HRX_BADOCTETLOW}, +/* Bit41 */ { SK_PNMI_HRX_MACC_UNKWN, SK_PNMI_HRX_BADOCTETHIGH}, +/* Bit42 */ { SK_PNMI_HRX_BURST, SK_PNMI_HRX_UNDERSIZE}, +/* Bit43 */ { SK_PNMI_HRX_MISSED, SK_PNMI_HRX_RUNT}, +/* Bit44 */ { SK_PNMI_HRX_FRAMING, SK_PNMI_HRX_64}, +/* Bit45 */ { SK_PNMI_HRX_OVERFLOW, SK_PNMI_HRX_127}, +/* Bit46 */ { SK_PNMI_HRX_JABBER, SK_PNMI_HRX_255}, +/* Bit47 */ { SK_PNMI_HRX_CARRIER, SK_PNMI_HRX_511}, +/* Bit48 */ { SK_PNMI_HRX_IRLENGTH, SK_PNMI_HRX_1023}, +/* Bit49 */ { SK_PNMI_HRX_SYMBOL, SK_PNMI_HRX_MAX}, +/* Bit50 */ { SK_PNMI_HRX_SHORTS, SK_PNMI_HRX_LONGFRAMES}, +/* Bit51 */ { SK_PNMI_HRX_RUNT, SK_PNMI_HRX_TOO_LONG}, +/* Bit52 */ { SK_PNMI_HRX_TOO_LONG, SK_PNMI_HRX_JABBER}, +/* Bit53 */ { SK_PNMI_HRX_FCS, SK_PNMI_HRX_RESERVED}, +/* Bit54 */ { SK_PNMI_HRX_RESERVED, SK_PNMI_HRX_OVERFLOW}, +/* Bit55 */ { SK_PNMI_HRX_CEXT, SK_PNMI_HRX_RESERVED}, +/* Bit56 */ { SK_PNMI_HRX_UTILUNDER, SK_PNMI_HRX_RESERVED}, +/* Bit57 */ { SK_PNMI_HRX_UTILOVER, SK_PNMI_HRX_RESERVED}, +/* Bit58 */ { SK_PNMI_HRX_64, SK_PNMI_HRX_RESERVED}, +/* Bit59 */ { SK_PNMI_HRX_127, SK_PNMI_HRX_RESERVED}, +/* Bit60 */ { SK_PNMI_HRX_255, SK_PNMI_HRX_RESERVED}, +/* Bit61 */ { SK_PNMI_HRX_511, SK_PNMI_HRX_RESERVED}, +/* Bit62 */ { SK_PNMI_HRX_1023, SK_PNMI_HRX_RESERVED}, +/* Bit63 */ { SK_PNMI_HRX_MAX, SK_PNMI_HRX_RESERVED} +}; + +/* + * Table for hardware register saving on resets and port switches + */ +PNMI_STATIC const SK_PNMI_STATADDR StatAddr[SK_PNMI_MAX_IDX][SK_PNMI_MAC_TYPES] = { + /* SK_PNMI_HTX */ + {{XM_TXF_OK, SK_TRUE}, {0, SK_FALSE}}, + /* SK_PNMI_HTX_OCTETHIGH */ + {{XM_TXO_OK_HI, SK_TRUE}, {GM_TXO_OK_HI, SK_TRUE}}, + /* SK_PNMI_HTX_OCTETLOW */ + {{XM_TXO_OK_LO, SK_FALSE}, {GM_TXO_OK_LO, SK_FALSE}}, + /* SK_PNMI_HTX_BROADCAST */ + {{XM_TXF_BC_OK, SK_TRUE}, {GM_TXF_BC_OK, SK_TRUE}}, + /* SK_PNMI_HTX_MULTICAST */ + {{XM_TXF_MC_OK, SK_TRUE}, {GM_TXF_MC_OK, SK_TRUE}}, + /* SK_PNMI_HTX_UNICAST */ + {{XM_TXF_UC_OK, SK_TRUE}, {GM_TXF_UC_OK, SK_TRUE}}, + /* SK_PNMI_HTX_BURST */ + {{XM_TXE_BURST, SK_TRUE}, {0, SK_FALSE}}, + /* SK_PNMI_HTX_PMACC */ + {{XM_TXF_MPAUSE, SK_TRUE}, {GM_TXF_MPAUSE, SK_TRUE}}, + /* SK_PNMI_HTX_MACC */ + {{XM_TXF_MCTRL, SK_TRUE}, {0, SK_FALSE}}, + /* SK_PNMI_HTX_COL */ + {{0, SK_FALSE}, {GM_TXF_COL, SK_TRUE}}, + /* SK_PNMI_HTX_SINGLE_COL */ + {{XM_TXF_SNG_COL, SK_TRUE}, {GM_TXF_SNG_COL, SK_TRUE}}, + /* SK_PNMI_HTX_MULTI_COL */ + {{XM_TXF_MUL_COL, SK_TRUE}, {GM_TXF_MUL_COL, SK_TRUE}}, + /* SK_PNMI_HTX_EXCESS_COL */ + {{XM_TXF_ABO_COL, SK_TRUE}, {GM_TXF_ABO_COL, SK_TRUE}}, + /* SK_PNMI_HTX_LATE_COL */ + {{XM_TXF_LAT_COL, SK_TRUE}, {GM_TXF_LAT_COL, SK_TRUE}}, + /* SK_PNMI_HTX_DEFFERAL */ + {{XM_TXF_DEF, SK_TRUE}, {0, SK_FALSE}}, + /* SK_PNMI_HTX_EXCESS_DEF */ + {{XM_TXF_EX_DEF, SK_TRUE}, {0, SK_FALSE}}, + /* SK_PNMI_HTX_UNDERRUN */ + {{XM_TXE_FIFO_UR, SK_TRUE}, {GM_TXE_FIFO_UR, SK_TRUE}}, + /* SK_PNMI_HTX_CARRIER */ + {{XM_TXE_CS_ERR, SK_TRUE}, {0, SK_FALSE}}, + /* SK_PNMI_HTX_UTILUNDER */ + {{0, SK_FALSE}, {0, SK_FALSE}}, + /* SK_PNMI_HTX_UTILOVER */ + {{0, SK_FALSE}, {0, SK_FALSE}}, + /* SK_PNMI_HTX_64 */ + {{XM_TXF_64B, SK_TRUE}, {GM_TXF_64B, SK_TRUE}}, + /* SK_PNMI_HTX_127 */ + {{XM_TXF_127B, SK_TRUE}, {GM_TXF_127B, SK_TRUE}}, + /* SK_PNMI_HTX_255 */ + {{XM_TXF_255B, SK_TRUE}, {GM_TXF_255B, SK_TRUE}}, + /* SK_PNMI_HTX_511 */ + {{XM_TXF_511B, SK_TRUE}, {GM_TXF_511B, SK_TRUE}}, + /* SK_PNMI_HTX_1023 */ + {{XM_TXF_1023B, SK_TRUE}, {GM_TXF_1023B, SK_TRUE}}, + /* SK_PNMI_HTX_MAX */ + {{XM_TXF_MAX_SZ, SK_TRUE}, {GM_TXF_1518B, SK_TRUE}}, + /* SK_PNMI_HTX_LONGFRAMES */ + {{XM_TXF_LONG, SK_TRUE}, {GM_TXF_MAX_SZ, SK_TRUE}}, + /* SK_PNMI_HTX_SYNC */ + {{0, SK_FALSE}, {0, SK_FALSE}}, + /* SK_PNMI_HTX_SYNC_OCTET */ + {{0, SK_FALSE}, {0, SK_FALSE}}, + /* SK_PNMI_HTX_RESERVED */ + {{0, SK_FALSE}, {0, SK_FALSE}}, + /* SK_PNMI_HRX */ + {{XM_RXF_OK, SK_TRUE}, {0, SK_FALSE}}, + /* SK_PNMI_HRX_OCTETHIGH */ + {{XM_RXO_OK_HI, SK_TRUE}, {GM_RXO_OK_HI, SK_TRUE}}, + /* SK_PNMI_HRX_OCTETLOW */ + {{XM_RXO_OK_LO, SK_FALSE}, {GM_RXO_OK_LO, SK_FALSE}}, + /* SK_PNMI_HRX_BADOCTETHIGH */ + {{0, SK_FALSE}, {GM_RXO_ERR_HI, SK_TRUE}}, + /* SK_PNMI_HRX_BADOCTETLOW */ + {{0, SK_FALSE}, {GM_RXO_ERR_LO, SK_TRUE}}, + /* SK_PNMI_HRX_BROADCAST */ + {{XM_RXF_BC_OK, SK_TRUE}, {GM_RXF_BC_OK, SK_TRUE}}, + /* SK_PNMI_HRX_MULTICAST */ + {{XM_RXF_MC_OK, SK_TRUE}, {GM_RXF_MC_OK, SK_TRUE}}, + /* SK_PNMI_HRX_UNICAST */ + {{XM_RXF_UC_OK, SK_TRUE}, {GM_RXF_UC_OK, SK_TRUE}}, + /* SK_PNMI_HRX_PMACC */ + {{XM_RXF_MPAUSE, SK_TRUE}, {GM_RXF_MPAUSE, SK_TRUE}}, + /* SK_PNMI_HRX_MACC */ + {{XM_RXF_MCTRL, SK_TRUE}, {0, SK_FALSE}}, + /* SK_PNMI_HRX_PMACC_ERR */ + {{XM_RXF_INV_MP, SK_TRUE}, {0, SK_FALSE}}, + /* SK_PNMI_HRX_MACC_UNKWN */ + {{XM_RXF_INV_MOC, SK_TRUE}, {0, SK_FALSE}}, + /* SK_PNMI_HRX_BURST */ + {{XM_RXE_BURST, SK_TRUE}, {0, SK_FALSE}}, + /* SK_PNMI_HRX_MISSED */ + {{XM_RXE_FMISS, SK_TRUE}, {0, SK_FALSE}}, + /* SK_PNMI_HRX_FRAMING */ + {{XM_RXF_FRA_ERR, SK_TRUE}, {0, SK_FALSE}}, + /* SK_PNMI_HRX_UNDERSIZE */ + {{0, SK_FALSE}, {GM_RXF_SHT, SK_TRUE}}, + /* SK_PNMI_HRX_OVERFLOW */ + {{XM_RXE_FIFO_OV, SK_TRUE}, {GM_RXE_FIFO_OV, SK_TRUE}}, + /* SK_PNMI_HRX_JABBER */ + {{XM_RXF_JAB_PKT, SK_TRUE}, {GM_RXF_JAB_PKT, SK_TRUE}}, + /* SK_PNMI_HRX_CARRIER */ + {{XM_RXE_CAR_ERR, SK_TRUE}, {0, SK_FALSE}}, + /* SK_PNMI_HRX_IRLENGTH */ + {{XM_RXF_LEN_ERR, SK_TRUE}, {0, SK_FALSE}}, + /* SK_PNMI_HRX_SYMBOL */ + {{XM_RXE_SYM_ERR, SK_TRUE}, {0, SK_FALSE}}, + /* SK_PNMI_HRX_SHORTS */ + {{XM_RXE_SHT_ERR, SK_TRUE}, {0, SK_FALSE}}, + /* SK_PNMI_HRX_RUNT */ + {{XM_RXE_RUNT, SK_TRUE}, {GM_RXE_FRAG, SK_TRUE}}, + /* SK_PNMI_HRX_TOO_LONG */ + {{XM_RXF_LNG_ERR, SK_TRUE}, {GM_RXF_LNG_ERR, SK_TRUE}}, + /* SK_PNMI_HRX_FCS */ + {{XM_RXF_FCS_ERR, SK_TRUE}, {GM_RXF_FCS_ERR, SK_TRUE}}, + /* SK_PNMI_HRX_CEXT */ + {{XM_RXF_CEX_ERR, SK_TRUE}, {0, SK_FALSE}}, + /* SK_PNMI_HRX_UTILUNDER */ + {{0, SK_FALSE}, {0, SK_FALSE}}, + /* SK_PNMI_HRX_UTILOVER */ + {{0, SK_FALSE}, {0, SK_FALSE}}, + /* SK_PNMI_HRX_64 */ + {{XM_RXF_64B, SK_TRUE}, {GM_RXF_64B, SK_TRUE}}, + /* SK_PNMI_HRX_127 */ + {{XM_RXF_127B, SK_TRUE}, {GM_RXF_127B, SK_TRUE}}, + /* SK_PNMI_HRX_255 */ + {{XM_RXF_255B, SK_TRUE}, {GM_RXF_255B, SK_TRUE}}, + /* SK_PNMI_HRX_511 */ + {{XM_RXF_511B, SK_TRUE}, {GM_RXF_511B, SK_TRUE}}, + /* SK_PNMI_HRX_1023 */ + {{XM_RXF_1023B, SK_TRUE}, {GM_RXF_1023B, SK_TRUE}}, + /* SK_PNMI_HRX_MAX */ + {{XM_RXF_MAX_SZ, SK_TRUE}, {GM_RXF_1518B, SK_TRUE}}, + /* SK_PNMI_HRX_LONGFRAMES */ + {{0, SK_FALSE}, {GM_RXF_MAX_SZ, SK_TRUE}}, + /* SK_PNMI_HRX_RESERVED */ + {{0, SK_FALSE}, {0, SK_FALSE}} +}; + + +/***************************************************************************** + * + * Public functions + * + */ + +/***************************************************************************** + * + * SkPnmiInit - Init function of PNMI + * + * Description: + * SK_INIT_DATA: Initialises the data structures + * SK_INIT_IO: Resets the XMAC statistics, determines the device and + * connector type. + * SK_INIT_RUN: Starts a timer event for port switch per hour + * calculation. + * + * Returns: + * Always 0 + */ +int SkPnmiInit( +SK_AC *pAC, /* Pointer to adapter context */ +SK_IOC IoC, /* IO context handle */ +int Level) /* Initialization level */ +{ + unsigned int PortMax; /* Number of ports */ + unsigned int PortIndex; /* Current port index in loop */ + SK_EVPARA EventParam; /* Event struct for timer event */ + + SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL, + ("PNMI: SkPnmiInit: Called, level=%d\n", Level)); + + switch (Level) { + + case SK_INIT_DATA: + SK_MEMSET((char *)&pAC->Pnmi, 0, sizeof(pAC->Pnmi)); + + pAC->Pnmi.TrapBufFree = SK_PNMI_TRAP_QUEUE_LEN; + pAC->Pnmi.StartUpTime = SK_PNMI_HUNDREDS_SEC(SkOsGetTime(pAC)); + pAC->Pnmi.RlmtChangeThreshold = SK_PNMI_DEF_RLMT_CHG_THRES; + + for (PortIndex = 0; PortIndex < SK_MAX_MACS; PortIndex ++) { + + pAC->Pnmi.Port[PortIndex].ActiveFlag = SK_FALSE; + pAC->Pnmi.DualNetActiveFlag = SK_FALSE; + + /* Initialize DSP variables for Vct() to 0xff => Never written! */ + pAC->GIni.GP[PortIndex].PCableLen = 0xff; + pAC->Pnmi.VctBackup[PortIndex].CableLen = 0xff; + } + +#ifdef SK_PNMI_CHECK + if (SK_PNMI_MAX_IDX != SK_PNMI_CNT_NO) { + + SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR049, SK_PNMI_ERR049MSG); + + SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_INIT | SK_DBGCAT_FATAL, + ("CounterOffset struct size (%d) differs from" + "SK_PNMI_MAX_IDX (%d)\n", + SK_PNMI_CNT_NO, SK_PNMI_MAX_IDX)); + } + + if (SK_PNMI_MAX_IDX != + (sizeof(StatAddr) / (sizeof(SK_PNMI_STATADDR) * SK_PNMI_MAC_TYPES))) { + + SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR050, SK_PNMI_ERR050MSG); + + SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_INIT | SK_DBGCAT_FATAL, + ("StatAddr table size (%d) differs from " + "SK_PNMI_MAX_IDX (%d)\n", + (sizeof(StatAddr) / + (sizeof(SK_PNMI_STATADDR) * SK_PNMI_MAC_TYPES)), + SK_PNMI_MAX_IDX)); + } +#endif /* SK_PNMI_CHECK */ + break; + + case SK_INIT_IO: + + /* Reset MAC counters. */ + PortMax = pAC->GIni.GIMacsFound; + + for (PortIndex = 0; PortIndex < PortMax; PortIndex ++) { + + pAC->GIni.GIFunc.pFnMacResetCounter(pAC, IoC, PortIndex); + } + + /* Get PCI bus speed. */ + if (pAC->GIni.GIPciClock66) { + + pAC->Pnmi.PciBusSpeed = 66; + } + else { + pAC->Pnmi.PciBusSpeed = 33; + } + + /* Get PCI bus width. */ + if (pAC->GIni.GIPciSlot64) { + + pAC->Pnmi.PciBusWidth = 64; + } + else { + pAC->Pnmi.PciBusWidth = 32; + } + + /* Get chipset. */ + switch (pAC->GIni.GIChipId) { + + case CHIP_ID_GENESIS: + pAC->Pnmi.Chipset = SK_PNMI_CHIPSET_XMAC; + break; + + case CHIP_ID_YUKON: + pAC->Pnmi.Chipset = SK_PNMI_CHIPSET_YUKON; + break; + + case CHIP_ID_YUKON_LITE: + pAC->Pnmi.Chipset = SK_PNMI_CHIPSET_YUKON_LITE; + break; + + case CHIP_ID_YUKON_LP: + pAC->Pnmi.Chipset = SK_PNMI_CHIPSET_YUKON_LP; + break; + + case CHIP_ID_YUKON_XL: + pAC->Pnmi.Chipset = SK_PNMI_CHIPSET_YUKON_XL; + break; + + case CHIP_ID_YUKON_EC: + pAC->Pnmi.Chipset = SK_PNMI_CHIPSET_YUKON_EC; + break; + + case CHIP_ID_YUKON_FE: + pAC->Pnmi.Chipset = SK_PNMI_CHIPSET_YUKON_FE; + break; + + default: + break; + } + + /* Get PMD and Device Type. */ + switch (pAC->GIni.GIPmdTyp) { + + case 'S': + pAC->Pnmi.PMD = 3; + pAC->Pnmi.DeviceType = 0x00020001; + break; + + case 'L': + pAC->Pnmi.PMD = 2; + pAC->Pnmi.DeviceType = 0x00020003; + break; + + case 'C': + pAC->Pnmi.PMD = 4; + pAC->Pnmi.DeviceType = 0x00020005; + break; + + case 'T': + pAC->Pnmi.PMD = 5; + pAC->Pnmi.DeviceType = 0x00020007; + break; + + default : + pAC->Pnmi.PMD = 1; + pAC->Pnmi.DeviceType = 0; + break; + } + + if (pAC->GIni.GIMacsFound > 1) { + + pAC->Pnmi.DeviceType++; + } + + /* Get connector type. */ + switch (pAC->GIni.GIConTyp) { + + case 'C': + pAC->Pnmi.Connector = 2; + break; + + case 'D': + pAC->Pnmi.Connector = 3; + break; + + case 'F': + pAC->Pnmi.Connector = 4; + break; + + case 'J': + pAC->Pnmi.Connector = 5; + break; + + case 'V': + pAC->Pnmi.Connector = 6; + break; + + default: + pAC->Pnmi.Connector = 1; + break; + } + break; + + case SK_INIT_RUN: + + /* Start timer for RLMT change counter. */ + SK_MEMSET((char *)&EventParam, 0, sizeof(EventParam)); + + SkTimerStart(pAC, IoC, &pAC->Pnmi.RlmtChangeEstimate.EstTimer, + SK_PNMI_EVT_TIMER_CHECK, SKGE_PNMI, SK_PNMI_EVT_CHG_EST_TIMER, + EventParam); + break; + + default: + break; /* Nothing to do. */ + } + + return (0); +} + +/***************************************************************************** + * + * SkPnmiGetVar - Retrieves the value of a single OID + * + * Description: + * Calls a general sub-function for all this stuff. If the instance + * -1 is passed, the values of all instances are returned in an + * array of values. + * + * Returns: + * SK_PNMI_ERR_OK The request was successfully performed + * SK_PNMI_ERR_GENERAL A general severe internal error occured + * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to take + * the data. + * SK_PNMI_ERR_UNKNOWN_OID The requested OID is unknown + * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't + * exist (e.g. port instance 3 on a two port + * adapter. + */ +int SkPnmiGetVar( +SK_AC *pAC, /* Pointer to adapter context */ +SK_IOC IoC, /* IO context handle */ +SK_U32 Id, /* Object ID that is to be processed */ +void *pBuf, /* Buffer to which the management data will be copied */ +unsigned int *pLen, /* On call: buffer length. On return: used buffer */ +SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */ +SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */ +{ + SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL, + ("PNMI: SkPnmiGetVar: Called, Id=0x%x, BufLen=%d, Instance=%d, NetIndex=%d\n", + Id, *pLen, Instance, NetIndex)); + + return (PnmiVar(pAC, IoC, SK_PNMI_GET, Id, (char *)pBuf, pLen, + Instance, NetIndex)); +} + +/***************************************************************************** + * + * SkPnmiPreSetVar - Presets the value of a single OID + * + * Description: + * Calls a general sub-function for all this stuff. The preset does + * the same as a set, but returns just before finally setting the + * new value. This is usefull to check if a set might be successfull. + * If the instance -1 is passed, an array of values is supposed and + * all instances of the OID will be set. + * + * Returns: + * SK_PNMI_ERR_OK The request was successfully performed. + * SK_PNMI_ERR_GENERAL A general severe internal error occured. + * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain + * the correct data (e.g. a 32bit value is + * needed, but a 16 bit value was passed). + * SK_PNMI_ERR_BAD_VALUE The passed value is not in the valid + * value range. + * SK_PNMI_ERR_READ_ONLY The OID is read-only and cannot be set. + * SK_PNMI_ERR_UNKNOWN_OID The requested OID is unknown. + * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't + * exist (e.g. port instance 3 on a two port + * adapter. + */ +int SkPnmiPreSetVar( +SK_AC *pAC, /* Pointer to adapter context */ +SK_IOC IoC, /* IO context handle */ +SK_U32 Id, /* Object ID that is to be processed */ +void *pBuf, /* Buffer to which the management data will be copied */ +unsigned int *pLen, /* Total length of management data */ +SK_U32 Instance, /* Instance (1..n) that is to be set or -1 */ +SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */ +{ + SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL, + ("PNMI: SkPnmiPreSetVar: Called, Id=0x%x, BufLen=%d, Instance=%d, NetIndex=%d\n", + Id, *pLen, Instance, NetIndex)); + + return (PnmiVar(pAC, IoC, SK_PNMI_PRESET, Id, (char *)pBuf, pLen, + Instance, NetIndex)); +} + +/***************************************************************************** + * + * SkPnmiSetVar - Sets the value of a single OID + * + * Description: + * Calls a general sub-function for all this stuff. The preset does + * the same as a set, but returns just before finally setting the + * new value. This is usefull to check if a set might be successfull. + * If the instance -1 is passed, an array of values is supposed and + * all instances of the OID will be set. + * + * Returns: + * SK_PNMI_ERR_OK The request was successfully performed. + * SK_PNMI_ERR_GENERAL A general severe internal error occured. + * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain + * the correct data (e.g. a 32bit value is + * needed, but a 16 bit value was passed). + * SK_PNMI_ERR_BAD_VALUE The passed value is not in the valid + * value range. + * SK_PNMI_ERR_READ_ONLY The OID is read-only and cannot be set. + * SK_PNMI_ERR_UNKNOWN_OID The requested OID is unknown. + * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't + * exist (e.g. port instance 3 on a two port + * adapter. + */ +int SkPnmiSetVar( +SK_AC *pAC, /* Pointer to adapter context */ +SK_IOC IoC, /* IO context handle */ +SK_U32 Id, /* Object ID that is to be processed */ +void *pBuf, /* Buffer to which the management data will be copied */ +unsigned int *pLen, /* Total length of management data */ +SK_U32 Instance, /* Instance (1..n) that is to be set or -1 */ +SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */ +{ + SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL, + ("PNMI: SkPnmiSetVar: Called, Id=0x%x, BufLen=%d, Instance=%d, NetIndex=%d\n", + Id, *pLen, Instance, NetIndex)); + + return (PnmiVar(pAC, IoC, SK_PNMI_SET, Id, (char *)pBuf, pLen, + Instance, NetIndex)); +} + +/***************************************************************************** + * + * SkPnmiGetStruct - Retrieves the management database in SK_PNMI_STRUCT_DATA + * + * Description: + * Runs through the IdTable, queries the single OIDs and stores the + * returned data into the management database structure + * SK_PNMI_STRUCT_DATA. The offset of the OID in the structure + * is stored in the IdTable. The return value of the function will also + * be stored in SK_PNMI_STRUCT_DATA if the passed buffer has the + * minimum size of SK_PNMI_MIN_STRUCT_SIZE. + * + * Returns: + * SK_PNMI_ERR_OK The request was successfully performed + * SK_PNMI_ERR_GENERAL A general severe internal error occured + * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to take + * the data. + * SK_PNMI_ERR_UNKNOWN_NET The requested NetIndex doesn't exist + */ +int SkPnmiGetStruct( +SK_AC *pAC, /* Pointer to adapter context */ +SK_IOC IoC, /* IO context handle */ +void *pBuf, /* Buffer to which the management data will be copied. */ +unsigned int *pLen, /* Length of buffer */ +SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */ +{ + int Ret; + unsigned int TableIndex; + unsigned int DstOffset; + unsigned int InstanceNo; + unsigned int InstanceCnt; + SK_U32 Instance; + unsigned int TmpLen; + char KeyArr[SK_PNMI_VPD_ENTRIES][SK_PNMI_VPD_KEY_SIZE]; + + SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL, + ("PNMI: SkPnmiGetStruct: Called, BufLen=%d, NetIndex=%d\n", + *pLen, NetIndex)); + + if (*pLen < SK_PNMI_STRUCT_SIZE) { + + if (*pLen >= SK_PNMI_MIN_STRUCT_SIZE) { + + SK_PNMI_SET_STAT(pBuf, SK_PNMI_ERR_TOO_SHORT, (SK_U32)(-1)); + } + + *pLen = SK_PNMI_STRUCT_SIZE; + return (SK_PNMI_ERR_TOO_SHORT); + } + + /* Check NetIndex. */ + if (NetIndex >= pAC->Rlmt.NumNets) { + return (SK_PNMI_ERR_UNKNOWN_NET); + } + + /* Update statistics. */ + SK_PNMI_CHECKFLAGS("SkPnmiGetStruct: On call"); + + if ((Ret = MacUpdate(pAC, IoC, 0, pAC->GIni.GIMacsFound - 1)) != + SK_PNMI_ERR_OK) { + + SK_PNMI_SET_STAT(pBuf, Ret, (SK_U32)(-1)); + *pLen = SK_PNMI_MIN_STRUCT_SIZE; + return (Ret); + } + + if ((Ret = RlmtUpdate(pAC, IoC, NetIndex)) != SK_PNMI_ERR_OK) { + + SK_PNMI_SET_STAT(pBuf, Ret, (SK_U32)(-1)); + *pLen = SK_PNMI_MIN_STRUCT_SIZE; + return (Ret); + } + + if ((Ret = SirqUpdate(pAC, IoC)) != SK_PNMI_ERR_OK) { + + SK_PNMI_SET_STAT(pBuf, Ret, (SK_U32)(-1)); + *pLen = SK_PNMI_MIN_STRUCT_SIZE; + return (Ret); + } + + /* Increment semaphores to indicate that an update was already done. */ + pAC->Pnmi.MacUpdatedFlag ++; + pAC->Pnmi.RlmtUpdatedFlag ++; + pAC->Pnmi.SirqUpdatedFlag ++; + + /* + * Get VPD keys for instance calculation. + * Please read comment in Vpd(). + */ + if (pAC->Pnmi.VpdKeyReadError == SK_FALSE) { + Ret = GetVpdKeyArr(pAC, IoC, &KeyArr[0][0], sizeof(KeyArr), &TmpLen); + if (Ret != SK_PNMI_ERR_OK) { + + pAC->Pnmi.MacUpdatedFlag --; + pAC->Pnmi.RlmtUpdatedFlag --; + pAC->Pnmi.SirqUpdatedFlag --; + + SK_PNMI_CHECKFLAGS("SkPnmiGetStruct: On return"); + SK_PNMI_SET_STAT(pBuf, Ret, (SK_U32)(-1)); + *pLen = SK_PNMI_MIN_STRUCT_SIZE; + return (SK_PNMI_ERR_GENERAL); + } + } + + /* Retrieve values. */ + SK_MEMSET((char *)pBuf, 0, SK_PNMI_STRUCT_SIZE); + + for (TableIndex = 0; TableIndex < ID_TABLE_SIZE; TableIndex ++) { + + InstanceNo = IdTable[TableIndex].InstanceNo; + for (InstanceCnt = 1; InstanceCnt <= InstanceNo; InstanceCnt ++) { + + DstOffset = IdTable[TableIndex].Offset + + (InstanceCnt - 1) * + IdTable[TableIndex].StructSize; + + /* + * For the VPD the instance is not an index number + * but the key itself. Determin with the instance + * counter the VPD key to be used. + */ + if (IdTable[TableIndex].Id == OID_SKGE_VPD_KEY || + IdTable[TableIndex].Id == OID_SKGE_VPD_VALUE || + IdTable[TableIndex].Id == OID_SKGE_VPD_ACCESS || + IdTable[TableIndex].Id == OID_SKGE_VPD_ACTION) { + + SK_STRNCPY((char *)&Instance, KeyArr[InstanceCnt - 1], 4); + } + else { + Instance = (SK_U32)InstanceCnt; + } + + TmpLen = *pLen - DstOffset; + Ret = IdTable[TableIndex].Func(pAC, IoC, SK_PNMI_GET, + IdTable[TableIndex].Id, (char *)pBuf + + DstOffset, &TmpLen, Instance, TableIndex, NetIndex); + + /* + * An unknown instance error means that we reached + * the last instance of that variable. Proceed with + * the next OID in the table and ignore the return + * code. + */ + if (Ret == SK_PNMI_ERR_UNKNOWN_INST) { + + break; + } + + if (Ret != SK_PNMI_ERR_OK) { + + pAC->Pnmi.MacUpdatedFlag --; + pAC->Pnmi.RlmtUpdatedFlag --; + pAC->Pnmi.SirqUpdatedFlag --; + + SK_PNMI_CHECKFLAGS("SkPnmiGetStruct: On return"); + SK_PNMI_SET_STAT(pBuf, Ret, DstOffset); + *pLen = SK_PNMI_MIN_STRUCT_SIZE; + return (Ret); + } + } + } + + pAC->Pnmi.MacUpdatedFlag --; + pAC->Pnmi.RlmtUpdatedFlag --; + pAC->Pnmi.SirqUpdatedFlag --; + + *pLen = SK_PNMI_STRUCT_SIZE; + SK_PNMI_CHECKFLAGS("SkPnmiGetStruct: On return"); + SK_PNMI_SET_STAT(pBuf, SK_PNMI_ERR_OK, (SK_U32)(-1)); + return (SK_PNMI_ERR_OK); +} + +/***************************************************************************** + * + * SkPnmiPreSetStruct - Presets the management database in SK_PNMI_STRUCT_DATA + * + * Description: + * Calls a general sub-function for all this set stuff. The preset does + * the same as a set, but returns just before finally setting the + * new value. This is usefull to check if a set might be successfull. + * The sub-function runs through the IdTable, checks which OIDs are able + * to set, and calls the handler function of the OID to perform the + * preset. The return value of the function will also be stored in + * SK_PNMI_STRUCT_DATA if the passed buffer has the minimum size of + * SK_PNMI_MIN_STRUCT_SIZE. + * + * Returns: + * SK_PNMI_ERR_OK The request was successfully performed. + * SK_PNMI_ERR_GENERAL A general severe internal error occured. + * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain + * the correct data (e.g. a 32bit value is + * needed, but a 16 bit value was passed). + * SK_PNMI_ERR_BAD_VALUE The passed value is not in the valid + * value range. + */ +int SkPnmiPreSetStruct( +SK_AC *pAC, /* Pointer to adapter context */ +SK_IOC IoC, /* IO context handle */ +void *pBuf, /* Buffer which contains the data to be set */ +unsigned int *pLen, /* Length of buffer */ +SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */ +{ + SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL, + ("PNMI: SkPnmiPreSetStruct: Called, BufLen=%d, NetIndex=%d\n", + *pLen, NetIndex)); + + return (PnmiStruct(pAC, IoC, SK_PNMI_PRESET, (char *)pBuf, + pLen, NetIndex)); +} + +/***************************************************************************** + * + * SkPnmiSetStruct - Sets the management database in SK_PNMI_STRUCT_DATA + * + * Description: + * Calls a general sub-function for all this set stuff. The return value + * of the function will also be stored in SK_PNMI_STRUCT_DATA if the + * passed buffer has the minimum size of SK_PNMI_MIN_STRUCT_SIZE. + * The sub-function runs through the IdTable, checks which OIDs are able + * to set, and calls the handler function of the OID to perform the + * set. The return value of the function will also be stored in + * SK_PNMI_STRUCT_DATA if the passed buffer has the minimum size of + * SK_PNMI_MIN_STRUCT_SIZE. + * + * Returns: + * SK_PNMI_ERR_OK The request was successfully performed. + * SK_PNMI_ERR_GENERAL A general severe internal error occured. + * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain + * the correct data (e.g. a 32bit value is + * needed, but a 16 bit value was passed). + * SK_PNMI_ERR_BAD_VALUE The passed value is not in the valid + * value range. + */ +int SkPnmiSetStruct( +SK_AC *pAC, /* Pointer to adapter context */ +SK_IOC IoC, /* IO context handle */ +void *pBuf, /* Buffer which contains the data to be set */ +unsigned int *pLen, /* Length of buffer */ +SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */ +{ + SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL, + ("PNMI: SkPnmiSetStruct: Called, BufLen=%d, NetIndex=%d\n", + *pLen, NetIndex)); + + return (PnmiStruct(pAC, IoC, SK_PNMI_SET, (char *)pBuf, + pLen, NetIndex)); +} + +/***************************************************************************** + * + * SkPnmiEvent - Event handler + * + * Description: + * Handles the following events: + * SK_PNMI_EVT_SIRQ_OVERFLOW When a hardware counter overflows an + * interrupt will be generated which is + * first handled by SIRQ which generates a + * this event. The event increments the + * upper 32 bit of the 64 bit counter. + * SK_PNMI_EVT_SEN_XXX The event is generated by the I2C module + * when a sensor reports a warning or + * error. The event will store a trap + * message in the trap buffer. + * SK_PNMI_EVT_CHG_EST_TIMER The timer event was initiated by this + * module and is used to calculate the + * port switches per hour. + * SK_PNMI_EVT_CLEAR_COUNTER The event clears all counters and + * timestamps. + * SK_PNMI_EVT_XMAC_RESET The event is generated by the driver + * before a hard reset of the XMAC is + * performed. All counters will be saved + * and added to the hardware counter + * values after reset to grant continuous + * counter values. + * SK_PNMI_EVT_RLMT_PORT_UP Generated by RLMT to notify that a port + * went logically up. A trap message will + * be stored to the trap buffer. + * SK_PNMI_EVT_RLMT_PORT_DOWN Generated by RLMT to notify that a port + * went logically down. A trap message will + * be stored to the trap buffer. + * SK_PNMI_EVT_RLMT_SEGMENTATION Generated by RLMT to notify that two + * spanning tree root bridges were + * detected. A trap message will be stored + * to the trap buffer. + * SK_PNMI_EVT_RLMT_ACTIVE_DOWN Notifies PNMI that an active port went + * down. PNMI will not further add the + * statistic values to the virtual port. + * SK_PNMI_EVT_RLMT_ACTIVE_UP Notifies PNMI that a port went up and + * is now an active port. PNMI will now + * add the statistic data of this port to + * the virtual port. + * SK_PNMI_EVT_RLMT_SET_NETS Notifies PNMI about the net mode. The first parameter + * contains the number of nets. 1 means single net, 2 means + * dual net. The second parameter is -1 + * + * Returns: + * Always 0 + */ +int SkPnmiEvent( +SK_AC *pAC, /* Pointer to adapter context */ +SK_IOC IoC, /* IO context handle */ +SK_U32 Event, /* Event-Id */ +SK_EVPARA Param) /* Event dependent parameter */ +{ + unsigned int PhysPortIndex; + unsigned int MaxNetNumber; + int CounterIndex; + SK_U16 MacStatus; + SK_U64 OverflowStatus; + SK_U64 Mask; + int MacType; + SK_U64 Value; + SK_U32 Val32; + SK_U16 Register; + SK_EVPARA EventParam; + SK_U64 NewestValue; + SK_U64 OldestValue; + SK_U64 Delta; + SK_PNMI_ESTIMATE *pEst; + SK_U32 NetIndex; + SK_U32 RetCode; + +#ifdef DEBUG + if (Event != SK_PNMI_EVT_XMAC_RESET) { + + SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL, + ("PNMI: SkPnmiEvent: Called, Event=0x%x, Param=0x%x\n", + (unsigned int)Event, (unsigned int)Param.Para64)); + } +#endif /* DEBUG */ + SK_PNMI_CHECKFLAGS("SkPnmiEvent: On call"); + + MacType = pAC->GIni.GIMacType; + + switch (Event) { + + case SK_PNMI_EVT_SIRQ_OVERFLOW: + PhysPortIndex = (int)Param.Para32[0]; + MacStatus = (SK_U16)Param.Para32[1]; +#ifdef DEBUG + if (PhysPortIndex >= SK_MAX_MACS) { + + SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL, + ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_SIRQ_OVERFLOW parameter" + " wrong, PhysPortIndex=0x%x\n", + PhysPortIndex)); + return (0); + } +#endif /* DEBUG */ + OverflowStatus = 0; + + /* Check which source caused an overflow interrupt. */ + if ((pAC->GIni.GIFunc.pFnMacOverflow(pAC, IoC, PhysPortIndex, + MacStatus, &OverflowStatus) != 0) || + (OverflowStatus == 0)) { + + SK_PNMI_CHECKFLAGS("SkPnmiEvent: On return"); + return (0); + } + + /* + * Check the overflow status register and increment + * the upper dword of corresponding counter. + */ + for (CounterIndex = 0; CounterIndex < sizeof(Mask) * 8; + CounterIndex ++) { + + Mask = (SK_U64)1 << CounterIndex; + if ((OverflowStatus & Mask) == 0) { + continue; + } + + switch (StatOvrflwBit[CounterIndex][MacType]) { + + case SK_PNMI_HTX_UTILUNDER: + case SK_PNMI_HTX_UTILOVER: + if (MacType == SK_MAC_XMAC) { + XM_IN16(IoC, PhysPortIndex, XM_TX_CMD, &Register); + Register |= XM_TX_SAM_LINE; + XM_OUT16(IoC, PhysPortIndex, XM_TX_CMD, Register); + } + break; + + case SK_PNMI_HRX_UTILUNDER: + case SK_PNMI_HRX_UTILOVER: + if (MacType == SK_MAC_XMAC) { + XM_IN16(IoC, PhysPortIndex, XM_RX_CMD, &Register); + Register |= XM_RX_SAM_LINE; + XM_OUT16(IoC, PhysPortIndex, XM_RX_CMD, Register); + } + break; + + case SK_PNMI_HTX_OCTETHIGH: + case SK_PNMI_HTX_OCTETLOW: + case SK_PNMI_HTX_RESERVED: + case SK_PNMI_HRX_OCTETHIGH: + case SK_PNMI_HRX_OCTETLOW: + case SK_PNMI_HRX_IRLENGTH: + case SK_PNMI_HRX_RESERVED: + + /* The following counters aren't be handled (id > 63). */ + case SK_PNMI_HTX_SYNC: + case SK_PNMI_HTX_SYNC_OCTET: + break; + + case SK_PNMI_HRX_LONGFRAMES: + if (MacType == SK_MAC_GMAC) { + pAC->Pnmi.Port[PhysPortIndex]. + CounterHigh[CounterIndex] ++; + } + break; + + default: + pAC->Pnmi.Port[PhysPortIndex]. + CounterHigh[CounterIndex] ++; + } + } + break; + + case SK_PNMI_EVT_SEN_WAR_LOW: +#ifdef DEBUG + if ((unsigned int)Param.Para64 >= (unsigned int)pAC->I2c.MaxSens) { + + SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL, + ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_SEN_WAR_LOW parameter wrong, SensorIndex=%d\n", + (unsigned int)Param.Para64)); + return (0); + } +#endif /* DEBUG */ + + /* + * Store a trap message in the trap buffer and generate + * an event for user space applications with the + * SK_DRIVER_SENDEVENT macro. + */ + QueueSensorTrap(pAC, OID_SKGE_TRAP_SEN_WAR_LOW, + (unsigned int)Param.Para64); + (void)SK_DRIVER_SENDEVENT(pAC, IoC); + break; + + case SK_PNMI_EVT_SEN_WAR_UPP: +#ifdef DEBUG + if ((unsigned int)Param.Para64 >= (unsigned int)pAC->I2c.MaxSens) { + + SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL, + ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_SEN_WAR_UPP parameter wrong, SensorIndex=%d\n", + (unsigned int)Param.Para64)); + return (0); + } +#endif /* DEBUG */ + + /* + * Store a trap message in the trap buffer and generate + * an event for user space applications with the + * SK_DRIVER_SENDEVENT macro. + */ + QueueSensorTrap(pAC, OID_SKGE_TRAP_SEN_WAR_UPP, + (unsigned int)Param.Para64); + (void)SK_DRIVER_SENDEVENT(pAC, IoC); + break; + + case SK_PNMI_EVT_SEN_ERR_LOW: +#ifdef DEBUG + if ((unsigned int)Param.Para64 >= (unsigned int)pAC->I2c.MaxSens) { + + SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL, + ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_SEN_ERR_LOW parameter wrong, SensorIndex=%d\n", + (unsigned int)Param.Para64)); + return (0); + } +#endif /* DEBUG */ + + /* + * Store a trap message in the trap buffer and generate + * an event for user space applications with the + * SK_DRIVER_SENDEVENT macro. + */ + QueueSensorTrap(pAC, OID_SKGE_TRAP_SEN_ERR_LOW, + (unsigned int)Param.Para64); + (void)SK_DRIVER_SENDEVENT(pAC, IoC); + break; + + case SK_PNMI_EVT_SEN_ERR_UPP: +#ifdef DEBUG + if ((unsigned int)Param.Para64 >= (unsigned int)pAC->I2c.MaxSens) { + + SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL, + ("PNMI: ERR: SK_PNMI_EVT_SEN_ERR_UPP parameter wrong, SensorIndex=%d\n", + (unsigned int)Param.Para64)); + return (0); + } +#endif /* DEBUG */ + + /* + * Store a trap message in the trap buffer and generate + * an event for user space applications with the + * SK_DRIVER_SENDEVENT macro. + */ + QueueSensorTrap(pAC, OID_SKGE_TRAP_SEN_ERR_UPP, + (unsigned int)Param.Para64); + (void)SK_DRIVER_SENDEVENT(pAC, IoC); + break; + + case SK_PNMI_EVT_CHG_EST_TIMER: + /* + * Calculate port switch average on a per hour basis + * Time interval for check : 28125 ms (SK_PNMI_EVT_TIMER_CHECK) + * Number of values for average : 8 + * + * Be careful in changing these values, on change check + * - typedef of SK_PNMI_ESTIMATE (Size of EstValue + * array one less than value number) + * - Timer initialization SkTimerStart() in SkPnmiInit + * - Delta value below must be multiplicated with power of 2 + */ + pEst = &pAC->Pnmi.RlmtChangeEstimate; + CounterIndex = pEst->EstValueIndex + 1; + if (CounterIndex == 7) { + + CounterIndex = 0; + } + pEst->EstValueIndex = CounterIndex; + + NewestValue = pAC->Pnmi.RlmtChangeCts; + OldestValue = pEst->EstValue[CounterIndex]; + pEst->EstValue[CounterIndex] = NewestValue; + + /* + * Calculate average. Delta stores the number of + * port switches per 28125 * 8 = 225000 ms + */ + if (NewestValue >= OldestValue) { + + Delta = NewestValue - OldestValue; + } + else { + /* Overflow situation. */ + Delta = (SK_U64)(0 - OldestValue) + NewestValue; + } + + /* + * Extrapolate delta to port switches per hour. + * Estimate = Delta * (3600000 / 225000) + * = Delta * 16 + * = Delta << 4 + */ + pAC->Pnmi.RlmtChangeEstimate.Estimate = Delta << 4; + + /* + * Check if threshold is exceeded. If the threshold is + * permanently exceeded every 28125 ms an event will be + * generated to remind the user of this condition. + */ + if ((pAC->Pnmi.RlmtChangeThreshold != 0) && + (pAC->Pnmi.RlmtChangeEstimate.Estimate >= + pAC->Pnmi.RlmtChangeThreshold)) { + + QueueSimpleTrap(pAC, OID_SKGE_TRAP_RLMT_CHANGE_THRES); + (void)SK_DRIVER_SENDEVENT(pAC, IoC); + } + + SK_MEMSET((char *)&EventParam, 0, sizeof(EventParam)); + + SkTimerStart(pAC, IoC, &pAC->Pnmi.RlmtChangeEstimate.EstTimer, + SK_PNMI_EVT_TIMER_CHECK, SKGE_PNMI, SK_PNMI_EVT_CHG_EST_TIMER, + EventParam); + break; + + case SK_PNMI_EVT_CLEAR_COUNTER: + /* + * Param.Para32[0] contains the NetIndex (0 ..1). + * Param.Para32[1] is reserved, contains -1. + */ + NetIndex = (SK_U32)Param.Para32[0]; + +#ifdef DEBUG + if (NetIndex >= pAC->Rlmt.NumNets) { + + SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL, + ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_CLEAR_COUNTER parameter wrong, NetIndex=%d\n", + NetIndex)); + + return (0); + } +#endif /* DEBUG */ + + /* + * Set all counters and timestamps to zero. + * The according NetIndex is required as a + * parameter of the event. + */ + ResetCounter(pAC, IoC, NetIndex); + break; + + case SK_PNMI_EVT_XMAC_RESET: + /* + * To grant continuous counter values store the current + * XMAC statistic values to the entries 1..n of the + * CounterOffset array. XMAC Errata #2 + */ +#ifdef DEBUG + if ((unsigned int)Param.Para64 >= SK_MAX_MACS) { + + SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL, + ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_XMAC_RESET parameter wrong, PhysPortIndex=%d\n", + (unsigned int)Param.Para64)); + return (0); + } +#endif /* DEBUG */ + + PhysPortIndex = (unsigned int)Param.Para64; + + /* Update XMAC statistic to get fresh values. */ + if (MacUpdate(pAC, IoC, 0, pAC->GIni.GIMacsFound - 1) != + SK_PNMI_ERR_OK) { + + SK_PNMI_CHECKFLAGS("SkPnmiEvent: On return"); + return (0); + } + + /* Increment semaphore to indicate that an update was already done. */ + pAC->Pnmi.MacUpdatedFlag ++; + + for (CounterIndex = 0; CounterIndex < SK_PNMI_MAX_IDX; + CounterIndex ++) { + + if (!StatAddr[CounterIndex][MacType].GetOffset) { + continue; + } + + pAC->Pnmi.Port[PhysPortIndex].CounterOffset[CounterIndex] = + GetPhysStatVal(pAC, IoC, PhysPortIndex, CounterIndex); + + pAC->Pnmi.Port[PhysPortIndex].CounterHigh[CounterIndex] = 0; + } + + pAC->Pnmi.MacUpdatedFlag --; + break; + + case SK_PNMI_EVT_RLMT_PORT_UP: + PhysPortIndex = (unsigned int)Param.Para32[0]; +#ifdef DEBUG + if (PhysPortIndex >= SK_MAX_MACS) { + + SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL, + ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_RLMT_PORT_UP parameter" + " wrong, PhysPortIndex=%d\n", PhysPortIndex)); + + return (0); + } +#endif /* DEBUG */ + + /* + * Store a trap message in the trap buffer and generate an event for + * user space applications with the SK_DRIVER_SENDEVENT macro. + */ + QueueRlmtPortTrap(pAC, OID_SKGE_TRAP_RLMT_PORT_UP, PhysPortIndex); + (void)SK_DRIVER_SENDEVENT(pAC, IoC); + + /* Bugfix for XMAC errata (#10620). */ + if (MacType == SK_MAC_XMAC) { + /* Add incremental difference to offset (#10620). */ + (void)pAC->GIni.GIFunc.pFnMacStatistic(pAC, IoC, PhysPortIndex, + XM_RXE_SHT_ERR, &Val32); + + Value = (((SK_U64)pAC->Pnmi.Port[PhysPortIndex]. + CounterHigh[SK_PNMI_HRX_SHORTS] << 32) | (SK_U64)Val32); + + pAC->Pnmi.Port[PhysPortIndex].CounterOffset[SK_PNMI_HRX_SHORTS] += + Value - pAC->Pnmi.Port[PhysPortIndex].RxShortZeroMark; + } + + /* Tell VctStatus() that a link was up meanwhile. */ + pAC->Pnmi.VctStatus[PhysPortIndex] |= SK_PNMI_VCT_LINK; + break; + + case SK_PNMI_EVT_RLMT_PORT_DOWN: + PhysPortIndex = (unsigned int)Param.Para32[0]; + +#ifdef DEBUG + if (PhysPortIndex >= SK_MAX_MACS) { + + SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL, + ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_RLMT_PORT_DOWN parameter" + " wrong, PhysPortIndex=%d\n", PhysPortIndex)); + + return (0); + } +#endif /* DEBUG */ + + /* + * Store a trap message in the trap buffer and generate an event for + * user space applications with the SK_DRIVER_SENDEVENT macro. + */ + QueueRlmtPortTrap(pAC, OID_SKGE_TRAP_RLMT_PORT_DOWN, PhysPortIndex); + (void)SK_DRIVER_SENDEVENT(pAC, IoC); + + /* Bugfix #10620 - get zero level for incremental difference. */ + if (MacType == SK_MAC_XMAC) { + + (void)pAC->GIni.GIFunc.pFnMacStatistic(pAC, IoC, PhysPortIndex, + XM_RXE_SHT_ERR, &Val32); + + pAC->Pnmi.Port[PhysPortIndex].RxShortZeroMark = + (((SK_U64)pAC->Pnmi.Port[PhysPortIndex]. + CounterHigh[SK_PNMI_HRX_SHORTS] << 32) | (SK_U64)Val32); + } + break; + + case SK_PNMI_EVT_RLMT_ACTIVE_DOWN: + PhysPortIndex = (unsigned int)Param.Para32[0]; + NetIndex = (SK_U32)Param.Para32[1]; + +#ifdef DEBUG + if (PhysPortIndex >= SK_MAX_MACS) { + + SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL, + ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_RLMT_ACTIVE_DOWN parameter too high, PhysPort=%d\n", + PhysPortIndex)); + } + + if (NetIndex >= pAC->Rlmt.NumNets) { + + SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL, + ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_RLMT_ACTIVE_DOWN parameter too high, NetIndex=%d\n", + NetIndex)); + } +#endif /* DEBUG */ + + /* For now, ignore event if NetIndex != 0. */ + if (Param.Para32[1] != 0) { + + return (0); + } + + /* Nothing to do if port is already inactive. */ + if (!pAC->Pnmi.Port[PhysPortIndex].ActiveFlag) { + + return (0); + } + + /* + * Update statistic counters to calculate new offset for the virtual + * port and increment semaphore to indicate that an update was already + * done. + */ + if (MacUpdate(pAC, IoC, 0, pAC->GIni.GIMacsFound - 1) != + SK_PNMI_ERR_OK) { + + SK_PNMI_CHECKFLAGS("SkPnmiEvent: On return"); + return (0); + } + pAC->Pnmi.MacUpdatedFlag ++; + + /* + * Calculate new counter offset for virtual port to grant continous + * counting on port switches. The virtual port consists of all currently + * active ports. The port down event indicates that a port is removed + * from the virtual port. Therefore add the counter value of the removed + * port to the CounterOffset for the virtual port to grant the same + * counter value. + */ + for (CounterIndex = 0; CounterIndex < SK_PNMI_MAX_IDX; + CounterIndex ++) { + + if (!StatAddr[CounterIndex][MacType].GetOffset) { + continue; + } + + Value = GetPhysStatVal(pAC, IoC, PhysPortIndex, CounterIndex); + + pAC->Pnmi.VirtualCounterOffset[CounterIndex] += Value; + } + + /* Set port to inactive. */ + pAC->Pnmi.Port[PhysPortIndex].ActiveFlag = SK_FALSE; + + pAC->Pnmi.MacUpdatedFlag --; + break; + + case SK_PNMI_EVT_RLMT_ACTIVE_UP: + PhysPortIndex = (unsigned int)Param.Para32[0]; + NetIndex = (SK_U32)Param.Para32[1]; + +#ifdef DEBUG + if (PhysPortIndex >= SK_MAX_MACS) { + + SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL, + ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_RLMT_ACTIVE_UP parameter too high, PhysPort=%d\n", + PhysPortIndex)); + } + + if (NetIndex >= pAC->Rlmt.NumNets) { + + SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL, + ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_RLMT_ACTIVE_UP parameter too high, NetIndex=%d\n", + NetIndex)); + } +#endif /* DEBUG */ + + /* For now, ignore event if NetIndex != 0. */ + if (Param.Para32[1] != 0) { + + return (0); + } + + /* Nothing to do if port is already inactive. */ + if (pAC->Pnmi.Port[PhysPortIndex].ActiveFlag) { + + return (0); + } + + /* Statistic maintenance. */ + pAC->Pnmi.RlmtChangeCts ++; + pAC->Pnmi.RlmtChangeTime = SK_PNMI_HUNDREDS_SEC(SkOsGetTime(pAC)); + + /* + * Store a trap message in the trap buffer and generate an event for + * user space applications with the SK_DRIVER_SENDEVENT macro. + */ + QueueRlmtNewMacTrap(pAC, PhysPortIndex); + (void)SK_DRIVER_SENDEVENT(pAC, IoC); + + /* + * Update statistic counters to calculate new offset for the virtual + * port and increment semaphore to indicate that an update was + * already done. + */ + if (MacUpdate(pAC, IoC, 0, pAC->GIni.GIMacsFound - 1) != + SK_PNMI_ERR_OK) { + + SK_PNMI_CHECKFLAGS("SkPnmiEvent: On return"); + return (0); + } + pAC->Pnmi.MacUpdatedFlag ++; + + /* + * Calculate new counter offset for virtual port to grant continous + * counting on port switches. A new port is added to the virtual port. + * Therefore substract the counter value of the new port from the + * CounterOffset for the virtual port to grant the same value. + */ + for (CounterIndex = 0; CounterIndex < SK_PNMI_MAX_IDX; + CounterIndex ++) { + + if (!StatAddr[CounterIndex][MacType].GetOffset) { + continue; + } + + Value = GetPhysStatVal(pAC, IoC, PhysPortIndex, CounterIndex); + + pAC->Pnmi.VirtualCounterOffset[CounterIndex] -= Value; + } + + /* Set port to active. */ + pAC->Pnmi.Port[PhysPortIndex].ActiveFlag = SK_TRUE; + + pAC->Pnmi.MacUpdatedFlag --; + break; + + case SK_PNMI_EVT_RLMT_SEGMENTATION: + /* Para.Para32[0] contains the NetIndex. */ + + /* + * Store a trap message in the trap buffer and generate an event for + * user space applications with the SK_DRIVER_SENDEVENT macro. + */ + QueueSimpleTrap(pAC, OID_SKGE_TRAP_RLMT_SEGMENTATION); + (void)SK_DRIVER_SENDEVENT(pAC, IoC); + break; + + case SK_PNMI_EVT_RLMT_SET_NETS: + /* + * Param.Para32[0] contains the number of Nets. + * Param.Para32[1] is reserved, contains -1. + */ + /* Check number of nets. */ + MaxNetNumber = pAC->GIni.GIMacsFound; + + if (((unsigned int)Param.Para32[0] < 1) || + ((unsigned int)Param.Para32[0] > MaxNetNumber)) { + + return (SK_PNMI_ERR_UNKNOWN_NET); + } + + if ((unsigned int)Param.Para32[0] == 1) { /* SingleNet mode. */ + pAC->Pnmi.DualNetActiveFlag = SK_FALSE; + } + else { /* DualNet mode. */ + pAC->Pnmi.DualNetActiveFlag = SK_TRUE; + } + break; + + case SK_PNMI_EVT_VCT_RESET: + PhysPortIndex = Param.Para32[0]; + + if (pAC->Pnmi.VctStatus[PhysPortIndex] & SK_PNMI_VCT_PENDING) { + + RetCode = SkGmCableDiagStatus(pAC, IoC, PhysPortIndex, SK_FALSE); + + if (RetCode == 2) { + /* + * VCT test is still running. + * Start VCT timer counter again. + */ + SK_MEMSET((char *)&Param, 0, sizeof(Param)); + + Param.Para32[0] = PhysPortIndex; + Param.Para32[1] = -1; + + SkTimerStart(pAC, IoC, &pAC->Pnmi.VctTimeout[PhysPortIndex], + SK_PNMI_VCT_TIMER_CHECK, SKGE_PNMI, SK_PNMI_EVT_VCT_RESET, Param); + + break; + } + + VctGetResults(pAC, IoC, PhysPortIndex); + + EventParam.Para32[0] = PhysPortIndex; + EventParam.Para32[1] = -1; + SkEventQueue(pAC, SKGE_DRV, SK_DRV_PORT_RESET, EventParam); + + /* SkEventDispatcher(pAC, IoC); */ + } + + break; + + default: + break; + } + + SK_PNMI_CHECKFLAGS("SkPnmiEvent: On return"); + return (0); +} + + +/****************************************************************************** + * + * Private functions + * + */ + +/***************************************************************************** + * + * PnmiVar - Gets, presets, and sets single OIDs + * + * Description: + * Looks up the requested OID, calls the corresponding handler + * function, and passes the parameters with the get, preset, or + * set command. The function is called by SkGePnmiGetVar, + * SkGePnmiPreSetVar, or SkGePnmiSetVar. + * + * Returns: + * SK_PNMI_ERR_XXX. For details have a look at the description of the + * calling functions. + * SK_PNMI_ERR_UNKNOWN_NET The requested NetIndex doesn't exist + */ +PNMI_STATIC int PnmiVar( +SK_AC *pAC, /* Pointer to adapter context */ +SK_IOC IoC, /* IO context handle */ +int Action, /* GET/PRESET/SET action */ +SK_U32 Id, /* Object ID that is to be processed */ +char *pBuf, /* Buffer used for the management data transfer */ +unsigned int *pLen, /* Total length of pBuf management data */ +SK_U32 Instance, /* Instance (1..n) that is to be set or -1 */ +SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */ +{ + unsigned int TableIndex; + int Ret; + + if ((TableIndex = LookupId(Id)) == (unsigned int)(-1)) { + + *pLen = 0; + return (SK_PNMI_ERR_UNKNOWN_OID); + } + + /* Check NetIndex. */ + if (NetIndex >= pAC->Rlmt.NumNets) { + return (SK_PNMI_ERR_UNKNOWN_NET); + } + + SK_PNMI_CHECKFLAGS("PnmiVar: On call"); + + Ret = IdTable[TableIndex].Func(pAC, IoC, Action, Id, pBuf, pLen, + Instance, TableIndex, NetIndex); + + SK_PNMI_CHECKFLAGS("PnmiVar: On return"); + + return (Ret); +} + +/***************************************************************************** + * + * PnmiStruct - Presets and Sets data in structure SK_PNMI_STRUCT_DATA + * + * Description: + * The return value of the function will also be stored in + * SK_PNMI_STRUCT_DATA if the passed buffer has the minimum size of + * SK_PNMI_MIN_STRUCT_SIZE. The sub-function runs through the IdTable, + * checks which OIDs are able to set, and calls the handler function of + * the OID to perform the set. The return value of the function will + * also be stored in SK_PNMI_STRUCT_DATA if the passed buffer has the + * minimum size of SK_PNMI_MIN_STRUCT_SIZE. The function is called + * by SkGePnmiPreSetStruct and SkGePnmiSetStruct. + * + * Returns: + * SK_PNMI_ERR_XXX. The codes are described in the calling functions. + * SK_PNMI_ERR_UNKNOWN_NET The requested NetIndex doesn't exist + */ +PNMI_STATIC int PnmiStruct( +SK_AC *pAC, /* Pointer to adapter context */ +SK_IOC IoC, /* IO context handle */ +int Action, /* PRESET/SET action to be performed */ +char *pBuf, /* Buffer used for the management data transfer */ +unsigned int *pLen, /* Length of pBuf management data buffer */ +SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */ +{ + int Ret; + unsigned int TableIndex; + unsigned int DstOffset; + unsigned int Len; + unsigned int InstanceNo; + unsigned int InstanceCnt; + SK_U32 Instance; + SK_U32 Id; + + /* Check if the passed buffer has the right size. */ + if (*pLen < SK_PNMI_STRUCT_SIZE) { + + /* Check if we can return the error within the buffer. */ + if (*pLen >= SK_PNMI_MIN_STRUCT_SIZE) { + + SK_PNMI_SET_STAT(pBuf, SK_PNMI_ERR_TOO_SHORT, (SK_U32)(-1)); + } + + *pLen = SK_PNMI_STRUCT_SIZE; + return (SK_PNMI_ERR_TOO_SHORT); + } + + /* Check NetIndex. */ + if (NetIndex >= pAC->Rlmt.NumNets) { + return (SK_PNMI_ERR_UNKNOWN_NET); + } + + SK_PNMI_CHECKFLAGS("PnmiStruct: On call"); + + /* + * Update the values of RLMT and SIRQ and increment semaphores to + * indicate that an update was already done. + */ + if ((Ret = RlmtUpdate(pAC, IoC, NetIndex)) != SK_PNMI_ERR_OK) { + + SK_PNMI_SET_STAT(pBuf, Ret, (SK_U32)(-1)); + *pLen = SK_PNMI_MIN_STRUCT_SIZE; + return (Ret); + } + + if ((Ret = SirqUpdate(pAC, IoC)) != SK_PNMI_ERR_OK) { + + SK_PNMI_SET_STAT(pBuf, Ret, (SK_U32)(-1)); + *pLen = SK_PNMI_MIN_STRUCT_SIZE; + return (Ret); + } + + pAC->Pnmi.RlmtUpdatedFlag ++; + pAC->Pnmi.SirqUpdatedFlag ++; + + /* PRESET/SET values. */ + for (TableIndex = 0; TableIndex < ID_TABLE_SIZE; TableIndex ++) { + + if ((IdTable[TableIndex].Access != SK_PNMI_RW) && + (IdTable[TableIndex].Access != SK_PNMI_WO)) { + continue; + } + + InstanceNo = IdTable[TableIndex].InstanceNo; + Id = IdTable[TableIndex].Id; + + for (InstanceCnt = 1; InstanceCnt <= InstanceNo; + InstanceCnt ++) { + + DstOffset = IdTable[TableIndex].Offset + + (InstanceCnt - 1) * IdTable[TableIndex].StructSize; + + /* + * Because VPD multiple instance variables are + * not setable we do not need to evaluate VPD + * instances. Have a look to VPD instance + * calculation in SkPnmiGetStruct(). + */ + Instance = (SK_U32)InstanceCnt; + + /* Evaluate needed buffer length. */ + Len = 0; + Ret = IdTable[TableIndex].Func(pAC, IoC, + SK_PNMI_GET, IdTable[TableIndex].Id, + NULL, &Len, Instance, TableIndex, NetIndex); + + if (Ret == SK_PNMI_ERR_UNKNOWN_INST) { + + break; + } + if (Ret != SK_PNMI_ERR_TOO_SHORT) { + + pAC->Pnmi.RlmtUpdatedFlag --; + pAC->Pnmi.SirqUpdatedFlag --; + + SK_PNMI_CHECKFLAGS("PnmiStruct: On return"); + SK_PNMI_SET_STAT(pBuf, SK_PNMI_ERR_GENERAL, DstOffset); + *pLen = SK_PNMI_MIN_STRUCT_SIZE; + return (SK_PNMI_ERR_GENERAL); + } + if (Id == OID_SKGE_VPD_ACTION) { + + switch (*(pBuf + DstOffset)) { + + case SK_PNMI_VPD_CREATE: + Len = 3 + *(pBuf + DstOffset + 3); + break; + + case SK_PNMI_VPD_DELETE: + Len = 3; + break; + + default: + Len = 1; + break; + } + } + + /* Call the OID handler function. */ + Ret = IdTable[TableIndex].Func(pAC, IoC, Action, + IdTable[TableIndex].Id, pBuf + DstOffset, + &Len, Instance, TableIndex, NetIndex); + + if (Ret != SK_PNMI_ERR_OK) { + + pAC->Pnmi.RlmtUpdatedFlag --; + pAC->Pnmi.SirqUpdatedFlag --; + + SK_PNMI_CHECKFLAGS("PnmiStruct: On return"); + SK_PNMI_SET_STAT(pBuf, SK_PNMI_ERR_BAD_VALUE, DstOffset); + *pLen = SK_PNMI_MIN_STRUCT_SIZE; + return (SK_PNMI_ERR_BAD_VALUE); + } + } + } + + pAC->Pnmi.RlmtUpdatedFlag --; + pAC->Pnmi.SirqUpdatedFlag --; + + SK_PNMI_CHECKFLAGS("PnmiStruct: On return"); + SK_PNMI_SET_STAT(pBuf, SK_PNMI_ERR_OK, (SK_U32)(-1)); + return (SK_PNMI_ERR_OK); +} + +/***************************************************************************** + * + * LookupId - Lookup an OID in the IdTable + * + * Description: + * Scans the IdTable to find the table entry of an OID. + * + * Returns: + * The table index or -1 if not found. + */ +PNMI_STATIC int LookupId( +SK_U32 Id) /* Object identifier to be searched */ +{ + int i; + + for (i = 0; i < ID_TABLE_SIZE; i++) { + + if (IdTable[i].Id == Id) { + + return (i); + } + } + + return (-1); +} + +/***************************************************************************** + * + * OidStruct - Handler of OID_SKGE_ALL_DATA + * + * Description: + * This OID performs a Get/Preset/SetStruct call and returns all data + * in a SK_PNMI_STRUCT_DATA structure. + * + * Returns: + * SK_PNMI_ERR_OK The request was successfully performed. + * SK_PNMI_ERR_GENERAL A general severe internal error occured. + * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain + * the correct data (e.g. a 32bit value is + * needed, but a 16 bit value was passed). + * SK_PNMI_ERR_BAD_VALUE The passed value is not in the valid + * value range. + * SK_PNMI_ERR_READ_ONLY The OID is read-only and cannot be set. + * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't + * exist (e.g. port instance 3 on a two port + * adapter. + */ +PNMI_STATIC int OidStruct( +SK_AC *pAC, /* Pointer to adapter context */ +SK_IOC IoC, /* IO context handle */ +int Action, /* GET/PRESET/SET action */ +SK_U32 Id, /* Object ID that is to be processed */ +char *pBuf, /* Buffer used for the management data transfer */ +unsigned int *pLen, /* On call: pBuf buffer length. On return: used buffer */ +SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */ +unsigned int TableIndex, /* Index to the Id table */ +SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */ +{ + if (Id != OID_SKGE_ALL_DATA) { + + SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR003, SK_PNMI_ERR003MSG); + + *pLen = 0; + return (SK_PNMI_ERR_GENERAL); + } + + /* Check instance. We only handle single instance variables. */ + if (Instance != (SK_U32)(-1) && Instance != 1) { + + *pLen = 0; + return (SK_PNMI_ERR_UNKNOWN_INST); + } + + switch (Action) { + + case SK_PNMI_GET: + return (SkPnmiGetStruct(pAC, IoC, pBuf, pLen, NetIndex)); + + case SK_PNMI_PRESET: + return (SkPnmiPreSetStruct(pAC, IoC, pBuf, pLen, NetIndex)); + + case SK_PNMI_SET: + return (SkPnmiSetStruct(pAC, IoC, pBuf, pLen, NetIndex)); + } + + SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR004, SK_PNMI_ERR004MSG); + + *pLen = 0; + return (SK_PNMI_ERR_GENERAL); +} + +/***************************************************************************** + * + * Perform - OID handler of OID_SKGE_ACTION + * + * Description: + * None. + * + * Returns: + * SK_PNMI_ERR_OK The request was successfully performed. + * SK_PNMI_ERR_GENERAL A general severe internal error occured. + * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain + * the correct data (e.g. a 32bit value is + * needed, but a 16 bit value was passed). + * SK_PNMI_ERR_BAD_VALUE The passed value is not in the valid + * value range. + * SK_PNMI_ERR_READ_ONLY The OID is read-only and cannot be set. + * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't + * exist (e.g. port instance 3 on a two port + * adapter. + */ +PNMI_STATIC int Perform( +SK_AC *pAC, /* Pointer to adapter context */ +SK_IOC IoC, /* IO context handle */ +int Action, /* GET/PRESET/SET action */ +SK_U32 Id, /* Object ID that is to be processed */ +char *pBuf, /* Buffer used for the management data transfer */ +unsigned int *pLen, /* On call: pBuf buffer length. On return: used buffer */ +SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */ +unsigned int TableIndex, /* Index to the Id table */ +SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */ +{ + int Ret; + SK_U32 ActionOp; + + /* Check instance. We only handle single instance variables. */ + if (Instance != (SK_U32)(-1) && Instance != 1) { + + *pLen = 0; + return (SK_PNMI_ERR_UNKNOWN_INST); + } + + if (*pLen < sizeof(SK_U32)) { + + *pLen = sizeof(SK_U32); + return (SK_PNMI_ERR_TOO_SHORT); + } + + /* Check if a GET should be performed. */ + if (Action == SK_PNMI_GET) { + + /* A GET is easy. We always return the same value. */ + ActionOp = (SK_U32)SK_PNMI_ACT_IDLE; + SK_PNMI_STORE_U32(pBuf, ActionOp); + *pLen = sizeof(SK_U32); + + return (SK_PNMI_ERR_OK); + } + + /* Continue with PRESET/SET action. */ + if (*pLen > sizeof(SK_U32)) { + + return (SK_PNMI_ERR_BAD_VALUE); + } + + /* Check if the command is a known one. */ + SK_PNMI_READ_U32(pBuf, ActionOp); + if (*pLen > sizeof(SK_U32) || + (ActionOp != SK_PNMI_ACT_IDLE && + ActionOp != SK_PNMI_ACT_RESET && + ActionOp != SK_PNMI_ACT_SELFTEST && + ActionOp != SK_PNMI_ACT_RESETCNT)) { + + *pLen = 0; + return (SK_PNMI_ERR_BAD_VALUE); + } + + /* A PRESET ends here. */ + if (Action == SK_PNMI_PRESET) { + + return (SK_PNMI_ERR_OK); + } + + switch (ActionOp) { + + case SK_PNMI_ACT_IDLE: + /* Nothing to do. */ + break; + + case SK_PNMI_ACT_RESET: + /* Perform a driver reset or something that comes near to this. */ + Ret = SK_DRIVER_RESET(pAC, IoC); + if (Ret != 0) { + + SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR005, SK_PNMI_ERR005MSG); + + return (SK_PNMI_ERR_GENERAL); + } + break; + + case SK_PNMI_ACT_SELFTEST: + /* + * Perform a driver selftest or something similar to this. + * Currently this feature is not used and will probably + * implemented in another way. + */ + Ret = SK_DRIVER_SELFTEST(pAC, IoC); + pAC->Pnmi.TestResult = Ret; + break; + + case SK_PNMI_ACT_RESETCNT: + /* Set all counters and timestamps to zero. */ + ResetCounter(pAC, IoC, NetIndex); + break; + + default: + SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR006, SK_PNMI_ERR006MSG); + + return (SK_PNMI_ERR_GENERAL); + } + + return (SK_PNMI_ERR_OK); +} + +/***************************************************************************** + * + * Mac8023Stat - OID handler of OID_GEN_XXX and OID_802_3_XXX + * + * Description: + * Retrieves the statistic values of the virtual port (logical + * index 0). Only special OIDs of NDIS are handled which consist + * of a 32 bit instead of a 64 bit value. The OIDs are public + * because perhaps some other platform can use them too. + * + * Returns: + * SK_PNMI_ERR_OK The request was successfully performed. + * SK_PNMI_ERR_GENERAL A general severe internal error occured. + * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain + * the correct data (e.g. a 32bit value is + * needed, but a 16 bit value was passed). + * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't + * exist (e.g. port instance 3 on a two port + * adapter. + */ +PNMI_STATIC int Mac8023Stat( +SK_AC *pAC, /* Pointer to adapter context */ +SK_IOC IoC, /* IO context handle */ +int Action, /* GET/PRESET/SET action */ +SK_U32 Id, /* Object ID that is to be processed */ +char *pBuf, /* Buffer used for the management data transfer */ +unsigned int *pLen, /* On call: pBuf buffer length. On return: used buffer */ +SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */ +unsigned int TableIndex, /* Index to the Id table */ +SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */ +{ + int Ret; + SK_U64 StatVal; + SK_U32 StatVal32; + SK_BOOL Is64BitReq = SK_FALSE; + + /* Only the active MAC is returned. */ + if (Instance != (SK_U32)(-1) && Instance != 1) { + + *pLen = 0; + return (SK_PNMI_ERR_UNKNOWN_INST); + } + + /* Check action type. */ + if (Action != SK_PNMI_GET) { + + *pLen = 0; + return (SK_PNMI_ERR_READ_ONLY); + } + + /* Check length. */ + switch (Id) { + + case OID_802_3_PERMANENT_ADDRESS: + case OID_802_3_CURRENT_ADDRESS: + if (*pLen < sizeof(SK_MAC_ADDR)) { + + *pLen = sizeof(SK_MAC_ADDR); + return (SK_PNMI_ERR_TOO_SHORT); + } + break; + + default: +#ifndef SK_NDIS_64BIT_CTR + if (*pLen < sizeof(SK_U32)) { + *pLen = sizeof(SK_U32); + return (SK_PNMI_ERR_TOO_SHORT); + } + +#else /* SK_NDIS_64BIT_CTR */ + + /* For compatibility, at least 32 bits are required for OID. */ + if (*pLen < sizeof(SK_U32)) { + /* + * Indicate handling for 64 bit values, + * if insufficient space is provided. + */ + *pLen = sizeof(SK_U64); + return (SK_PNMI_ERR_TOO_SHORT); + } + + Is64BitReq = (*pLen < sizeof(SK_U64)) ? SK_FALSE : SK_TRUE; +#endif /* SK_NDIS_64BIT_CTR */ + break; + } + + /* + * Update all statistics, because we retrieve virtual MAC, which + * consists of multiple physical statistics and increment semaphore + * to indicate that an update was already done. + */ + Ret = MacUpdate(pAC, IoC, 0, pAC->GIni.GIMacsFound - 1); + if (Ret != SK_PNMI_ERR_OK) { + + *pLen = 0; + return (Ret); + } + pAC->Pnmi.MacUpdatedFlag ++; + + /* Get value (MAC index 0 identifies the virtual MAC). */ + switch (Id) { + + case OID_802_3_PERMANENT_ADDRESS: + CopyMac(pBuf, &pAC->Addr.Net[NetIndex].PermanentMacAddress); + *pLen = sizeof(SK_MAC_ADDR); + break; + + case OID_802_3_CURRENT_ADDRESS: + CopyMac(pBuf, &pAC->Addr.Net[NetIndex].CurrentMacAddress); + *pLen = sizeof(SK_MAC_ADDR); + break; + + default: + StatVal = GetStatVal(pAC, IoC, 0, IdTable[TableIndex].Param, NetIndex); + + /* By default 32 bit values are evaluated. */ + if (!Is64BitReq) { + StatVal32 = (SK_U32)StatVal; + SK_PNMI_STORE_U32(pBuf, StatVal32); + *pLen = sizeof(SK_U32); + } + else { + SK_PNMI_STORE_U64(pBuf, StatVal); + *pLen = sizeof(SK_U64); + } + break; + } + + pAC->Pnmi.MacUpdatedFlag --; + + return (SK_PNMI_ERR_OK); +} + +/***************************************************************************** + * + * MacPrivateStat - OID handler function of OID_SKGE_STAT_XXX + * + * Description: + * Retrieves the MAC statistic data. + * + * Returns: + * SK_PNMI_ERR_OK The request was successfully performed. + * SK_PNMI_ERR_GENERAL A general severe internal error occured. + * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain + * the correct data (e.g. a 32bit value is + * needed, but a 16 bit value was passed). + * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't + * exist (e.g. port instance 3 on a two port + * adapter. + */ +PNMI_STATIC int MacPrivateStat( +SK_AC *pAC, /* Pointer to adapter context */ +SK_IOC IoC, /* IO context handle */ +int Action, /* GET/PRESET/SET action */ +SK_U32 Id, /* Object ID that is to be processed */ +char *pBuf, /* Buffer used for the management data transfer */ +unsigned int *pLen, /* On call: pBuf buffer length. On return: used buffer */ +SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */ +unsigned int TableIndex, /* Index to the Id table */ +SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */ +{ + unsigned int LogPortMax; + unsigned int LogPortIndex; + unsigned int PhysPortMax; + unsigned int Limit; + unsigned int Offset; + int MacType; + int Ret; + SK_U64 StatVal; + + /* Calculate instance if wished. MAC index 0 is the virtual MAC. */ + PhysPortMax = pAC->GIni.GIMacsFound; + LogPortMax = SK_PNMI_PORT_PHYS2LOG(PhysPortMax); + + MacType = pAC->GIni.GIMacType; + + if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { /* DualNet mode. */ + LogPortMax--; + } + + if ((Instance != (SK_U32)(-1))) { /* Only one specific instance is queried. */ + /* Check instance range. */ + if ((Instance < 1) || (Instance > LogPortMax)) { + + *pLen = 0; + return (SK_PNMI_ERR_UNKNOWN_INST); + } + LogPortIndex = SK_PNMI_PORT_INST2LOG(Instance); + Limit = LogPortIndex + 1; + } + + else { /* Instance == (SK_U32)(-1), get all Instances of that OID. */ + + LogPortIndex = 0; + Limit = LogPortMax; + } + + /* Check action. */ + if (Action != SK_PNMI_GET) { + + *pLen = 0; + return (SK_PNMI_ERR_READ_ONLY); + } + + /* Check length. */ + if (*pLen < (Limit - LogPortIndex) * sizeof(SK_U64)) { + + *pLen = (Limit - LogPortIndex) * sizeof(SK_U64); + return (SK_PNMI_ERR_TOO_SHORT); + } + + /* + * Update MAC statistic and increment semaphore to indicate that + * an update was already done. + */ + Ret = MacUpdate(pAC, IoC, 0, pAC->GIni.GIMacsFound - 1); + if (Ret != SK_PNMI_ERR_OK) { + + *pLen = 0; + return (Ret); + } + pAC->Pnmi.MacUpdatedFlag ++; + + /* Get value. */ + Offset = 0; + for (; LogPortIndex < Limit; LogPortIndex ++) { + + switch (Id) { + +/* XXX not yet implemented due to XMAC problems + case OID_SKGE_STAT_TX_UTIL: + return (SK_PNMI_ERR_GENERAL); +*/ +/* XXX not yet implemented due to XMAC problems + case OID_SKGE_STAT_RX_UTIL: + return (SK_PNMI_ERR_GENERAL); +*/ + case OID_SKGE_STAT_RX: + if (MacType == SK_MAC_GMAC) { + StatVal = + GetStatVal(pAC, IoC, LogPortIndex, + SK_PNMI_HRX_BROADCAST, NetIndex) + + GetStatVal(pAC, IoC, LogPortIndex, + SK_PNMI_HRX_MULTICAST, NetIndex) + + GetStatVal(pAC, IoC, LogPortIndex, + SK_PNMI_HRX_UNICAST, NetIndex) + + GetStatVal(pAC, IoC, LogPortIndex, + SK_PNMI_HRX_UNDERSIZE, NetIndex); + } + else { + StatVal = GetStatVal(pAC, IoC, LogPortIndex, + IdTable[TableIndex].Param, NetIndex); + } + break; + + case OID_SKGE_STAT_TX: + if (MacType == SK_MAC_GMAC) { + StatVal = + GetStatVal(pAC, IoC, LogPortIndex, + SK_PNMI_HTX_BROADCAST, NetIndex) + + GetStatVal(pAC, IoC, LogPortIndex, + SK_PNMI_HTX_MULTICAST, NetIndex) + + GetStatVal(pAC, IoC, LogPortIndex, + SK_PNMI_HTX_UNICAST, NetIndex); + } + else { + StatVal = GetStatVal(pAC, IoC, LogPortIndex, + IdTable[TableIndex].Param, NetIndex); + } + break; + + default: + StatVal = GetStatVal(pAC, IoC, LogPortIndex, + IdTable[TableIndex].Param, NetIndex); + } + SK_PNMI_STORE_U64(pBuf + Offset, StatVal); + + Offset += sizeof(SK_U64); + } + *pLen = Offset; + + pAC->Pnmi.MacUpdatedFlag --; + + return (SK_PNMI_ERR_OK); +} + +/***************************************************************************** + * + * Addr - OID handler function of OID_SKGE_PHYS_CUR_ADDR and _FAC_ADDR + * + * Description: + * Get/Presets/Sets the current and factory MAC address. The MAC + * address of the virtual port, which is reported to the OS, may + * not be changed, but the physical ones. A set to the virtual port + * will be ignored. No error should be reported because otherwise + * a multiple instance set (-1) would always fail. + * + * Returns: + * SK_PNMI_ERR_OK The request was successfully performed. + * SK_PNMI_ERR_GENERAL A general severe internal error occured. + * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain + * the correct data (e.g. a 32bit value is + * needed, but a 16 bit value was passed). + * SK_PNMI_ERR_BAD_VALUE The passed value is not in the valid + * value range. + * SK_PNMI_ERR_READ_ONLY The OID is read-only and cannot be set. + * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't + * exist (e.g. port instance 3 on a two port + * adapter. + */ +PNMI_STATIC int Addr( +SK_AC *pAC, /* Pointer to adapter context */ +SK_IOC IoC, /* IO context handle */ +int Action, /* GET/PRESET/SET action */ +SK_U32 Id, /* Object ID that is to be processed */ +char *pBuf, /* Buffer used for the management data transfer */ +unsigned int *pLen, /* On call: pBuf buffer length. On return: used buffer */ +SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */ +unsigned int TableIndex, /* Index to the Id table */ +SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */ +{ + int Ret; + unsigned int LogPortMax; + unsigned int PhysPortMax; + unsigned int LogPortIndex; + unsigned int PhysPortIndex; + unsigned int Limit; + unsigned int Offset = 0; + + /* Calculate instance if wished. MAC index 0 is the virtual MAC. */ + PhysPortMax = pAC->GIni.GIMacsFound; + LogPortMax = SK_PNMI_PORT_PHYS2LOG(PhysPortMax); + + if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { /* DualNet mode. */ + LogPortMax--; + } + + if ((Instance != (SK_U32)(-1))) { /* Only one specific instance is queried. */ + /* Check instance range. */ + if ((Instance < 1) || (Instance > LogPortMax)) { + + *pLen = 0; + return (SK_PNMI_ERR_UNKNOWN_INST); + } + LogPortIndex = SK_PNMI_PORT_INST2LOG(Instance); + Limit = LogPortIndex + 1; + } + else { /* Instance == (SK_U32)(-1), get all Instances of that OID. */ + + LogPortIndex = 0; + Limit = LogPortMax; + } + + /* Perform action. */ + if (Action == SK_PNMI_GET) { + + /* Check length. */ + if (*pLen < (Limit - LogPortIndex) * 6) { + + *pLen = (Limit - LogPortIndex) * 6; + return (SK_PNMI_ERR_TOO_SHORT); + } + + /* Get value. */ + for (; LogPortIndex < Limit; LogPortIndex ++) { + + switch (Id) { + + case OID_SKGE_PHYS_CUR_ADDR: + if (LogPortIndex == 0) { + CopyMac(pBuf + Offset, &pAC->Addr.Net[NetIndex].CurrentMacAddress); + } + else { + PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(pAC, LogPortIndex); + + CopyMac(pBuf + Offset, + &pAC->Addr.Port[PhysPortIndex].CurrentMacAddress); + } + Offset += 6; + break; + + case OID_SKGE_PHYS_FAC_ADDR: + if (LogPortIndex == 0) { + CopyMac(pBuf + Offset, + &pAC->Addr.Net[NetIndex].PermanentMacAddress); + } + else { + PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(pAC, LogPortIndex); + + CopyMac(pBuf + Offset, + &pAC->Addr.Port[PhysPortIndex].PermanentMacAddress); + } + Offset += 6; + break; + + default: + SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR008, SK_PNMI_ERR008MSG); + + *pLen = 0; + return (SK_PNMI_ERR_GENERAL); + } + } + + *pLen = Offset; + } + else { + /* + * The logical MAC address may not be changed, + * only the physical ones. + */ + if (Id == OID_SKGE_PHYS_FAC_ADDR) { + + *pLen = 0; + return (SK_PNMI_ERR_READ_ONLY); + } + + /* Only the current address may be changed. */ + if (Id != OID_SKGE_PHYS_CUR_ADDR) { + + SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR009, SK_PNMI_ERR009MSG); + + *pLen = 0; + return (SK_PNMI_ERR_GENERAL); + } + + /* Check length. */ + if (*pLen < (Limit - LogPortIndex) * 6) { + + *pLen = (Limit - LogPortIndex) * 6; + return (SK_PNMI_ERR_TOO_SHORT); + } + if (*pLen > (Limit - LogPortIndex) * 6) { + + *pLen = 0; + return (SK_PNMI_ERR_BAD_VALUE); + } + + /* Check action. */ + if (Action == SK_PNMI_PRESET) { + + *pLen = 0; + return (SK_PNMI_ERR_OK); + } + + /* Set OID_SKGE_MAC_CUR_ADDR. */ + for (; LogPortIndex < Limit; LogPortIndex ++, Offset += 6) { + + /* + * A set to virtual port and set of broadcast + * address will be ignored. + */ + if (LogPortIndex == 0 || SK_MEMCMP(pBuf + Offset, + "\xff\xff\xff\xff\xff\xff", 6) == 0) { + continue; + } + + PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(pAC, LogPortIndex); + + Ret = SkAddrOverride(pAC, IoC, PhysPortIndex, + (SK_MAC_ADDR *)(pBuf + Offset), + (LogPortIndex == 0 ? SK_ADDR_VIRTUAL_ADDRESS : + SK_ADDR_PHYSICAL_ADDRESS)); + if (Ret != SK_ADDR_OVERRIDE_SUCCESS) { + + return (SK_PNMI_ERR_GENERAL); + } + } + *pLen = Offset; + } + + return (SK_PNMI_ERR_OK); +} + +/***************************************************************************** + * + * CsumStat - OID handler function of OID_SKGE_CHKSM_XXX + * + * Description: + * Retrieves the statistic values of the CSUM module. The CSUM data + * structure must be available in the SK_AC even if the CSUM module + * is not included, because PNMI reads the statistic data from the + * CSUM part of SK_AC directly. + * + * Returns: + * SK_PNMI_ERR_OK The request was successfully performed. + * SK_PNMI_ERR_GENERAL A general severe internal error occured. + * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain + * the correct data (e.g. a 32bit value is + * needed, but a 16 bit value was passed). + * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't + * exist (e.g. port instance 3 on a two port + * adapter. + */ +PNMI_STATIC int CsumStat( +SK_AC *pAC, /* Pointer to adapter context */ +SK_IOC IoC, /* IO context handle */ +int Action, /* GET/PRESET/SET action */ +SK_U32 Id, /* Object ID that is to be processed */ +char *pBuf, /* Buffer used for the management data transfer */ +unsigned int *pLen, /* On call: pBuf buffer length. On return: used buffer */ +SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */ +unsigned int TableIndex, /* Index to the Id table */ +SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */ +{ + unsigned int Index; + unsigned int Limit; + unsigned int Offset = 0; + SK_U64 StatVal; + + /* Calculate instance if wished. */ + if (Instance != (SK_U32)(-1)) { + + if ((Instance < 1) || (Instance > SKCS_NUM_PROTOCOLS)) { + + *pLen = 0; + return (SK_PNMI_ERR_UNKNOWN_INST); + } + Index = (unsigned int)Instance - 1; + Limit = Index + 1; + } + else { + Index = 0; + Limit = SKCS_NUM_PROTOCOLS; + } + + /* Check action. */ + if (Action != SK_PNMI_GET) { + + *pLen = 0; + return (SK_PNMI_ERR_READ_ONLY); + } + + /* Check length. */ + if (*pLen < (Limit - Index) * sizeof(SK_U64)) { + + *pLen = (Limit - Index) * sizeof(SK_U64); + return (SK_PNMI_ERR_TOO_SHORT); + } + + /* Get value. */ + for (; Index < Limit; Index ++) { + + switch (Id) { + + case OID_SKGE_CHKSM_RX_OK_CTS: + StatVal = pAC->Csum.ProtoStats[NetIndex][Index].RxOkCts; + break; + + case OID_SKGE_CHKSM_RX_UNABLE_CTS: + StatVal = pAC->Csum.ProtoStats[NetIndex][Index].RxUnableCts; + break; + + case OID_SKGE_CHKSM_RX_ERR_CTS: + StatVal = pAC->Csum.ProtoStats[NetIndex][Index].RxErrCts; + break; + + case OID_SKGE_CHKSM_TX_OK_CTS: + StatVal = pAC->Csum.ProtoStats[NetIndex][Index].TxOkCts; + break; + + case OID_SKGE_CHKSM_TX_UNABLE_CTS: + StatVal = pAC->Csum.ProtoStats[NetIndex][Index].TxUnableCts; + break; + + default: + SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR010, SK_PNMI_ERR010MSG); + + *pLen = 0; + return (SK_PNMI_ERR_GENERAL); + } + + SK_PNMI_STORE_U64(pBuf + Offset, StatVal); + Offset += sizeof(SK_U64); + } + + /* Store used buffer space. */ + *pLen = Offset; + + return (SK_PNMI_ERR_OK); +} + +/***************************************************************************** + * + * SensorStat - OID handler function of OID_SKGE_SENSOR_XXX + * + * Description: + * Retrieves the statistic values of the I2C module, which handles + * the temperature and voltage sensors. + * + * Returns: + * SK_PNMI_ERR_OK The request was successfully performed. + * SK_PNMI_ERR_GENERAL A general severe internal error occured. + * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain + * the correct data (e.g. a 32bit value is + * needed, but a 16 bit value was passed). + * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't + * exist (e.g. port instance 3 on a two port + * adapter. + */ +PNMI_STATIC int SensorStat( +SK_AC *pAC, /* Pointer to adapter context */ +SK_IOC IoC, /* IO context handle */ +int Action, /* GET/PRESET/SET action */ +SK_U32 Id, /* Object ID that is to be processed */ +char *pBuf, /* Buffer used for the management data transfer */ +unsigned int *pLen, /* On call: pBuf buffer length. On return: used buffer */ +SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */ +unsigned int TableIndex, /* Index to the Id table */ +SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */ +{ + unsigned int i; + unsigned int Index; + unsigned int Limit; + unsigned int Offset; + unsigned int Len; + SK_U32 Val32; + SK_U64 Val64; + + /* Calculate instance if wished. */ + if ((Instance != (SK_U32)(-1))) { + + if ((Instance < 1) || (Instance > (SK_U32)pAC->I2c.MaxSens)) { + + *pLen = 0; + return (SK_PNMI_ERR_UNKNOWN_INST); + } + + Index = (unsigned int)Instance -1; + Limit = (unsigned int)Instance; + } + else { + Index = 0; + Limit = (unsigned int) pAC->I2c.MaxSens; + } + + /* Check action. */ + if (Action != SK_PNMI_GET) { + + *pLen = 0; + return (SK_PNMI_ERR_READ_ONLY); + } + + /* Check length. */ + switch (Id) { + + case OID_SKGE_SENSOR_VALUE: + case OID_SKGE_SENSOR_WAR_THRES_LOW: + case OID_SKGE_SENSOR_WAR_THRES_UPP: + case OID_SKGE_SENSOR_ERR_THRES_LOW: + case OID_SKGE_SENSOR_ERR_THRES_UPP: + if (*pLen < (Limit - Index) * sizeof(SK_U32)) { + + *pLen = (Limit - Index) * sizeof(SK_U32); + return (SK_PNMI_ERR_TOO_SHORT); + } + break; + + case OID_SKGE_SENSOR_DESCR: + for (Offset = 0, i = Index; i < Limit; i ++) { + + Len = (unsigned int) + SK_STRLEN(pAC->I2c.SenTable[i].SenDesc) + 1; + if (Len >= SK_PNMI_STRINGLEN2) { + + SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR011, + SK_PNMI_ERR011MSG); + + *pLen = 0; + return (SK_PNMI_ERR_GENERAL); + } + Offset += Len; + } + if (*pLen < Offset) { + + *pLen = Offset; + return (SK_PNMI_ERR_TOO_SHORT); + } + break; + + case OID_SKGE_SENSOR_INDEX: + case OID_SKGE_SENSOR_TYPE: + case OID_SKGE_SENSOR_STATUS: + if (*pLen < Limit - Index) { + + *pLen = Limit - Index; + return (SK_PNMI_ERR_TOO_SHORT); + } + break; + + case OID_SKGE_SENSOR_WAR_CTS: + case OID_SKGE_SENSOR_WAR_TIME: + case OID_SKGE_SENSOR_ERR_CTS: + case OID_SKGE_SENSOR_ERR_TIME: + if (*pLen < (Limit - Index) * sizeof(SK_U64)) { + + *pLen = (Limit - Index) * sizeof(SK_U64); + return (SK_PNMI_ERR_TOO_SHORT); + } + break; + + default: + SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR012, SK_PNMI_ERR012MSG); + + *pLen = 0; + return (SK_PNMI_ERR_GENERAL); + + } + + /* Get value. */ + for (Offset = 0; Index < Limit; Index ++) { + + switch (Id) { + + case OID_SKGE_SENSOR_INDEX: + *(pBuf + Offset) = (char)Index; + Offset ++; + break; + + case OID_SKGE_SENSOR_DESCR: + Len = SK_STRLEN(pAC->I2c.SenTable[Index].SenDesc); + SK_MEMCPY(pBuf + Offset + 1, pAC->I2c.SenTable[Index].SenDesc, Len); + *(pBuf + Offset) = (char)Len; + Offset += Len + 1; + break; + + case OID_SKGE_SENSOR_TYPE: + *(pBuf + Offset) = (char)pAC->I2c.SenTable[Index].SenType; + Offset ++; + break; + + case OID_SKGE_SENSOR_VALUE: + Val32 = (SK_U32)pAC->I2c.SenTable[Index].SenValue; + SK_PNMI_STORE_U32(pBuf + Offset, Val32); + Offset += sizeof(SK_U32); + break; + + case OID_SKGE_SENSOR_WAR_THRES_LOW: + Val32 = (SK_U32)pAC->I2c.SenTable[Index]. + SenThreWarnLow; + SK_PNMI_STORE_U32(pBuf + Offset, Val32); + Offset += sizeof(SK_U32); + break; + + case OID_SKGE_SENSOR_WAR_THRES_UPP: + Val32 = (SK_U32)pAC->I2c.SenTable[Index]. + SenThreWarnHigh; + SK_PNMI_STORE_U32(pBuf + Offset, Val32); + Offset += sizeof(SK_U32); + break; + + case OID_SKGE_SENSOR_ERR_THRES_LOW: + Val32 = (SK_U32)pAC->I2c.SenTable[Index]. + SenThreErrLow; + SK_PNMI_STORE_U32(pBuf + Offset, Val32); + Offset += sizeof(SK_U32); + break; + + case OID_SKGE_SENSOR_ERR_THRES_UPP: + Val32 = pAC->I2c.SenTable[Index].SenThreErrHigh; + SK_PNMI_STORE_U32(pBuf + Offset, Val32); + Offset += sizeof(SK_U32); + break; + + case OID_SKGE_SENSOR_STATUS: + *(pBuf + Offset) = (char)pAC->I2c.SenTable[Index].SenErrFlag; + Offset ++; + break; + + case OID_SKGE_SENSOR_WAR_CTS: + Val64 = pAC->I2c.SenTable[Index].SenWarnCts; + SK_PNMI_STORE_U64(pBuf + Offset, Val64); + Offset += sizeof(SK_U64); + break; + + case OID_SKGE_SENSOR_ERR_CTS: + Val64 = pAC->I2c.SenTable[Index].SenErrCts; + SK_PNMI_STORE_U64(pBuf + Offset, Val64); + Offset += sizeof(SK_U64); + break; + + case OID_SKGE_SENSOR_WAR_TIME: + Val64 = SK_PNMI_HUNDREDS_SEC(pAC->I2c.SenTable[Index]. + SenBegWarnTS); + SK_PNMI_STORE_U64(pBuf + Offset, Val64); + Offset += sizeof(SK_U64); + break; + + case OID_SKGE_SENSOR_ERR_TIME: + Val64 = SK_PNMI_HUNDREDS_SEC(pAC->I2c.SenTable[Index]. + SenBegErrTS); + SK_PNMI_STORE_U64(pBuf + Offset, Val64); + Offset += sizeof(SK_U64); + break; + + default: + SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_ERR, + ("SensorStat: Unknown OID should be handled before")); + + return (SK_PNMI_ERR_GENERAL); + } + } + + /* Store used buffer space. */ + *pLen = Offset; + + return (SK_PNMI_ERR_OK); +} + +/***************************************************************************** + * + * Vpd - OID handler function of OID_SKGE_VPD_XXX + * + * Description: + * Get/preset/set of VPD data. As instance the name of a VPD key + * can be passed. The Instance parameter is a SK_U32 and can be + * used as a string buffer for the VPD key, because their maximum + * length is 4 byte. + * + * Returns: + * SK_PNMI_ERR_OK The request was successfully performed. + * SK_PNMI_ERR_GENERAL A general severe internal error occured. + * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain + * the correct data (e.g. a 32bit value is + * needed, but a 16 bit value was passed). + * SK_PNMI_ERR_BAD_VALUE The passed value is not in the valid + * value range. + * SK_PNMI_ERR_READ_ONLY The OID is read-only and cannot be set. + * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't + * exist (e.g. port instance 3 on a two port + * adapter. + */ +PNMI_STATIC int Vpd( +SK_AC *pAC, /* Pointer to adapter context */ +SK_IOC IoC, /* IO context handle */ +int Action, /* GET/PRESET/SET action */ +SK_U32 Id, /* Object ID that is to be processed */ +char *pBuf, /* Buffer used for the management data transfer */ +unsigned int *pLen, /* On call: pBuf buffer length. On return: used buffer */ +SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */ +unsigned int TableIndex, /* Index to the Id table */ +SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */ +{ + SK_VPD_STATUS *pVpdStatus; + unsigned int BufLen; + char Buf[256]; + char KeyArr[SK_PNMI_VPD_ENTRIES][SK_PNMI_VPD_KEY_SIZE]; + char KeyStr[SK_PNMI_VPD_KEY_SIZE]; + unsigned int KeyNo; + unsigned int Offset; + unsigned int Index; + unsigned int FirstIndex; + unsigned int LastIndex; + unsigned int Len; + int Ret; + SK_U32 Val32; + + /* + * VpdKeyReadError will be set in GetVpdKeyArr() if an error occurs. + * Due to the fact that some drivers use SkPnmiGetStruct() to retrieve + * all statistical data, an error in GetVpdKeyArr() will generate a PNMI + * error and terminate SkPnmiGetStruct() without filling in statistical + * data into the PNMI struct. In this case the driver will get no values + * for statistical purposes (netstat, ifconfig etc.). GetVpdKeyArr() is + * the first function to be called in SkPnmiGetStruct(), so any error + * will terminate SkPnmiGetStruct() immediately. Hence, VpdKeyReadError will + * be set during the first call to GetVpdKeyArr() to make successful calls + * to SkPnmiGetStruct() possible. But there is another point to consider: + * When filling in the statistical data into the PNMI struct, the VPD + * handler Vpd() will also be called. If GetVpdKeyArr() in Vpd() would + * return with SK_PNMI_ERR_GENERAL, SkPnmiGetStruct() would fail again. + * For this reason VpdKeyReadError is checked here and, if set, Vpd() + * will return without doing anything and the return value SK_PNMI_ERR_OK. + * Therefore SkPnmiGetStruct() is able to continue and fill in all other + * statistical data. + */ + if (pAC->Pnmi.VpdKeyReadError == SK_TRUE) { + return (SK_PNMI_ERR_OK); + } + + /* Get array of all currently stored VPD keys. */ + Ret = GetVpdKeyArr(pAC, IoC, &KeyArr[0][0], sizeof(KeyArr), &KeyNo); + if (Ret != SK_PNMI_ERR_OK) { + *pLen = 0; + return (Ret); + } + + /* + * If instance is not -1, try to find the requested VPD key for + * the multiple instance variables. The other OIDs as for example + * OID VPD_ACTION are single instance variables and must be + * handled separatly. + */ + FirstIndex = 0; + LastIndex = KeyNo; + + if ((Instance != (SK_U32)(-1))) { + + if (Id == OID_SKGE_VPD_KEY || Id == OID_SKGE_VPD_VALUE || + Id == OID_SKGE_VPD_ACCESS) { + + SK_STRNCPY(KeyStr, (char *)&Instance, 4); + KeyStr[4] = 0; + + for (Index = 0; Index < KeyNo; Index ++) { + + if (SK_STRCMP(KeyStr, KeyArr[Index]) == 0) { + FirstIndex = Index; + LastIndex = Index+1; + break; + } + } + if (Index == KeyNo) { + + *pLen = 0; + return (SK_PNMI_ERR_UNKNOWN_INST); + } + } + else if (Instance != 1) { + + *pLen = 0; + return (SK_PNMI_ERR_UNKNOWN_INST); + } + } + + /* Get value, if a query should be performed. */ + if (Action == SK_PNMI_GET) { + + switch (Id) { + + case OID_SKGE_VPD_FREE_BYTES: + /* Check length of buffer. */ + if (*pLen < sizeof(SK_U32)) { + + *pLen = sizeof(SK_U32); + return (SK_PNMI_ERR_TOO_SHORT); + } + /* Get number of free bytes. */ + pVpdStatus = VpdStat(pAC, IoC); + if (pVpdStatus == NULL) { + + SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL, + (SK_PNMI_ERR017MSG)); + + *pLen = 0; + return (SK_PNMI_ERR_GENERAL); + } + if ((pVpdStatus->vpd_status & VPD_VALID) == 0) { + + SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL, + (SK_PNMI_ERR018MSG)); + + *pLen = 0; + return (SK_PNMI_ERR_GENERAL); + } + + Val32 = (SK_U32)pVpdStatus->vpd_free_rw; + SK_PNMI_STORE_U32(pBuf, Val32); + *pLen = sizeof(SK_U32); + break; + + case OID_SKGE_VPD_ENTRIES_LIST: + /* Check length. */ + for (Len = 0, Index = 0; Index < KeyNo; Index ++) { + + Len += SK_STRLEN(KeyArr[Index]) + 1; + } + if (*pLen < Len) { + + *pLen = Len; + return (SK_PNMI_ERR_TOO_SHORT); + } + + /* Get value. */ + *(pBuf) = (char)Len - 1; + for (Offset = 1, Index = 0; Index < KeyNo; Index ++) { + + Len = SK_STRLEN(KeyArr[Index]); + SK_MEMCPY(pBuf + Offset, KeyArr[Index], Len); + + Offset += Len; + + if (Index < KeyNo - 1) { + + *(pBuf + Offset) = ' '; + Offset ++; + } + } + *pLen = Offset; + break; + + case OID_SKGE_VPD_ENTRIES_NUMBER: + /* Check length. */ + if (*pLen < sizeof(SK_U32)) { + + *pLen = sizeof(SK_U32); + return (SK_PNMI_ERR_TOO_SHORT); + } + + Val32 = (SK_U32)KeyNo; + SK_PNMI_STORE_U32(pBuf, Val32); + *pLen = sizeof(SK_U32); + break; + + case OID_SKGE_VPD_KEY: + /* Check buffer length, if it is large enough. */ + for (Len = 0, Index = FirstIndex; + Index < LastIndex; Index ++) { + + Len += SK_STRLEN(KeyArr[Index]) + 1; + } + if (*pLen < Len) { + + *pLen = Len; + return (SK_PNMI_ERR_TOO_SHORT); + } + + /* + * Get the key to an intermediate buffer, because + * we have to prepend a length byte. + */ + for (Offset = 0, Index = FirstIndex; Index < LastIndex; Index ++) { + + Len = SK_STRLEN(KeyArr[Index]); + + *(pBuf + Offset) = (char)Len; + SK_MEMCPY(pBuf + Offset + 1, KeyArr[Index], Len); + Offset += Len + 1; + } + *pLen = Offset; + break; + + case OID_SKGE_VPD_VALUE: + /* Check the buffer length if it is large enough. */ + for (Offset = 0, Index = FirstIndex; Index < LastIndex; Index ++) { + + BufLen = 256; + if (VpdRead(pAC, IoC, KeyArr[Index], Buf, + (int *)&BufLen) > 0 || + BufLen >= SK_PNMI_VPD_DATALEN) { + + SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL, + (SK_PNMI_ERR021MSG)); + + return (SK_PNMI_ERR_GENERAL); + } + Offset += BufLen + 1; + } + if (*pLen < Offset) { + + *pLen = Offset; + return (SK_PNMI_ERR_TOO_SHORT); + } + + /* + * Get the value to an intermediate buffer, because + * we have to prepend a length byte. + */ + for (Offset = 0, Index = FirstIndex; Index < LastIndex; Index ++) { + + BufLen = 256; + if (VpdRead(pAC, IoC, KeyArr[Index], Buf, + (int *)&BufLen) > 0 || + BufLen >= SK_PNMI_VPD_DATALEN) { + + SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL, + (SK_PNMI_ERR022MSG)); + + *pLen = 0; + return (SK_PNMI_ERR_GENERAL); + } + + *(pBuf + Offset) = (char)BufLen; + SK_MEMCPY(pBuf + Offset + 1, Buf, BufLen); + Offset += BufLen + 1; + } + *pLen = Offset; + break; + + case OID_SKGE_VPD_ACCESS: + if (*pLen < LastIndex - FirstIndex) { + + *pLen = LastIndex - FirstIndex; + return (SK_PNMI_ERR_TOO_SHORT); + } + + for (Offset = 0, Index = FirstIndex; Index < LastIndex; Index ++) { + + if (VpdMayWrite(KeyArr[Index])) { + + *(pBuf + Offset) = SK_PNMI_VPD_RW; + } + else { + *(pBuf + Offset) = SK_PNMI_VPD_RO; + } + Offset ++; + } + *pLen = Offset; + break; + + case OID_SKGE_VPD_ACTION: + Offset = LastIndex - FirstIndex; + if (*pLen < Offset) { + + *pLen = Offset; + return (SK_PNMI_ERR_TOO_SHORT); + } + SK_MEMSET(pBuf, 0, Offset); + *pLen = Offset; + break; + + default: + SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL, + (SK_PNMI_ERR023MSG)); + + *pLen = 0; + return (SK_PNMI_ERR_GENERAL); + } + } + else { + /* The only OID which can be set is VPD_ACTION. */ + if (Id != OID_SKGE_VPD_ACTION) { + + if (Id == OID_SKGE_VPD_FREE_BYTES || + Id == OID_SKGE_VPD_ENTRIES_LIST || + Id == OID_SKGE_VPD_ENTRIES_NUMBER || + Id == OID_SKGE_VPD_KEY || + Id == OID_SKGE_VPD_VALUE || + Id == OID_SKGE_VPD_ACCESS) { + + *pLen = 0; + return (SK_PNMI_ERR_READ_ONLY); + } + + SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL, + (SK_PNMI_ERR024MSG)); + + *pLen = 0; + return (SK_PNMI_ERR_GENERAL); + } + + /* + * From this point we handle VPD_ACTION. Check the buffer + * length. It should at least have the size of one byte. + */ + if (*pLen < 1) { + + *pLen = 1; + return (SK_PNMI_ERR_TOO_SHORT); + } + + /* The first byte contains the VPD action type we should perform. */ + switch (*pBuf) { + + case SK_PNMI_VPD_IGNORE: + /* Nothing to do. */ + break; + + case SK_PNMI_VPD_CREATE: + /* + * We have to create a new VPD entry or we modify + * an existing one. Check first the buffer length. + */ + if (*pLen < 4) { + + *pLen = 4; + return (SK_PNMI_ERR_TOO_SHORT); + } + KeyStr[0] = pBuf[1]; + KeyStr[1] = pBuf[2]; + KeyStr[2] = 0; + + /* + * Is the entry writable or does it belong to the + * read-only area? + */ + if (!VpdMayWrite(KeyStr)) { + + *pLen = 0; + return (SK_PNMI_ERR_BAD_VALUE); + } + + Offset = (int)pBuf[3] & 0xFF; + + SK_MEMCPY(Buf, pBuf + 4, Offset); + Buf[Offset] = 0; + + /* A PRESET ends here. */ + if (Action == SK_PNMI_PRESET) { + + return (SK_PNMI_ERR_OK); + } + + /* Write the new entry or modify an existing one .*/ + Ret = VpdWrite(pAC, IoC, KeyStr, Buf); + if (Ret == SK_PNMI_VPD_NOWRITE ) { + + *pLen = 0; + return (SK_PNMI_ERR_BAD_VALUE); + } + else if (Ret != SK_PNMI_VPD_OK) { + + SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL, + (SK_PNMI_ERR025MSG)); + + *pLen = 0; + return (SK_PNMI_ERR_GENERAL); + } + + /* + * Perform an update of the VPD data. This is + * not mandantory, but just to be sure. + */ + Ret = VpdUpdate(pAC, IoC); + if (Ret != SK_PNMI_VPD_OK) { + + SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL, + (SK_PNMI_ERR026MSG)); + + *pLen = 0; + return (SK_PNMI_ERR_GENERAL); + } + break; + + case SK_PNMI_VPD_DELETE: + /* Check if the buffer size is plausible. */ + if (*pLen < 3) { + + *pLen = 3; + return (SK_PNMI_ERR_TOO_SHORT); + } + if (*pLen > 3) { + + *pLen = 0; + return (SK_PNMI_ERR_BAD_VALUE); + } + KeyStr[0] = pBuf[1]; + KeyStr[1] = pBuf[2]; + KeyStr[2] = 0; + + /* Find the passed key in the array. */ + for (Index = 0; Index < KeyNo; Index ++) { + + if (SK_STRCMP(KeyStr, KeyArr[Index]) == 0) { + + break; + } + } + + /* + * If we cannot find the key it is wrong, so we + * return an appropriate error value. + */ + if (Index == KeyNo) { + + *pLen = 0; + return (SK_PNMI_ERR_BAD_VALUE); + } + + if (Action == SK_PNMI_PRESET) { + + return (SK_PNMI_ERR_OK); + } + + /* Ok, you wanted it and you will get it. */ + Ret = VpdDelete(pAC, IoC, KeyStr); + if (Ret != SK_PNMI_VPD_OK) { + + SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL, + (SK_PNMI_ERR027MSG)); + + *pLen = 0; + return (SK_PNMI_ERR_GENERAL); + } + + /* + * Perform an update of the VPD data. This is + * not mandantory, but just to be sure. + */ + Ret = VpdUpdate(pAC, IoC); + if (Ret != SK_PNMI_VPD_OK) { + + SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL, + (SK_PNMI_ERR028MSG)); + + *pLen = 0; + return (SK_PNMI_ERR_GENERAL); + } + break; + + default: + *pLen = 0; + return (SK_PNMI_ERR_BAD_VALUE); + } + } + + return (SK_PNMI_ERR_OK); +} + +/***************************************************************************** + * + * General - OID handler function of various single instance OIDs + * + * Description: + * The code is simple. No description necessary. + * + * Returns: + * SK_PNMI_ERR_OK The request was successfully performed. + * SK_PNMI_ERR_GENERAL A general severe internal error occured. + * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain + * the correct data (e.g. a 32bit value is + * needed, but a 16 bit value was passed). + * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't + * exist (e.g. port instance 3 on a two port + * adapter. + */ +PNMI_STATIC int General( +SK_AC *pAC, /* Pointer to adapter context */ +SK_IOC IoC, /* IO context handle */ +int Action, /* GET/PRESET/SET action */ +SK_U32 Id, /* Object ID that is to be processed */ +char *pBuf, /* Buffer used for the management data transfer */ +unsigned int *pLen, /* On call: buffer length. On return: used buffer */ +SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */ +unsigned int TableIndex, /* Index to the Id table */ +SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */ +{ + int Ret; + unsigned int Index; + unsigned int Len; + unsigned int Offset; + unsigned int Val; + SK_U8 Val8; + SK_U16 Val16; + SK_U32 Val32; + SK_U64 Val64; + SK_U64 Val64RxHwErrs = 0; + SK_U64 Val64RxRunt = 0; + SK_U64 Val64RxFcs = 0; + SK_U64 Val64TxHwErrs = 0; + SK_BOOL Is64BitReq = SK_FALSE; + char Buf[256]; + int MacType; + + /* Check instance. We only handle single instance variables. */ + if (Instance != (SK_U32)(-1) && Instance != 1) { + + *pLen = 0; + return (SK_PNMI_ERR_UNKNOWN_INST); + } + + /* Check action. We only allow get requests. */ + if (Action != SK_PNMI_GET) { + + *pLen = 0; + return (SK_PNMI_ERR_READ_ONLY); + } + + MacType = pAC->GIni.GIMacType; + + /* Check length for the various supported OIDs. */ + switch (Id) { + + case OID_GEN_XMIT_ERROR: + case OID_GEN_RCV_ERROR: + case OID_GEN_RCV_NO_BUFFER: +#ifndef SK_NDIS_64BIT_CTR + if (*pLen < sizeof(SK_U32)) { + *pLen = sizeof(SK_U32); + return (SK_PNMI_ERR_TOO_SHORT); + } + +#else /* SK_NDIS_64BIT_CTR */ + + /* For compatibility, at least 32bit are required for OID. */ + if (*pLen < sizeof(SK_U32)) { + /* + * Indicate handling for 64bit values, + * if insufficient space is provided. + */ + *pLen = sizeof(SK_U64); + return (SK_PNMI_ERR_TOO_SHORT); + } + + Is64BitReq = (*pLen < sizeof(SK_U64)) ? SK_FALSE : SK_TRUE; +#endif /* SK_NDIS_64BIT_CTR */ + break; + + case OID_SKGE_PORT_NUMBER: + case OID_SKGE_DEVICE_TYPE: + case OID_SKGE_RESULT: + case OID_SKGE_RLMT_MONITOR_NUMBER: + case OID_GEN_TRANSMIT_QUEUE_LENGTH: + case OID_SKGE_TRAP_NUMBER: + case OID_SKGE_MDB_VERSION: + case OID_SKGE_BOARDLEVEL: + case OID_SKGE_CHIPID: + case OID_SKGE_RAMSIZE: + if (*pLen < sizeof(SK_U32)) { + + *pLen = sizeof(SK_U32); + return (SK_PNMI_ERR_TOO_SHORT); + } + break; + + case OID_SKGE_CHIPSET: + if (*pLen < sizeof(SK_U16)) { + + *pLen = sizeof(SK_U16); + return (SK_PNMI_ERR_TOO_SHORT); + } + break; + + case OID_SKGE_BUS_TYPE: + case OID_SKGE_BUS_SPEED: + case OID_SKGE_BUS_WIDTH: + case OID_SKGE_SENSOR_NUMBER: + case OID_SKGE_CHKSM_NUMBER: + case OID_SKGE_VAUXAVAIL: + if (*pLen < sizeof(SK_U8)) { + + *pLen = sizeof(SK_U8); + return (SK_PNMI_ERR_TOO_SHORT); + } + break; + + case OID_SKGE_TX_SW_QUEUE_LEN: + case OID_SKGE_TX_SW_QUEUE_MAX: + case OID_SKGE_TX_RETRY: + case OID_SKGE_RX_INTR_CTS: + case OID_SKGE_TX_INTR_CTS: + case OID_SKGE_RX_NO_BUF_CTS: + case OID_SKGE_TX_NO_BUF_CTS: + case OID_SKGE_TX_USED_DESCR_NO: + case OID_SKGE_RX_DELIVERED_CTS: + case OID_SKGE_RX_OCTETS_DELIV_CTS: + case OID_SKGE_RX_HW_ERROR_CTS: + case OID_SKGE_TX_HW_ERROR_CTS: + case OID_SKGE_IN_ERRORS_CTS: + case OID_SKGE_OUT_ERROR_CTS: + case OID_SKGE_ERR_RECOVERY_CTS: + case OID_SKGE_SYSUPTIME: + if (*pLen < sizeof(SK_U64)) { + + *pLen = sizeof(SK_U64); + return (SK_PNMI_ERR_TOO_SHORT); + } + break; + + default: + /* Checked later. */ + break; + } + + /* Update statistics. */ + if (Id == OID_SKGE_RX_HW_ERROR_CTS || + Id == OID_SKGE_TX_HW_ERROR_CTS || + Id == OID_SKGE_IN_ERRORS_CTS || + Id == OID_SKGE_OUT_ERROR_CTS || + Id == OID_GEN_XMIT_ERROR || + Id == OID_GEN_RCV_ERROR) { + + /* + * Force the XMAC to update its statistic counters and + * Increment semaphore to indicate that an update was + * already done. + */ + Ret = MacUpdate(pAC, IoC, 0, pAC->GIni.GIMacsFound - 1); + if (Ret != SK_PNMI_ERR_OK) { + + *pLen = 0; + return (Ret); + } + pAC->Pnmi.MacUpdatedFlag ++; + + /* + * Some OIDs consist of multiple hardware counters. Those + * values which are contained in all of them will be added + * now. + */ + switch (Id) { + + case OID_SKGE_RX_HW_ERROR_CTS: + case OID_SKGE_IN_ERRORS_CTS: + case OID_GEN_RCV_ERROR: + Val64RxHwErrs = + GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_MISSED, NetIndex) + + GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_FRAMING, NetIndex) + + GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_OVERFLOW, NetIndex) + + GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_JABBER, NetIndex) + + GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_CARRIER, NetIndex) + + GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_IRLENGTH, NetIndex) + + GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_SYMBOL, NetIndex) + + GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_SHORTS, NetIndex) + + GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_TOO_LONG, NetIndex) + + GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_CEXT, NetIndex); + + + /* + * In some cases the runt and fcs counters are incremented when collisions + * occur. We have to correct those counters here. + */ + Val64RxRunt = GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_RUNT, NetIndex); + Val64RxFcs = GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_FCS, NetIndex); + + if (Val64RxRunt > Val64RxFcs) { + Val64RxRunt -= Val64RxFcs; + Val64RxHwErrs += Val64RxRunt; + } + else { + Val64RxFcs -= Val64RxRunt; + Val64RxHwErrs += Val64RxFcs; + } + break; + + case OID_SKGE_TX_HW_ERROR_CTS: + case OID_SKGE_OUT_ERROR_CTS: + case OID_GEN_XMIT_ERROR: + Val64TxHwErrs = + GetStatVal(pAC, IoC, 0, SK_PNMI_HTX_EXCESS_COL, NetIndex) + + GetStatVal(pAC, IoC, 0, SK_PNMI_HTX_LATE_COL, NetIndex) + + GetStatVal(pAC, IoC, 0, SK_PNMI_HTX_UNDERRUN, NetIndex) + + GetStatVal(pAC, IoC, 0, SK_PNMI_HTX_CARRIER, NetIndex); + break; + } + } + + /* Retrieve value. */ + switch (Id) { + + case OID_SKGE_SUPPORTED_LIST: + Len = ID_TABLE_SIZE * sizeof(SK_U32); + if (*pLen < Len) { + + *pLen = Len; + return (SK_PNMI_ERR_TOO_SHORT); + } + for (Offset = 0, Index = 0; Offset < Len; Index ++) { + + Val32 = (SK_U32)IdTable[Index].Id; + SK_PNMI_STORE_U32(pBuf + Offset, Val32); + Offset += sizeof(SK_U32); + } + *pLen = Len; + break; + + case OID_SKGE_BOARDLEVEL: + Val32 = (SK_U32)pAC->GIni.GILevel; + SK_PNMI_STORE_U32(pBuf, Val32); + *pLen = sizeof(SK_U32); + break; + + case OID_SKGE_PORT_NUMBER: + Val32 = (SK_U32)pAC->GIni.GIMacsFound; + SK_PNMI_STORE_U32(pBuf, Val32); + *pLen = sizeof(SK_U32); + break; + + case OID_SKGE_DEVICE_TYPE: + Val32 = (SK_U32)pAC->Pnmi.DeviceType; + SK_PNMI_STORE_U32(pBuf, Val32); + *pLen = sizeof(SK_U32); + break; + + case OID_SKGE_DRIVER_DESCR: + if (pAC->Pnmi.pDriverDescription == NULL) { + + SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR007, SK_PNMI_ERR007MSG); + + *pLen = 0; + return (SK_PNMI_ERR_GENERAL); + } + + Len = SK_STRLEN(pAC->Pnmi.pDriverDescription) + 1; + if (Len > SK_PNMI_STRINGLEN1) { + + SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR029, SK_PNMI_ERR029MSG); + + *pLen = 0; + return (SK_PNMI_ERR_GENERAL); + } + + if (*pLen < Len) { + + *pLen = Len; + return (SK_PNMI_ERR_TOO_SHORT); + } + *pBuf = (char)(Len - 1); + SK_MEMCPY(pBuf + 1, pAC->Pnmi.pDriverDescription, Len - 1); + *pLen = Len; + break; + + case OID_SKGE_DRIVER_VERSION: + if (pAC->Pnmi.pDriverVersion == NULL) { + + SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR030, SK_PNMI_ERR030MSG); + + *pLen = 0; + return (SK_PNMI_ERR_GENERAL); + } + + Len = SK_STRLEN(pAC->Pnmi.pDriverVersion) + 1; + if (Len > SK_PNMI_STRINGLEN1) { + + SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR031, SK_PNMI_ERR031MSG); + + *pLen = 0; + return (SK_PNMI_ERR_GENERAL); + } + + if (*pLen < Len) { + + *pLen = Len; + return (SK_PNMI_ERR_TOO_SHORT); + } + *pBuf = (char)(Len - 1); + SK_MEMCPY(pBuf + 1, pAC->Pnmi.pDriverVersion, Len - 1); + *pLen = Len; + break; + + case OID_SKGE_DRIVER_RELDATE: + if (pAC->Pnmi.pDriverReleaseDate == NULL) { + + SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR053, SK_PNMI_ERR053MSG); + + *pLen = 0; + return (SK_PNMI_ERR_GENERAL); + } + + Len = SK_STRLEN(pAC->Pnmi.pDriverReleaseDate) + 1; + if (Len > SK_PNMI_STRINGLEN1) { + + SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR054, SK_PNMI_ERR054MSG); + + *pLen = 0; + return (SK_PNMI_ERR_GENERAL); + } + + if (*pLen < Len) { + + *pLen = Len; + return (SK_PNMI_ERR_TOO_SHORT); + } + *pBuf = (char)(Len - 1); + SK_MEMCPY(pBuf + 1, pAC->Pnmi.pDriverReleaseDate, Len - 1); + *pLen = Len; + break; + + case OID_SKGE_DRIVER_FILENAME: + if (pAC->Pnmi.pDriverFileName == NULL) { + + SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR055, SK_PNMI_ERR055MSG); + + *pLen = 0; + return (SK_PNMI_ERR_GENERAL); + } + + Len = SK_STRLEN(pAC->Pnmi.pDriverFileName) + 1; + if (Len > SK_PNMI_STRINGLEN1) { + + SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR056, SK_PNMI_ERR056MSG); + + *pLen = 0; + return (SK_PNMI_ERR_GENERAL); + } + + if (*pLen < Len) { + + *pLen = Len; + return (SK_PNMI_ERR_TOO_SHORT); + } + *pBuf = (char)(Len - 1); + SK_MEMCPY(pBuf + 1, pAC->Pnmi.pDriverFileName, Len - 1); + *pLen = Len; + break; + + case OID_SKGE_HW_DESCR: + /* + * The hardware description is located in the VPD. This + * query may move to the initialisation routine. But + * the VPD data is cached and therefore a call here + * will not make much difference. + * Please read comment in Vpd(). + */ + if (pAC->Pnmi.VpdKeyReadError == SK_TRUE) { + return (SK_PNMI_ERR_OK); + } + + Len = 256; + if (VpdRead(pAC, IoC, VPD_NAME, Buf, (int *)&Len) > 0) { + + SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR032, SK_PNMI_ERR032MSG); + + *pLen = 0; + return (SK_PNMI_ERR_GENERAL); + } + Len ++; + if (Len > SK_PNMI_STRINGLEN1) { + + SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR033, SK_PNMI_ERR033MSG); + + *pLen = 0; + return (SK_PNMI_ERR_GENERAL); + } + if (*pLen < Len) { + + *pLen = Len; + return (SK_PNMI_ERR_TOO_SHORT); + } + *pBuf = (char)(Len - 1); + SK_MEMCPY(pBuf + 1, Buf, Len - 1); + *pLen = Len; + break; + + case OID_SKGE_HW_VERSION: + if (*pLen < 5) { + + *pLen = 5; + return (SK_PNMI_ERR_TOO_SHORT); + } + Val8 = (SK_U8)pAC->GIni.GIPciHwRev; + pBuf[0] = 4; + pBuf[1] = 'v'; + pBuf[2] = (char)('0' | ((Val8 >> 4) & 0x0f)); + pBuf[3] = '.'; + pBuf[4] = (char)('0' | (Val8 & 0x0f)); + *pLen = 5; + break; + + case OID_SKGE_CHIPSET: + Val16 = pAC->Pnmi.Chipset; + SK_PNMI_STORE_U16(pBuf, Val16); + *pLen = sizeof(SK_U16); + break; + + case OID_SKGE_CHIPID: + Val32 = pAC->GIni.GIChipId; + SK_PNMI_STORE_U32(pBuf, Val32); + *pLen = sizeof(SK_U32); + break; + + case OID_SKGE_RAMSIZE: + Val32 = pAC->GIni.GIRamSize; + SK_PNMI_STORE_U32(pBuf, Val32); + *pLen = sizeof(SK_U32); + break; + + case OID_SKGE_VAUXAVAIL: + *pBuf = (char)pAC->GIni.GIVauxAvail; + *pLen = sizeof(char); + break; + + case OID_SKGE_BUS_TYPE: + *pBuf = (char)SK_PNMI_BUS_PCI; + *pLen = sizeof(char); + break; + + case OID_SKGE_BUS_SPEED: + *pBuf = pAC->Pnmi.PciBusSpeed; + *pLen = sizeof(char); + break; + + case OID_SKGE_BUS_WIDTH: + *pBuf = pAC->Pnmi.PciBusWidth; + *pLen = sizeof(char); + break; + + case OID_SKGE_RESULT: + Val32 = pAC->Pnmi.TestResult; + SK_PNMI_STORE_U32(pBuf, Val32); + *pLen = sizeof(SK_U32); + break; + + case OID_SKGE_SENSOR_NUMBER: + *pBuf = (char)pAC->I2c.MaxSens; + *pLen = sizeof(char); + break; + + case OID_SKGE_CHKSM_NUMBER: + *pBuf = SKCS_NUM_PROTOCOLS; + *pLen = sizeof(char); + break; + + case OID_SKGE_TRAP_NUMBER: + GetTrapQueueLen(pAC, &Len, &Val); + Val32 = (SK_U32)Val; + SK_PNMI_STORE_U32(pBuf, Val32); + *pLen = sizeof(SK_U32); + break; + + case OID_SKGE_TRAP: + GetTrapQueueLen(pAC, &Len, &Val); + if (*pLen < Len) { + + *pLen = Len; + return (SK_PNMI_ERR_TOO_SHORT); + } + CopyTrapQueue(pAC, pBuf); + *pLen = Len; + break; + + case OID_SKGE_RLMT_MONITOR_NUMBER: + /* Not yet implemented by RLMT, therefore we return zero elements. */ + Val32 = 0; + SK_PNMI_STORE_U32(pBuf, Val32); + *pLen = sizeof(SK_U32); + break; + + case OID_SKGE_TX_SW_QUEUE_LEN: + /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort). */ + if (MacType == SK_MAC_XMAC) { + /* DualNet mode. */ + if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { + Val64 = pAC->Pnmi.BufPort[NetIndex].TxSwQueueLen; + } + /* SingleNet mode. */ + else { + Val64 = pAC->Pnmi.BufPort[0].TxSwQueueLen + + pAC->Pnmi.BufPort[1].TxSwQueueLen; + } + } + else { + /* DualNet mode. */ + if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { + Val64 = pAC->Pnmi.Port[NetIndex].TxSwQueueLen; + } + /* SingleNet mode. */ + else { + Val64 = pAC->Pnmi.Port[0].TxSwQueueLen + + pAC->Pnmi.Port[1].TxSwQueueLen; + } + } + SK_PNMI_STORE_U64(pBuf, Val64); + *pLen = sizeof(SK_U64); + break; + + + case OID_SKGE_TX_SW_QUEUE_MAX: + /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort). */ + if (MacType == SK_MAC_XMAC) { + /* DualNet mode. */ + if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { + Val64 = pAC->Pnmi.BufPort[NetIndex].TxSwQueueMax; + } + /* SingleNet mode. */ + else { + Val64 = pAC->Pnmi.BufPort[0].TxSwQueueMax + + pAC->Pnmi.BufPort[1].TxSwQueueMax; + } + } + else { + /* DualNet mode. */ + if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { + Val64 = pAC->Pnmi.Port[NetIndex].TxSwQueueMax; + } + /* SingleNet mode. */ + else { + Val64 = pAC->Pnmi.Port[0].TxSwQueueMax + + pAC->Pnmi.Port[1].TxSwQueueMax; + } + } + SK_PNMI_STORE_U64(pBuf, Val64); + *pLen = sizeof(SK_U64); + break; + + case OID_SKGE_TX_RETRY: + /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort). */ + if (MacType == SK_MAC_XMAC) { + /* DualNet mode. */ + if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { + Val64 = pAC->Pnmi.BufPort[NetIndex].TxRetryCts; + } + /* SingleNet mode. */ + else { + Val64 = pAC->Pnmi.BufPort[0].TxRetryCts + + pAC->Pnmi.BufPort[1].TxRetryCts; + } + } + else { + /* DualNet mode. */ + if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { + Val64 = pAC->Pnmi.Port[NetIndex].TxRetryCts; + } + /* SingleNet mode. */ + else { + Val64 = pAC->Pnmi.Port[0].TxRetryCts + + pAC->Pnmi.Port[1].TxRetryCts; + } + } + SK_PNMI_STORE_U64(pBuf, Val64); + *pLen = sizeof(SK_U64); + break; + + case OID_SKGE_RX_INTR_CTS: + /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort). */ + if (MacType == SK_MAC_XMAC) { + /* DualNet mode. */ + if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { + Val64 = pAC->Pnmi.BufPort[NetIndex].RxIntrCts; + } + /* SingleNet mode. */ + else { + Val64 = pAC->Pnmi.BufPort[0].RxIntrCts + + pAC->Pnmi.BufPort[1].RxIntrCts; + } + } + else { + /* DualNet mode. */ + if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { + Val64 = pAC->Pnmi.Port[NetIndex].RxIntrCts; + } + /* SingleNet mode. */ + else { + Val64 = pAC->Pnmi.Port[0].RxIntrCts + + pAC->Pnmi.Port[1].RxIntrCts; + } + } + SK_PNMI_STORE_U64(pBuf, Val64); + *pLen = sizeof(SK_U64); + break; + + case OID_SKGE_TX_INTR_CTS: + /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort). */ + if (MacType == SK_MAC_XMAC) { + /* DualNet mode. */ + if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { + Val64 = pAC->Pnmi.BufPort[NetIndex].TxIntrCts; + } + /* SingleNet mode. */ + else { + Val64 = pAC->Pnmi.BufPort[0].TxIntrCts + + pAC->Pnmi.BufPort[1].TxIntrCts; + } + } + else { + /* DualNet mode. */ + if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { + Val64 = pAC->Pnmi.Port[NetIndex].TxIntrCts; + } + /* SingleNet mode. */ + else { + Val64 = pAC->Pnmi.Port[0].TxIntrCts + + pAC->Pnmi.Port[1].TxIntrCts; + } + } + SK_PNMI_STORE_U64(pBuf, Val64); + *pLen = sizeof(SK_U64); + break; + + case OID_SKGE_RX_NO_BUF_CTS: + /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort). */ + if (MacType == SK_MAC_XMAC) { + /* DualNet mode. */ + if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { + Val64 = pAC->Pnmi.BufPort[NetIndex].RxNoBufCts; + } + /* SingleNet mode. */ + else { + Val64 = pAC->Pnmi.BufPort[0].RxNoBufCts + + pAC->Pnmi.BufPort[1].RxNoBufCts; + } + } + else { + /* DualNet mode. */ + if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { + Val64 = pAC->Pnmi.Port[NetIndex].RxNoBufCts; + } + /* SingleNet mode. */ + else { + Val64 = pAC->Pnmi.Port[0].RxNoBufCts + + pAC->Pnmi.Port[1].RxNoBufCts; + } + } + SK_PNMI_STORE_U64(pBuf, Val64); + *pLen = sizeof(SK_U64); + break; + + case OID_SKGE_TX_NO_BUF_CTS: + /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort). */ + if (MacType == SK_MAC_XMAC) { + /* DualNet mode. */ + if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { + Val64 = pAC->Pnmi.BufPort[NetIndex].TxNoBufCts; + } + /* SingleNet mode. */ + else { + Val64 = pAC->Pnmi.BufPort[0].TxNoBufCts + + pAC->Pnmi.BufPort[1].TxNoBufCts; + } + } + else { + /* DualNet mode. */ + if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { + Val64 = pAC->Pnmi.Port[NetIndex].TxNoBufCts; + } + /* SingleNet mode. */ + else { + Val64 = pAC->Pnmi.Port[0].TxNoBufCts + + pAC->Pnmi.Port[1].TxNoBufCts; + } + } + SK_PNMI_STORE_U64(pBuf, Val64); + *pLen = sizeof(SK_U64); + break; + + case OID_SKGE_TX_USED_DESCR_NO: + /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort). */ + if (MacType == SK_MAC_XMAC) { + /* DualNet mode. */ + if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { + Val64 = pAC->Pnmi.BufPort[NetIndex].TxUsedDescrNo; + } + /* SingleNet mode. */ + else { + Val64 = pAC->Pnmi.BufPort[0].TxUsedDescrNo + + pAC->Pnmi.BufPort[1].TxUsedDescrNo; + } + } + else { + /* DualNet mode. */ + if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { + Val64 = pAC->Pnmi.Port[NetIndex].TxUsedDescrNo; + } + /* SingleNet mode. */ + else { + Val64 = pAC->Pnmi.Port[0].TxUsedDescrNo + + pAC->Pnmi.Port[1].TxUsedDescrNo; + } + } + SK_PNMI_STORE_U64(pBuf, Val64); + *pLen = sizeof(SK_U64); + break; + + case OID_SKGE_RX_DELIVERED_CTS: + /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort). */ + if (MacType == SK_MAC_XMAC) { + /* DualNet mode. */ + if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { + Val64 = pAC->Pnmi.BufPort[NetIndex].RxDeliveredCts; + } + /* SingleNet mode. */ + else { + Val64 = pAC->Pnmi.BufPort[0].RxDeliveredCts + + pAC->Pnmi.BufPort[1].RxDeliveredCts; + } + } + else { + /* DualNet mode. */ + if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { + Val64 = pAC->Pnmi.Port[NetIndex].RxDeliveredCts; + } + /* SingleNet mode. */ + else { + Val64 = pAC->Pnmi.Port[0].RxDeliveredCts + + pAC->Pnmi.Port[1].RxDeliveredCts; + } + } + SK_PNMI_STORE_U64(pBuf, Val64); + *pLen = sizeof(SK_U64); + break; + + case OID_SKGE_RX_OCTETS_DELIV_CTS: + /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort). */ + if (MacType == SK_MAC_XMAC) { + /* DualNet mode. */ + if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { + Val64 = pAC->Pnmi.BufPort[NetIndex].RxOctetsDeliveredCts; + } + /* SingleNet mode. */ + else { + Val64 = pAC->Pnmi.BufPort[0].RxOctetsDeliveredCts + + pAC->Pnmi.BufPort[1].RxOctetsDeliveredCts; + } + } + else { + /* DualNet mode. */ + if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { + Val64 = pAC->Pnmi.Port[NetIndex].RxOctetsDeliveredCts; + } + /* SingleNet mode. */ + else { + Val64 = pAC->Pnmi.Port[0].RxOctetsDeliveredCts + + pAC->Pnmi.Port[1].RxOctetsDeliveredCts; + } + } + SK_PNMI_STORE_U64(pBuf, Val64); + *pLen = sizeof(SK_U64); + break; + + case OID_SKGE_RX_HW_ERROR_CTS: + SK_PNMI_STORE_U64(pBuf, Val64RxHwErrs); + *pLen = sizeof(SK_U64); + break; + + case OID_SKGE_TX_HW_ERROR_CTS: + SK_PNMI_STORE_U64(pBuf, Val64TxHwErrs); + *pLen = sizeof(SK_U64); + break; + + case OID_SKGE_IN_ERRORS_CTS: + /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort). */ + if (MacType == SK_MAC_XMAC) { + /* DualNet mode. */ + if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { + Val64 = Val64RxHwErrs + pAC->Pnmi.BufPort[NetIndex].RxNoBufCts; + } + /* SingleNet mode. */ + else { + Val64 = Val64RxHwErrs + + pAC->Pnmi.BufPort[0].RxNoBufCts + + pAC->Pnmi.BufPort[1].RxNoBufCts; + } + } + else { + /* DualNet mode. */ + if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { + Val64 = Val64RxHwErrs + pAC->Pnmi.Port[NetIndex].RxNoBufCts; + } + /* SingleNet mode. */ + else { + Val64 = Val64RxHwErrs + + pAC->Pnmi.Port[0].RxNoBufCts + + pAC->Pnmi.Port[1].RxNoBufCts; + } + } + SK_PNMI_STORE_U64(pBuf, Val64); + *pLen = sizeof(SK_U64); + break; + + case OID_SKGE_OUT_ERROR_CTS: + /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort). */ + if (MacType == SK_MAC_XMAC) { + /* DualNet mode. */ + if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { + Val64 = Val64TxHwErrs + pAC->Pnmi.BufPort[NetIndex].TxNoBufCts; + } + /* SingleNet mode. */ + else { + Val64 = Val64TxHwErrs + + pAC->Pnmi.BufPort[0].TxNoBufCts + + pAC->Pnmi.BufPort[1].TxNoBufCts; + } + } + else { + /* DualNet mode. */ + if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { + Val64 = Val64TxHwErrs + pAC->Pnmi.Port[NetIndex].TxNoBufCts; + } + /* SingleNet mode. */ + else { + Val64 = Val64TxHwErrs + + pAC->Pnmi.Port[0].TxNoBufCts + + pAC->Pnmi.Port[1].TxNoBufCts; + } + } + SK_PNMI_STORE_U64(pBuf, Val64); + *pLen = sizeof(SK_U64); + break; + + case OID_SKGE_ERR_RECOVERY_CTS: + /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort). */ + if (MacType == SK_MAC_XMAC) { + /* DualNet mode. */ + if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { + Val64 = pAC->Pnmi.BufPort[NetIndex].ErrRecoveryCts; + } + /* SingleNet mode. */ + else { + Val64 = pAC->Pnmi.BufPort[0].ErrRecoveryCts + + pAC->Pnmi.BufPort[1].ErrRecoveryCts; + } + } + else { + /* DualNet mode. */ + if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { + Val64 = pAC->Pnmi.Port[NetIndex].ErrRecoveryCts; + } + /* SingleNet mode. */ + else { + Val64 = pAC->Pnmi.Port[0].ErrRecoveryCts + + pAC->Pnmi.Port[1].ErrRecoveryCts; + } + } + SK_PNMI_STORE_U64(pBuf, Val64); + *pLen = sizeof(SK_U64); + break; + + case OID_SKGE_SYSUPTIME: + Val64 = SK_PNMI_HUNDREDS_SEC(SkOsGetTime(pAC)); + Val64 -= pAC->Pnmi.StartUpTime; + SK_PNMI_STORE_U64(pBuf, Val64); + *pLen = sizeof(SK_U64); + break; + + case OID_SKGE_MDB_VERSION: + Val32 = SK_PNMI_MDB_VERSION; + SK_PNMI_STORE_U32(pBuf, Val32); + *pLen = sizeof(SK_U32); + break; + + case OID_GEN_RCV_ERROR: + /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort). */ + if (MacType == SK_MAC_XMAC) { + Val64 = Val64RxHwErrs + pAC->Pnmi.BufPort[NetIndex].RxNoBufCts; + } + else { + Val64 = Val64RxHwErrs + pAC->Pnmi.Port[NetIndex].RxNoBufCts; + } + + /* + * By default 32bit values are evaluated. + */ + if (!Is64BitReq) { + Val32 = (SK_U32)Val64; + SK_PNMI_STORE_U32(pBuf, Val32); + *pLen = sizeof(SK_U32); + } + else { + SK_PNMI_STORE_U64(pBuf, Val64); + *pLen = sizeof(SK_U64); + } + break; + + case OID_GEN_XMIT_ERROR: + /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort). */ + if (MacType == SK_MAC_XMAC) { + Val64 = Val64TxHwErrs + pAC->Pnmi.BufPort[NetIndex].TxNoBufCts; + } + else { + Val64 = Val64TxHwErrs + pAC->Pnmi.Port[NetIndex].TxNoBufCts; + } + + /* + * By default 32bit values are evaluated. + */ + if (!Is64BitReq) { + Val32 = (SK_U32)Val64; + SK_PNMI_STORE_U32(pBuf, Val32); + *pLen = sizeof(SK_U32); + } + else { + SK_PNMI_STORE_U64(pBuf, Val64); + *pLen = sizeof(SK_U64); + } + break; + + case OID_GEN_RCV_NO_BUFFER: + /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort). */ + if (MacType == SK_MAC_XMAC) { + Val64 = pAC->Pnmi.BufPort[NetIndex].RxNoBufCts + + GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_OVERFLOW, NetIndex); + + } + else { + Val64 = pAC->Pnmi.Port[NetIndex].RxNoBufCts + + GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_OVERFLOW, NetIndex); + } + + /* + * By default 32bit values are evaluated. + */ + if (!Is64BitReq) { + Val32 = (SK_U32)Val64; + SK_PNMI_STORE_U32(pBuf, Val32); + *pLen = sizeof(SK_U32); + } + else { + SK_PNMI_STORE_U64(pBuf, Val64); + *pLen = sizeof(SK_U64); + } + break; + + case OID_GEN_TRANSMIT_QUEUE_LENGTH: + Val32 = (SK_U32)pAC->Pnmi.Port[NetIndex].TxSwQueueLen; + SK_PNMI_STORE_U32(pBuf, Val32); + *pLen = sizeof(SK_U32); + break; + + default: + SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR034, SK_PNMI_ERR034MSG); + + *pLen = 0; + return (SK_PNMI_ERR_GENERAL); + } + + if (Id == OID_SKGE_RX_HW_ERROR_CTS || + Id == OID_SKGE_TX_HW_ERROR_CTS || + Id == OID_SKGE_IN_ERRORS_CTS || + Id == OID_SKGE_OUT_ERROR_CTS || + Id == OID_GEN_XMIT_ERROR || + Id == OID_GEN_RCV_ERROR) { + + pAC->Pnmi.MacUpdatedFlag --; + } + + return (SK_PNMI_ERR_OK); +} + +/***************************************************************************** + * + * Rlmt - OID handler function of OID_SKGE_RLMT_XXX single instance. + * + * Description: + * Get/Presets/Sets the RLMT OIDs. + * + * Returns: + * SK_PNMI_ERR_OK The request was successfully performed. + * SK_PNMI_ERR_GENERAL A general severe internal error occured. + * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain + * the correct data (e.g. a 32bit value is + * needed, but a 16 bit value was passed). + * SK_PNMI_ERR_BAD_VALUE The passed value is not in the valid + * value range. + * SK_PNMI_ERR_READ_ONLY The OID is read-only and cannot be set. + * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't + * exist (e.g. port instance 3 on a two port + * adapter. + */ +PNMI_STATIC int Rlmt( +SK_AC *pAC, /* Pointer to adapter context */ +SK_IOC IoC, /* IO context handle */ +int Action, /* GET/PRESET/SET action */ +SK_U32 Id, /* Object ID that is to be processed */ +char *pBuf, /* Buffer used for the management data transfer */ +unsigned int *pLen, /* On call: pBuf buffer length. On return: used buffer */ +SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */ +unsigned int TableIndex, /* Index to the Id table */ +SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */ +{ + int Ret; + unsigned int PhysPortIndex; + unsigned int PhysPortMax; + SK_EVPARA EventParam; + SK_U32 Val32; + SK_U64 Val64; + + /* Check instance. Only single instance OIDs are allowed here. */ + if (Instance != (SK_U32)(-1) && Instance != 1) { + + *pLen = 0; + return (SK_PNMI_ERR_UNKNOWN_INST); + } + + /* Perform the requested action. */ + if (Action == SK_PNMI_GET) { + + /* Check if the buffer length is large enough. */ + switch (Id) { + + case OID_SKGE_RLMT_MODE: + case OID_SKGE_RLMT_PORT_ACTIVE: + case OID_SKGE_RLMT_PORT_PREFERRED: + if (*pLen < sizeof(SK_U8)) { + + *pLen = sizeof(SK_U8); + return (SK_PNMI_ERR_TOO_SHORT); + } + break; + + case OID_SKGE_RLMT_PORT_NUMBER: + if (*pLen < sizeof(SK_U32)) { + + *pLen = sizeof(SK_U32); + return (SK_PNMI_ERR_TOO_SHORT); + } + break; + + case OID_SKGE_RLMT_CHANGE_CTS: + case OID_SKGE_RLMT_CHANGE_TIME: + case OID_SKGE_RLMT_CHANGE_ESTIM: + case OID_SKGE_RLMT_CHANGE_THRES: + if (*pLen < sizeof(SK_U64)) { + + *pLen = sizeof(SK_U64); + return (SK_PNMI_ERR_TOO_SHORT); + } + break; + + default: + SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR035, SK_PNMI_ERR035MSG); + + *pLen = 0; + return (SK_PNMI_ERR_GENERAL); + } + + /* + * Update RLMT statistic and increment semaphores to indicate + * that an update was already done. Maybe RLMT will hold its + * statistic always up to date some time. Then we can + * remove this type of call. + */ + if ((Ret = RlmtUpdate(pAC, IoC, NetIndex)) != SK_PNMI_ERR_OK) { + + *pLen = 0; + return (Ret); + } + pAC->Pnmi.RlmtUpdatedFlag ++; + + /* Retrieve value. */ + switch (Id) { + + case OID_SKGE_RLMT_MODE: + *pBuf = (char)pAC->Rlmt.Net[0].RlmtMode; + *pLen = sizeof(char); + break; + + case OID_SKGE_RLMT_PORT_NUMBER: + Val32 = (SK_U32)pAC->GIni.GIMacsFound; + SK_PNMI_STORE_U32(pBuf, Val32); + *pLen = sizeof(SK_U32); + break; + + case OID_SKGE_RLMT_PORT_ACTIVE: + *pBuf = 0; + /* + * If multiple ports may become active this OID + * doesn't make sense any more. A new variable in + * the port structure should be created. However, + * for this variable the first active port is + * returned. + */ + PhysPortMax = pAC->GIni.GIMacsFound; + + for (PhysPortIndex = 0; PhysPortIndex < PhysPortMax; + PhysPortIndex ++) { + + if (pAC->Pnmi.Port[PhysPortIndex].ActiveFlag) { + + *pBuf = (char)SK_PNMI_PORT_PHYS2LOG(PhysPortIndex); + break; + } + } + *pLen = sizeof(char); + break; + + case OID_SKGE_RLMT_PORT_PREFERRED: + *pBuf = (char)SK_PNMI_PORT_PHYS2LOG(pAC->Rlmt.Net[NetIndex].Preference); + *pLen = sizeof(char); + break; + + case OID_SKGE_RLMT_CHANGE_CTS: + Val64 = pAC->Pnmi.RlmtChangeCts; + SK_PNMI_STORE_U64(pBuf, Val64); + *pLen = sizeof(SK_U64); + break; + + case OID_SKGE_RLMT_CHANGE_TIME: + Val64 = pAC->Pnmi.RlmtChangeTime; + SK_PNMI_STORE_U64(pBuf, Val64); + *pLen = sizeof(SK_U64); + break; + + case OID_SKGE_RLMT_CHANGE_ESTIM: + Val64 = pAC->Pnmi.RlmtChangeEstimate.Estimate; + SK_PNMI_STORE_U64(pBuf, Val64); + *pLen = sizeof(SK_U64); + break; + + case OID_SKGE_RLMT_CHANGE_THRES: + Val64 = pAC->Pnmi.RlmtChangeThreshold; + SK_PNMI_STORE_U64(pBuf, Val64); + *pLen = sizeof(SK_U64); + break; + + default: + SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_ERR, + ("Rlmt: Unknown OID should be handled before")); + + pAC->Pnmi.RlmtUpdatedFlag --; + *pLen = 0; + return (SK_PNMI_ERR_GENERAL); + } + + pAC->Pnmi.RlmtUpdatedFlag --; + } + else { + /* Perform a PRESET or SET. */ + switch (Id) { + + case OID_SKGE_RLMT_MODE: + /* Check if the buffer length is plausible. */ + if (*pLen < sizeof(char)) { + + *pLen = sizeof(char); + return (SK_PNMI_ERR_TOO_SHORT); + } + /* Check if the value range is correct. */ + if (*pLen != sizeof(char) || + (*pBuf & SK_PNMI_RLMT_MODE_CHK_LINK) == 0 || + *(SK_U8 *)pBuf > 15) { + + *pLen = 0; + return (SK_PNMI_ERR_BAD_VALUE); + } + /* The PRESET ends here. */ + if (Action == SK_PNMI_PRESET) { + + *pLen = 0; + return (SK_PNMI_ERR_OK); + } + /* Send an event to RLMT to change the mode. */ + SK_MEMSET((char *)&EventParam, 0, sizeof(EventParam)); + + EventParam.Para32[0] |= (SK_U32)(*pBuf); + EventParam.Para32[1] = 0; + if (SkRlmtEvent(pAC, IoC, SK_RLMT_MODE_CHANGE, + EventParam) > 0) { + + SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR037, SK_PNMI_ERR037MSG); + + *pLen = 0; + return (SK_PNMI_ERR_GENERAL); + } + break; + + case OID_SKGE_RLMT_PORT_PREFERRED: + /* PRESET/SET action makes no sense in Dual Net mode. */ + if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { + break; + } + + /* Check if the buffer length is plausible. */ + if (*pLen < sizeof(char)) { + + *pLen = sizeof(char); + return (SK_PNMI_ERR_TOO_SHORT); + } + /* Check if the value range is correct. */ + if (*pLen != sizeof(char) || *(SK_U8 *)pBuf > + (SK_U8)pAC->GIni.GIMacsFound) { + + *pLen = 0; + return (SK_PNMI_ERR_BAD_VALUE); + } + /* The PRESET ends here. */ + if (Action == SK_PNMI_PRESET) { + + *pLen = 0; + return (SK_PNMI_ERR_OK); + } + + /* + * Send an event to RLMT change the preferred port. + * A param of -1 means automatic mode. RLMT will + * make the decision which is the preferred port. + */ + SK_MEMSET((char *)&EventParam, 0, sizeof(EventParam)); + + EventParam.Para32[0] = (SK_U32)(*pBuf) - 1; + EventParam.Para32[1] = NetIndex; + if (SkRlmtEvent(pAC, IoC, SK_RLMT_PREFPORT_CHANGE, + EventParam) > 0) { + + SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR038, SK_PNMI_ERR038MSG); + + *pLen = 0; + return (SK_PNMI_ERR_GENERAL); + } + break; + + case OID_SKGE_RLMT_CHANGE_THRES: + /* Check if the buffer length is plausible. */ + if (*pLen < sizeof(SK_U64)) { + + *pLen = sizeof(SK_U64); + return (SK_PNMI_ERR_TOO_SHORT); + } + + /* There are not many restrictions to the value range. */ + if (*pLen != sizeof(SK_U64)) { + + *pLen = 0; + return (SK_PNMI_ERR_BAD_VALUE); + } + /* The PRESET ends here. */ + if (Action == SK_PNMI_PRESET) { + + *pLen = 0; + return (SK_PNMI_ERR_OK); + } + /* + * Store the new threshold, which will be taken + * on the next timer event. + */ + SK_PNMI_READ_U64(pBuf, Val64); + pAC->Pnmi.RlmtChangeThreshold = Val64; + break; + + default: + /* The other OIDs are not be able for set. */ + *pLen = 0; + return (SK_PNMI_ERR_READ_ONLY); + } + } + + return (SK_PNMI_ERR_OK); +} + +/***************************************************************************** + * + * RlmtStat - OID handler function of OID_SKGE_RLMT_XXX multiple instance. + * + * Description: + * Performs get requests on multiple instance variables. + * + * Returns: + * SK_PNMI_ERR_OK The request was successfully performed. + * SK_PNMI_ERR_GENERAL A general severe internal error occured. + * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain + * the correct data (e.g. a 32bit value is + * needed, but a 16 bit value was passed). + * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't + * exist (e.g. port instance 3 on a two port + * adapter. + */ +PNMI_STATIC int RlmtStat( +SK_AC *pAC, /* Pointer to adapter context */ +SK_IOC IoC, /* IO context handle */ +int Action, /* GET/PRESET/SET action */ +SK_U32 Id, /* Object ID that is to be processed */ +char *pBuf, /* Buffer used for the management data transfer */ +unsigned int *pLen, /* On call: pBuf buffer length. On return: used buffer */ +SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */ +unsigned int TableIndex, /* Index to the Id table */ +SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */ +{ + unsigned int PhysPortMax; + unsigned int PhysPortIndex; + unsigned int Limit; + unsigned int Offset; + int Ret; + SK_U32 Val32; + SK_U64 Val64; + + + /* Calculate the port indexes from the instance. */ + PhysPortMax = pAC->GIni.GIMacsFound; + + if ((Instance != (SK_U32)(-1))) { + /* Check instance range. */ + if ((Instance < 1) || (Instance > PhysPortMax)) { + + *pLen = 0; + return (SK_PNMI_ERR_UNKNOWN_INST); + } + + /* SingleNet mode. */ + PhysPortIndex = Instance - 1; + + /* DualNet mode. */ + if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { + PhysPortIndex = NetIndex; + } + + /* Both net modes. */ + Limit = PhysPortIndex + 1; + } + else { + /* SingleNet mode. */ + PhysPortIndex = 0; + Limit = PhysPortMax; + + /* DualNet mode. */ + if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { + PhysPortIndex = NetIndex; + Limit = PhysPortIndex + 1; + } + } + + /* Currently only GET requests are allowed. */ + if (Action != SK_PNMI_GET) { + + *pLen = 0; + return (SK_PNMI_ERR_READ_ONLY); + } + + /* Check if the buffer length is large enough. */ + switch (Id) { + + case OID_SKGE_RLMT_PORT_INDEX: + case OID_SKGE_RLMT_STATUS: + if (*pLen < (Limit - PhysPortIndex) * sizeof(SK_U32)) { + + *pLen = (Limit - PhysPortIndex) * sizeof(SK_U32); + return (SK_PNMI_ERR_TOO_SHORT); + } + break; + + case OID_SKGE_RLMT_TX_HELLO_CTS: + case OID_SKGE_RLMT_RX_HELLO_CTS: + case OID_SKGE_RLMT_TX_SP_REQ_CTS: + case OID_SKGE_RLMT_RX_SP_CTS: + if (*pLen < (Limit - PhysPortIndex) * sizeof(SK_U64)) { + + *pLen = (Limit - PhysPortIndex) * sizeof(SK_U64); + return (SK_PNMI_ERR_TOO_SHORT); + } + break; + + default: + SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR039, SK_PNMI_ERR039MSG); + + *pLen = 0; + return (SK_PNMI_ERR_GENERAL); + + } + + /* + * Update statistic and increment semaphores to indicate that + * an update was already done. + */ + if ((Ret = RlmtUpdate(pAC, IoC, NetIndex)) != SK_PNMI_ERR_OK) { + + *pLen = 0; + return (Ret); + } + pAC->Pnmi.RlmtUpdatedFlag ++; + + /* Get value. */ + Offset = 0; + for (; PhysPortIndex < Limit; PhysPortIndex ++) { + + switch (Id) { + + case OID_SKGE_RLMT_PORT_INDEX: + Val32 = PhysPortIndex; + SK_PNMI_STORE_U32(pBuf + Offset, Val32); + Offset += sizeof(SK_U32); + break; + + case OID_SKGE_RLMT_STATUS: + if (pAC->Rlmt.Port[PhysPortIndex].PortState == + SK_RLMT_PS_INIT || + pAC->Rlmt.Port[PhysPortIndex].PortState == + SK_RLMT_PS_DOWN) { + + Val32 = SK_PNMI_RLMT_STATUS_ERROR; + } + else if (pAC->Pnmi.Port[PhysPortIndex].ActiveFlag) { + + Val32 = SK_PNMI_RLMT_STATUS_ACTIVE; + } + else { + Val32 = SK_PNMI_RLMT_STATUS_STANDBY; + } + SK_PNMI_STORE_U32(pBuf + Offset, Val32); + Offset += sizeof(SK_U32); + break; + + case OID_SKGE_RLMT_TX_HELLO_CTS: + Val64 = pAC->Rlmt.Port[PhysPortIndex].TxHelloCts; + SK_PNMI_STORE_U64(pBuf + Offset, Val64); + Offset += sizeof(SK_U64); + break; + + case OID_SKGE_RLMT_RX_HELLO_CTS: + Val64 = pAC->Rlmt.Port[PhysPortIndex].RxHelloCts; + SK_PNMI_STORE_U64(pBuf + Offset, Val64); + Offset += sizeof(SK_U64); + break; + + case OID_SKGE_RLMT_TX_SP_REQ_CTS: + Val64 = pAC->Rlmt.Port[PhysPortIndex].TxSpHelloReqCts; + SK_PNMI_STORE_U64(pBuf + Offset, Val64); + Offset += sizeof(SK_U64); + break; + + case OID_SKGE_RLMT_RX_SP_CTS: + Val64 = pAC->Rlmt.Port[PhysPortIndex].RxSpHelloCts; + SK_PNMI_STORE_U64(pBuf + Offset, Val64); + Offset += sizeof(SK_U64); + break; + + default: + SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_ERR, + ("RlmtStat: Unknown OID should be errored before")); + + pAC->Pnmi.RlmtUpdatedFlag --; + *pLen = 0; + return (SK_PNMI_ERR_GENERAL); + } + } + *pLen = Offset; + + pAC->Pnmi.RlmtUpdatedFlag --; + + return (SK_PNMI_ERR_OK); +} + +/***************************************************************************** + * + * MacPrivateConf - OID handler function of OIDs concerning the configuration + * + * Description: + * Get/Presets/Sets the OIDs concerning the configuration. + * + * Returns: + * SK_PNMI_ERR_OK The request was successfully performed. + * SK_PNMI_ERR_GENERAL A general severe internal error occured. + * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain + * the correct data (e.g. a 32bit value is + * needed, but a 16 bit value was passed). + * SK_PNMI_ERR_BAD_VALUE The passed value is not in the valid + * value range. + * SK_PNMI_ERR_READ_ONLY The OID is read-only and cannot be set. + * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't + * exist (e.g. port instance 3 on a two port + * adapter. + */ +PNMI_STATIC int MacPrivateConf( +SK_AC *pAC, /* Pointer to adapter context */ +SK_IOC IoC, /* IO context handle */ +int Action, /* GET/PRESET/SET action */ +SK_U32 Id, /* Object ID that is to be processed */ +char *pBuf, /* Buffer used for the management data transfer */ +unsigned int *pLen, /* On call: pBuf buffer length. On return: used buffer */ +SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */ +unsigned int TableIndex, /* Index to the Id table */ +SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */ +{ + unsigned int PhysPortMax; + unsigned int PhysPortIndex; + unsigned int LogPortMax; + unsigned int LogPortIndex; + unsigned int Limit; + unsigned int Offset; + char Val8; + char *pBufPtr; + int Ret; + SK_EVPARA EventParam; + SK_U32 Val32; +#ifdef SK_PHY_LP_MODE + SK_U8 CurrentPhyPowerState; +#endif /* SK_PHY_LP_MODE */ + + + /* Calculate instance if wished. MAC index 0 is the virtual MAC. */ + PhysPortMax = pAC->GIni.GIMacsFound; + LogPortMax = SK_PNMI_PORT_PHYS2LOG(PhysPortMax); + + if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { /* DualNet mode. */ + LogPortMax--; + } + + if ((Instance != (SK_U32)(-1))) { /* Only one specific instance is queried. */ + /* Check instance range. */ + if ((Instance < 1) || (Instance > LogPortMax)) { + + *pLen = 0; + return (SK_PNMI_ERR_UNKNOWN_INST); + } + LogPortIndex = SK_PNMI_PORT_INST2LOG(Instance); + Limit = LogPortIndex + 1; + } + + else { /* Instance == (SK_U32)(-1), get all Instances of that OID. */ + + LogPortIndex = 0; + Limit = LogPortMax; + } + + /* Perform action. */ + if (Action == SK_PNMI_GET) { + + /* Check length. */ + switch (Id) { + + case OID_SKGE_PMD: + case OID_SKGE_CONNECTOR: + case OID_SKGE_LINK_CAP: + case OID_SKGE_LINK_MODE: + case OID_SKGE_LINK_MODE_STATUS: + case OID_SKGE_LINK_STATUS: + case OID_SKGE_FLOWCTRL_CAP: + case OID_SKGE_FLOWCTRL_MODE: + case OID_SKGE_FLOWCTRL_STATUS: + case OID_SKGE_PHY_OPERATION_CAP: + case OID_SKGE_PHY_OPERATION_MODE: + case OID_SKGE_PHY_OPERATION_STATUS: + case OID_SKGE_SPEED_CAP: + case OID_SKGE_SPEED_MODE: + case OID_SKGE_SPEED_STATUS: +#ifdef SK_PHY_LP_MODE + case OID_SKGE_PHY_LP_MODE: +#endif + if (*pLen < (Limit - LogPortIndex) * sizeof(SK_U8)) { + + *pLen = (Limit - LogPortIndex) * sizeof(SK_U8); + return (SK_PNMI_ERR_TOO_SHORT); + } + break; + + case OID_SKGE_MTU: + case OID_SKGE_PHY_TYPE: + if (*pLen < (Limit - LogPortIndex) * sizeof(SK_U32)) { + + *pLen = (Limit - LogPortIndex) * sizeof(SK_U32); + return (SK_PNMI_ERR_TOO_SHORT); + } + break; + + default: + SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR041, SK_PNMI_ERR041MSG); + *pLen = 0; + return (SK_PNMI_ERR_GENERAL); + } + + /* + * Update statistic and increment semaphore to indicate + * that an update was already done. + */ + if ((Ret = SirqUpdate(pAC, IoC)) != SK_PNMI_ERR_OK) { + + *pLen = 0; + return (Ret); + } + pAC->Pnmi.SirqUpdatedFlag ++; + + /* Get value. */ + Offset = 0; + for (; LogPortIndex < Limit; LogPortIndex ++) { + + pBufPtr = pBuf + Offset; + + switch (Id) { + + case OID_SKGE_PMD: + *pBufPtr = pAC->Pnmi.PMD; + Offset ++; + break; + + case OID_SKGE_CONNECTOR: + *pBufPtr = pAC->Pnmi.Connector; + Offset ++; + break; + + case OID_SKGE_PHY_TYPE: + if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNet mode. */ + if (LogPortIndex == 0) { + continue; + } + /* Get value for physical port. */ + PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(pAC, LogPortIndex); + Val32 = pAC->GIni.GP[PhysPortIndex].PhyType; + } + else { /* DualNet mode. */ + + Val32 = pAC->GIni.GP[NetIndex].PhyType; + } + SK_PNMI_STORE_U32(pBufPtr, Val32); + Offset += sizeof(SK_U32); + break; + +#ifdef SK_PHY_LP_MODE + case OID_SKGE_PHY_LP_MODE: + if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNet mode. */ + if (LogPortIndex == 0) { + continue; + } + /* Get value for physical port. */ + PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(pAC, LogPortIndex); + *pBufPtr = (SK_U8)pAC->GIni.GP[PhysPortIndex].PPhyPowerState; + } + else { /* DualNet mode. */ + + *pBufPtr = (SK_U8)pAC->GIni.GP[NetIndex].PPhyPowerState; + } + Offset += sizeof(SK_U8); + break; +#endif + + case OID_SKGE_LINK_CAP: + if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNet mode. */ + if (LogPortIndex == 0) { + /* Get value for virtual port. */ + VirtualConf(pAC, IoC, Id, pBufPtr); + } + else { + /* Get value for physical port. */ + PhysPortIndex = SK_PNMI_PORT_LOG2PHYS( + pAC, LogPortIndex); + + *pBufPtr = pAC->GIni.GP[PhysPortIndex].PLinkCap; + } + } + else { /* DualNet mode. */ + + *pBufPtr = pAC->GIni.GP[NetIndex].PLinkCap; + } + Offset ++; + break; + + case OID_SKGE_LINK_MODE: + if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNet mode. */ + if (LogPortIndex == 0) { + /* Get value for virtual port. */ + VirtualConf(pAC, IoC, Id, pBufPtr); + } + else { + /* Get value for physical port. */ + PhysPortIndex = SK_PNMI_PORT_LOG2PHYS( + pAC, LogPortIndex); + + *pBufPtr = pAC->GIni.GP[PhysPortIndex].PLinkModeConf; + } + } + else { /* DualNet mode. */ + + *pBufPtr = pAC->GIni.GP[NetIndex].PLinkModeConf; + } + Offset ++; + break; + + case OID_SKGE_LINK_MODE_STATUS: + if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNet mode. */ + if (LogPortIndex == 0) { + /* Get value for virtual port. */ + VirtualConf(pAC, IoC, Id, pBufPtr); + } + else { + /* Get value for physical port. */ + PhysPortIndex = SK_PNMI_PORT_LOG2PHYS( + pAC, LogPortIndex); + + *pBufPtr = + CalculateLinkModeStatus(pAC, IoC, PhysPortIndex); + } + } + else { /* DualNet mode. */ + + *pBufPtr = CalculateLinkModeStatus(pAC, IoC, NetIndex); + } + Offset ++; + break; + + case OID_SKGE_LINK_STATUS: + if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNet mode. */ + if (LogPortIndex == 0) { + /* Get value for virtual port. */ + VirtualConf(pAC, IoC, Id, pBufPtr); + } + else { + /* Get value for physical port. */ + PhysPortIndex = SK_PNMI_PORT_LOG2PHYS( + pAC, LogPortIndex); + + *pBufPtr = CalculateLinkStatus(pAC, IoC, PhysPortIndex); + } + } + else { /* DualNet mode. */ + + *pBufPtr = CalculateLinkStatus(pAC, IoC, NetIndex); + } + Offset ++; + break; + + case OID_SKGE_FLOWCTRL_CAP: + if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNet mode. */ + if (LogPortIndex == 0) { + /* Get value for virtual port. */ + VirtualConf(pAC, IoC, Id, pBufPtr); + } + else { + /* Get value for physical port. */ + PhysPortIndex = SK_PNMI_PORT_LOG2PHYS( + pAC, LogPortIndex); + + *pBufPtr = pAC->GIni.GP[PhysPortIndex].PFlowCtrlCap; + } + } + else { /* DualNet mode. */ + + *pBufPtr = pAC->GIni.GP[NetIndex].PFlowCtrlCap; + } + Offset ++; + break; + + case OID_SKGE_FLOWCTRL_MODE: + if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNet mode. */ + if (LogPortIndex == 0) { + /* Get value for virtual port. */ + VirtualConf(pAC, IoC, Id, pBufPtr); + } + else { + /* Get value for physical port. */ + PhysPortIndex = SK_PNMI_PORT_LOG2PHYS( + pAC, LogPortIndex); + + *pBufPtr = pAC->GIni.GP[PhysPortIndex].PFlowCtrlMode; + } + } + else { /* DualNet mode. */ + + *pBufPtr = pAC->GIni.GP[NetIndex].PFlowCtrlMode; + } + Offset ++; + break; + + case OID_SKGE_FLOWCTRL_STATUS: + if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNet mode. */ + if (LogPortIndex == 0) { + /* Get value for virtual port. */ + VirtualConf(pAC, IoC, Id, pBufPtr); + } + else { + /* Get value for physical port. */ + PhysPortIndex = SK_PNMI_PORT_LOG2PHYS( + pAC, LogPortIndex); + + *pBufPtr = pAC->GIni.GP[PhysPortIndex].PFlowCtrlStatus; + } + } + else { /* DualNet mode. */ + + *pBufPtr = pAC->GIni.GP[NetIndex].PFlowCtrlStatus; + } + Offset ++; + break; + + case OID_SKGE_PHY_OPERATION_CAP: + if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNet Mode. */ + if (LogPortIndex == 0) { + /* Get value for virtual port. */ + VirtualConf(pAC, IoC, Id, pBufPtr); + } + else { + /* Get value for physical port. */ + PhysPortIndex = SK_PNMI_PORT_LOG2PHYS( + pAC, LogPortIndex); + + *pBufPtr = pAC->GIni.GP[PhysPortIndex].PMSCap; + } + } + else { /* DualNet mode. */ + + *pBufPtr = pAC->GIni.GP[NetIndex].PMSCap; + } + Offset ++; + break; + + case OID_SKGE_PHY_OPERATION_MODE: + if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNet mode. */ + if (LogPortIndex == 0) { + /* Get value for virtual port. */ + VirtualConf(pAC, IoC, Id, pBufPtr); + } + else { + /* Get value for physical port. */ + PhysPortIndex = SK_PNMI_PORT_LOG2PHYS( + pAC, LogPortIndex); + + *pBufPtr = pAC->GIni.GP[PhysPortIndex].PMSMode; + } + } + else { /* DualNet mode. */ + + *pBufPtr = pAC->GIni.GP[NetIndex].PMSMode; + } + Offset ++; + break; + + case OID_SKGE_PHY_OPERATION_STATUS: + if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNet mode. */ + if (LogPortIndex == 0) { + /* Get value for virtual port. */ + VirtualConf(pAC, IoC, Id, pBufPtr); + } + else { + /* Get value for physical port. */ + PhysPortIndex = SK_PNMI_PORT_LOG2PHYS( + pAC, LogPortIndex); + + *pBufPtr = pAC->GIni.GP[PhysPortIndex].PMSStatus; + } + } + else { + + *pBufPtr = pAC->GIni.GP[NetIndex].PMSStatus; + } + Offset ++; + break; + + case OID_SKGE_SPEED_CAP: + if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNet mode. */ + if (LogPortIndex == 0) { + /* Get value for virtual port. */ + VirtualConf(pAC, IoC, Id, pBufPtr); + } + else { + /* Get value for physical port. */ + PhysPortIndex = SK_PNMI_PORT_LOG2PHYS( + pAC, LogPortIndex); + + *pBufPtr = pAC->GIni.GP[PhysPortIndex].PLinkSpeedCap; + } + } + else { /* DualNet mode. */ + + *pBufPtr = pAC->GIni.GP[NetIndex].PLinkSpeedCap; + } + Offset ++; + break; + + case OID_SKGE_SPEED_MODE: + if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNet mode. */ + if (LogPortIndex == 0) { + /* Get value for virtual port. */ + VirtualConf(pAC, IoC, Id, pBufPtr); + } + else { + /* Get value for physical port. */ + PhysPortIndex = SK_PNMI_PORT_LOG2PHYS( + pAC, LogPortIndex); + + *pBufPtr = pAC->GIni.GP[PhysPortIndex].PLinkSpeed; + } + } + else { /* DualNet mode. */ + + *pBufPtr = pAC->GIni.GP[NetIndex].PLinkSpeed; + } + Offset ++; + break; + + case OID_SKGE_SPEED_STATUS: + if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNet mode. */ + if (LogPortIndex == 0) { + /* Get value for virtual port. */ + VirtualConf(pAC, IoC, Id, pBufPtr); + } + else { + /* Get value for physical port. */ + PhysPortIndex = SK_PNMI_PORT_LOG2PHYS( + pAC, LogPortIndex); + + *pBufPtr = pAC->GIni.GP[PhysPortIndex].PLinkSpeedUsed; + } + } + else { /* DualNet mode. */ + + *pBufPtr = pAC->GIni.GP[NetIndex].PLinkSpeedUsed; + } + Offset ++; + break; + + case OID_SKGE_MTU: + Val32 = SK_DRIVER_GET_MTU(pAC, IoC, NetIndex); + SK_PNMI_STORE_U32(pBufPtr, Val32); + Offset += sizeof(SK_U32); + break; + + default: + SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_ERR, + ("MacPrivateConf: Unknown OID should be handled before")); + + pAC->Pnmi.SirqUpdatedFlag --; + return (SK_PNMI_ERR_GENERAL); + } + } + *pLen = Offset; + pAC->Pnmi.SirqUpdatedFlag --; + + return (SK_PNMI_ERR_OK); + } + + /* + * From here SET or PRESET action. Check if the passed + * buffer length is plausible. + */ + switch (Id) { + + case OID_SKGE_LINK_MODE: + case OID_SKGE_FLOWCTRL_MODE: + case OID_SKGE_PHY_OPERATION_MODE: + case OID_SKGE_SPEED_MODE: + if (*pLen < Limit - LogPortIndex) { + + *pLen = Limit - LogPortIndex; + return (SK_PNMI_ERR_TOO_SHORT); + } + if (*pLen != Limit - LogPortIndex) { + + *pLen = 0; + return (SK_PNMI_ERR_BAD_VALUE); + } + break; + +#ifdef SK_PHY_LP_MODE + case OID_SKGE_PHY_LP_MODE: + if (*pLen < Limit - LogPortIndex) { + + *pLen = Limit - LogPortIndex; + return (SK_PNMI_ERR_TOO_SHORT); + } + break; +#endif /* SK_PHY_LP_MODE */ + + case OID_SKGE_MTU: + if (*pLen < (Limit - LogPortIndex) * sizeof(SK_U32)) { + + *pLen = (Limit - LogPortIndex) * sizeof(SK_U32); + return (SK_PNMI_ERR_TOO_SHORT); + } + break; + + default: + *pLen = 0; + return (SK_PNMI_ERR_READ_ONLY); + } + + /* Perform PRESET or SET. */ + Offset = 0; + for (; LogPortIndex < Limit; LogPortIndex ++) { + + Val8 = *(pBuf + Offset); + + switch (Id) { + + case OID_SKGE_LINK_MODE: + /* Check the value range. */ + if (Val8 == 0) { + Offset++; + break; + } + if (Val8 < SK_LMODE_HALF || + (LogPortIndex != 0 && Val8 > SK_LMODE_AUTOSENSE) || + (LogPortIndex == 0 && Val8 > SK_LMODE_INDETERMINATED)) { + + *pLen = 0; + return (SK_PNMI_ERR_BAD_VALUE); + } + + /* The PRESET ends here. */ + if (Action == SK_PNMI_PRESET) { + + return (SK_PNMI_ERR_OK); + } + + if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNet mode. */ + if (LogPortIndex == 0) { + /* + * The virtual port consists of all currently + * active ports. Find them and send an event + * with the new link mode to SIRQ. + */ + for (PhysPortIndex = 0; PhysPortIndex < PhysPortMax; + PhysPortIndex ++) { + + if (!pAC->Pnmi.Port[PhysPortIndex].ActiveFlag) { + continue; + } + + EventParam.Para32[0] = PhysPortIndex; + EventParam.Para32[1] = (SK_U32)Val8; + if (SkGeSirqEvent(pAC, IoC, + SK_HWEV_SET_LMODE, + EventParam) > 0) { + + SK_ERR_LOG(pAC, SK_ERRCL_SW, + SK_PNMI_ERR043, + SK_PNMI_ERR043MSG); + + *pLen = 0; + return (SK_PNMI_ERR_GENERAL); + } + } /* for */ + } + else { + /* + * Send an event with the new link mode to + * the SIRQ module. + */ + EventParam.Para32[0] = SK_PNMI_PORT_LOG2PHYS( + pAC, LogPortIndex); + EventParam.Para32[1] = (SK_U32)Val8; + if (SkGeSirqEvent(pAC, IoC, SK_HWEV_SET_LMODE, + EventParam) > 0) { + + SK_ERR_LOG(pAC, SK_ERRCL_SW, + SK_PNMI_ERR043, + SK_PNMI_ERR043MSG); + + *pLen = 0; + return (SK_PNMI_ERR_GENERAL); + } + } + } + else { /* DualNet mode. */ + + /* + * Send an event with the new link mode to + * the SIRQ module. + */ + EventParam.Para32[0] = NetIndex; + EventParam.Para32[1] = (SK_U32)Val8; + if (SkGeSirqEvent(pAC, IoC, SK_HWEV_SET_LMODE, + EventParam) > 0) { + + SK_ERR_LOG(pAC, SK_ERRCL_SW, + SK_PNMI_ERR043, + SK_PNMI_ERR043MSG); + + *pLen = 0; + return (SK_PNMI_ERR_GENERAL); + } + } + Offset++; + break; + + case OID_SKGE_FLOWCTRL_MODE: + /* Check the value range. */ + if (Val8 == 0) { + Offset++; + break; + } + if (Val8 < SK_FLOW_MODE_NONE || + (LogPortIndex != 0 && Val8 > SK_FLOW_MODE_SYM_OR_REM) || + (LogPortIndex == 0 && Val8 > SK_FLOW_MODE_INDETERMINATED)) { + + *pLen = 0; + return (SK_PNMI_ERR_BAD_VALUE); + } + + /* The PRESET ends here. */ + if (Action == SK_PNMI_PRESET) { + + return (SK_PNMI_ERR_OK); + } + + if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNet mode. */ + if (LogPortIndex == 0) { + /* + * The virtual port consists of all currently + * active ports. Find them and send an event + * with the new flow control mode to SIRQ. + */ + for (PhysPortIndex = 0; PhysPortIndex < PhysPortMax; + PhysPortIndex ++) { + + if (!pAC->Pnmi.Port[PhysPortIndex].ActiveFlag) { + continue; + } + + EventParam.Para32[0] = PhysPortIndex; + EventParam.Para32[1] = (SK_U32)Val8; + if (SkGeSirqEvent(pAC, IoC, + SK_HWEV_SET_FLOWMODE, + EventParam) > 0) { + + SK_ERR_LOG(pAC, SK_ERRCL_SW, + SK_PNMI_ERR044, + SK_PNMI_ERR044MSG); + + *pLen = 0; + return (SK_PNMI_ERR_GENERAL); + } + } + } + else { + /* + * Send an event with the new flow control + * mode to the SIRQ module. + */ + EventParam.Para32[0] = SK_PNMI_PORT_LOG2PHYS( + pAC, LogPortIndex); + EventParam.Para32[1] = (SK_U32)Val8; + if (SkGeSirqEvent(pAC, IoC, + SK_HWEV_SET_FLOWMODE, + EventParam) > 0) { + + SK_ERR_LOG(pAC, SK_ERRCL_SW, + SK_PNMI_ERR044, + SK_PNMI_ERR044MSG); + + *pLen = 0; + return (SK_PNMI_ERR_GENERAL); + } + } + } + else { /* DualNet mode. */ + + /* + * Send an event with the new link mode to + * the SIRQ module. + */ + EventParam.Para32[0] = NetIndex; + EventParam.Para32[1] = (SK_U32)Val8; + if (SkGeSirqEvent(pAC, IoC, SK_HWEV_SET_FLOWMODE, + EventParam) > 0) { + + SK_ERR_LOG(pAC, SK_ERRCL_SW, + SK_PNMI_ERR044, + SK_PNMI_ERR044MSG); + + *pLen = 0; + return (SK_PNMI_ERR_GENERAL); + } + } + Offset++; + break; + + case OID_SKGE_PHY_OPERATION_MODE : + /* Check the value range. */ + if (Val8 == 0) { + /* Mode of this port remains unchanged. */ + Offset++; + break; + } + if (Val8 < SK_MS_MODE_AUTO || + (LogPortIndex != 0 && Val8 > SK_MS_MODE_SLAVE) || + (LogPortIndex == 0 && Val8 > SK_MS_MODE_INDETERMINATED)) { + + *pLen = 0; + return (SK_PNMI_ERR_BAD_VALUE); + } + + /* The PRESET ends here. */ + if (Action == SK_PNMI_PRESET) { + + return (SK_PNMI_ERR_OK); + } + + if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNet mode. */ + if (LogPortIndex == 0) { + /* + * The virtual port consists of all currently + * active ports. Find them and send an event + * with new master/slave (role) mode to SIRQ. + */ + for (PhysPortIndex = 0; PhysPortIndex < PhysPortMax; + PhysPortIndex ++) { + + if (!pAC->Pnmi.Port[PhysPortIndex].ActiveFlag) { + continue; + } + + EventParam.Para32[0] = PhysPortIndex; + EventParam.Para32[1] = (SK_U32)Val8; + if (SkGeSirqEvent(pAC, IoC, + SK_HWEV_SET_ROLE, + EventParam) > 0) { + + SK_ERR_LOG(pAC, SK_ERRCL_SW, + SK_PNMI_ERR042, + SK_PNMI_ERR042MSG); + + *pLen = 0; + return (SK_PNMI_ERR_GENERAL); + } + } + } + else { + /* + * Send an event with the new master/slave + * (role) mode to the SIRQ module. + */ + EventParam.Para32[0] = SK_PNMI_PORT_LOG2PHYS( + pAC, LogPortIndex); + EventParam.Para32[1] = (SK_U32)Val8; + if (SkGeSirqEvent(pAC, IoC, + SK_HWEV_SET_ROLE, EventParam) > 0) { + + SK_ERR_LOG(pAC, SK_ERRCL_SW, + SK_PNMI_ERR042, + SK_PNMI_ERR042MSG); + + *pLen = 0; + return (SK_PNMI_ERR_GENERAL); + } + } + } + else { /* DualNet mode. */ + + /* + * Send an event with the new link mode to + * the SIRQ module. + */ + EventParam.Para32[0] = NetIndex; + EventParam.Para32[1] = (SK_U32)Val8; + if (SkGeSirqEvent(pAC, IoC, SK_HWEV_SET_ROLE, + EventParam) > 0) { + + SK_ERR_LOG(pAC, SK_ERRCL_SW, + SK_PNMI_ERR042, + SK_PNMI_ERR042MSG); + + *pLen = 0; + return (SK_PNMI_ERR_GENERAL); + } + } + Offset++; + break; + + case OID_SKGE_SPEED_MODE: + /* Check the value range. */ + if (Val8 == 0) { + Offset++; + break; + } + if (Val8 < (SK_LSPEED_AUTO) || + (LogPortIndex != 0 && Val8 > (SK_LSPEED_1000MBPS)) || + (LogPortIndex == 0 && Val8 > (SK_LSPEED_INDETERMINATED))) { + + *pLen = 0; + return (SK_PNMI_ERR_BAD_VALUE); + } + + /* The PRESET ends here. */ + if (Action == SK_PNMI_PRESET) { + + return (SK_PNMI_ERR_OK); + } + + if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNet mode. */ + if (LogPortIndex == 0) { + + /* + * The virtual port consists of all currently + * active ports. Find them and send an event + * with the new flow control mode to SIRQ. + */ + for (PhysPortIndex = 0; PhysPortIndex < PhysPortMax; + PhysPortIndex ++) { + + if (!pAC->Pnmi.Port[PhysPortIndex].ActiveFlag) { + continue; + } + + EventParam.Para32[0] = PhysPortIndex; + EventParam.Para32[1] = (SK_U32)Val8; + if (SkGeSirqEvent(pAC, IoC, + SK_HWEV_SET_SPEED, + EventParam) > 0) { + + SK_ERR_LOG(pAC, SK_ERRCL_SW, + SK_PNMI_ERR045, + SK_PNMI_ERR045MSG); + + *pLen = 0; + return (SK_PNMI_ERR_GENERAL); + } + } + } + else { + /* + * Send an event with the new flow control + * mode to the SIRQ module. + */ + EventParam.Para32[0] = SK_PNMI_PORT_LOG2PHYS( + pAC, LogPortIndex); + EventParam.Para32[1] = (SK_U32)Val8; + if (SkGeSirqEvent(pAC, IoC, + SK_HWEV_SET_SPEED, + EventParam) > 0) { + + SK_ERR_LOG(pAC, SK_ERRCL_SW, + SK_PNMI_ERR045, + SK_PNMI_ERR045MSG); + + *pLen = 0; + return (SK_PNMI_ERR_GENERAL); + } + } + } + else { /* DualNet mode. */ + + /* + * Send an event with the new link mode to + * the SIRQ module. + */ + EventParam.Para32[0] = NetIndex; + EventParam.Para32[1] = (SK_U32)Val8; + if (SkGeSirqEvent(pAC, IoC, SK_HWEV_SET_SPEED, + EventParam) > 0) { + + SK_ERR_LOG(pAC, SK_ERRCL_SW, + SK_PNMI_ERR045, + SK_PNMI_ERR045MSG); + + *pLen = 0; + return (SK_PNMI_ERR_GENERAL); + } + } + Offset++; + break; + + case OID_SKGE_MTU: + /* Check the value range. */ + SK_PNMI_READ_U32((pBuf + Offset), Val32); + + if (Val32 == 0) { + /* MTU of this port remains unchanged. */ + Offset += sizeof(SK_U32); + break; + } + + if (SK_DRIVER_PRESET_MTU(pAC, IoC, NetIndex, Val32) != 0) { + *pLen = 0; + return (SK_PNMI_ERR_BAD_VALUE); + } + + /* The PRESET ends here. */ + if (Action == SK_PNMI_PRESET) { + return (SK_PNMI_ERR_OK); + } + + if (SK_DRIVER_SET_MTU(pAC, IoC, NetIndex, Val32) != 0) { + return (SK_PNMI_ERR_GENERAL); + } + + Offset += sizeof(SK_U32); + break; + +#ifdef SK_PHY_LP_MODE + case OID_SKGE_PHY_LP_MODE: + /* The PRESET ends here. */ + if (Action == SK_PNMI_PRESET) { + + return (SK_PNMI_ERR_OK); + } + + if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNet mode. */ + if (LogPortIndex == 0) { + Offset = 0; + continue; + } + } + /* Set value for physical port. */ + PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(pAC, LogPortIndex); + CurrentPhyPowerState = pAC->GIni.GP[PhysPortIndex].PPhyPowerState; + + switch (Val8) { + case PHY_PM_OPERATIONAL_MODE: + /* If LowPowerMode is active, we can leave it. */ + if (CurrentPhyPowerState) { + + Val32 = SkGmLeaveLowPowerMode(pAC, IoC, PhysPortIndex); + + if ((CurrentPhyPowerState == PHY_PM_DEEP_SLEEP) || + (CurrentPhyPowerState == PHY_PM_IEEE_POWER_DOWN)) { + + SkDrvInitAdapter(pAC); + } + break; + } + else { + *pLen = 0; + return (SK_PNMI_ERR_GENERAL); + } + case PHY_PM_DEEP_SLEEP: + case PHY_PM_IEEE_POWER_DOWN: + /* If no LowPowerMode is active, we can enter it. */ + if (!CurrentPhyPowerState) { + SkDrvDeInitAdapter(pAC); + } + + case PHY_PM_ENERGY_DETECT: + case PHY_PM_ENERGY_DETECT_PLUS: + /* If no LowPowerMode is active, we can enter it. */ + if (!CurrentPhyPowerState) { + + Val32 = SkGmEnterLowPowerMode(pAC, IoC, PhysPortIndex, *pBuf); + break; + } + else { + *pLen = 0; + return (SK_PNMI_ERR_GENERAL); + } + default: + *pLen = 0; + return (SK_PNMI_ERR_BAD_VALUE); + } + Offset++; + break; +#endif /* SK_PHY_LP_MODE */ + + default: + SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_ERR, + ("MacPrivateConf: Unknown OID should be handled before set")); + + *pLen = 0; + return (SK_PNMI_ERR_GENERAL); + } + } + + return (SK_PNMI_ERR_OK); +} + +/***************************************************************************** + * + * Monitor - OID handler function for RLMT_MONITOR_XXX + * + * Description: + * Because RLMT currently does not support the monitoring of + * remote adapter cards, we return always an empty table. + * + * Returns: + * SK_PNMI_ERR_OK The request was successfully performed. + * SK_PNMI_ERR_GENERAL A general severe internal error occured. + * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain + * the correct data (e.g. a 32bit value is + * needed, but a 16 bit value was passed). + * SK_PNMI_ERR_BAD_VALUE The passed value is not in the valid + * value range. + * SK_PNMI_ERR_READ_ONLY The OID is read-only and cannot be set. + * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't + * exist (e.g. port instance 3 on a two port + * adapter. + */ +PNMI_STATIC int Monitor( +SK_AC *pAC, /* Pointer to adapter context */ +SK_IOC IoC, /* IO context handle */ +int Action, /* GET/PRESET/SET action */ +SK_U32 Id, /* Object ID that is to be processed */ +char *pBuf, /* Buffer used for the management data transfer */ +unsigned int *pLen, /* On call: pBuf buffer length. On return: used buffer */ +SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */ +unsigned int TableIndex, /* Index to the Id table */ +SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */ +{ + unsigned int Index; + unsigned int Limit; + unsigned int Offset; + unsigned int Entries; + + /* Not implemented yet. Return always an empty table. */ + Entries = 0; + + /* Calculate instance if wished. */ + if ((Instance != (SK_U32)(-1))) { + + if ((Instance < 1) || (Instance > Entries)) { + + *pLen = 0; + return (SK_PNMI_ERR_UNKNOWN_INST); + } + + Index = (unsigned int)Instance - 1; + Limit = (unsigned int)Instance; + } + else { + Index = 0; + Limit = Entries; + } + + /* GET/SET value. */ + if (Action == SK_PNMI_GET) { + + for (Offset = 0; Index < Limit; Index ++) { + + switch (Id) { + + case OID_SKGE_RLMT_MONITOR_INDEX: + case OID_SKGE_RLMT_MONITOR_ADDR: + case OID_SKGE_RLMT_MONITOR_ERRS: + case OID_SKGE_RLMT_MONITOR_TIMESTAMP: + case OID_SKGE_RLMT_MONITOR_ADMIN: + break; + + default: + SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR046, + SK_PNMI_ERR046MSG); + + *pLen = 0; + return (SK_PNMI_ERR_GENERAL); + } + } + *pLen = Offset; + } + else { + /* Only MONITOR_ADMIN can be set. */ + if (Id != OID_SKGE_RLMT_MONITOR_ADMIN) { + + *pLen = 0; + return (SK_PNMI_ERR_READ_ONLY); + } + + /* Check if the length is plausible. */ + if (*pLen < (Limit - Index)) { + + return (SK_PNMI_ERR_TOO_SHORT); + } + /* Okay, we have a wide value range. */ + if (*pLen != (Limit - Index)) { + + *pLen = 0; + return (SK_PNMI_ERR_BAD_VALUE); + } + + /* + * Not yet implemented. Return always BAD_VALUE, + * because the table is empty. + */ + *pLen = 0; + return (SK_PNMI_ERR_BAD_VALUE); + } + + return (SK_PNMI_ERR_OK); +} + +/***************************************************************************** + * + * VirtualConf - Calculates the values of configuration OIDs for virtual port + * + * Description: + * We handle here the get of the configuration group OIDs, which are + * a little bit complicated. The virtual port consists of all currently + * active physical ports. If multiple ports are active and configured + * differently we get in some trouble to return a single value. So we + * get the value of the first active port and compare it with that of + * the other active ports. If they are not the same, we return a value + * that indicates that the state is indeterminated. + * + * Returns: + * Nothing + */ +PNMI_STATIC void VirtualConf( +SK_AC *pAC, /* Pointer to adapter context */ +SK_IOC IoC, /* IO context handle */ +SK_U32 Id, /* Object ID that is to be processed */ +char *pBuf) /* Buffer used for the management data transfer */ +{ + unsigned int PhysPortMax; + unsigned int PhysPortIndex; + SK_U8 Val8; + SK_U32 Val32; + SK_BOOL PortActiveFlag; + SK_GEPORT *pPrt; + + *pBuf = 0; + PortActiveFlag = SK_FALSE; + PhysPortMax = pAC->GIni.GIMacsFound; + + for (PhysPortIndex = 0; PhysPortIndex < PhysPortMax; PhysPortIndex ++) { + + pPrt = &pAC->GIni.GP[PhysPortIndex]; + + /* Check if the physical port is active. */ + if (!pAC->Pnmi.Port[PhysPortIndex].ActiveFlag) { + continue; + } + + PortActiveFlag = SK_TRUE; + + switch (Id) { + + case OID_SKGE_PHY_TYPE: + /* Check if it is the first active port. */ + if (*pBuf == 0) { + Val32 = pPrt->PhyType; + SK_PNMI_STORE_U32(pBuf, Val32); + continue; + } + break; + + case OID_SKGE_LINK_CAP: + + /* + * Different capabilities should not happen, but + * in the case of the cases OR them all together. + * From a curious point of view the virtual port + * is capable of all found capabilities. + */ + *pBuf |= pPrt->PLinkCap; + break; + + case OID_SKGE_LINK_MODE: + /* Check if it is the first active port. */ + if (*pBuf == 0) { + + *pBuf = pPrt->PLinkModeConf; + continue; + } + + /* + * If we find an active port with a different link mode + * than the first one we return indeterminated. + */ + if (*pBuf != pPrt->PLinkModeConf) { + + *pBuf = SK_LMODE_INDETERMINATED; + } + break; + + case OID_SKGE_LINK_MODE_STATUS: + /* Get the link mode of the physical port. */ + Val8 = CalculateLinkModeStatus(pAC, IoC, PhysPortIndex); + + /* Check if it is the first active port. */ + if (*pBuf == 0) { + + *pBuf = Val8; + continue; + } + + /* + * If we find an active port with a different link mode status + * than the first one we return indeterminated. + */ + if (*pBuf != Val8) { + + *pBuf = SK_LMODE_STAT_INDETERMINATED; + } + break; + + case OID_SKGE_LINK_STATUS: + /* Get the link status of the physical port. */ + Val8 = CalculateLinkStatus(pAC, IoC, PhysPortIndex); + + /* Check if it is the first active port. */ + if (*pBuf == 0) { + + *pBuf = Val8; + continue; + } + + /* + * If we find an active port with a different link status + * than the first one we return indeterminated. + */ + if (*pBuf != Val8) { + + *pBuf = SK_PNMI_RLMT_LSTAT_INDETERMINATED; + } + break; + + case OID_SKGE_FLOWCTRL_CAP: + /* Check if it is the first active port. */ + if (*pBuf == 0) { + + *pBuf = pPrt->PFlowCtrlCap; + continue; + } + + /* + * From a curious point of view the virtual port + * is capable of all found capabilities. + */ + *pBuf |= pPrt->PFlowCtrlCap; + break; + + case OID_SKGE_FLOWCTRL_MODE: + /* Check if it is the first active port. */ + if (*pBuf == 0) { + + *pBuf = pPrt->PFlowCtrlMode; + continue; + } + + /* + * If we find an active port with a different flow-control mode + * than the first one we return indeterminated. + */ + if (*pBuf != pPrt->PFlowCtrlMode) { + + *pBuf = SK_FLOW_MODE_INDETERMINATED; + } + break; + + case OID_SKGE_FLOWCTRL_STATUS: + /* Check if it is the first active port. */ + if (*pBuf == 0) { + + *pBuf = pPrt->PFlowCtrlStatus; + continue; + } + + /* + * If we find an active port with a different flow-control status + * than the first one we return indeterminated. + */ + if (*pBuf != pPrt->PFlowCtrlStatus) { + + *pBuf = SK_FLOW_STAT_INDETERMINATED; + } + break; + + case OID_SKGE_PHY_OPERATION_CAP: + /* Check if it is the first active port. */ + if (*pBuf == 0) { + + *pBuf = pPrt->PMSCap; + continue; + } + + /* + * From a curious point of view the virtual port + * is capable of all found capabilities. + */ + *pBuf |= pPrt->PMSCap; + break; + + case OID_SKGE_PHY_OPERATION_MODE: + /* Check if it is the first active port. */ + if (*pBuf == 0) { + + *pBuf = pPrt->PMSMode; + continue; + } + + /* + * If we find an active port with a different master/slave mode + * than the first one we return indeterminated. + */ + if (*pBuf != pPrt->PMSMode) { + + *pBuf = SK_MS_MODE_INDETERMINATED; + } + break; + + case OID_SKGE_PHY_OPERATION_STATUS: + /* Check if it is the first active port. */ + if (*pBuf == 0) { + + *pBuf = pPrt->PMSStatus; + continue; + } + + /* + * If we find an active port with a different master/slave status + * than the first one we return indeterminated. + */ + if (*pBuf != pPrt->PMSStatus) { + + *pBuf = SK_MS_STAT_INDETERMINATED; + } + break; + + case OID_SKGE_SPEED_MODE: + /* Check if it is the first active port. */ + if (*pBuf == 0) { + + *pBuf = pPrt->PLinkSpeed; + continue; + } + + /* + * If we find an active port with a different link speed + * than the first one we return indeterminated. + */ + if (*pBuf != pPrt->PLinkSpeed) { + + *pBuf = SK_LSPEED_INDETERMINATED; + } + break; + + case OID_SKGE_SPEED_STATUS: + /* Check if it is the first active port. */ + if (*pBuf == 0) { + + *pBuf = pPrt->PLinkSpeedUsed; + continue; + } + + /* + * If we find an active port with a different link speed used + * than the first one we return indeterminated. + */ + if (*pBuf != pPrt->PLinkSpeedUsed) { + + *pBuf = SK_LSPEED_STAT_INDETERMINATED; + } + break; + } + } + + /* If no port is active return an indeterminated answer. */ + if (!PortActiveFlag) { + + switch (Id) { + + case OID_SKGE_LINK_CAP: + *pBuf = SK_LMODE_CAP_INDETERMINATED; + break; + + case OID_SKGE_LINK_MODE: + *pBuf = SK_LMODE_INDETERMINATED; + break; + + case OID_SKGE_LINK_MODE_STATUS: + *pBuf = SK_LMODE_STAT_INDETERMINATED; + break; + + case OID_SKGE_LINK_STATUS: + *pBuf = SK_PNMI_RLMT_LSTAT_INDETERMINATED; + break; + + case OID_SKGE_FLOWCTRL_CAP: + case OID_SKGE_FLOWCTRL_MODE: + *pBuf = SK_FLOW_MODE_INDETERMINATED; + break; + + case OID_SKGE_FLOWCTRL_STATUS: + *pBuf = SK_FLOW_STAT_INDETERMINATED; + break; + + case OID_SKGE_PHY_OPERATION_CAP: + *pBuf = SK_MS_CAP_INDETERMINATED; + break; + + case OID_SKGE_PHY_OPERATION_MODE: + *pBuf = SK_MS_MODE_INDETERMINATED; + break; + + case OID_SKGE_PHY_OPERATION_STATUS: + *pBuf = SK_MS_STAT_INDETERMINATED; + break; + case OID_SKGE_SPEED_CAP: + *pBuf = SK_LSPEED_CAP_INDETERMINATED; + break; + + case OID_SKGE_SPEED_MODE: + *pBuf = SK_LSPEED_INDETERMINATED; + break; + + case OID_SKGE_SPEED_STATUS: + *pBuf = SK_LSPEED_STAT_INDETERMINATED; + break; + } + } +} + +/***************************************************************************** + * + * CalculateLinkStatus - Determins the link status of a physical port + * + * Description: + * Determins the link status the following way: + * LSTAT_PHY_DOWN: Link is down + * LSTAT_AUTONEG: Auto-negotiation failed + * LSTAT_LOG_DOWN: Link is up but RLMT did not yet put the port + * logically up. + * LSTAT_LOG_UP: RLMT marked the port as up + * + * Returns: + * Link status of physical port + */ +PNMI_STATIC SK_U8 CalculateLinkStatus( +SK_AC *pAC, /* Pointer to adapter context */ +SK_IOC IoC, /* IO context handle */ +unsigned int PhysPortIndex) /* Physical port index */ +{ + SK_U8 Result; + + if (!pAC->GIni.GP[PhysPortIndex].PHWLinkUp) { + + Result = SK_PNMI_RLMT_LSTAT_PHY_DOWN; + } + else if (pAC->GIni.GP[PhysPortIndex].PAutoNegFail > 0) { + + Result = SK_PNMI_RLMT_LSTAT_AUTONEG; + } + else if (!pAC->Rlmt.Port[PhysPortIndex].PortDown) { + + Result = SK_PNMI_RLMT_LSTAT_LOG_UP; + } + else { + Result = SK_PNMI_RLMT_LSTAT_LOG_DOWN; + } + + return (Result); +} + +/***************************************************************************** + * + * CalculateLinkModeStatus - Determins the link mode status of a phys. port + * + * Description: + * The COMMON module only tells us if the mode is half or full duplex. + * But in the decade of auto sensing it is usefull for the user to + * know if the mode was negotiated or forced. Therefore we have a + * look to the mode, which was last used by the negotiation process. + * + * Returns: + * The link mode status + */ +PNMI_STATIC SK_U8 CalculateLinkModeStatus( +SK_AC *pAC, /* Pointer to adapter context */ +SK_IOC IoC, /* IO context handle */ +unsigned int PhysPortIndex) /* Physical port index */ +{ + SK_U8 Result; + + /* Get the current mode, which can be full or half duplex. */ + Result = pAC->GIni.GP[PhysPortIndex].PLinkModeStatus; + + /* Check if no valid mode could be found (link is down). */ + if (Result < SK_LMODE_STAT_HALF) { + + Result = SK_LMODE_STAT_UNKNOWN; + } + else if (pAC->GIni.GP[PhysPortIndex].PLinkMode >= SK_LMODE_AUTOHALF) { + /* + * Auto-negotiation was used to bring up the link. Change + * the already found duplex status that it indicates + * auto-negotiation was involved. + */ + if (Result == SK_LMODE_STAT_HALF) { + + Result = SK_LMODE_STAT_AUTOHALF; + } + else if (Result == SK_LMODE_STAT_FULL) { + + Result = SK_LMODE_STAT_AUTOFULL; + } + } + + return (Result); +} + +/***************************************************************************** + * + * GetVpdKeyArr - Obtain an array of VPD keys + * + * Description: + * Read the VPD keys and build an array of VPD keys, which are + * easy to access. + * + * Returns: + * SK_PNMI_ERR_OK Task successfully performed. + * SK_PNMI_ERR_GENERAL Something went wrong. + */ +PNMI_STATIC int GetVpdKeyArr( +SK_AC *pAC, /* Pointer to adapter context */ +SK_IOC IoC, /* IO context handle */ +char *pKeyArr, /* Ptr KeyArray */ +unsigned int KeyArrLen, /* Length of array in bytes */ +unsigned int *pKeyNo) /* Number of keys */ +{ + unsigned int BufKeysLen = SK_PNMI_VPD_BUFSIZE; + char BufKeys[SK_PNMI_VPD_BUFSIZE]; + unsigned int StartOffset; + unsigned int Offset; + int Index; + int Ret; + + SK_MEMSET(pKeyArr, 0, KeyArrLen); + + /* Get VPD key list. */ + Ret = VpdKeys(pAC, IoC, BufKeys, (int *)&BufKeysLen, + (int *)pKeyNo); + + if (Ret > 0) { + + SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL, + (SK_PNMI_ERR014MSG)); + + /* Please read comment in Vpd(). */ + pAC->Pnmi.VpdKeyReadError = SK_TRUE; + return (SK_PNMI_ERR_GENERAL); + } + /* If no keys are available return now. */ + if (*pKeyNo == 0 || BufKeysLen == 0) { + + return (SK_PNMI_ERR_OK); + } + /* + * If the key list is too long for us trunc it and give a + * errorlog notification. This case should not happen because + * the maximum number of keys is limited due to RAM limitations. + */ + if (*pKeyNo > SK_PNMI_VPD_ENTRIES) { + + SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL, + (SK_PNMI_ERR015MSG)); + + *pKeyNo = SK_PNMI_VPD_ENTRIES; + } + + /* + * Now build an array of fixed string length size and copy + * the keys together. + */ + for (Index = 0, StartOffset = 0, Offset = 0; Offset < BufKeysLen; + Offset ++) { + + if (BufKeys[Offset] != 0) { + continue; + } + + if (Offset - StartOffset > SK_PNMI_VPD_KEY_SIZE) { + + SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL, + (SK_PNMI_ERR016MSG)); + + return (SK_PNMI_ERR_GENERAL); + } + + SK_STRNCPY(pKeyArr + Index * SK_PNMI_VPD_KEY_SIZE, + &BufKeys[StartOffset], SK_PNMI_VPD_KEY_SIZE); + + Index ++; + StartOffset = Offset + 1; + } + + /* Last key not zero terminated? Get it anyway. */ + if (StartOffset < Offset) { + + SK_STRNCPY(pKeyArr + Index * SK_PNMI_VPD_KEY_SIZE, + &BufKeys[StartOffset], SK_PNMI_VPD_KEY_SIZE); + } + + return (SK_PNMI_ERR_OK); +} + +/***************************************************************************** + * + * SirqUpdate - Let the SIRQ update its internal values + * + * Description: + * Just to be sure that the SIRQ module holds its internal data + * structures up to date, we send an update event before we make + * any access. + * + * Returns: + * SK_PNMI_ERR_OK Task successfully performed. + * SK_PNMI_ERR_GENERAL Something went wrong. + */ +PNMI_STATIC int SirqUpdate( +SK_AC *pAC, /* Pointer to adapter context */ +SK_IOC IoC) /* IO context handle */ +{ + SK_EVPARA EventParam; + + /* Was the module already updated during the current PNMI call? */ + if (pAC->Pnmi.SirqUpdatedFlag > 0) { + + return (SK_PNMI_ERR_OK); + } + + /* Send an synchronuous update event to the module. */ + SK_MEMSET((char *)&EventParam, 0, sizeof(EventParam)); + + if (SkGeSirqEvent(pAC, IoC, SK_HWEV_UPDATE_STAT, EventParam)) { + + SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR047, SK_PNMI_ERR047MSG); + + return (SK_PNMI_ERR_GENERAL); + } + + return (SK_PNMI_ERR_OK); +} + +/***************************************************************************** + * + * RlmtUpdate - Let the RLMT update its internal values + * + * Description: + * Just to be sure that the RLMT module holds its internal data + * structures up to date, we send an update event before we make + * any access. + * + * Returns: + * SK_PNMI_ERR_OK Task successfully performed. + * SK_PNMI_ERR_GENERAL Something went wrong. + */ +PNMI_STATIC int RlmtUpdate( +SK_AC *pAC, /* Pointer to adapter context */ +SK_IOC IoC, /* IO context handle */ +SK_U32 NetIndex) /* NetIndex (0..n), in single net mode allways zero */ +{ + SK_EVPARA EventParam; + + /* Was the module already updated during the current PNMI call? */ + if (pAC->Pnmi.RlmtUpdatedFlag > 0) { + + return (SK_PNMI_ERR_OK); + } + + /* Send an synchronuous update event to the module. */ + SK_MEMSET((char *)&EventParam, 0, sizeof(EventParam)); + EventParam.Para32[0] = NetIndex; + EventParam.Para32[1] = (SK_U32)-1; + if (SkRlmtEvent(pAC, IoC, SK_RLMT_STATS_UPDATE, EventParam) > 0) { + + SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR048, SK_PNMI_ERR048MSG); + + return (SK_PNMI_ERR_GENERAL); + } + + return (SK_PNMI_ERR_OK); +} + +/***************************************************************************** + * + * MacUpdate - Force the XMAC to output the current statistic + * + * Description: + * The XMAC holds its statistic internally. To obtain the current + * values we must send a command so that the statistic data will + * be written to a predefined memory area on the adapter. + * + * Returns: + * SK_PNMI_ERR_OK Task successfully performed. + * SK_PNMI_ERR_GENERAL Something went wrong. + */ +PNMI_STATIC int MacUpdate( +SK_AC *pAC, /* Pointer to adapter context */ +SK_IOC IoC, /* IO context handle */ +unsigned int FirstMac, /* Index of the first Mac to be updated */ +unsigned int LastMac) /* Index of the last Mac to be updated */ +{ + unsigned int MacIndex; + + /* + * Were the statistics already updated during the + * current PNMI call? + */ + if (pAC->Pnmi.MacUpdatedFlag > 0) { + + return (SK_PNMI_ERR_OK); + } + + /* Send an update command to all MACs specified. */ + for (MacIndex = FirstMac; MacIndex <= LastMac; MacIndex ++) { + + /* + * 2002-09-13 pweber: Freeze the current SW counters. + * (That should be done as close as + * possible to the update of the + * HW counters). + */ + if (pAC->GIni.GIMacType == SK_MAC_XMAC) { + pAC->Pnmi.BufPort[MacIndex] = pAC->Pnmi.Port[MacIndex]; + } + + /* 2002-09-13 pweber: Update the HW counter. */ + if (pAC->GIni.GIFunc.pFnMacUpdateStats(pAC, IoC, MacIndex) != 0) { + + return (SK_PNMI_ERR_GENERAL); + } + } + + return (SK_PNMI_ERR_OK); +} + +/***************************************************************************** + * + * GetStatVal - Retrieve an XMAC statistic counter + * + * Description: + * Retrieves the statistic counter of a virtual or physical port. The + * virtual port is identified by the index 0. It consists of all + * currently active ports. To obtain the counter value for this port + * we must add the statistic counter of all active ports. To grant + * continuous counter values for the virtual port even when port + * switches occur we must additionally add a delta value, which was + * calculated during a SK_PNMI_EVT_RLMT_ACTIVE_UP event. + * + * Returns: + * Requested statistic value + */ +PNMI_STATIC SK_U64 GetStatVal( +SK_AC *pAC, /* Pointer to adapter context */ +SK_IOC IoC, /* IO context handle */ +unsigned int LogPortIndex, /* Index of the logical Port to be processed */ +unsigned int StatIndex, /* Index to statistic value */ +SK_U32 NetIndex) /* NetIndex (0..n), in single net mode allways zero */ +{ + unsigned int PhysPortIndex; + unsigned int PhysPortMax; + SK_U64 Val = 0; + + + if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { /* DualNet mode. */ + + PhysPortIndex = NetIndex; + + Val = GetPhysStatVal(pAC, IoC, PhysPortIndex, StatIndex); + } + else { /* SingleNet mode. */ + + if (LogPortIndex == 0) { + + PhysPortMax = pAC->GIni.GIMacsFound; + + /* Add counter of all active ports. */ + for (PhysPortIndex = 0; PhysPortIndex < PhysPortMax; + PhysPortIndex ++) { + + if (pAC->Pnmi.Port[PhysPortIndex].ActiveFlag) { + + Val += GetPhysStatVal(pAC, IoC, PhysPortIndex, StatIndex); + } + } + + /* Correct value because of port switches. */ + Val += pAC->Pnmi.VirtualCounterOffset[StatIndex]; + } + else { + /* Get counter value of physical port. */ + PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(pAC, LogPortIndex); + + Val = GetPhysStatVal(pAC, IoC, PhysPortIndex, StatIndex); + } + } + return (Val); +} + +/***************************************************************************** + * + * GetPhysStatVal - Get counter value for physical port + * + * Description: + * Builds a 64bit counter value. Except for the octet counters + * the lower 32bit are counted in hardware and the upper 32bit + * in software by monitoring counter overflow interrupts in the + * event handler. To grant continous counter values during XMAC + * resets (caused by a workaround) we must add a delta value. + * The delta was calculated in the event handler when a + * SK_PNMI_EVT_XMAC_RESET was received. + * + * Returns: + * Counter value + */ +PNMI_STATIC SK_U64 GetPhysStatVal( +SK_AC *pAC, /* Pointer to adapter context */ +SK_IOC IoC, /* IO context handle */ +unsigned int PhysPortIndex, /* Index of the logical Port to be processed */ +unsigned int StatIndex) /* Index to statistic value */ +{ + SK_U64 Val = 0; + SK_U32 LowVal = 0; + SK_U32 HighVal = 0; + SK_U16 Word; + int MacType; + unsigned int HelpIndex; + SK_GEPORT *pPrt; + + SK_PNMI_PORT *pPnmiPrt; + SK_GEMACFUNC *pFnMac; + + pPrt = &pAC->GIni.GP[PhysPortIndex]; + + MacType = pAC->GIni.GIMacType; + + /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort). */ + if (MacType == SK_MAC_XMAC) { + pPnmiPrt = &pAC->Pnmi.BufPort[PhysPortIndex]; + } + else { + pPnmiPrt = &pAC->Pnmi.Port[PhysPortIndex]; + } + + pFnMac = &pAC->GIni.GIFunc; + + switch (StatIndex) { + case SK_PNMI_HTX: + if (MacType == SK_MAC_GMAC) { + (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex, + StatAddr[SK_PNMI_HTX_BROADCAST][MacType].Reg, + &LowVal); + (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex, + StatAddr[SK_PNMI_HTX_MULTICAST][MacType].Reg, + &HighVal); + LowVal += HighVal; + (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex, + StatAddr[SK_PNMI_HTX_UNICAST][MacType].Reg, + &HighVal); + LowVal += HighVal; + } + else { + (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex, + StatAddr[StatIndex][MacType].Reg, + &LowVal); + } + HighVal = pPnmiPrt->CounterHigh[StatIndex]; + break; + + case SK_PNMI_HRX: + if (MacType == SK_MAC_GMAC) { + (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex, + StatAddr[SK_PNMI_HRX_BROADCAST][MacType].Reg, + &LowVal); + (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex, + StatAddr[SK_PNMI_HRX_MULTICAST][MacType].Reg, + &HighVal); + LowVal += HighVal; + (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex, + StatAddr[SK_PNMI_HRX_UNICAST][MacType].Reg, + &HighVal); + LowVal += HighVal; + } + else { + (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex, + StatAddr[StatIndex][MacType].Reg, + &LowVal); + } + HighVal = pPnmiPrt->CounterHigh[StatIndex]; + break; + + case SK_PNMI_HTX_OCTET: + case SK_PNMI_HRX_OCTET: + (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex, + StatAddr[StatIndex][MacType].Reg, + &HighVal); + (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex, + StatAddr[StatIndex + 1][MacType].Reg, + &LowVal); + break; + + case SK_PNMI_HTX_BURST: + case SK_PNMI_HTX_EXCESS_DEF: + case SK_PNMI_HTX_CARRIER: + /* Not supported by GMAC. */ + if (MacType == SK_MAC_GMAC) { + return (Val); + } + + (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex, + StatAddr[StatIndex][MacType].Reg, + &LowVal); + HighVal = pPnmiPrt->CounterHigh[StatIndex]; + break; + + case SK_PNMI_HTX_MACC: + /* GMAC only supports PAUSE MAC control frames. */ + if (MacType == SK_MAC_GMAC) { + HelpIndex = SK_PNMI_HTX_PMACC; + } + else { + HelpIndex = StatIndex; + } + + (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex, + StatAddr[HelpIndex][MacType].Reg, + &LowVal); + + HighVal = pPnmiPrt->CounterHigh[StatIndex]; + break; + + case SK_PNMI_HTX_COL: + case SK_PNMI_HRX_UNDERSIZE: + /* Not supported by XMAC. */ + if (MacType == SK_MAC_XMAC) { + return (Val); + } + + (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex, + StatAddr[StatIndex][MacType].Reg, + &LowVal); + HighVal = pPnmiPrt->CounterHigh[StatIndex]; + break; + + case SK_PNMI_HTX_DEFFERAL: + /* Not supported by GMAC. */ + if (MacType == SK_MAC_GMAC) { + return (Val); + } + + /* + * XMAC counts frames with deferred transmission + * even in full-duplex mode. + * + * In full-duplex mode the counter remains constant! + */ + if ((pPrt->PLinkModeStatus == SK_LMODE_STAT_AUTOFULL) || + (pPrt->PLinkModeStatus == SK_LMODE_STAT_FULL)) { + + LowVal = 0; + HighVal = 0; + } + else { + /* Otherwise get contents of hardware register. */ + (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex, + StatAddr[StatIndex][MacType].Reg, + &LowVal); + HighVal = pPnmiPrt->CounterHigh[StatIndex]; + } + break; + + case SK_PNMI_HRX_BADOCTET: + /* Not supported by XMAC. */ + if (MacType == SK_MAC_XMAC) { + return (Val); + } + + (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex, + StatAddr[StatIndex][MacType].Reg, + &HighVal); + (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex, + StatAddr[StatIndex + 1][MacType].Reg, + &LowVal); + break; + + case SK_PNMI_HTX_OCTETLOW: + case SK_PNMI_HRX_OCTETLOW: + case SK_PNMI_HRX_BADOCTETLOW: + return (Val); + + case SK_PNMI_HRX_LONGFRAMES: + /* For XMAC the SW counter is managed by PNMI. */ + if (MacType == SK_MAC_XMAC) { + return (pPnmiPrt->StatRxLongFrameCts); + } + + (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex, + StatAddr[StatIndex][MacType].Reg, + &LowVal); + HighVal = pPnmiPrt->CounterHigh[StatIndex]; + break; + + case SK_PNMI_HRX_TOO_LONG: + (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex, + StatAddr[StatIndex][MacType].Reg, + &LowVal); + HighVal = pPnmiPrt->CounterHigh[StatIndex]; + + Val = (((SK_U64)HighVal << 32) | (SK_U64)LowVal); + + if (MacType == SK_MAC_GMAC) { + /* For GMAC the SW counter is additionally managed by PNMI. */ + Val += pPnmiPrt->StatRxFrameTooLongCts; + } + else { + /* + * Frames longer than IEEE 802.3 frame max size are counted + * by XMAC in frame_too_long counter even reception of long + * frames was enabled and the frame was correct. + * So correct the value by subtracting RxLongFrame counter. + */ + Val -= pPnmiPrt->StatRxLongFrameCts; + } + + LowVal = (SK_U32)Val; + HighVal = (SK_U32)(Val >> 32); + break; + + case SK_PNMI_HRX_SHORTS: + /* Not supported by GMAC. */ + if (MacType == SK_MAC_GMAC) { + /* GM_RXE_FRAG?? */ + return (Val); + } + + /* + * XMAC counts short frame errors even if link down (#10620). + * If the link is down, the counter remains constant. + */ + if (pPrt->PLinkModeStatus != SK_LMODE_STAT_UNKNOWN) { + + /* Otherwise get incremental difference. */ + (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex, + StatAddr[StatIndex][MacType].Reg, + &LowVal); + HighVal = pPnmiPrt->CounterHigh[StatIndex]; + + Val = (((SK_U64)HighVal << 32) | (SK_U64)LowVal); + Val -= pPnmiPrt->RxShortZeroMark; + + LowVal = (SK_U32)Val; + HighVal = (SK_U32)(Val >> 32); + } + break; + + case SK_PNMI_HRX_MACC: + case SK_PNMI_HRX_MACC_UNKWN: + case SK_PNMI_HRX_BURST: + case SK_PNMI_HRX_MISSED: + case SK_PNMI_HRX_FRAMING: + case SK_PNMI_HRX_CARRIER: + case SK_PNMI_HRX_IRLENGTH: + case SK_PNMI_HRX_SYMBOL: + case SK_PNMI_HRX_CEXT: + /* Not supported by GMAC. */ + if (MacType == SK_MAC_GMAC) { + return (Val); + } + + (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex, + StatAddr[StatIndex][MacType].Reg, + &LowVal); + HighVal = pPnmiPrt->CounterHigh[StatIndex]; + break; + + case SK_PNMI_HRX_PMACC_ERR: + /* For GMAC the SW counter is managed by PNMI. */ + if (MacType == SK_MAC_GMAC) { + return (pPnmiPrt->StatRxPMaccErr); + } + + (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex, + StatAddr[StatIndex][MacType].Reg, + &LowVal); + HighVal = pPnmiPrt->CounterHigh[StatIndex]; + break; + + /* SW counter managed by PNMI. */ + case SK_PNMI_HTX_SYNC: + LowVal = (SK_U32)pPnmiPrt->StatSyncCts; + HighVal = (SK_U32)(pPnmiPrt->StatSyncCts >> 32); + break; + + /* SW counter managed by PNMI. */ + case SK_PNMI_HTX_SYNC_OCTET: + LowVal = (SK_U32)pPnmiPrt->StatSyncOctetsCts; + HighVal = (SK_U32)(pPnmiPrt->StatSyncOctetsCts >> 32); + break; + + case SK_PNMI_HRX_FCS: + /* + * Broadcom filters FCS errors and counts them in + * Receive Error Counter register. + */ + if (pPrt->PhyType == SK_PHY_BCOM) { +#ifdef GENESIS + /* Do not read while not initialized (PHY_READ hangs!). */ + if (pPrt->PState != SK_PRT_RESET) { + SkXmPhyRead(pAC, IoC, PhysPortIndex, PHY_BCOM_RE_CTR, &Word); + + LowVal = Word; + } + HighVal = pPnmiPrt->CounterHigh[StatIndex]; +#endif /* GENESIS */ + } + else { + (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex, + StatAddr[StatIndex][MacType].Reg, + &LowVal); + HighVal = pPnmiPrt->CounterHigh[StatIndex]; + } + break; + + default: + (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex, + StatAddr[StatIndex][MacType].Reg, + &LowVal); + HighVal = pPnmiPrt->CounterHigh[StatIndex]; + break; + } + + Val = (((SK_U64)HighVal << 32) | (SK_U64)LowVal); + + /* Correct value because of possible XMAC reset (XMAC Errata #2). */ + Val += pPnmiPrt->CounterOffset[StatIndex]; + + return (Val); +} + +/***************************************************************************** + * + * ResetCounter - Set all counters and timestamps to zero + * + * Description: + * Notifies other common modules which store statistic data to + * reset their counters and finally reset our own counters. + * + * Returns: + * Nothing + */ +PNMI_STATIC void ResetCounter( +SK_AC *pAC, /* Pointer to adapter context */ +SK_IOC IoC, /* IO context handle */ +SK_U32 NetIndex) +{ + unsigned int PhysPortIndex; + SK_EVPARA EventParam; + + SK_MEMSET((char *)&EventParam, 0, sizeof(EventParam)); + + /* Notify sensor module. */ + SkEventQueue(pAC, SKGE_I2C, SK_I2CEV_CLEAR, EventParam); + + /* Notify RLMT module. */ + EventParam.Para32[0] = NetIndex; + EventParam.Para32[1] = (SK_U32)-1; + SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_STATS_CLEAR, EventParam); + EventParam.Para32[1] = 0; + + /* Notify SIRQ module. */ + SkEventQueue(pAC, SKGE_HWAC, SK_HWEV_CLEAR_STAT, EventParam); + + /* Notify CSUM module. */ +#ifdef SK_USE_CSUM + EventParam.Para32[0] = NetIndex; + EventParam.Para32[1] = (SK_U32)-1; + SkEventQueue(pAC, SKGE_CSUM, SK_CSUM_EVENT_CLEAR_PROTO_STATS, + EventParam); +#endif /* SK_USE_CSUM */ + + /* Clear XMAC statistics. */ + for (PhysPortIndex = 0; PhysPortIndex < + (unsigned int)pAC->GIni.GIMacsFound; PhysPortIndex ++) { + + (void)pAC->GIni.GIFunc.pFnMacResetCounter(pAC, IoC, PhysPortIndex); + + SK_MEMSET((char *)&pAC->Pnmi.Port[PhysPortIndex].CounterHigh, + 0, sizeof(pAC->Pnmi.Port[PhysPortIndex].CounterHigh)); + SK_MEMSET((char *)&pAC->Pnmi.Port[PhysPortIndex]. + CounterOffset, 0, sizeof(pAC->Pnmi.Port[ + PhysPortIndex].CounterOffset)); + SK_MEMSET((char *)&pAC->Pnmi.Port[PhysPortIndex].StatSyncCts, + 0, sizeof(pAC->Pnmi.Port[PhysPortIndex].StatSyncCts)); + SK_MEMSET((char *)&pAC->Pnmi.Port[PhysPortIndex]. + StatSyncOctetsCts, 0, sizeof(pAC->Pnmi.Port[ + PhysPortIndex].StatSyncOctetsCts)); + SK_MEMSET((char *)&pAC->Pnmi.Port[PhysPortIndex]. + StatRxLongFrameCts, 0, sizeof(pAC->Pnmi.Port[ + PhysPortIndex].StatRxLongFrameCts)); + SK_MEMSET((char *)&pAC->Pnmi.Port[PhysPortIndex]. + StatRxFrameTooLongCts, 0, sizeof(pAC->Pnmi.Port[ + PhysPortIndex].StatRxFrameTooLongCts)); + SK_MEMSET((char *)&pAC->Pnmi.Port[PhysPortIndex]. + StatRxPMaccErr, 0, sizeof(pAC->Pnmi.Port[ + PhysPortIndex].StatRxPMaccErr)); + } + + /* Clear local statistics. */ + SK_MEMSET((char *)&pAC->Pnmi.VirtualCounterOffset, 0, + sizeof(pAC->Pnmi.VirtualCounterOffset)); + + pAC->Pnmi.RlmtChangeCts = 0; + pAC->Pnmi.RlmtChangeTime = 0; + + SK_MEMSET((char *)&pAC->Pnmi.RlmtChangeEstimate.EstValue[0], 0, + sizeof(pAC->Pnmi.RlmtChangeEstimate.EstValue)); + pAC->Pnmi.RlmtChangeEstimate.EstValueIndex = 0; + pAC->Pnmi.RlmtChangeEstimate.Estimate = 0; + pAC->Pnmi.Port[NetIndex].TxSwQueueMax = 0; + pAC->Pnmi.Port[NetIndex].TxRetryCts = 0; + pAC->Pnmi.Port[NetIndex].RxIntrCts = 0; + pAC->Pnmi.Port[NetIndex].TxIntrCts = 0; + pAC->Pnmi.Port[NetIndex].RxNoBufCts = 0; + pAC->Pnmi.Port[NetIndex].TxNoBufCts = 0; + pAC->Pnmi.Port[NetIndex].TxUsedDescrNo = 0; + pAC->Pnmi.Port[NetIndex].RxDeliveredCts = 0; + pAC->Pnmi.Port[NetIndex].RxOctetsDeliveredCts = 0; + pAC->Pnmi.Port[NetIndex].ErrRecoveryCts = 0; +} + +/***************************************************************************** + * + * GetTrapEntry - Get an entry in the trap buffer + * + * Description: + * The trap buffer stores various events. A user application somehow + * gets notified that an event occured and retrieves the trap buffer + * contens (or simply polls the buffer). The buffer is organized as + * a ring which stores the newest traps at the beginning. The oldest + * traps are overwritten by the newest ones. Each trap entry has a + * unique number, so that applications may detect new trap entries. + * + * Returns: + * A pointer to the trap entry + */ +PNMI_STATIC char* GetTrapEntry( +SK_AC *pAC, /* Pointer to adapter context */ +SK_U32 TrapId, /* SNMP ID of the trap */ +unsigned int Size) /* Space needed for trap entry */ +{ + unsigned int BufPad = pAC->Pnmi.TrapBufPad; + unsigned int BufFree = pAC->Pnmi.TrapBufFree; + unsigned int Beg = pAC->Pnmi.TrapQueueBeg; + unsigned int End = pAC->Pnmi.TrapQueueEnd; + char *pBuf = &pAC->Pnmi.TrapBuf[0]; + int Wrap; + unsigned int NeededSpace; + unsigned int EntrySize; + SK_U32 Val32; + SK_U64 Val64; + + /* Last byte of entry will get a copy of the entry length. */ + Size ++; + + /* Calculate needed buffer space. */ + if (Beg >= Size) { + + NeededSpace = Size; + Wrap = SK_FALSE; + } + else { + NeededSpace = Beg + Size; + Wrap = SK_TRUE; + } + + /* + * Check if enough buffer space is provided. Otherwise + * free some entries. Leave one byte space between begin + * and end of buffer to make it possible to detect whether + * the buffer is full or empty. + */ + while (BufFree < NeededSpace + 1) { + + if (End == 0) { + + End = SK_PNMI_TRAP_QUEUE_LEN; + } + + EntrySize = (unsigned int)*((unsigned char *)pBuf + End - 1); + BufFree += EntrySize; + End -= EntrySize; +#ifdef DEBUG + SK_MEMSET(pBuf + End, (char)(-1), EntrySize); +#endif /* DEBUG */ + if (End == BufPad) { +#ifdef DEBUG + SK_MEMSET(pBuf, (char)(-1), End); +#endif /* DEBUG */ + BufFree += End; + End = 0; + BufPad = 0; + } + } + + /* + * Insert new entry as first entry. Newest entries are + * stored at the beginning of the queue. + */ + if (Wrap) { + + BufPad = Beg; + Beg = SK_PNMI_TRAP_QUEUE_LEN - Size; + } + else { + Beg = Beg - Size; + } + BufFree -= NeededSpace; + + /* Save the current offsets. */ + pAC->Pnmi.TrapQueueBeg = Beg; + pAC->Pnmi.TrapQueueEnd = End; + pAC->Pnmi.TrapBufPad = BufPad; + pAC->Pnmi.TrapBufFree = BufFree; + + /* Initialize the trap entry. */ + *(pBuf + Beg + Size - 1) = (char)Size; + *(pBuf + Beg) = (char)Size; + Val32 = (pAC->Pnmi.TrapUnique) ++; + SK_PNMI_STORE_U32(pBuf + Beg + 1, Val32); + SK_PNMI_STORE_U32(pBuf + Beg + 1 + sizeof(SK_U32), TrapId); + Val64 = SK_PNMI_HUNDREDS_SEC(SkOsGetTime(pAC)); + SK_PNMI_STORE_U64(pBuf + Beg + 1 + 2 * sizeof(SK_U32), Val64); + + return (pBuf + Beg); +} + +/***************************************************************************** + * + * CopyTrapQueue - Copies the trap buffer for the TRAP OID + * + * Description: + * On a query of the TRAP OID the trap buffer contents will be + * copied continuously to the request buffer, which must be large + * enough. No length check is performed. + * + * Returns: + * Nothing + */ +PNMI_STATIC void CopyTrapQueue( +SK_AC *pAC, /* Pointer to adapter context */ +char *pDstBuf) /* Buffer to which the queued traps will be copied */ +{ + unsigned int BufPad = pAC->Pnmi.TrapBufPad; + unsigned int Trap = pAC->Pnmi.TrapQueueBeg; + unsigned int End = pAC->Pnmi.TrapQueueEnd; + char *pBuf = &pAC->Pnmi.TrapBuf[0]; + unsigned int Len; + unsigned int DstOff = 0; + + while (Trap != End) { + + Len = (unsigned int)*(pBuf + Trap); + + /* + * Last byte containing a copy of the length will + * not be copied. + */ + *(pDstBuf + DstOff) = (char)(Len - 1); + SK_MEMCPY(pDstBuf + DstOff + 1, pBuf + Trap + 1, Len - 2); + DstOff += Len - 1; + + Trap += Len; + if (Trap == SK_PNMI_TRAP_QUEUE_LEN) { + + Trap = BufPad; + } + } +} + +/***************************************************************************** + * + * GetTrapQueueLen - Get the length of the trap buffer + * + * Description: + * Evaluates the number of currently stored traps and the needed + * buffer size to retrieve them. + * + * Returns: + * Nothing + */ +PNMI_STATIC void GetTrapQueueLen( +SK_AC *pAC, /* Pointer to adapter context */ +unsigned int *pLen, /* Length in Bytes of all queued traps */ +unsigned int *pEntries) /* Returns number of trapes stored in queue */ +{ + unsigned int BufPad = pAC->Pnmi.TrapBufPad; + unsigned int Trap = pAC->Pnmi.TrapQueueBeg; + unsigned int End = pAC->Pnmi.TrapQueueEnd; + char *pBuf = &pAC->Pnmi.TrapBuf[0]; + unsigned int Len; + unsigned int Entries = 0; + unsigned int TotalLen = 0; + + while (Trap != End) { + + Len = (unsigned int)*(pBuf + Trap); + TotalLen += Len - 1; + Entries ++; + + Trap += Len; + if (Trap == SK_PNMI_TRAP_QUEUE_LEN) { + + Trap = BufPad; + } + } + + *pEntries = Entries; + *pLen = TotalLen; +} + +/***************************************************************************** + * + * QueueSimpleTrap - Store a simple trap to the trap buffer + * + * Description: + * A simple trap is a trap with now additional data. It consists + * simply of a trap code. + * + * Returns: + * Nothing + */ +PNMI_STATIC void QueueSimpleTrap( +SK_AC *pAC, /* Pointer to adapter context */ +SK_U32 TrapId) /* Type of sensor trap */ +{ + GetTrapEntry(pAC, TrapId, SK_PNMI_TRAP_SIMPLE_LEN); +} + +/***************************************************************************** + * + * QueueSensorTrap - Stores a sensor trap in the trap buffer + * + * Description: + * Gets an entry in the trap buffer and fills it with sensor related + * data. + * + * Returns: + * Nothing + */ +PNMI_STATIC void QueueSensorTrap( +SK_AC *pAC, /* Pointer to adapter context */ +SK_U32 TrapId, /* Type of sensor trap */ +unsigned int SensorIndex) /* Index of sensor which caused the trap */ +{ + char *pBuf; + unsigned int Offset; + unsigned int DescrLen; + SK_U32 Val32; + + /* Get trap buffer entry. */ + DescrLen = SK_STRLEN(pAC->I2c.SenTable[SensorIndex].SenDesc); + + pBuf = GetTrapEntry(pAC, TrapId, + SK_PNMI_TRAP_SENSOR_LEN_BASE + DescrLen); + Offset = SK_PNMI_TRAP_SIMPLE_LEN; + + /* Store additionally sensor trap related data. */ + Val32 = OID_SKGE_SENSOR_INDEX; + SK_PNMI_STORE_U32(pBuf + Offset, Val32); + *(pBuf + Offset + 4) = 4; + Val32 = (SK_U32)SensorIndex; + SK_PNMI_STORE_U32(pBuf + Offset + 5, Val32); + Offset += 9; + + Val32 = (SK_U32)OID_SKGE_SENSOR_DESCR; + SK_PNMI_STORE_U32(pBuf + Offset, Val32); + *(pBuf + Offset + 4) = (char)DescrLen; + SK_MEMCPY(pBuf + Offset + 5, pAC->I2c.SenTable[SensorIndex].SenDesc, + DescrLen); + Offset += DescrLen + 5; + + Val32 = OID_SKGE_SENSOR_TYPE; + SK_PNMI_STORE_U32(pBuf + Offset, Val32); + *(pBuf + Offset + 4) = 1; + *(pBuf + Offset + 5) = (char)pAC->I2c.SenTable[SensorIndex].SenType; + Offset += 6; + + Val32 = OID_SKGE_SENSOR_VALUE; + SK_PNMI_STORE_U32(pBuf + Offset, Val32); + *(pBuf + Offset + 4) = 4; + Val32 = (SK_U32)pAC->I2c.SenTable[SensorIndex].SenValue; + SK_PNMI_STORE_U32(pBuf + Offset + 5, Val32); +} + +/***************************************************************************** + * + * QueueRlmtNewMacTrap - Store a port switch trap in the trap buffer + * + * Description: + * Nothing further to explain. + * + * Returns: + * Nothing + */ +PNMI_STATIC void QueueRlmtNewMacTrap( +SK_AC *pAC, /* Pointer to adapter context */ +unsigned int ActiveMac) /* Index (0..n) of the currently active port */ +{ + char *pBuf; + SK_U32 Val32; + + pBuf = GetTrapEntry(pAC, OID_SKGE_TRAP_RLMT_CHANGE_PORT, + SK_PNMI_TRAP_RLMT_CHANGE_LEN); + + Val32 = OID_SKGE_RLMT_PORT_ACTIVE; + SK_PNMI_STORE_U32(pBuf + SK_PNMI_TRAP_SIMPLE_LEN, Val32); + *(pBuf + SK_PNMI_TRAP_SIMPLE_LEN + 4) = 1; + *(pBuf + SK_PNMI_TRAP_SIMPLE_LEN + 5) = (char)ActiveMac; +} + +/***************************************************************************** + * + * QueueRlmtPortTrap - Store port related RLMT trap to trap buffer + * + * Description: + * Nothing further to explain. + * + * Returns: + * Nothing + */ +PNMI_STATIC void QueueRlmtPortTrap( +SK_AC *pAC, /* Pointer to adapter context */ +SK_U32 TrapId, /* Type of RLMT port trap */ +unsigned int PortIndex) /* Index of the port, which changed its state */ +{ + char *pBuf; + SK_U32 Val32; + + pBuf = GetTrapEntry(pAC, TrapId, SK_PNMI_TRAP_RLMT_PORT_LEN); + + Val32 = OID_SKGE_RLMT_PORT_INDEX; + SK_PNMI_STORE_U32(pBuf + SK_PNMI_TRAP_SIMPLE_LEN, Val32); + *(pBuf + SK_PNMI_TRAP_SIMPLE_LEN + 4) = 1; + *(pBuf + SK_PNMI_TRAP_SIMPLE_LEN + 5) = (char)PortIndex; +} + +/***************************************************************************** + * + * CopyMac - Copies a MAC address + * + * Description: + * Nothing further to explain. + * + * Returns: + * Nothing + */ +PNMI_STATIC void CopyMac( +char *pDst, /* Pointer to destination buffer */ +SK_MAC_ADDR *pMac) /* Pointer of Source */ +{ + int i; + + for (i = 0; i < sizeof(SK_MAC_ADDR); i ++) { + + *(pDst + i) = pMac->a[i]; + } +} + +#ifdef SK_POWER_MGMT +/***************************************************************************** + * + * PowerManagement - OID handler function of PowerManagement OIDs + * + * Description: + * The code is simple. No description necessary. + * + * Returns: + * SK_PNMI_ERR_OK The request was successfully performed. + * SK_PNMI_ERR_GENERAL A general severe internal error occured. + * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain + * the correct data (e.g. a 32bit value is + * needed, but a 16 bit value was passed). + * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't + * exist (e.g. port instance 3 on a two port + * adapter. + */ + +PNMI_STATIC int PowerManagement( +SK_AC *pAC, /* Pointer to adapter context */ +SK_IOC IoC, /* IO context handle */ +int Action, /* Get/PreSet/Set action */ +SK_U32 Id, /* Object ID that is to be processed */ +char *pBuf, /* Buffer to which to mgmt data will be retrieved */ +unsigned int *pLen, /* On call: buffer length. On return: used buffer */ +SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */ +unsigned int TableIndex, /* Index to the Id table */ +SK_U32 NetIndex) /* NetIndex (0..n), in single net mode allways zero */ +{ + + int i; + unsigned int HwPortIndex; + + SK_U32 RetCode = SK_PNMI_ERR_GENERAL; + + /* Check instance. We only handle single instance variables. */ + if ((Instance != (SK_U32)(-1))) { + + *pLen = 0; + return (SK_PNMI_ERR_UNKNOWN_INST); + } + + /* Get hardware port index */ + HwPortIndex = NetIndex; + + /* Check length. */ + switch (Id) { + + case OID_PNP_CAPABILITIES: + if (*pLen < sizeof(SK_PNP_CAPABILITIES)) { + + *pLen = sizeof(SK_PNP_CAPABILITIES); + return (SK_PNMI_ERR_TOO_SHORT); + } + break; + + case OID_PNP_SET_POWER: + case OID_PNP_QUERY_POWER: + if (*pLen < sizeof(SK_DEVICE_POWER_STATE)) + { + *pLen = sizeof(SK_DEVICE_POWER_STATE); + return (SK_PNMI_ERR_TOO_SHORT); + } + break; + + case OID_PNP_ADD_WAKE_UP_PATTERN: + case OID_PNP_REMOVE_WAKE_UP_PATTERN: + if (*pLen < sizeof(SK_PM_PACKET_PATTERN)) { + + *pLen = sizeof(SK_PM_PACKET_PATTERN); + return (SK_PNMI_ERR_TOO_SHORT); + } + break; + + case OID_PNP_ENABLE_WAKE_UP: + if (*pLen < sizeof(SK_U32)) { + + *pLen = sizeof(SK_U32); + return (SK_PNMI_ERR_TOO_SHORT); + } + break; + } + + /* Perform action. */ + if (Action == SK_PNMI_GET) { + + /* Get value. */ + switch (Id) { + + case OID_PNP_CAPABILITIES: + RetCode = SkPowerQueryPnPCapabilities(pAC, IoC, pBuf, pLen); + break; + + case OID_PNP_QUERY_POWER: + /* + * The Windows DDK describes: An OID_PNP_QUERY_POWER requests + * the miniport to indicate whether it can transition its NIC + * to the low-power state. + * A miniport driver must always return NDIS_STATUS_SUCCESS + * to a query of OID_PNP_QUERY_POWER. + */ + *pLen = sizeof(SK_DEVICE_POWER_STATE); + RetCode = SK_PNMI_ERR_OK; + break; + + /* + * NDIS handles these OIDs as write-only. + * So in case of get action the buffer with written length = 0 + * is returned. + */ + case OID_PNP_SET_POWER: + case OID_PNP_ADD_WAKE_UP_PATTERN: + case OID_PNP_REMOVE_WAKE_UP_PATTERN: + *pLen = 0; + RetCode = SK_PNMI_ERR_NOT_SUPPORTED; + break; + + case OID_PNP_ENABLE_WAKE_UP: + RetCode = SkPowerGetEnableWakeUp(pAC, IoC, HwPortIndex, pBuf, pLen); + break; + + default: + RetCode = SK_PNMI_ERR_GENERAL; + break; + } + + return (RetCode); + } + + /* Perform PRESET or SET. */ + + /* The POWER module does not support PRESET action. */ + if (Action == SK_PNMI_PRESET) { + + return (SK_PNMI_ERR_OK); + } + + /* */ + i= HwPortIndex; + + switch (Id) { + case OID_PNP_SET_POWER: + /* Dual net mode? */ + for (i = 0; i < pAC->GIni.GIMacsFound; i++) { + if (RetCode = SkPowerSetPower(pAC, IoC, i, pBuf, pLen)) { + break; + } + } + break; + + case OID_PNP_ADD_WAKE_UP_PATTERN: + for (i = 0; i < pAC->GIni.GIMacsFound; i++) { + if (RetCode = SkPowerAddWakeUpPattern(pAC, IoC, i, pBuf, pLen)) { + break; + } + } + break; + + case OID_PNP_REMOVE_WAKE_UP_PATTERN: + for (i = 0; i < pAC->GIni.GIMacsFound; i++) { + if (RetCode = SkPowerRemoveWakeUpPattern(pAC, IoC, i, pBuf, pLen)) { + break; + } + } + break; + + case OID_PNP_ENABLE_WAKE_UP: + for (i = 0; i < pAC->GIni.GIMacsFound; i++) { + if (RetCode = SkPowerSetEnableWakeUp(pAC, IoC, i, pBuf, pLen)) { + break; + } + } + break; + + default: + RetCode = SK_PNMI_ERR_READ_ONLY; + } + + return (RetCode); +} +#endif /* SK_POWER_MGMT */ + +#ifdef SK_DIAG_SUPPORT +/***************************************************************************** + * + * DiagActions - OID handler function of Diagnostic driver + * + * Description: + * The code is simple. No description necessary. + * + * Returns: + * SK_PNMI_ERR_OK The request was successfully performed. + * SK_PNMI_ERR_GENERAL A general severe internal error occured. + * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain + * the correct data (e.g. a 32bit value is + * needed, but a 16 bit value was passed). + * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't + * exist (e.g. port instance 3 on a two port + * adapter. + */ + +PNMI_STATIC int DiagActions( +SK_AC *pAC, /* Pointer to adapter context */ +SK_IOC IoC, /* IO context handle */ +int Action, /* GET/PRESET/SET action */ +SK_U32 Id, /* Object ID that is to be processed */ +char *pBuf, /* Buffer used for the management data transfer */ +unsigned int *pLen, /* On call: pBuf buffer length. On return: used buffer */ +SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */ +unsigned int TableIndex, /* Index to the Id table */ +SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */ +{ + SK_U32 DiagStatus; + SK_U32 RetCode = SK_PNMI_ERR_GENERAL; + + /* Check instance. We only handle single instance variables. */ + if (Instance != (SK_U32)(-1) && Instance != 1) { + + *pLen = 0; + return (SK_PNMI_ERR_UNKNOWN_INST); + } + + /* Check length. */ + switch (Id) { + + case OID_SKGE_DIAG_MODE: + if (*pLen < sizeof(SK_U32)) { + + *pLen = sizeof(SK_U32); + return (SK_PNMI_ERR_TOO_SHORT); + } + break; + + default: + SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR040, SK_PNMI_ERR040MSG); + *pLen = 0; + return (SK_PNMI_ERR_GENERAL); + } + + /* Perform action. */ + if (Action == SK_PNMI_GET) { + + /* Get value. */ + switch (Id) { + + case OID_SKGE_DIAG_MODE: + DiagStatus = pAC->Pnmi.DiagAttached; + SK_PNMI_STORE_U32(pBuf, DiagStatus); + *pLen = sizeof(SK_U32); + RetCode = SK_PNMI_ERR_OK; + break; + + default: + *pLen = 0; + RetCode = SK_PNMI_ERR_GENERAL; + break; + } + return (RetCode); + } + + /* From here SET or PRESET value. */ + + /* PRESET value is not supported. */ + if (Action == SK_PNMI_PRESET) { + + return (SK_PNMI_ERR_OK); + } + + /* SET value. */ + switch (Id) { + case OID_SKGE_DIAG_MODE: + + /* Handle the SET. */ + switch (*pBuf) { + + /* Attach the DIAG to this adapter. */ + case SK_DIAG_ATTACHED: + /* Check if we come from running. */ + if (pAC->Pnmi.DiagAttached == SK_DIAG_RUNNING) { + + RetCode = SkDrvLeaveDiagMode(pAC); + + } + else if (pAC->Pnmi.DiagAttached == SK_DIAG_IDLE) { + + RetCode = SK_PNMI_ERR_OK; + } + + else { + + RetCode = SK_PNMI_ERR_GENERAL; + + } + + if (RetCode == SK_PNMI_ERR_OK) { + + pAC->Pnmi.DiagAttached = SK_DIAG_ATTACHED; + } + break; + + /* Enter the DIAG mode in the driver. */ + case SK_DIAG_RUNNING: + RetCode = SK_PNMI_ERR_OK; + + /* + * If DiagAttached is set, we can tell the driver + * to enter the DIAG mode. + */ + if (pAC->Pnmi.DiagAttached == SK_DIAG_ATTACHED) { + /* If DiagMode is not active, we can enter it. */ + if (!pAC->DiagModeActive) { + + RetCode = SkDrvEnterDiagMode(pAC); + } + else { + + RetCode = SK_PNMI_ERR_GENERAL; + } + } + else { + + RetCode = SK_PNMI_ERR_GENERAL; + } + + if (RetCode == SK_PNMI_ERR_OK) { + + pAC->Pnmi.DiagAttached = SK_DIAG_RUNNING; + } + break; + + case SK_DIAG_IDLE: + /* Check if we come from running. */ + if (pAC->Pnmi.DiagAttached == SK_DIAG_RUNNING) { + + RetCode = SkDrvLeaveDiagMode(pAC); + + } + else if (pAC->Pnmi.DiagAttached == SK_DIAG_ATTACHED) { + + RetCode = SK_PNMI_ERR_OK; + } + + else { + + RetCode = SK_PNMI_ERR_GENERAL; + + } + + if (RetCode == SK_PNMI_ERR_OK) { + + pAC->Pnmi.DiagAttached = SK_DIAG_IDLE; + } + break; + + default: + RetCode = SK_PNMI_ERR_BAD_VALUE; + break; + } + break; + + default: + RetCode = SK_PNMI_ERR_GENERAL; + } + + if (RetCode == SK_PNMI_ERR_OK) { + *pLen = sizeof(SK_U32); + } + else { + + *pLen = 0; + } + return (RetCode); +} +#endif /* SK_DIAG_SUPPORT */ + +/***************************************************************************** + * + * Vct - OID handler function of OIDs for Virtual Cable Tester (VCT) + * + * Description: + * The code is simple. No description necessary. + * + * Returns: + * SK_PNMI_ERR_OK The request was performed successfully. + * SK_PNMI_ERR_GENERAL A general severe internal error occured. + * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain + * the correct data (e.g. a 32bit value is + * needed, but a 16 bit value was passed). + * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't + * exist (e.g. port instance 3 on a two port + * adapter). + * SK_PNMI_ERR_READ_ONLY Only the Get action is allowed. + * + */ + +PNMI_STATIC int Vct( +SK_AC *pAC, /* Pointer to adapter context */ +SK_IOC IoC, /* IO context handle */ +int Action, /* GET/PRESET/SET action */ +SK_U32 Id, /* Object ID that is to be processed */ +char *pBuf, /* Buffer used for the management data transfer */ +unsigned int *pLen, /* On call: pBuf buffer length. On return: used buffer */ +SK_U32 Instance, /* Instance (-1,2..n) that is to be queried */ +unsigned int TableIndex, /* Index to the Id table */ +SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */ +{ + SK_GEPORT *pPrt; + SK_PNMI_VCT *pVctBackupData; + SK_U32 LogPortMax; + SK_U32 PhysPortMax; + SK_U32 PhysPortIndex; + SK_U32 Limit; + SK_U32 Offset; + SK_U32 RetCode; + int i; + SK_EVPARA Para; + + RetCode = SK_PNMI_ERR_GENERAL; + + /* Calculate the port indexes from the instance. */ + PhysPortMax = pAC->GIni.GIMacsFound; + LogPortMax = SK_PNMI_PORT_PHYS2LOG(PhysPortMax); + + /* Dual net mode? */ + if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { + LogPortMax--; + } + + if ((Instance != (SK_U32) (-1))) { + /* + * Get one instance of that OID, so check the instance range: + * There is no virtual port with an Instance == 1, so we get + * the values from one physical port only. + */ + if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { + PhysPortIndex = NetIndex; + } + else { + if ((Instance < 2) || (Instance > LogPortMax)) { + *pLen = 0; + return (SK_PNMI_ERR_UNKNOWN_INST); + } + PhysPortIndex = Instance - 2; + } + Limit = PhysPortIndex + 1; + } + else { + /* + * Instance == (SK_U32) (-1), so get all instances of that OID. + * There is no virtual port with an Instance == 1, so we get + * the values from all physical ports. + */ + PhysPortIndex = 0; + Limit = PhysPortMax; + } + + /* Check MAC type. */ + if ((Id != OID_SKGE_VCT_CAPABILITIES) && + (pAC->GIni.GP[PhysPortIndex].PhyType != SK_PHY_MARV_COPPER)) { + *pLen = 0; + return (SK_PNMI_ERR_NOT_SUPPORTED); + } + + /* Check action type. */ + if (Action == SK_PNMI_GET) { + /* Check length. */ + switch (Id) { + + case OID_SKGE_VCT_GET: + if (*pLen < (Limit - PhysPortIndex) * sizeof(SK_PNMI_VCT)) { + *pLen = (Limit - PhysPortIndex) * sizeof(SK_PNMI_VCT); + return (SK_PNMI_ERR_TOO_SHORT); + } + break; + + case OID_SKGE_VCT_STATUS: + case OID_SKGE_VCT_CAPABILITIES: + if (*pLen < (Limit - PhysPortIndex) * sizeof(SK_U8)) { + *pLen = (Limit - PhysPortIndex) * sizeof(SK_U8); + return (SK_PNMI_ERR_TOO_SHORT); + } + break; + + default: + *pLen = 0; + return (SK_PNMI_ERR_GENERAL); + } + + /* Get value. */ + Offset = 0; + for (; PhysPortIndex < Limit; PhysPortIndex++) { + + pPrt = &pAC->GIni.GP[PhysPortIndex]; + + switch (Id) { + + case OID_SKGE_VCT_GET: + if (!pPrt->PHWLinkUp && + (pAC->Pnmi.VctStatus[PhysPortIndex] & SK_PNMI_VCT_PENDING)) { + + RetCode = SkGmCableDiagStatus(pAC, IoC, PhysPortIndex, SK_FALSE); + + if (RetCode == 0) { + + /* VCT test is finished, so save the data. */ + VctGetResults(pAC, IoC, PhysPortIndex); + + Para.Para32[0] = PhysPortIndex; + Para.Para32[1] = -1; + SkEventQueue(pAC, SKGE_DRV, SK_DRV_PORT_RESET, Para); + + /* SkEventDispatcher(pAC, IoC); */ + } + } + + /* Initialize backup data pointer. */ + pVctBackupData = &pAC->Pnmi.VctBackup[PhysPortIndex]; + + /* Get all results. */ + CheckVctStatus(pAC, IoC, pBuf, Offset, PhysPortIndex); + + Offset++; + *(pBuf + Offset) = pPrt->PCableLen; + Offset++; + for (i = 0; i < 4; i++) { + + SK_PNMI_STORE_U32((pBuf + Offset), pVctBackupData->MdiPairLen[i]); + Offset += sizeof(SK_U32); + } + for (i = 0; i < 4; i++) { + + *(pBuf + Offset) = pVctBackupData->MdiPairSts[i]; + Offset++; + } + + RetCode = SK_PNMI_ERR_OK; + break; + + case OID_SKGE_VCT_STATUS: + CheckVctStatus(pAC, IoC, pBuf, Offset, PhysPortIndex); + + Offset++; + RetCode = SK_PNMI_ERR_OK; + break; + + case OID_SKGE_VCT_CAPABILITIES: + if (pPrt->PhyType != SK_PHY_MARV_COPPER) { + *(pBuf + Offset) = SK_PNMI_VCT_NOT_SUPPORTED; + } + else { + *(pBuf + Offset) = SK_PNMI_VCT_SUPPORTED; + } + Offset++; + + RetCode = SK_PNMI_ERR_OK; + break; + + default: + *pLen = 0; + return (SK_PNMI_ERR_GENERAL); + } + } /* for */ + *pLen = Offset; + return (RetCode); + + } /* if SK_PNMI_GET */ + + /* + * From here SET or PRESET action. Check if the passed + * buffer length is plausible. + */ + + /* Check length. */ + switch (Id) { + case OID_SKGE_VCT_SET: + if (*pLen < (Limit - PhysPortIndex) * sizeof(SK_U32)) { + *pLen = (Limit - PhysPortIndex) * sizeof(SK_U32); + return (SK_PNMI_ERR_TOO_SHORT); + } + break; + + default: + *pLen = 0; + return (SK_PNMI_ERR_GENERAL); + } + + /* Perform PRESET or SET. */ + + /* VCT does not support PRESET action. */ + if (Action == SK_PNMI_PRESET) { + + return (SK_PNMI_ERR_OK); + } + + Offset = 0; + for (; PhysPortIndex < Limit; PhysPortIndex++) { + + pPrt = &pAC->GIni.GP[PhysPortIndex]; + + switch (Id) { + case OID_SKGE_VCT_SET: /* Start VCT test. */ + if (!pPrt->PHWLinkUp) { + SkGeStopPort(pAC, IoC, PhysPortIndex, SK_STOP_ALL, SK_SOFT_RST); + + RetCode = SkGmCableDiagStatus(pAC, IoC, PhysPortIndex, SK_TRUE); + + if (RetCode == 0) { /* RetCode: 0 => Start! */ + pAC->Pnmi.VctStatus[PhysPortIndex] |= SK_PNMI_VCT_PENDING; + pAC->Pnmi.VctStatus[PhysPortIndex] &= + ~(SK_PNMI_VCT_NEW_VCT_DATA | SK_PNMI_VCT_LINK); + + /* Start VCT timer counter. */ + SK_MEMSET((char *)&Para, 0, sizeof(Para)); + Para.Para32[0] = PhysPortIndex; + Para.Para32[1] = -1; + + SkTimerStart(pAC, IoC, &pAC->Pnmi.VctTimeout[PhysPortIndex], + SK_PNMI_VCT_TIMER_CHECK, SKGE_PNMI, SK_PNMI_EVT_VCT_RESET, Para); + + SK_PNMI_STORE_U32((pBuf + Offset), RetCode); + RetCode = SK_PNMI_ERR_OK; + } + else { /* RetCode: 2 => Running! */ + SK_PNMI_STORE_U32((pBuf + Offset), RetCode); + RetCode = SK_PNMI_ERR_OK; + } + } + else { /* RetCode: 4 => Link! */ + RetCode = 4; + SK_PNMI_STORE_U32((pBuf + Offset), RetCode); + RetCode = SK_PNMI_ERR_OK; + } + Offset += sizeof(SK_U32); + break; + + default: + *pLen = 0; + return (SK_PNMI_ERR_GENERAL); + } + } /* for */ + *pLen = Offset; + return (RetCode); + +} /* Vct */ + + +PNMI_STATIC void VctGetResults( +SK_AC *pAC, +SK_IOC IoC, +SK_U32 Port) +{ + SK_GEPORT *pPrt; + int i; + SK_U8 PairLen; + SK_U8 PairSts; + SK_U32 MinLength; + SK_U32 CableLength; + + pPrt = &pAC->GIni.GP[Port]; + + if (pAC->GIni.GIChipId == CHIP_ID_YUKON_FE) { + MinLength = 25; + } + else { + MinLength = 35; + } + + /* Copy results for later use to PNMI struct. */ + for (i = 0; i < 4; i++) { + + PairLen = pPrt->PMdiPairLen[i]; + + if (((pPrt->PLinkSpeedCap & SK_LSPEED_CAP_1000MBPS) == 0) && (i > 1)) { + PairSts = SK_PNMI_VCT_NOT_PRESENT; + } + else { + PairSts = pPrt->PMdiPairSts[i]; + } + + if ((PairSts == SK_PNMI_VCT_NORMAL_CABLE) && + (PairLen > 28) && (PairLen < 0xff)) { + + PairSts = SK_PNMI_VCT_IMPEDANCE_MISMATCH; + } + + /* Ignore values <= MinLength, the linear factor is 4/5. */ + if ((PairLen > MinLength) && (PairLen < 0xff)) { + + CableLength = 1000UL * (PairLen - MinLength) * 4 / 5; + } + else { + /* No cable or short cable. */ + CableLength = 0; + } + + pAC->Pnmi.VctBackup[Port].MdiPairLen[i] = CableLength; + pAC->Pnmi.VctBackup[Port].MdiPairSts[i] = PairSts; + } + + pAC->Pnmi.VctStatus[Port] &= ~SK_PNMI_VCT_PENDING; + pAC->Pnmi.VctStatus[Port] |= (SK_PNMI_VCT_NEW_VCT_DATA | + SK_PNMI_VCT_TEST_DONE); + +} /* GetVctResults */ + +PNMI_STATIC void CheckVctStatus( +SK_AC *pAC, +SK_IOC IoC, +char *pBuf, +SK_U32 Offset, +SK_U32 PhysPortIndex) +{ + SK_GEPORT *pPrt; + SK_PNMI_VCT *pVctData; + SK_U8 VctStatus; + SK_U32 RetCode; + + pPrt = &pAC->GIni.GP[PhysPortIndex]; + + pVctData = (SK_PNMI_VCT *) (pBuf + Offset); + pVctData->VctStatus = SK_PNMI_VCT_NONE; + + VctStatus = pAC->Pnmi.VctStatus[PhysPortIndex]; + + if (!pPrt->PHWLinkUp) { + + /* Was a VCT test ever made before? */ + if (VctStatus & SK_PNMI_VCT_TEST_DONE) { + if (VctStatus & SK_PNMI_VCT_LINK) { + pVctData->VctStatus |= SK_PNMI_VCT_OLD_VCT_DATA; + } + else { + pVctData->VctStatus |= SK_PNMI_VCT_NEW_VCT_DATA; + } + } + + /* Check VCT test status. */ + RetCode = SkGmCableDiagStatus(pAC,IoC, PhysPortIndex, SK_FALSE); + + if (RetCode == 2) { /* VCT test is running. */ + pVctData->VctStatus |= SK_PNMI_VCT_RUNNING; + } + else { /* VCT data was copied to pAC here. Check PENDING state. */ + if (VctStatus & SK_PNMI_VCT_PENDING) { + pVctData->VctStatus |= SK_PNMI_VCT_NEW_VCT_DATA; + } + } + + if (pPrt->PCableLen != 0xff) { /* Old DSP value. */ + pVctData->VctStatus |= SK_PNMI_VCT_OLD_DSP_DATA; + } + } + else { + /* Was a VCT test ever made before? */ + if (VctStatus & SK_PNMI_VCT_TEST_DONE) { + pVctData->VctStatus &= ~SK_PNMI_VCT_NEW_VCT_DATA; + pVctData->VctStatus |= SK_PNMI_VCT_OLD_VCT_DATA; + } + + /* DSP only valid in 100/1000 modes. */ + if (pPrt->PLinkSpeedUsed != SK_LSPEED_STAT_10MBPS) { + pVctData->VctStatus |= SK_PNMI_VCT_NEW_DSP_DATA; + } + } + +} /* CheckVctStatus */ + + +/***************************************************************************** + * + * SkPnmiGenIoctl - Handles new generic PNMI IOCTL, calls the needed + * PNMI function depending on the subcommand and + * returns all data belonging to the complete database + * or OID request. + * + * Description: + * Looks up the requested subcommand, calls the corresponding handler + * function and passes all required parameters to it. + * The function is called by the driver. It is needed to handle the new + * generic PNMI IOCTL. This IOCTL is given to the driver and contains both + * the OID and a subcommand to decide what kind of request has to be done. + * + * Returns: + * SK_PNMI_ERR_OK The request was successfully performed + * SK_PNMI_ERR_GENERAL A general severe internal error occured + * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to take + * the data. + * SK_PNMI_ERR_UNKNOWN_OID The requested OID is unknown + * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't + * exist (e.g. port instance 3 on a two port + * adapter. + */ +int SkPnmiGenIoctl( +SK_AC *pAC, /* Pointer to adapter context struct */ +SK_IOC IoC, /* I/O context */ +void *pBuf, /* Buffer used for the management data transfer */ +unsigned int *pLen, /* Length of buffer */ +SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */ +{ +SK_I32 Mode; /* Store value of subcommand. */ +SK_U32 Oid; /* Store value of OID. */ +int ReturnCode; /* Store return value to show status of PNMI action. */ +int HeaderLength; /* Length of desired action plus OID. */ + + ReturnCode = SK_PNMI_ERR_GENERAL; + + SK_MEMCPY(&Mode, pBuf, sizeof(SK_I32)); + SK_MEMCPY(&Oid, (char *)pBuf + sizeof(SK_I32), sizeof(SK_U32)); + HeaderLength = sizeof(SK_I32) + sizeof(SK_U32); + *pLen = *pLen - HeaderLength; + SK_MEMCPY((char *)pBuf + sizeof(SK_I32), (char *)pBuf + HeaderLength, *pLen); + + switch(Mode) { + case SK_GET_SINGLE_VAR: + ReturnCode = SkPnmiGetVar(pAC, IoC, Oid, + (char *)pBuf + sizeof(SK_I32), pLen, + ((SK_U32) (-1)), NetIndex); + SK_PNMI_STORE_U32(pBuf, ReturnCode); + *pLen = *pLen + sizeof(SK_I32); + break; + case SK_PRESET_SINGLE_VAR: + ReturnCode = SkPnmiPreSetVar(pAC, IoC, Oid, + (char *)pBuf + sizeof(SK_I32), pLen, + ((SK_U32) (-1)), NetIndex); + SK_PNMI_STORE_U32(pBuf, ReturnCode); + *pLen = *pLen + sizeof(SK_I32); + break; + case SK_SET_SINGLE_VAR: + ReturnCode = SkPnmiSetVar(pAC, IoC, Oid, + (char *)pBuf + sizeof(SK_I32), pLen, + ((SK_U32) (-1)), NetIndex); + SK_PNMI_STORE_U32(pBuf, ReturnCode); + *pLen = *pLen + sizeof(SK_I32); + break; + case SK_GET_FULL_MIB: + ReturnCode = SkPnmiGetStruct(pAC, IoC, pBuf, pLen, NetIndex); + break; + case SK_PRESET_FULL_MIB: + ReturnCode = SkPnmiPreSetStruct(pAC, IoC, pBuf, pLen, NetIndex); + break; + case SK_SET_FULL_MIB: + ReturnCode = SkPnmiSetStruct(pAC, IoC, pBuf, pLen, NetIndex); + break; + default: + break; + } + + return (ReturnCode); + +} /* SkGeIocGen */ + +#ifdef SK_ASF +/***************************************************************************** + * + * Asf + * + * Description: + * The code is simple. No description necessary. + * + * Returns: + * SK_PNMI_ERR_OK The request was successfully performed. + * SK_PNMI_ERR_GENERAL A general severe internal error occured. + * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain + * the correct data (e.g. a 32bit value is + * needed, but a 16 bit value was passed). + * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't + * exist (e.g. port instance 3 on a two port + * adapter. + */ + +PNMI_STATIC int Asf( +SK_AC *pAC, /* Pointer to adapter context */ +SK_IOC IoC, /* IO context handle */ +int Action, /* GET/PRESET/SET action */ +SK_U32 Id, /* Object ID that is to be processed */ +char *pBuf, /* Buffer used for the management data transfer */ +unsigned int *pLen, /* On call: pBuf buffer length. On return: used buffer */ +SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */ +unsigned int TableIndex, /* Index to the Id table */ +SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */ +{ + SK_U32 RetCode = SK_PNMI_ERR_GENERAL; + + /* + * Check instance. We only handle single instance variables. + */ + if (Instance != (SK_U32)(-1) && Instance != 1) { + + *pLen = 0; + return (SK_PNMI_ERR_UNKNOWN_INST); + } + + /* Perform action. */ + /* GET value. */ + if (Action == SK_PNMI_GET) { + switch (Id) { + case OID_SKGE_ASF: + RetCode = SkAsfGet(pAC, IoC, (SK_U8 *) pBuf, pLen); + break; + default: + RetCode = SkAsfGetOid( pAC, IoC, Id, Instance, (SK_U8 *) pBuf, pLen ); + break; + } + + return (RetCode); + } + + /* PRESET value. */ + if (Action == SK_PNMI_PRESET) { + switch (Id) { + case OID_SKGE_ASF: + RetCode = SkAsfPreSet(pAC, IoC, (SK_U8 *) pBuf, pLen); + break; + default: + RetCode = SkAsfPreSetOid( pAC, IoC, Id, Instance, (SK_U8 *) pBuf, pLen ); + break; + } + } + + /* SET value. */ + if (Action == SK_PNMI_SET) { + switch (Id) { + case OID_SKGE_ASF: + RetCode = SkAsfSet(pAC, IoC, (SK_U8 *) pBuf, pLen); + break; + default: + RetCode = SkAsfSetOid( pAC, IoC, Id, Instance, (SK_U8 *) pBuf, pLen ); + break; + } + } + return (RetCode); +} +#endif /* SK_ASF */ diff -urN linux-2.4.32-600/drivers/net/sk98lin/skgesirq.c linux-2.4.32-600-sk98_831/drivers/net/sk98lin/skgesirq.c --- linux-2.4.32-600/drivers/net/sk98lin/skgesirq.c Sat Mar 20 10:08:19 2004 +++ linux-2.4.32-600-sk98_831/drivers/net/sk98lin/skgesirq.c Sun Feb 26 11:13:02 2006 @@ -2,21 +2,24 @@ * * Name: skgesirq.c * Project: Gigabit Ethernet Adapters, Common Modules + * Version: $Revision: 2.26 $ + * Date: $Date: 2005/12/14 16:11:35 $ * Purpose: Special IRQ module * ******************************************************************************/ /****************************************************************************** * + * LICENSE: * (C)Copyright 1998-2002 SysKonnect. - * (C)Copyright 2002-2003 Marvell. + * (C)Copyright 2002-2005 Marvell. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. - * * The information in this file is provided "AS IS" without warranty. + * /LICENSE * ******************************************************************************/ @@ -36,7 +39,7 @@ * right after this ISR. * * The Interrupt source register of the adapter is NOT read by this module. - * SO if the drivers implementor needs a while loop around the + * SO if the drivers implementor needs a while loop around the * slow data paths interrupt bits, he needs to call the SkGeSirqIsr() for * each loop entered. * @@ -44,11 +47,6 @@ * */ -#if (defined(DEBUG) || ((!defined(LINT)) && (!defined(SK_SLIM)))) -static const char SysKonnectFileId[] = - "@(#) $Id: skgesirq.c,v 1.92 2003/09/16 14:37:07 rschmidt Exp $ (C) Marvell."; -#endif - #include "h/skdrv1st.h" /* Driver Specific Definitions */ #ifndef SK_SLIM #include "h/skgepnmi.h" /* PNMI Definitions */ @@ -56,6 +54,13 @@ #endif #include "h/skdrv2nd.h" /* Adapter Control and Driver specific Def. */ +/* local variables ************************************************************/ + +#if (defined(DEBUG) || ((!defined(LINT)) && (!defined(SK_SLIM)))) +static const char SysKonnectFileId[] = + "@(#) $Id: skgesirq.c,v 2.26 2005/12/14 16:11:35 ibrueder Exp $ (C) Marvell."; +#endif + /* local function prototypes */ #ifdef GENESIS static int SkGePortCheckUpXmac(SK_AC*, SK_IOC, int, SK_BOOL); @@ -84,7 +89,7 @@ XM_RXF_511B, XM_RXF_1023B, XM_RXF_MAX_SZ -} ; +}; #endif /* GENESIS */ #ifdef __C2MAN__ @@ -107,8 +112,8 @@ * Returns: N/A */ static void SkHWInitDefSense( -SK_AC *pAC, /* adapter context */ -SK_IOC IoC, /* IO context */ +SK_AC *pAC, /* Adapter Context */ +SK_IOC IoC, /* I/O context */ int Port) /* Port Index (MAC_1 + n) */ { SK_GEPORT *pPrt; /* GIni Port struct pointer */ @@ -117,7 +122,7 @@ pPrt->PAutoNegTimeOut = 0; - if (pPrt->PLinkModeConf != SK_LMODE_AUTOSENSE) { + if (pPrt->PLinkModeConf != (SK_U8)SK_LMODE_AUTOSENSE) { pPrt->PLinkMode = pPrt->PLinkModeConf; return; } @@ -143,8 +148,8 @@ * */ static SK_U8 SkHWSenseGetNext( -SK_AC *pAC, /* adapter context */ -SK_IOC IoC, /* IO context */ +SK_AC *pAC, /* Adapter Context */ +SK_IOC IoC, /* I/O context */ int Port) /* Port Index (MAC_1 + n) */ { SK_GEPORT *pPrt; /* GIni Port struct pointer */ @@ -153,18 +158,18 @@ pPrt->PAutoNegTimeOut = 0; - if (pPrt->PLinkModeConf != (SK_U8)SK_LMODE_AUTOSENSE) { + if (pPrt->PLinkModeConf != (SK_U8)SK_LMODE_AUTOSENSE) { /* Leave all as configured */ return(pPrt->PLinkModeConf); } - if (pPrt->PLinkMode == (SK_U8)SK_LMODE_AUTOFULL) { + if (pPrt->PLinkMode == (SK_U8)SK_LMODE_AUTOFULL) { /* Return next mode AUTOBOTH */ - return ((SK_U8)SK_LMODE_AUTOBOTH); + return((SK_U8)SK_LMODE_AUTOBOTH); } /* Return default autofull */ - return ((SK_U8)SK_LMODE_AUTOFULL); + return((SK_U8)SK_LMODE_AUTOFULL); } /* SkHWSenseGetNext */ @@ -177,8 +182,8 @@ * Returns: N/A */ static void SkHWSenseSetNext( -SK_AC *pAC, /* adapter context */ -SK_IOC IoC, /* IO context */ +SK_AC *pAC, /* Adapter Context */ +SK_IOC IoC, /* I/O context */ int Port, /* Port Index (MAC_1 + n) */ SK_U8 NewMode) /* New Mode to be written in sense mode */ { @@ -188,7 +193,7 @@ pPrt->PAutoNegTimeOut = 0; - if (pPrt->PLinkModeConf != (SK_U8)SK_LMODE_AUTOSENSE) { + if (pPrt->PLinkModeConf != (SK_U8)SK_LMODE_AUTOSENSE) { return; } @@ -212,8 +217,8 @@ * Returns: N/A */ void SkHWLinkDown( -SK_AC *pAC, /* adapter context */ -SK_IOC IoC, /* IO context */ +SK_AC *pAC, /* Adapter Context */ +SK_IOC IoC, /* I/O context */ int Port) /* Port Index (MAC_1 + n) */ { SK_GEPORT *pPrt; /* GIni Port struct pointer */ @@ -225,11 +230,11 @@ /* Disable Receiver and Transmitter */ SkMacRxTxDisable(pAC, IoC, Port); - + /* Init default sense mode */ SkHWInitDefSense(pAC, IoC, Port); - if (pPrt->PHWLinkUp == SK_FALSE) { + if (!pPrt->PHWLinkUp) { return; } @@ -239,10 +244,12 @@ /* Set Link to DOWN */ pPrt->PHWLinkUp = SK_FALSE; +#ifndef SK_SLIM /* Reset Port stati */ - pPrt->PLinkModeStatus = (SK_U8)SK_LMODE_STAT_UNKNOWN; - pPrt->PFlowCtrlStatus = (SK_U8)SK_FLOW_STAT_NONE; + pPrt->PLinkModeStatus = (SK_U8)SK_LMODE_STAT_UNKNOWN; + pPrt->PFlowCtrlStatus = (SK_U8)SK_FLOW_STAT_NONE; pPrt->PLinkSpeedUsed = (SK_U8)SK_LSPEED_STAT_INDETERMINATED; +#endif /* !SK_SLIM */ /* Re-init Phy especially when the AutoSense default is set now */ SkMacInitPhy(pAC, IoC, Port, SK_FALSE); @@ -264,8 +271,8 @@ * Returns: N/A */ void SkHWLinkUp( -SK_AC *pAC, /* adapter context */ -SK_IOC IoC, /* IO context */ +SK_AC *pAC, /* Adapter Context */ +SK_IOC IoC, /* I/O context */ int Port) /* Port Index (MAC_1 + n) */ { SK_GEPORT *pPrt; /* GIni Port struct pointer */ @@ -278,12 +285,14 @@ } pPrt->PHWLinkUp = SK_TRUE; + +#ifndef SK_SLIM pPrt->PAutoNegFail = SK_FALSE; - pPrt->PLinkModeStatus = (SK_U8)SK_LMODE_STAT_UNKNOWN; + pPrt->PLinkModeStatus = (SK_U8)SK_LMODE_STAT_UNKNOWN; - if (pPrt->PLinkMode != (SK_U8)SK_LMODE_AUTOHALF && - pPrt->PLinkMode != (SK_U8)SK_LMODE_AUTOFULL && - pPrt->PLinkMode != (SK_U8)SK_LMODE_AUTOBOTH) { + if (pPrt->PLinkMode != (SK_U8)SK_LMODE_AUTOHALF && + pPrt->PLinkMode != (SK_U8)SK_LMODE_AUTOFULL && + pPrt->PLinkMode != (SK_U8)SK_LMODE_AUTOBOTH) { /* Link is up and no Auto-negotiation should be done */ /* Link speed should be the configured one */ @@ -291,7 +300,9 @@ case SK_LSPEED_AUTO: /* default is 1000 Mbps */ case SK_LSPEED_1000MBPS: - pPrt->PLinkSpeedUsed = (SK_U8)SK_LSPEED_STAT_1000MBPS; + pPrt->PLinkSpeedUsed = + (SK_U8)((pPrt->PLinkSpeedCap & SK_LSPEED_CAP_1000MBPS) != 0) ? + SK_LSPEED_STAT_1000MBPS : SK_LSPEED_STAT_100MBPS; break; case SK_LSPEED_100MBPS: pPrt->PLinkSpeedUsed = (SK_U8)SK_LSPEED_STAT_100MBPS; @@ -302,19 +313,22 @@ } /* Set Link Mode Status */ - if (pPrt->PLinkMode == SK_LMODE_FULL) { + if (pPrt->PLinkMode == (SK_U8)SK_LMODE_FULL) { pPrt->PLinkModeStatus = (SK_U8)SK_LMODE_STAT_FULL; } else { - pPrt->PLinkModeStatus = (SK_U8)SK_LMODE_STAT_HALF; + pPrt->PLinkModeStatus = (SK_U8)SK_LMODE_STAT_HALF; } /* No flow control without auto-negotiation */ - pPrt->PFlowCtrlStatus = (SK_U8)SK_FLOW_STAT_NONE; + pPrt->PFlowCtrlStatus = (SK_U8)SK_FLOW_STAT_NONE; +#endif /* !SK_SLIM */ /* enable Rx/Tx */ - (void)SkMacRxTxEnable(pAC, IoC, Port); + (void)SkMacRxTxEnable(pAC, IoC, Port); +#ifndef SK_SLIM } +#endif /* !SK_SLIM */ } /* SkHWLinkUp */ @@ -327,14 +341,16 @@ * Returns: N/A */ static void SkMacParity( -SK_AC *pAC, /* adapter context */ -SK_IOC IoC, /* IO context */ -int Port) /* Port Index of the port failed */ +SK_AC *pAC, /* Adapter Context */ +SK_IOC IoC, /* I/O context */ +int Port) /* Port Index (MAC_1 + n) */ { SK_EVPARA Para; SK_GEPORT *pPrt; /* GIni Port struct pointer */ SK_U32 TxMax; /* Tx Max Size Counter */ + TxMax = 0; + pPrt = &pAC->GIni.GP[Port]; /* Clear IRQ Tx Parity Error */ @@ -344,7 +360,7 @@ SK_OUT16(IoC, MR_ADDR(Port, TX_MFF_CTRL1), MFF_CLR_PERR); } #endif /* GENESIS */ - + #ifdef YUKON if (pAC->GIni.GIYukon) { /* HW-Bug #8: cleared by GMF_CLI_TX_FC instead of GMF_CLI_TX_PE */ @@ -353,7 +369,7 @@ pAC->GIni.GIChipRev == 0) ? GMF_CLI_TX_FC : GMF_CLI_TX_PE)); } #endif /* YUKON */ - + if (pPrt->PCheckPar) { if (Port == MAC_1) { @@ -364,7 +380,7 @@ } Para.Para64 = Port; SkEventQueue(pAC, SKGE_DRV, SK_DRV_PORT_FAIL, Para); - + Para.Para32[0] = Port; SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_LINK_DOWN, Para); @@ -376,18 +392,18 @@ if (pAC->GIni.GIGenesis) { /* Snap statistic counters */ (void)SkXmUpdateStats(pAC, IoC, Port); - + (void)SkXmMacStatistic(pAC, IoC, Port, XM_TXF_MAX_SZ, &TxMax); } #endif /* GENESIS */ - + #ifdef YUKON if (pAC->GIni.GIYukon) { (void)SkGmMacStatistic(pAC, IoC, Port, GM_TXF_1518B, &TxMax); } #endif /* YUKON */ - + if (TxMax > 0) { /* From now on check the parity */ pPrt->PCheckPar = SK_TRUE; @@ -397,15 +413,15 @@ /****************************************************************************** * - * SkGeHwErr() - Hardware Error service routine + * SkGeYuHwErr() - Hardware Error service routine (Genesis and Yukon) * * Description: handles all HW Error interrupts * * Returns: N/A */ -static void SkGeHwErr( -SK_AC *pAC, /* adapter context */ -SK_IOC IoC, /* IO context */ +static void SkGeYuHwErr( +SK_AC *pAC, /* Adapter Context */ +SK_IOC IoC, /* I/O context */ SK_U32 HwStatus) /* Interrupt status word */ { SK_EVPARA Para; @@ -421,10 +437,10 @@ } /* Reset all bits in the PCI STATUS register */ - SK_IN16(IoC, PCI_C(PCI_STATUS), &Word); - + SK_IN16(IoC, PCI_C(pAC, PCI_STATUS), &Word); + SK_OUT8(IoC, B2_TST_CTRL1, TST_CFG_WRITE_ON); - SK_OUT16(IoC, PCI_C(PCI_STATUS), (SK_U16)(Word | PCI_ERRBITS)); + SK_OUT16(IoC, PCI_C(pAC, PCI_STATUS), (SK_U16)(Word | PCI_ERRBITS)); SK_OUT8(IoC, B2_TST_CTRL1, TST_CFG_WRITE_OFF); Para.Para64 = 0; @@ -459,7 +475,7 @@ } } #endif /* GENESIS */ - + #ifdef YUKON if (pAC->GIni.GIYukon) { /* This is necessary only for Rx timing measurements */ @@ -482,14 +498,18 @@ #endif /* YUKON */ if ((HwStatus & IS_RAM_RD_PAR) != 0) { + SK_OUT16(IoC, B3_RI_CTRL, RI_CLR_RD_PERR); + SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E014, SKERR_SIRQ_E014MSG); Para.Para64 = 0; SkEventQueue(pAC, SKGE_DRV, SK_DRV_ADAP_FAIL, Para); } if ((HwStatus & IS_RAM_WR_PAR) != 0) { + SK_OUT16(IoC, B3_RI_CTRL, RI_CLR_WR_PERR); + SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E015, SKERR_SIRQ_E015MSG); Para.Para64 = 0; SkEventQueue(pAC, SKGE_DRV, SK_DRV_ADAP_FAIL, Para); @@ -510,7 +530,7 @@ SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E018, SKERR_SIRQ_E018MSG); Para.Para64 = MAC_1; SkEventQueue(pAC, SKGE_DRV, SK_DRV_PORT_FAIL, Para); - + Para.Para32[0] = MAC_1; SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_LINK_DOWN, Para); } @@ -522,37 +542,288 @@ SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E019, SKERR_SIRQ_E019MSG); Para.Para64 = MAC_2; SkEventQueue(pAC, SKGE_DRV, SK_DRV_PORT_FAIL, Para); - + Para.Para32[0] = MAC_2; SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_LINK_DOWN, Para); } -} /* SkGeHwErr */ +} /* SkGeYuHwErr */ + +#ifdef YUK2 +/****************************************************************************** + * + * SkYuk2HwPortErr() - Service HW Errors for specified port (Yukon-2 only) + * + * Description: handles the HW Error interrupts for a specific port. + * + * Returns: N/A + */ +static void SkYuk2HwPortErr( +SK_AC *pAC, /* Adapter Context */ +SK_IOC IoC, /* I/O Context */ +SK_U32 HwStatus, /* Interrupt status word */ +int Port) /* Port Index (MAC_1 + n) */ +{ + SK_EVPARA Para; + int Queue; + + if (Port == MAC_2) { + HwStatus >>= 8; + } + + if ((HwStatus & Y2_HWE_L1_MASK) == 0) { + return; + } + if ((HwStatus & Y2_IS_PAR_RD1) != 0) { + /* Clear IRQ */ + SK_OUT16(IoC, SELECT_RAM_BUFFER(Port, B3_RI_CTRL), RI_CLR_RD_PERR); + + if (Port == MAC_1) { + SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E028, SKERR_SIRQ_E028MSG); + } + else { + SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E030, SKERR_SIRQ_E030MSG); + } + } + + if ((HwStatus & Y2_IS_PAR_WR1) != 0) { + /* Clear IRQ */ + SK_OUT16(IoC, SELECT_RAM_BUFFER(Port, B3_RI_CTRL), RI_CLR_WR_PERR); + + if (Port == MAC_1) { + SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E029, SKERR_SIRQ_E029MSG); + } + else { + SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E031, SKERR_SIRQ_E031MSG); + } + } + + if ((HwStatus & Y2_IS_PAR_MAC1) != 0) { + /* Clear IRQ */ + SK_OUT8(IoC, MR_ADDR(Port, TX_GMF_CTRL_T), GMF_CLI_TX_PE); + + if (Port == MAC_1) { + SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E016, SKERR_SIRQ_E016MSG); + } + else { + SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E017, SKERR_SIRQ_E017MSG); + } + } + + if ((HwStatus & Y2_IS_PAR_RX1) != 0) { + if (Port == MAC_1) { + Queue = Q_R1; + SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E018, SKERR_SIRQ_E018MSG); + } + else { + Queue = Q_R2; + SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E019, SKERR_SIRQ_E019MSG); + } + /* Clear IRQ */ + SK_OUT32(IoC, Q_ADDR(Queue, Q_CSR), BMU_CLR_IRQ_PAR); + } + + if ((HwStatus & Y2_IS_TCP_TXS1) != 0) { + if (Port == MAC_1) { + Queue = Q_XS1; + SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E033, SKERR_SIRQ_E033MSG); + } + else { + Queue = Q_XS2; + SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E035, SKERR_SIRQ_E035MSG); + } + /* Clear IRQ */ + SK_OUT32(IoC, Q_ADDR(Queue, Q_CSR), BMU_CLR_IRQ_TCP); + } + + if ((HwStatus & Y2_IS_TCP_TXA1) != 0) { + if (Port == MAC_1) { + Queue = Q_XA1; + SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E032, SKERR_SIRQ_E032MSG); + } + else { + Queue = Q_XA2; + SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E034, SKERR_SIRQ_E034MSG); + } + /* Clear IRQ */ + SK_OUT32(IoC, Q_ADDR(Queue, Q_CSR), BMU_CLR_IRQ_TCP); + } + + Para.Para64 = Port; + SkEventQueue(pAC, SKGE_DRV, SK_DRV_PORT_FAIL, Para); + + Para.Para32[0] = Port; + SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_LINK_DOWN, Para); + +} /* SkYuk2HwPortErr */ /****************************************************************************** * - * SkGeSirqIsr() - Special Interrupt Service Routine + * SkYuk2HwErr() - Hardware Error service routine (Yukon-2 only) * - * Description: handles all non data transfer specific interrupts (slow path) + * Description: handles all HW Error interrupts + * + * Returns: N/A + */ +static void SkYuk2HwErr( +SK_AC *pAC, /* Adapter Context */ +SK_IOC IoC, /* I/O Context */ +SK_U32 HwStatus) /* Interrupt status word */ +{ + SK_EVPARA Para; + SK_U16 Word; + SK_U32 DWord; + SK_U32 TlpHead[4]; + int i; + + SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ, + ("HW-Error Status: 0x%08lX\n", HwStatus)); + + /* This is necessary only for Rx timing measurements */ + if ((HwStatus & Y2_IS_TIST_OV) != 0) { + /* increment Time Stamp Timer counter (high) */ + pAC->GIni.GITimeStampCnt++; + + /* Clear Time Stamp Timer IRQ */ + SK_OUT8(IoC, GMAC_TI_ST_CTRL, (SK_U8)GMT_ST_CLR_IRQ); + } + + /* Evaluate Y2_IS_PCI_NEXP before Y2_IS_MST_ERR or Y2_IS_IRQ_STAT */ + if ((HwStatus & Y2_IS_PCI_NEXP) != 0) { + /* + * This error is also mapped either to Master Abort (Y2_IS_MST_ERR) + * or Target Abort (Y2_IS_IRQ_STAT) bit and can only be cleared there. + * Therefore handle this event just by printing an error log entry. + */ + SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E027, SKERR_SIRQ_E027MSG); + } + + if ((HwStatus & (Y2_IS_MST_ERR | Y2_IS_IRQ_STAT)) != 0) { + /* PCI Errors occured */ + if ((HwStatus & Y2_IS_IRQ_STAT) != 0) { + SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E013, SKERR_SIRQ_E013MSG); + } + else { + SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E012, SKERR_SIRQ_E012MSG); + } + + /* Reset all bits in the PCI STATUS register */ + SK_IN16(IoC, PCI_C(pAC, PCI_STATUS), &Word); + + SK_OUT8(IoC, B2_TST_CTRL1, TST_CFG_WRITE_ON); + SK_OUT16(IoC, PCI_C(pAC, PCI_STATUS), (SK_U16)(Word | PCI_ERRBITS)); + SK_OUT8(IoC, B2_TST_CTRL1, TST_CFG_WRITE_OFF); + + Para.Para64 = 0; + SkEventQueue(pAC, SKGE_DRV, SK_DRV_ADAP_FAIL, Para); + } + + /* check for PCI-Express Uncorrectable Error */ + if ((HwStatus & Y2_IS_PCI_EXP) != 0) { + /* + * On PCI-Express bus bridges are called root complexes (RC). + * PCI-Express errors are recognized by the root complex too, + * which requests the system to handle the problem. After error + * occurence it may be that no access to the adapter may be performed + * any longer. + */ + + /* Get uncorrectable error status */ + SK_IN32(IoC, PCI_C(pAC, PEX_UNC_ERR_STAT), &DWord); + + SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ, + ("PEX Uncorr.Error Status: 0x%08lX\n", DWord)); + + if (DWord != PEX_UNSUP_REQ) { + /* ignore Unsupported Request Errors */ + SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E026, SKERR_SIRQ_E026MSG); + } + + if ((DWord & (PEX_FATAL_ERRORS | PEX_POIS_TLP)) != 0) { + /* + * Stop only, if the uncorrectable error is fatal or + * Poisoned TLP occured + */ + SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ, ("Header Log:")); + + for (i = 0; i < 4; i++) { + /* get TLP Header from Log Registers */ + SK_IN32(IoC, PCI_C(pAC, PEX_HEADER_LOG + i*4), &TlpHead[i]); + + SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ, + (" 0x%08lX", TlpHead[i])); + } + SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ, ("\n")); + + /* check for vendor defined broadcast message */ + if (TlpHead[0] == 0x73004001 && (SK_U8)TlpHead[1] == 0x7f) { + + SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ, + ("Vendor defined broadcast message\n")); + } + else { + Para.Para64 = 0; + SkEventQueue(pAC, SKGE_DRV, SK_DRV_ADAP_FAIL, Para); + + pAC->GIni.GIValHwIrqMask &= ~Y2_IS_PCI_EXP; + /* Rewrite HW IRQ mask */ + SK_OUT32(IoC, B0_HWE_IMSK, pAC->GIni.GIValHwIrqMask); + } + } + /* clear the interrupt */ + SK_OUT32(IoC, B2_TST_CTRL1, TST_CFG_WRITE_ON); + SK_OUT32(IoC, PCI_C(pAC, PEX_UNC_ERR_STAT), 0xffffffffUL); + SK_OUT32(IoC, B2_TST_CTRL1, TST_CFG_WRITE_OFF); + } + + for (i = 0; i < pAC->GIni.GIMacsFound; i++) { + + SkYuk2HwPortErr(pAC, IoC, HwStatus, i); + } + +} /* SkYuk2HwErr */ +#endif /* YUK2 */ + +/****************************************************************************** + * + * SkGeSirqIsr() - Wrapper for Special Interrupt Service Routine + * + * Description: calls the preselected special ISR (slow path) * * Returns: N/A */ void SkGeSirqIsr( -SK_AC *pAC, /* adapter context */ -SK_IOC IoC, /* IO context */ +SK_AC *pAC, /* Adapter Context */ +SK_IOC IoC, /* I/O context */ +SK_U32 Istatus) /* Interrupt status word */ +{ + pAC->GIni.GIFunc.pSkGeSirqIsr(pAC, IoC, Istatus); +} + +/****************************************************************************** + * + * SkGeYuSirqIsr() - Special Interrupt Service Routine + * + * Description: handles all non data transfer specific interrupts (slow path) + * + * Returns: N/A + */ +void SkGeYuSirqIsr( +SK_AC *pAC, /* Adapter Context */ +SK_IOC IoC, /* I/O Context */ SK_U32 Istatus) /* Interrupt status word */ { SK_EVPARA Para; SK_U32 RegVal32; /* Read register value */ SK_GEPORT *pPrt; /* GIni Port struct pointer */ - SK_U16 PhyInt; + SK_U16 PhyInt; int i; if (((Istatus & IS_HW_ERR) & pAC->GIni.GIValIrqMask) != 0) { /* read the HW Error Interrupt source */ SK_IN32(IoC, B0_HWE_ISRC, &RegVal32); - - SkGeHwErr(pAC, IoC, RegVal32); + + SkGeYuHwErr(pAC, IoC, RegVal32); } /* @@ -567,7 +838,7 @@ } if (((Istatus & (IS_PA_TO_RX2 | IS_PA_TO_TX2)) != 0) && - pAC->GIni.GP[MAC_2].PState == SK_PRT_RESET) { + pAC->GIni.GP[MAC_2].PState == SK_PRT_RESET) { /* MAC 2 was not initialized but Packet timeout occured */ SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_SIRQ_E005, SKERR_SIRQ_E005MSG); @@ -588,8 +859,8 @@ } if ((Istatus & IS_PA_TO_TX1) != 0) { - - pPrt = &pAC->GIni.GP[0]; + + pPrt = &pAC->GIni.GP[MAC_1]; /* May be a normal situation in a server with a slow network */ SK_OUT16(IoC, B3_PA_CTRL, PA_CLR_TO_TX1); @@ -610,25 +881,18 @@ * we ignore those */ pPrt->HalfDupTimerActive = SK_TRUE; -#ifdef XXX - Len = sizeof(SK_U64); - SkPnmiGetVar(pAC, IoC, OID_SKGE_STAT_TX_OCTETS, (char *)&Octets, - &Len, (SK_U32)SK_PNMI_PORT_PHYS2INST(pAC, 0), - pAC->Rlmt.Port[0].Net->NetNumber); - - pPrt->LastOctets = Octets; -#endif /* XXX */ + /* Snap statistic counters */ (void)SkXmUpdateStats(pAC, IoC, 0); (void)SkXmMacStatistic(pAC, IoC, 0, XM_TXO_OK_HI, &RegVal32); pPrt->LastOctets = (SK_U64)RegVal32 << 32; - + (void)SkXmMacStatistic(pAC, IoC, 0, XM_TXO_OK_LO, &RegVal32); pPrt->LastOctets += RegVal32; - + Para.Para32[0] = 0; SkTimerStart(pAC, IoC, &pPrt->HalfDupChkTimer, SK_HALFDUP_CHK_TIME, SKGE_HWAC, SK_HWEV_HALFDUP_CHK, Para); @@ -638,8 +902,8 @@ } if ((Istatus & IS_PA_TO_TX2) != 0) { - - pPrt = &pAC->GIni.GP[1]; + + pPrt = &pAC->GIni.GP[MAC_2]; /* May be a normal situation in a server with a slow network */ SK_OUT16(IoC, B3_PA_CTRL, PA_CLR_TO_TX2); @@ -651,25 +915,18 @@ pPrt->PLinkModeStatus == SK_LMODE_STAT_AUTOHALF) && !pPrt->HalfDupTimerActive) { pPrt->HalfDupTimerActive = SK_TRUE; -#ifdef XXX - Len = sizeof(SK_U64); - SkPnmiGetVar(pAC, IoC, OID_SKGE_STAT_TX_OCTETS, (char *)&Octets, - &Len, (SK_U32)SK_PNMI_PORT_PHYS2INST(pAC, 1), - pAC->Rlmt.Port[1].Net->NetNumber); - - pPrt->LastOctets = Octets; -#endif /* XXX */ + /* Snap statistic counters */ (void)SkXmUpdateStats(pAC, IoC, 1); (void)SkXmMacStatistic(pAC, IoC, 1, XM_TXO_OK_HI, &RegVal32); pPrt->LastOctets = (SK_U64)RegVal32 << 32; - + (void)SkXmMacStatistic(pAC, IoC, 1, XM_TXO_OK_LO, &RegVal32); pPrt->LastOctets += RegVal32; - + Para.Para32[0] = 1; SkTimerStart(pAC, IoC, &pPrt->HalfDupChkTimer, SK_HALFDUP_CHK_TIME, SKGE_HWAC, SK_HWEV_HALFDUP_CHK, Para); @@ -682,6 +939,7 @@ if ((Istatus & IS_R1_C) != 0) { /* Clear IRQ */ SK_OUT32(IoC, B0_R1_CSR, CSR_IRQ_CL_C); + SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_SIRQ_E006, SKERR_SIRQ_E006MSG); Para.Para64 = MAC_1; @@ -693,6 +951,7 @@ if ((Istatus & IS_R2_C) != 0) { /* Clear IRQ */ SK_OUT32(IoC, B0_R2_CSR, CSR_IRQ_CL_C); + SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_SIRQ_E007, SKERR_SIRQ_E007MSG); Para.Para64 = MAC_2; @@ -704,6 +963,7 @@ if ((Istatus & IS_XS1_C) != 0) { /* Clear IRQ */ SK_OUT32(IoC, B0_XS1_CSR, CSR_IRQ_CL_C); + SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_SIRQ_E008, SKERR_SIRQ_E008MSG); Para.Para64 = MAC_1; @@ -715,6 +975,7 @@ if ((Istatus & IS_XA1_C) != 0) { /* Clear IRQ */ SK_OUT32(IoC, B0_XA1_CSR, CSR_IRQ_CL_C); + SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_SIRQ_E009, SKERR_SIRQ_E009MSG); Para.Para64 = MAC_1; @@ -726,6 +987,7 @@ if ((Istatus & IS_XS2_C) != 0) { /* Clear IRQ */ SK_OUT32(IoC, B0_XS2_CSR, CSR_IRQ_CL_C); + SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_SIRQ_E010, SKERR_SIRQ_E010MSG); Para.Para64 = MAC_2; @@ -737,6 +999,7 @@ if ((Istatus & IS_XA2_C) != 0) { /* Clear IRQ */ SK_OUT32(IoC, B0_XA2_CSR, CSR_IRQ_CL_C); + SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_SIRQ_E011, SKERR_SIRQ_E011MSG); Para.Para64 = MAC_2; @@ -749,39 +1012,37 @@ if ((Istatus & IS_EXT_REG) != 0) { /* Test IRQs from PHY */ for (i = 0; i < pAC->GIni.GIMacsFound; i++) { - + pPrt = &pAC->GIni.GP[i]; - + if (pPrt->PState == SK_PRT_RESET) { continue; } - + #ifdef GENESIS if (pAC->GIni.GIGenesis) { - + switch (pPrt->PhyType) { - + case SK_PHY_XMAC: break; - + case SK_PHY_BCOM: SkXmPhyRead(pAC, IoC, i, PHY_BCOM_INT_STAT, &PhyInt); - + if ((PhyInt & ~PHY_B_DEF_MSK) != 0) { SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ, - ("Port %d Bcom Int: 0x%04X\n", - i, PhyInt)); + ("Port %d PHY Int: 0x%04X\n", i, PhyInt)); SkPhyIsrBcom(pAC, IoC, i, PhyInt); } break; #ifdef OTHER_PHY case SK_PHY_LONE: SkXmPhyRead(pAC, IoC, i, PHY_LONE_INT_STAT, &PhyInt); - + if ((PhyInt & PHY_L_DEF_MSK) != 0) { SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ, - ("Port %d Lone Int: %x\n", - i, PhyInt)); + ("Port %d PHY Int: 0x%04X\n", i, PhyInt)); SkPhyIsrLone(pAC, IoC, i, PhyInt); } break; @@ -789,7 +1050,7 @@ } } #endif /* GENESIS */ - + #ifdef YUKON if (pAC->GIni.GIYukon) { /* Read PHY Interrupt Status */ @@ -797,8 +1058,7 @@ if ((PhyInt & PHY_M_DEF_MSK) != 0) { SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ, - ("Port %d Marv Int: 0x%04X\n", - i, PhyInt)); + ("Port %d PHY Int: 0x%04X\n", i, PhyInt)); SkPhyIsrGmac(pAC, IoC, i, PhyInt); } } @@ -806,13 +1066,13 @@ } } - /* I2C Ready interrupt */ + /* TWSI Ready interrupt */ if ((Istatus & IS_I2C_READY) != 0) { #ifdef SK_SLIM - SK_OUT32(IoC, B2_I2C_IRQ, I2C_CLR_IRQ); -#else + SK_OUT32(IoC, B2_I2C_IRQ, I2C_CLR_IRQ); +#else SkI2cIsr(pAC, IoC); -#endif +#endif } /* SW forced interrupt */ @@ -827,7 +1087,7 @@ * us only a link going down. */ /* clear interrupt */ - SK_OUT8(IoC, MR_ADDR(MAC_1, LNK_SYNC_CTRL), LED_CLR_IRQ); + SK_OUT8(IoC, MR_ADDR(MAC_1, LNK_SYNC_CTRL), LNK_CLR_IRQ); } /* Check MAC after link sync counter */ @@ -842,7 +1102,7 @@ * us only a link going down. */ /* clear interrupt */ - SK_OUT8(IoC, MR_ADDR(MAC_2, LNK_SYNC_CTRL), LED_CLR_IRQ); + SK_OUT8(IoC, MR_ADDR(MAC_2, LNK_SYNC_CTRL), LNK_CLR_IRQ); } /* Check MAC after link sync counter */ @@ -858,13 +1118,189 @@ /* read the HW Error Interrupt source */ SK_IN32(IoC, B0_HWE_ISRC, &RegVal32); - SkGeHwErr(pAC, IoC, RegVal32); + SkGeYuHwErr(pAC, IoC, RegVal32); + } + + SkHwtIsr(pAC, IoC); + } + +} /* SkGeYuSirqIsr */ + +#ifdef YUK2 +/****************************************************************************** + * + * SkYuk2PortSirq() - Service HW Errors for specified port (Yukon-2 only) + * + * Description: handles the HW Error interrupts for a specific port. + * + * Returns: N/A + */ +static void SkYuk2PortSirq( +SK_AC *pAC, /* Adapter Context */ +SK_IOC IoC, /* I/O Context */ +SK_U32 IStatus, /* Interrupt status word */ +int Port) /* Port Index (MAC_1 + n) */ +{ + SK_EVPARA Para; + int Queue; + SK_U16 PhyInt; + + if (Port == MAC_2) { + IStatus >>= 8; + } + + /* Interrupt from PHY */ + if ((IStatus & Y2_IS_IRQ_PHY1) != 0) { + /* Read PHY Interrupt Status */ + SkGmPhyRead(pAC, IoC, Port, PHY_MARV_INT_STAT, &PhyInt); + + if ((PhyInt & PHY_M_DEF_MSK) != 0) { + SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ, + ("Port %d PHY Int: 0x%04X\n", Port, PhyInt)); + SkPhyIsrGmac(pAC, IoC, Port, PhyInt); + } + } + + /* Interrupt from MAC */ + if ((IStatus & Y2_IS_IRQ_MAC1) != 0) { + SkMacIrq(pAC, IoC, Port); + } + + if ((IStatus & (Y2_IS_CHK_RX1 | Y2_IS_CHK_TXS1 | Y2_IS_CHK_TXA1)) != 0) { + if ((IStatus & Y2_IS_CHK_RX1) != 0) { + if (Port == MAC_1) { + Queue = Q_R1; + SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E006, + SKERR_SIRQ_E006MSG); + } + else { + Queue = Q_R2; + SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E007, + SKERR_SIRQ_E007MSG); + } + /* Clear IRQ */ + SK_OUT32(IoC, Q_ADDR(Queue, Q_CSR), BMU_CLR_IRQ_CHK); + } + + if ((IStatus & Y2_IS_CHK_TXS1) != 0) { + if (Port == MAC_1) { + Queue = Q_XS1; + SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E008, + SKERR_SIRQ_E008MSG); + } + else { + Queue = Q_XS2; + SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E010, + SKERR_SIRQ_E010MSG); + } + /* Clear IRQ */ + SK_OUT32(IoC, Q_ADDR(Queue, Q_CSR), BMU_CLR_IRQ_CHK); + } + + if ((IStatus & Y2_IS_CHK_TXA1) != 0) { + if (Port == MAC_1) { + Queue = Q_XA1; + SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E009, + SKERR_SIRQ_E009MSG); + } + else { + Queue = Q_XA2; + SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E011, + SKERR_SIRQ_E011MSG); + } + /* Clear IRQ */ + SK_OUT32(IoC, Q_ADDR(Queue, Q_CSR), BMU_CLR_IRQ_CHK); } + Para.Para64 = Port; + SkEventQueue(pAC, SKGE_DRV, SK_DRV_PORT_FAIL, Para); + + Para.Para32[0] = Port; + SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_LINK_DOWN, Para); + } +} /* SkYuk2PortSirq */ +#endif /* YUK2 */ + +/****************************************************************************** + * + * SkYuk2SirqIsr() - Special Interrupt Service Routine (Yukon-2 only) + * + * Description: handles all non data transfer specific interrupts (slow path) + * + * Returns: N/A + */ +void SkYuk2SirqIsr( +SK_AC *pAC, /* Adapter Context */ +SK_IOC IoC, /* I/O Context */ +SK_U32 Istatus) /* Interrupt status word */ +{ +#ifdef YUK2 + SK_EVPARA Para; + SK_U32 RegVal32; /* Read register value */ + SK_U8 Value; + + /* HW Error indicated ? */ + if (((Istatus & Y2_IS_HW_ERR) & pAC->GIni.GIValIrqMask) != 0) { + /* read the HW Error Interrupt source */ + SK_IN32(IoC, B0_HWE_ISRC, &RegVal32); + + SkYuk2HwErr(pAC, IoC, RegVal32); + } + + /* Interrupt from ASF Subsystem */ + if ((Istatus & Y2_IS_ASF) != 0) { + /* clear IRQ */ + /* later on clearing should be done in ASF ISR handler */ + SK_IN8(IoC, B28_Y2_ASF_STAT_CMD, &Value); + Value |= Y2_ASF_CLR_HSTI; + SK_OUT8(IoC, B28_Y2_ASF_STAT_CMD, Value); + /* Call IRQ handler in ASF Module */ + /* TBD */ + } + + /* Check IRQ from polling unit */ + if ((Istatus & Y2_IS_POLL_CHK) != 0) { + /* Clear IRQ */ + SK_OUT32(IoC, POLL_CTRL, PC_CLR_IRQ_CHK); + + SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_SIRQ_E036, + SKERR_SIRQ_E036MSG); + Para.Para64 = 0; + SkEventQueue(pAC, SKGE_DRV, SK_DRV_ADAP_FAIL, Para); + } + + /* TWSI Ready interrupt */ + if ((Istatus & Y2_IS_TWSI_RDY) != 0) { +#ifdef SK_SLIM + SK_OUT32(IoC, B2_I2C_IRQ, I2C_CLR_IRQ); +#else + SkI2cIsr(pAC, IoC); +#endif + } + + /* SW forced interrupt */ + if ((Istatus & Y2_IS_IRQ_SW) != 0) { + /* clear the software IRQ */ + SK_OUT8(IoC, B0_CTST, CS_CL_SW_IRQ); + } + + if ((Istatus & Y2_IS_L1_MASK) != 0) { + SkYuk2PortSirq(pAC, IoC, Istatus, MAC_1); + } + + if ((Istatus & Y2_IS_L2_MASK) != 0) { + SkYuk2PortSirq(pAC, IoC, Istatus, MAC_2); + } + + /* Timer interrupt (served last) */ + if ((Istatus & Y2_IS_TIMINT) != 0) { + SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ, + ("Timer Int: 0x%08lX\n", Istatus)); SkHwtIsr(pAC, IoC); } +#endif /* YUK2 */ -} /* SkGeSirqIsr */ +} /* SkYuk2SirqIsr */ #ifdef GENESIS @@ -878,8 +1314,8 @@ */ static int SkGePortCheckShorts( SK_AC *pAC, /* Adapter Context */ -SK_IOC IoC, /* IO Context */ -int Port) /* Which port should be checked */ +SK_IOC IoC, /* I/O Context */ +int Port) /* Port Index (MAC_1 + n) */ { SK_U32 Shorts; /* Short Event Counter */ SK_U32 CheckShorts; /* Check value for Short Event Counter */ @@ -907,9 +1343,9 @@ RxCts = 0; for (i = 0; i < sizeof(SkGeRxRegs)/sizeof(SkGeRxRegs[0]); i++) { - + (void)SkXmMacStatistic(pAC, IoC, Port, SkGeRxRegs[i], &RxTmp); - + RxCts += (SK_U64)RxTmp; } @@ -926,11 +1362,11 @@ CheckShorts = 2; (void)SkXmMacStatistic(pAC, IoC, Port, XM_RXF_FCS_ERR, &FcsErrCts); - - if (pPrt->PLinkModeConf == SK_LMODE_AUTOSENSE && - pPrt->PLipaAutoNeg == SK_LIPA_UNKNOWN && - (pPrt->PLinkMode == SK_LMODE_HALF || - pPrt->PLinkMode == SK_LMODE_FULL)) { + + if (pPrt->PLinkModeConf == (SK_U8)SK_LMODE_AUTOSENSE && + pPrt->PLipaAutoNeg == (SK_U8)SK_LIPA_UNKNOWN && + (pPrt->PLinkMode == (SK_U8)SK_LMODE_HALF || + pPrt->PLinkMode == (SK_U8)SK_LMODE_FULL)) { /* * This is autosensing and we are in the fallback * manual full/half duplex mode. @@ -939,16 +1375,16 @@ /* Nothing received, restart link */ pPrt->PPrevFcs = FcsErrCts; pPrt->PPrevShorts = Shorts; - + return(SK_HW_PS_RESTART); } else { - pPrt->PLipaAutoNeg = SK_LIPA_MANUAL; + pPrt->PLipaAutoNeg = (SK_U8)SK_LIPA_MANUAL; } } if (((RxCts - pPrt->PPrevRx) > pPrt->PRxLim) || - (!(FcsErrCts - pPrt->PPrevFcs))) { + (!(FcsErrCts - pPrt->PPrevFcs))) { /* * Note: The compare with zero above has to be done the way shown, * otherwise the Linux driver will have a problem. @@ -993,29 +1429,25 @@ */ static int SkGePortCheckUp( SK_AC *pAC, /* Adapter Context */ -SK_IOC IoC, /* IO Context */ -int Port) /* Which port should be checked */ +SK_IOC IoC, /* I/O Context */ +int Port) /* Port Index (MAC_1 + n) */ { SK_GEPORT *pPrt; /* GIni Port struct pointer */ SK_BOOL AutoNeg; /* Is Auto-negotiation used ? */ int Rtv; /* Return value */ Rtv = SK_HW_PS_NONE; - + pPrt = &pAC->GIni.GP[Port]; - if (pPrt->PLinkMode == SK_LMODE_HALF || pPrt->PLinkMode == SK_LMODE_FULL) { - AutoNeg = SK_FALSE; - } - else { - AutoNeg = SK_TRUE; - } + AutoNeg = pPrt->PLinkMode != SK_LMODE_HALF && + pPrt->PLinkMode != SK_LMODE_FULL; #ifdef GENESIS if (pAC->GIni.GIGenesis) { switch (pPrt->PhyType) { - + case SK_PHY_XMAC: Rtv = SkGePortCheckUpXmac(pAC, IoC, Port, AutoNeg); break; @@ -1033,15 +1465,15 @@ } } #endif /* GENESIS */ - + #ifdef YUKON if (pAC->GIni.GIYukon) { - + Rtv = SkGePortCheckUpGmac(pAC, IoC, Port, AutoNeg); } #endif /* YUKON */ - return(Rtv); + return(Rtv); } /* SkGePortCheckUp */ @@ -1057,8 +1489,8 @@ */ static int SkGePortCheckUpXmac( SK_AC *pAC, /* Adapter Context */ -SK_IOC IoC, /* IO Context */ -int Port, /* Which port should be checked */ +SK_IOC IoC, /* I/O Context */ +int Port, /* Port Index (MAC_1 + n) */ SK_BOOL AutoNeg) /* Is Auto-negotiation used ? */ { SK_U32 Shorts; /* Short Event Counter */ @@ -1096,7 +1528,7 @@ XM_IN16(IoC, Port, XM_ISRC, &Isrc); IsrcSum |= Isrc; SkXmAutoNegLipaXmac(pAC, IoC, Port, IsrcSum); - + if ((Isrc & XM_IS_INP_ASS) == 0) { /* It has been in sync since last time */ /* Restart the PORT */ @@ -1115,14 +1547,14 @@ * Link Restart Workaround: * it may be possible that the other Link side * restarts its link as well an we detect - * another LinkBroken. To prevent this + * another PLinkBroken. To prevent this * happening we check for a maximum number * of consecutive restart. If those happens, * we do NOT restart the active link and * check whether the link is now o.k. */ pPrt->PLinkResCt++; - + pPrt->PAutoNegTimeOut = 0; if (pPrt->PLinkResCt < SK_MAX_LRESTART) { @@ -1130,13 +1562,13 @@ } pPrt->PLinkResCt = 0; - + SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, ("Do NOT restart on Port %d %x %x\n", Port, Isrc, IsrcSum)); } else { pPrt->PIsave = (SK_U16)(IsrcSum & XM_IS_AND); - + SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, ("Save Sync/nosync Port %d %x %x\n", Port, Isrc, IsrcSum)); @@ -1163,7 +1595,7 @@ if ((Isrc & XM_IS_INP_ASS) != 0) { pPrt->PLinkBroken = SK_TRUE; /* Re-Init Link partner Autoneg flag */ - pPrt->PLipaAutoNeg = SK_LIPA_UNKNOWN; + pPrt->PLipaAutoNeg = (SK_U8)SK_LIPA_UNKNOWN; SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ, ("Link broken Port %d\n", Port)); @@ -1176,7 +1608,7 @@ } else { SkXmAutoNegLipaXmac(pAC, IoC, Port, Isrc); - + if (SkGePortCheckShorts(pAC, IoC, Port) == SK_HW_PS_RESTART) { return(SK_HW_PS_RESTART); } @@ -1192,7 +1624,7 @@ IsrcSum |= Isrc; SkXmAutoNegLipaXmac(pAC, IoC, Port, IsrcSum); - + if ((GpReg & XM_GP_INP_ASS) != 0 || (IsrcSum & XM_IS_INP_ASS) != 0) { if ((GpReg & XM_GP_INP_ASS) == 0) { /* Save Auto-negotiation Done interrupt only if link is in sync */ @@ -1208,17 +1640,21 @@ } if (AutoNeg) { + /* Auto-Negotiation Done ? */ if ((IsrcSum & XM_IS_AND) != 0) { + SkHWLinkUp(pAC, IoC, Port); + Done = SkMacAutoNegDone(pAC, IoC, Port); + if (Done != SK_AND_OK) { /* Get PHY parameters, for debugging only */ SkXmPhyRead(pAC, IoC, Port, PHY_XMAC_AUNE_LP, &LpAb); SkXmPhyRead(pAC, IoC, Port, PHY_XMAC_RES_ABI, &ResAb); - SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, + SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_ERR, ("AutoNeg FAIL Port %d (LpAb %x, ResAb %x)\n", - Port, LpAb, ResAb)); - + Port, LpAb, ResAb)); + /* Try next possible mode */ NextMode = SkHWSenseGetNext(pAC, IoC, Port); SkHWLinkDown(pAC, IoC, Port); @@ -1234,42 +1670,41 @@ * (clear Page Received bit if set) */ SkXmPhyRead(pAC, IoC, Port, PHY_XMAC_AUNE_EXP, &ExtStat); - + return(SK_HW_PS_LINK); } - + /* AutoNeg not done, but HW link is up. Check for timeouts */ - pPrt->PAutoNegTimeOut++; - if (pPrt->PAutoNegTimeOut >= SK_AND_MAX_TO) { + if (pPrt->PAutoNegTimeOut++ >= SK_AND_MAX_TO) { /* Increase the Timeout counter */ pPrt->PAutoNegTOCt++; /* Timeout occured */ SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ, ("AutoNeg timeout Port %d\n", Port)); - if (pPrt->PLinkModeConf == SK_LMODE_AUTOSENSE && - pPrt->PLipaAutoNeg != SK_LIPA_AUTO) { + if (pPrt->PLinkModeConf == (SK_U8)SK_LMODE_AUTOSENSE && + pPrt->PLipaAutoNeg != (SK_U8)SK_LIPA_AUTO) { /* Set Link manually up */ SkHWSenseSetNext(pAC, IoC, Port, SK_LMODE_FULL); SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ, ("Set manual full duplex Port %d\n", Port)); } - if (pPrt->PLinkModeConf == SK_LMODE_AUTOSENSE && - pPrt->PLipaAutoNeg == SK_LIPA_AUTO && + if (pPrt->PLinkModeConf == (SK_U8)SK_LMODE_AUTOSENSE && + pPrt->PLipaAutoNeg == (SK_U8)SK_LIPA_AUTO && pPrt->PAutoNegTOCt >= SK_MAX_ANEG_TO) { /* * This is rather complicated. * we need to check here whether the LIPA_AUTO * we saw before is false alert. We saw at one - * switch ( SR8800) that on boot time it sends + * switch (SR8800) that on boot time it sends * just one auto-neg packet and does no further * auto-negotiation. * Solution: we restart the autosensing after * a few timeouts. */ pPrt->PAutoNegTOCt = 0; - pPrt->PLipaAutoNeg = SK_LIPA_UNKNOWN; + pPrt->PLipaAutoNeg = (SK_U8)SK_LIPA_UNKNOWN; SkHWInitDefSense(pAC, IoC, Port); } @@ -1280,18 +1715,18 @@ else { /* Link is up and we don't need more */ #ifdef DEBUG - if (pPrt->PLipaAutoNeg == SK_LIPA_AUTO) { - SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, + if (pPrt->PLipaAutoNeg == (SK_U8)SK_LIPA_AUTO) { + SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_ERR, ("ERROR: Lipa auto detected on port %d\n", Port)); } #endif /* DEBUG */ SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ, ("Link sync(GP), Port %d\n", Port)); SkHWLinkUp(pAC, IoC, Port); - + /* - * Link sync (GP) and so assume a good connection. But if not received - * a bunch of frames received in a time slot (maybe broken tx cable) + * Link sync (GP) and so assume a good connection. But if no + * bunch of frames received in a time slot (maybe broken Tx cable) * the port is restart. */ return(SK_HW_PS_LINK); @@ -1312,8 +1747,8 @@ */ static int SkGePortCheckUpBcom( SK_AC *pAC, /* Adapter Context */ -SK_IOC IoC, /* IO Context */ -int Port, /* Which port should be checked */ +SK_IOC IoC, /* I/O Context */ +int Port, /* Port Index (MAC_1 + n) */ SK_BOOL AutoNeg) /* Is Auto-negotiation used ? */ { SK_GEPORT *pPrt; /* GIni Port struct pointer */ @@ -1332,74 +1767,6 @@ /* Check for No HCD Link events (#10523) */ SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_INT_STAT, &Isrc); -#ifdef xDEBUG - if ((Isrc & ~(PHY_B_IS_HCT | PHY_B_IS_LCT) == - (PHY_B_IS_SCR_S_ER | PHY_B_IS_RRS_CHANGE | PHY_B_IS_LRS_CHANGE)) { - - SK_U32 Stat1, Stat2, Stat3; - - Stat1 = 0; - SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_INT_MASK, &Stat1); - CMSMPrintString( - pAC->pConfigTable, - MSG_TYPE_RUNTIME_INFO, - "CheckUp1 - Stat: %x, Mask: %x", - (void *)Isrc, - (void *)Stat1); - - Stat1 = 0; - SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_CTRL, &Stat1); - Stat2 = 0; - SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_STAT, &Stat2); - Stat1 = Stat1 << 16 | Stat2; - Stat2 = 0; - SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_AUNE_ADV, &Stat2); - Stat3 = 0; - SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_AUNE_LP, &Stat3); - Stat2 = Stat2 << 16 | Stat3; - CMSMPrintString( - pAC->pConfigTable, - MSG_TYPE_RUNTIME_INFO, - "Ctrl/Stat: %x, AN Adv/LP: %x", - (void *)Stat1, - (void *)Stat2); - - Stat1 = 0; - SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_AUNE_EXP, &Stat1); - Stat2 = 0; - SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_EXT_STAT, &Stat2); - Stat1 = Stat1 << 16 | Stat2; - Stat2 = 0; - SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_1000T_CTRL, &Stat2); - Stat3 = 0; - SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_1000T_STAT, &Stat3); - Stat2 = Stat2 << 16 | Stat3; - CMSMPrintString( - pAC->pConfigTable, - MSG_TYPE_RUNTIME_INFO, - "AN Exp/IEEE Ext: %x, 1000T Ctrl/Stat: %x", - (void *)Stat1, - (void *)Stat2); - - Stat1 = 0; - SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_P_EXT_CTRL, &Stat1); - Stat2 = 0; - SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_P_EXT_STAT, &Stat2); - Stat1 = Stat1 << 16 | Stat2; - Stat2 = 0; - SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_AUX_CTRL, &Stat2); - Stat3 = 0; - SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_AUX_STAT, &Stat3); - Stat2 = Stat2 << 16 | Stat3; - CMSMPrintString( - pAC->pConfigTable, - MSG_TYPE_RUNTIME_INFO, - "PHY Ext Ctrl/Stat: %x, Aux Ctrl/Stat: %x", - (void *)Stat1, - (void *)Stat2); - } -#endif /* DEBUG */ - if ((Isrc & (PHY_B_IS_NO_HDCL /* | PHY_B_IS_NO_HDC */)) != 0) { /* * Workaround BCom Errata: @@ -1412,14 +1779,6 @@ (SK_U16)(Ctrl & ~PHY_CT_LOOP)); SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, ("No HCD Link event, Port %d\n", Port)); -#ifdef xDEBUG - CMSMPrintString( - pAC->pConfigTable, - MSG_TYPE_RUNTIME_INFO, - "No HCD link event, port %d.", - (void *)Port, - (void *)NULL); -#endif /* DEBUG */ } /* Not obsolete: link status bit is latched to 0 and autoclearing! */ @@ -1429,72 +1788,6 @@ return(SK_HW_PS_NONE); } -#ifdef xDEBUG - { - SK_U32 Stat1, Stat2, Stat3; - - Stat1 = 0; - SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_INT_MASK, &Stat1); - CMSMPrintString( - pAC->pConfigTable, - MSG_TYPE_RUNTIME_INFO, - "CheckUp1a - Stat: %x, Mask: %x", - (void *)Isrc, - (void *)Stat1); - - Stat1 = 0; - SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_CTRL, &Stat1); - Stat2 = 0; - SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_STAT, &PhyStat); - Stat1 = Stat1 << 16 | PhyStat; - Stat2 = 0; - SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_AUNE_ADV, &Stat2); - Stat3 = 0; - SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_AUNE_LP, &Stat3); - Stat2 = Stat2 << 16 | Stat3; - CMSMPrintString( - pAC->pConfigTable, - MSG_TYPE_RUNTIME_INFO, - "Ctrl/Stat: %x, AN Adv/LP: %x", - (void *)Stat1, - (void *)Stat2); - - Stat1 = 0; - SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_AUNE_EXP, &Stat1); - Stat2 = 0; - SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_EXT_STAT, &Stat2); - Stat1 = Stat1 << 16 | Stat2; - Stat2 = 0; - SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_1000T_CTRL, &Stat2); - Stat3 = 0; - SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_1000T_STAT, &ResAb); - Stat2 = Stat2 << 16 | ResAb; - CMSMPrintString( - pAC->pConfigTable, - MSG_TYPE_RUNTIME_INFO, - "AN Exp/IEEE Ext: %x, 1000T Ctrl/Stat: %x", - (void *)Stat1, - (void *)Stat2); - - Stat1 = 0; - SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_P_EXT_CTRL, &Stat1); - Stat2 = 0; - SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_P_EXT_STAT, &Stat2); - Stat1 = Stat1 << 16 | Stat2; - Stat2 = 0; - SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_AUX_CTRL, &Stat2); - Stat3 = 0; - SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_AUX_STAT, &Stat3); - Stat2 = Stat2 << 16 | Stat3; - CMSMPrintString( - pAC->pConfigTable, - MSG_TYPE_RUNTIME_INFO, - "PHY Ext Ctrl/Stat: %x, Aux Ctrl/Stat: %x", - (void *)Stat1, - (void *)Stat2); - } -#endif /* DEBUG */ - /* * Here we usually can check whether the link is in sync and * auto-negotiation is done. @@ -1503,7 +1796,7 @@ SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_STAT, &PhyStat); SkMacAutoNegLipaPhy(pAC, IoC, Port, PhyStat); - + SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, ("CheckUp Port %d, PhyStat: 0x%04X\n", Port, PhyStat)); @@ -1511,88 +1804,62 @@ if ((ResAb & PHY_B_1000S_MSF) != 0) { /* Error */ - SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, - ("Master/Slave Fault port %d\n", Port)); - + SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_ERR, + ("Master/Slave Fault, ResAb: 0x%04X\n", ResAb)); + pPrt->PAutoNegFail = SK_TRUE; pPrt->PMSStatus = SK_MS_STAT_FAULT; - + return(SK_HW_PS_RESTART); } if ((PhyStat & PHY_ST_LSYNC) == 0) { return(SK_HW_PS_NONE); } - + pPrt->PMSStatus = ((ResAb & PHY_B_1000S_MSR) != 0) ? SK_MS_STAT_MASTER : SK_MS_STAT_SLAVE; - + SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, ("Port %d, ResAb: 0x%04X\n", Port, ResAb)); if (AutoNeg) { + /* Auto-Negotiation Over ? */ if ((PhyStat & PHY_ST_AN_OVER) != 0) { - + SkHWLinkUp(pAC, IoC, Port); - + Done = SkMacAutoNegDone(pAC, IoC, Port); - + if (Done != SK_AND_OK) { #ifdef DEBUG /* Get PHY parameters, for debugging only */ SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_AUNE_LP, &LpAb); SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_1000T_STAT, &ExtStat); - SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, + SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_ERR, ("AutoNeg FAIL Port %d (LpAb %x, 1000TStat %x)\n", Port, LpAb, ExtStat)); #endif /* DEBUG */ return(SK_HW_PS_RESTART); } else { -#ifdef xDEBUG - /* Dummy read ISR to prevent extra link downs/ups */ - SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_INT_STAT, &ExtStat); - - if ((ExtStat & ~(PHY_B_IS_HCT | PHY_B_IS_LCT)) != 0) { - CMSMPrintString( - pAC->pConfigTable, - MSG_TYPE_RUNTIME_INFO, - "CheckUp2 - Stat: %x", - (void *)ExtStat, - (void *)NULL); - } -#endif /* DEBUG */ return(SK_HW_PS_LINK); } } } else { /* !AutoNeg */ - /* Link is up and we don't need more. */ + /* Link is up and we don't need more */ #ifdef DEBUG - if (pPrt->PLipaAutoNeg == SK_LIPA_AUTO) { - SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, + if (pPrt->PLipaAutoNeg == (SK_U8)SK_LIPA_AUTO) { + SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_ERR, ("ERROR: Lipa auto detected on port %d\n", Port)); } #endif /* DEBUG */ -#ifdef xDEBUG - /* Dummy read ISR to prevent extra link downs/ups */ - SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_INT_STAT, &ExtStat); - - if ((ExtStat & ~(PHY_B_IS_HCT | PHY_B_IS_LCT)) != 0) { - CMSMPrintString( - pAC->pConfigTable, - MSG_TYPE_RUNTIME_INFO, - "CheckUp3 - Stat: %x", - (void *)ExtStat, - (void *)NULL); - } -#endif /* DEBUG */ - SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ, ("Link sync(GP), Port %d\n", Port)); SkHWLinkUp(pAC, IoC, Port); - + return(SK_HW_PS_LINK); } @@ -1613,17 +1880,18 @@ */ static int SkGePortCheckUpGmac( SK_AC *pAC, /* Adapter Context */ -SK_IOC IoC, /* IO Context */ -int Port, /* Which port should be checked */ +SK_IOC IoC, /* I/O Context */ +int Port, /* Port Index (MAC_1 + n) */ SK_BOOL AutoNeg) /* Is Auto-negotiation used ? */ { SK_GEPORT *pPrt; /* GIni Port struct pointer */ int Done; - SK_U16 PhyIsrc; /* PHY Interrupt source */ - SK_U16 PhyStat; /* PPY Status */ + SK_U16 PhyStat; /* PHY Status */ SK_U16 PhySpecStat;/* PHY Specific Status */ SK_U16 ResAb; /* Master/Slave resolution */ +#ifndef SK_SLIM SK_EVPARA Para; +#endif /* !SK_SLIM */ #ifdef DEBUG SK_U16 Word; /* I/O helper */ #endif /* DEBUG */ @@ -1640,94 +1908,124 @@ SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, ("CheckUp Port %d, PhyStat: 0x%04X\n", Port, PhyStat)); - /* Read PHY Interrupt Status */ - SkGmPhyRead(pAC, IoC, Port, PHY_MARV_INT_STAT, &PhyIsrc); + SkMacAutoNegLipaPhy(pAC, IoC, Port, PhyStat); - if ((PhyIsrc & PHY_M_IS_AN_COMPL) != 0) { - SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, - ("Auto-Negotiation Completed, PhyIsrc: 0x%04X\n", PhyIsrc)); - } + if ((pPrt->PLinkSpeedCap & SK_LSPEED_CAP_1000MBPS) != 0) { - if ((PhyIsrc & PHY_M_IS_LSP_CHANGE) != 0) { - SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, - ("Link Speed Changed, PhyIsrc: 0x%04X\n", PhyIsrc)); - } + SkGmPhyRead(pAC, IoC, Port, PHY_MARV_1000T_STAT, &ResAb); - SkMacAutoNegLipaPhy(pAC, IoC, Port, PhyStat); - - SkGmPhyRead(pAC, IoC, Port, PHY_MARV_1000T_STAT, &ResAb); + if ((ResAb & PHY_B_1000S_MSF) != 0) { + /* Error */ + SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_ERR, + ("Master/Slave Fault, ResAb: 0x%04X\n", ResAb)); - if ((ResAb & PHY_B_1000S_MSF) != 0) { - /* Error */ - SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, - ("Master/Slave Fault port %d\n", Port)); - - pPrt->PAutoNegFail = SK_TRUE; - pPrt->PMSStatus = SK_MS_STAT_FAULT; - - return(SK_HW_PS_RESTART); + pPrt->PAutoNegFail = SK_TRUE; + pPrt->PMSStatus = SK_MS_STAT_FAULT; + + return(SK_HW_PS_RESTART); + } } /* Read PHY Specific Status */ SkGmPhyRead(pAC, IoC, Port, PHY_MARV_PHY_STAT, &PhySpecStat); - + SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, ("Phy1000BT: 0x%04X, PhySpecStat: 0x%04X\n", ResAb, PhySpecStat)); #ifdef DEBUG SkGmPhyRead(pAC, IoC, Port, PHY_MARV_AUNE_EXP, &Word); - if ((PhyIsrc & PHY_M_IS_AN_PR) != 0 || (Word & PHY_ANE_RX_PG) != 0 || - (PhySpecStat & PHY_M_PS_PAGE_REC) != 0) { + if ((Word & PHY_ANE_RX_PG) != 0 || + (PhySpecStat & PHY_M_PS_PAGE_REC) != 0) { /* Read PHY Next Page Link Partner */ SkGmPhyRead(pAC, IoC, Port, PHY_MARV_NEPG_LP, &Word); SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, - ("Page Received, NextPage: 0x%04X\n", Word)); + ("Page received, NextPage: 0x%04X\n", Word)); } #endif /* DEBUG */ if ((PhySpecStat & PHY_M_PS_LINK_UP) == 0) { + /* Link down */ return(SK_HW_PS_NONE); } - - if ((PhySpecStat & PHY_M_PS_DOWNS_STAT) != 0 || - (PhyIsrc & PHY_M_IS_DOWNSH_DET) != 0) { - /* Downshift detected */ - SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E025, SKERR_SIRQ_E025MSG); - - Para.Para64 = Port; - SkEventQueue(pAC, SKGE_DRV, SK_DRV_DOWNSHIFT_DET, Para); - - SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, - ("Downshift detected, PhyIsrc: 0x%04X\n", PhyIsrc)); + +#ifdef XXX + SK_U16 PhyInt; + /* Read PHY Interrupt Status */ + SkGmPhyRead(pAC, IoC, Port, PHY_MARV_INT_STAT, &PhyInt); + + /* cross check that the link is really up */ + if ((PhyInt & PHY_M_IS_LST_CHANGE) == 0) { + /* Link Status unchanged */ + return(SK_HW_PS_NONE); } +#endif /* XXX */ + +#ifndef SK_SLIM + if (pAC->GIni.GICopperType) { + + if ((pPrt->PLinkSpeedCap & SK_LSPEED_CAP_1000MBPS) != 0) { + + if ((PhySpecStat & PHY_M_PS_DOWNS_STAT) != 0) { + /* Downshift detected */ + Para.Para64 = Port; + SkEventQueue(pAC, SKGE_DRV, SK_DRV_DOWNSHIFT_DET, Para); + + SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, + ("Downshift detected, PhySpecStat: 0x%04X\n", PhySpecStat)); + + SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E025, + SKERR_SIRQ_E025MSG); + } + + pPrt->PMSStatus = ((ResAb & PHY_B_1000S_MSR) != 0) ? + SK_MS_STAT_MASTER : SK_MS_STAT_SLAVE; + } + + if ((PhySpecStat & PHY_M_PS_MDI_X_STAT) != 0) { + SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, + ("MDI Xover detected, PhyStat: 0x%04X\n", PhySpecStat)); + } + + /* on PHY 88E1112 & 88E1145 cable length is in Reg. 26, Page 5 */ + if (pAC->GIni.GIChipId == CHIP_ID_YUKON_XL || + pAC->GIni.GIChipId == CHIP_ID_YUKON_EC_U) { + /* select page 5 to access VCT DSP distance register */ + SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_EXT_ADR, 5); + + /* get VCT DSP distance */ + SkGmPhyRead(pAC, IoC, Port, PHY_MARV_EXT_CTRL_2, &PhySpecStat); + + SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_EXT_ADR, 0); + + pPrt->PCableLen = (SK_U8)(PhySpecStat & PHY_M_EC2_FO_AM_MSK); + } + else { + pPrt->PCableLen = (SK_U8)((PhySpecStat & PHY_M_PS_CABLE_MSK) >> 7); + } + } +#endif /* !SK_SLIM */ - pPrt->PMSStatus = ((ResAb & PHY_B_1000S_MSR) != 0) ? - SK_MS_STAT_MASTER : SK_MS_STAT_SLAVE; - - pPrt->PCableLen = (SK_U8)((PhySpecStat & PHY_M_PS_CABLE_MSK) >> 7); - if (AutoNeg) { - /* Auto-Negotiation Over ? */ + /* Auto-Negotiation Complete ? */ if ((PhyStat & PHY_ST_AN_OVER) != 0) { - + SkHWLinkUp(pAC, IoC, Port); - + Done = SkMacAutoNegDone(pAC, IoC, Port); - + if (Done != SK_AND_OK) { return(SK_HW_PS_RESTART); } - + return(SK_HW_PS_LINK); } } else { /* !AutoNeg */ - /* Link is up and we don't need more */ #ifdef DEBUG - if (pPrt->PLipaAutoNeg == SK_LIPA_AUTO) { - SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, + if (pPrt->PLipaAutoNeg == (SK_U8)SK_LIPA_AUTO) { + SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_ERR, ("ERROR: Lipa auto detected on port %d\n", Port)); } #endif /* DEBUG */ @@ -1735,12 +2033,13 @@ SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ, ("Link sync, Port %d\n", Port)); SkHWLinkUp(pAC, IoC, Port); - + return(SK_HW_PS_LINK); } return(SK_HW_PS_NONE); } /* SkGePortCheckUpGmac */ + #endif /* YUKON */ @@ -1756,8 +2055,8 @@ */ static int SkGePortCheckUpLone( SK_AC *pAC, /* Adapter Context */ -SK_IOC IoC, /* IO Context */ -int Port, /* Which port should be checked */ +SK_IOC IoC, /* I/O Context */ +int Port, /* Port Index (MAC_1 + n) */ SK_BOOL AutoNeg) /* Is Auto-negotiation used ? */ { SK_GEPORT *pPrt; /* GIni Port struct pointer */ @@ -1786,7 +2085,7 @@ StatSum |= PhyStat; SkMacAutoNegLipaPhy(pAC, IoC, Port, PhyStat); - + if ((PhyStat & PHY_ST_LSYNC) == 0) { /* Save Auto-negotiation Done bit */ pPrt->PIsave = (SK_U16)(StatSum & PHY_ST_AN_OVER); @@ -1800,17 +2099,21 @@ } if (AutoNeg) { + /* Auto-Negotiation Over ? */ if ((StatSum & PHY_ST_AN_OVER) != 0) { + SkHWLinkUp(pAC, IoC, Port); + Done = SkMacAutoNegDone(pAC, IoC, Port); + if (Done != SK_AND_OK) { /* Get PHY parameters, for debugging only */ SkXmPhyRead(pAC, IoC, Port, PHY_LONE_AUNE_LP, &LpAb); SkXmPhyRead(pAC, IoC, Port, PHY_LONE_1000T_STAT, &ExtStat); - SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, + SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_ERR, ("AutoNeg FAIL Port %d (LpAb %x, 1000TStat %x)\n", Port, LpAb, ExtStat)); - + /* Try next possible mode */ NextMode = SkHWSenseGetNext(pAC, IoC, Port); SkHWLinkDown(pAC, IoC, Port); @@ -1831,15 +2134,14 @@ return(SK_HW_PS_LINK); } } - + /* AutoNeg not done, but HW link is up. Check for timeouts */ - pPrt->PAutoNegTimeOut++; - if (pPrt->PAutoNegTimeOut >= SK_AND_MAX_TO) { + if (pPrt->PAutoNegTimeOut++ >= SK_AND_MAX_TO) { /* Timeout occured */ SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ, ("AutoNeg timeout Port %d\n", Port)); - if (pPrt->PLinkModeConf == SK_LMODE_AUTOSENSE && - pPrt->PLipaAutoNeg != SK_LIPA_AUTO) { + if (pPrt->PLinkModeConf == (SK_U8)SK_LMODE_AUTOSENSE && + pPrt->PLipaAutoNeg != (SK_U8)SK_LIPA_AUTO) { /* Set Link manually up */ SkHWSenseSetNext(pAC, IoC, Port, SK_LMODE_FULL); SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ, @@ -1853,8 +2155,8 @@ else { /* Link is up and we don't need more */ #ifdef DEBUG - if (pPrt->PLipaAutoNeg == SK_LIPA_AUTO) { - SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, + if (pPrt->PLipaAutoNeg == (SK_U8)SK_LIPA_AUTO) { + SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_ERR, ("ERROR: Lipa auto detected on port %d\n", Port)); } #endif /* DEBUG */ @@ -1864,11 +2166,12 @@ * extra link down/ups */ SkXmPhyRead(pAC, IoC, Port, PHY_LONE_INT_STAT, &ExtStat); - + SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ, ("Link sync(GP), Port %d\n", Port)); + SkHWLinkUp(pAC, IoC, Port); - + return(SK_HW_PS_LINK); } @@ -1887,8 +2190,8 @@ */ static int SkGePortCheckUpNat( SK_AC *pAC, /* Adapter Context */ -SK_IOC IoC, /* IO Context */ -int Port, /* Which port should be checked */ +SK_IOC IoC, /* I/O Context */ +int Port, /* Port Index (MAC_1 + n) */ SK_BOOL AutoNeg) /* Is Auto-negotiation used ? */ { /* todo: National */ @@ -1907,38 +2210,40 @@ */ int SkGeSirqEvent( SK_AC *pAC, /* Adapter Context */ -SK_IOC IoC, /* Io Context */ +SK_IOC IoC, /* I/O Context */ SK_U32 Event, /* Module specific Event */ SK_EVPARA Para) /* Event specific Parameter */ { SK_GEPORT *pPrt; /* GIni Port struct pointer */ - SK_U32 Port; + int Port; SK_U32 Val32; int PortStat; +#ifndef SK_SLIM SK_U8 Val8; +#endif #ifdef GENESIS SK_U64 Octets; #endif /* GENESIS */ - Port = Para.Para32[0]; + Port = (int)Para.Para32[0]; pPrt = &pAC->GIni.GP[Port]; switch (Event) { case SK_HWEV_WATIM: if (pPrt->PState == SK_PRT_RESET) { - + PortStat = SK_HW_PS_NONE; } else { /* Check whether port came up */ - PortStat = SkGePortCheckUp(pAC, IoC, (int)Port); + PortStat = SkGePortCheckUp(pAC, IoC, Port); } switch (PortStat) { case SK_HW_PS_RESTART: if (pPrt->PHWLinkUp) { /* Set Link to down */ - SkHWLinkDown(pAC, IoC, (int)Port); + SkHWLinkDown(pAC, IoC, Port); /* * Signal directly to RLMT to ensure correct @@ -1956,22 +2261,28 @@ SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_LINK_UP, Para); break; } - + /* Start again the check Timer */ if (pPrt->PHWLinkUp) { + Val32 = SK_WA_ACT_TIME; } else { Val32 = SK_WA_INA_TIME; - } - /* Todo: still needed for non-XMAC PHYs??? */ + if (pAC->GIni.GIYukon) { + Val32 *= 5; + } + } /* Start workaround Errata #2 timer */ SkTimerStart(pAC, IoC, &pPrt->PWaTimer, Val32, SKGE_HWAC, SK_HWEV_WATIM, Para); + break; case SK_HWEV_PORT_START: + +#ifndef SK_SLIM if (pPrt->PHWLinkUp) { /* * Signal directly to RLMT to ensure correct @@ -1979,8 +2290,9 @@ */ SkRlmtEvent(pAC, IoC, SK_RLMT_LINK_DOWN, Para); } +#endif /* !SK_SLIM */ - SkHWLinkDown(pAC, IoC, (int)Port); + SkHWLinkDown(pAC, IoC, Port); /* Schedule Port RESET */ SkEventQueue(pAC, SKGE_DRV, SK_DRV_PORT_RESET, Para); @@ -1988,9 +2300,11 @@ /* Start workaround Errata #2 timer */ SkTimerStart(pAC, IoC, &pPrt->PWaTimer, SK_WA_INA_TIME, SKGE_HWAC, SK_HWEV_WATIM, Para); + break; case SK_HWEV_PORT_STOP: +#ifndef SK_SLIM if (pPrt->PHWLinkUp) { /* * Signal directly to RLMT to ensure correct @@ -1998,20 +2312,22 @@ */ SkRlmtEvent(pAC, IoC, SK_RLMT_LINK_DOWN, Para); } +#endif /* !SK_SLIM */ /* Stop Workaround Timer */ SkTimerStop(pAC, IoC, &pPrt->PWaTimer); - SkHWLinkDown(pAC, IoC, (int)Port); + SkHWLinkDown(pAC, IoC, Port); break; +#ifndef SK_SLIM case SK_HWEV_UPDATE_STAT: /* We do NOT need to update any statistics */ break; case SK_HWEV_CLEAR_STAT: /* We do NOT need to clear any statistics */ - for (Port = 0; Port < (SK_U32)pAC->GIni.GIMacsFound; Port++) { + for (Port = 0; Port < pAC->GIni.GIMacsFound; Port++) { pPrt->PPrevRx = 0; pPrt->PPrevFcs = 0; pPrt->PPrevShorts = 0; @@ -2072,6 +2388,7 @@ SkEventQueue(pAC, SKGE_HWAC, SK_HWEV_PORT_START, Para); } break; +#endif /* !SK_SLIM */ #ifdef GENESIS case SK_HWEV_HALFDUP_CHK: @@ -2083,23 +2400,18 @@ pPrt->HalfDupTimerActive = SK_FALSE; if (pPrt->PLinkModeStatus == SK_LMODE_STAT_HALF || pPrt->PLinkModeStatus == SK_LMODE_STAT_AUTOHALF) { -#ifdef XXX - Len = sizeof(SK_U64); - SkPnmiGetVar(pAC, IoC, OID_SKGE_STAT_TX_OCTETS, (char *)&Octets, - &Len, (SK_U32)SK_PNMI_PORT_PHYS2INST(pAC, Port), - pAC->Rlmt.Port[Port].Net->NetNumber); -#endif /* XXX */ + /* Snap statistic counters */ (void)SkXmUpdateStats(pAC, IoC, Port); (void)SkXmMacStatistic(pAC, IoC, Port, XM_TXO_OK_HI, &Val32); Octets = (SK_U64)Val32 << 32; - + (void)SkXmMacStatistic(pAC, IoC, Port, XM_TXO_OK_LO, &Val32); Octets += Val32; - + if (pPrt->LastOctets == Octets) { /* Tx hanging, a FIFO flush restarts it */ SkMacFlushTxFifo(pAC, IoC, Port); @@ -2108,7 +2420,7 @@ } break; #endif /* GENESIS */ - + default: SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_SIRQ_E001, SKERR_SIRQ_E001MSG); break; @@ -2129,8 +2441,8 @@ */ static void SkPhyIsrBcom( SK_AC *pAC, /* Adapter Context */ -SK_IOC IoC, /* Io Context */ -int Port, /* Port Num = PHY Num */ +SK_IOC IoC, /* I/O Context */ +int Port, /* Port Index (MAC_1 + n) */ SK_U16 IStatus) /* Interrupt Status */ { SK_GEPORT *pPrt; /* GIni Port struct pointer */ @@ -2143,7 +2455,7 @@ SK_ERR_LOG(pAC, SK_ERRCL_HW | SK_ERRCL_INIT, SKERR_SIRQ_E022, SKERR_SIRQ_E022MSG); } - + if ((IStatus & (PHY_B_IS_AN_PR | PHY_B_IS_LST_CHANGE)) != 0) { SkHWLinkDown(pAC, IoC, Port); @@ -2172,8 +2484,8 @@ */ static void SkPhyIsrGmac( SK_AC *pAC, /* Adapter Context */ -SK_IOC IoC, /* Io Context */ -int Port, /* Port Num = PHY Num */ +SK_IOC IoC, /* I/O Context */ +int Port, /* Port Index (MAC_1 + n) */ SK_U16 IStatus) /* Interrupt Status */ { SK_GEPORT *pPrt; /* GIni Port struct pointer */ @@ -2182,37 +2494,69 @@ pPrt = &pAC->GIni.GP[Port]; - if ((IStatus & (PHY_M_IS_AN_PR | PHY_M_IS_LST_CHANGE)) != 0) { - - SkHWLinkDown(pAC, IoC, Port); + SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, + ("Port %d PHY IRQ, PhyIsrc: 0x%04X\n", Port, IStatus)); - SkGmPhyRead(pAC, IoC, Port, PHY_MARV_AUNE_ADV, &Word); + if ((IStatus & PHY_M_IS_LST_CHANGE) != 0) { SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, - ("AutoNeg.Adv: 0x%04X\n", Word)); - - /* Set Auto-negotiation advertisement */ - if (pPrt->PFlowCtrlMode == SK_FLOW_MODE_SYM_OR_REM) { - /* restore Asymmetric Pause bit */ - SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_AUNE_ADV, - (SK_U16)(Word | PHY_M_AN_ASP)); - } - + ("Link Status changed\n")); + Para.Para32[0] = (SK_U32)Port; - /* Signal to RLMT */ - SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_LINK_DOWN, Para); + + if (pPrt->PHWLinkUp) { + + SkHWLinkDown(pAC, IoC, Port); + + SkGmPhyRead(pAC, IoC, Port, PHY_MARV_AUNE_ADV, &Word); + + SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, + ("AutoNeg.Adv: 0x%04X\n", Word)); + + /* Set Auto-negotiation advertisement */ + if (pAC->GIni.GIChipId != CHIP_ID_YUKON_FE && + pPrt->PFlowCtrlMode == SK_FLOW_MODE_SYM_OR_REM) { + /* restore Asymmetric Pause bit */ + SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_AUNE_ADV, + (SK_U16)(Word | PHY_M_AN_ASP)); + } + + /* Signal to RLMT */ + SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_LINK_DOWN, Para); + } + else { + if ((IStatus & PHY_M_IS_AN_COMPL) != 0) { + SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, + ("Auto-Negotiation completed\n")); + } + + if ((IStatus & PHY_M_IS_LSP_CHANGE) != 0) { + SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, + ("Link Speed changed\n")); + } + + SkEventQueue(pAC, SKGE_HWAC, SK_HWEV_WATIM, Para); + } } - + if ((IStatus & PHY_M_IS_AN_ERROR) != 0) { - /* Auto-Negotiation Error */ - SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E023, SKERR_SIRQ_E023MSG); + /* the copper PHY makes 1 retry */ + if (pAC->GIni.GICopperType) { + /* not logged as error, it might be the first attempt */ + SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, + ("Auto-Negotiation Error\n")); + } + else { + /* Auto-Negotiation Error */ + SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E023, SKERR_SIRQ_E023MSG); + } } - + if ((IStatus & PHY_M_IS_FIFO_ERROR) != 0) { /* FIFO Overflow/Underrun Error */ SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_SIRQ_E024, SKERR_SIRQ_E024MSG); } - + } /* SkPhyIsrGmac */ #endif /* YUKON */ @@ -2228,14 +2572,14 @@ */ static void SkPhyIsrLone( SK_AC *pAC, /* Adapter Context */ -SK_IOC IoC, /* Io Context */ -int Port, /* Port Num = PHY Num */ +SK_IOC IoC, /* I/O Context */ +int Port, /* Port Index (MAC_1 + n) */ SK_U16 IStatus) /* Interrupt Status */ { SK_EVPARA Para; if (IStatus & (PHY_L_IS_DUP | PHY_L_IS_ISOL)) { - + SkHWLinkDown(pAC, IoC, Port); Para.Para32[0] = (SK_U32)Port; @@ -2247,3 +2591,4 @@ #endif /* OTHER_PHY */ /* End of File */ + diff -urN linux-2.4.32-600/drivers/net/sk98lin/ski2c.c linux-2.4.32-600-sk98_831/drivers/net/sk98lin/ski2c.c --- linux-2.4.32-600/drivers/net/sk98lin/ski2c.c Sat Mar 20 10:08:19 2004 +++ linux-2.4.32-600-sk98_831/drivers/net/sk98lin/ski2c.c Thu Jan 1 01:00:00 1970 @@ -1,1294 +0,0 @@ -/****************************************************************************** - * - * Name: ski2c.c - * Project: Gigabit Ethernet Adapters, TWSI-Module - * Purpose: Functions to access Voltage and Temperature Sensor - * - ******************************************************************************/ - -/****************************************************************************** - * - * (C)Copyright 1998-2002 SysKonnect. - * (C)Copyright 2002-2003 Marvell. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * The information in this file is provided "AS IS" without warranty. - * - ******************************************************************************/ - -/* - * I2C Protocol - */ -#if (defined(DEBUG) || ((!defined(LINT)) && (!defined(SK_SLIM)))) -static const char SysKonnectFileId[] = - "@(#) $Id: ski2c.c,v 1.59 2003/10/20 09:07:25 rschmidt Exp $ (C) Marvell. "; -#endif - -#include "h/skdrv1st.h" /* Driver Specific Definitions */ -#include "h/lm80.h" -#include "h/skdrv2nd.h" /* Adapter Control- and Driver specific Def. */ - -#ifdef __C2MAN__ -/* - I2C protocol implementation. - - General Description: - - The I2C protocol is used for the temperature sensors and for - the serial EEPROM which hold the configuration. - - This file covers functions that allow to read write and do - some bulk requests a specified I2C address. - - The Genesis has 2 I2C buses. One for the EEPROM which holds - the VPD Data and one for temperature and voltage sensor. - The following picture shows the I2C buses, I2C devices and - their control registers. - - Note: The VPD functions are in skvpd.c -. -. PCI Config I2C Bus for VPD Data: -. -. +------------+ -. | VPD EEPROM | -. +------------+ -. | -. | <-- I2C -. | -. +-----------+-----------+ -. | | -. +-----------------+ +-----------------+ -. | PCI_VPD_ADR_REG | | PCI_VPD_DAT_REG | -. +-----------------+ +-----------------+ -. -. -. I2C Bus for LM80 sensor: -. -. +-----------------+ -. | Temperature and | -. | Voltage Sensor | -. | LM80 | -. +-----------------+ -. | -. | -. I2C --> | -. | -. +----+ -. +-------------->| OR |<--+ -. | +----+ | -. +------+------+ | -. | | | -. +--------+ +--------+ +----------+ -. | B2_I2C | | B2_I2C | | B2_I2C | -. | _CTRL | | _DATA | | _SW | -. +--------+ +--------+ +----------+ -. - The I2C bus may be driven by the B2_I2C_SW or by the B2_I2C_CTRL - and B2_I2C_DATA registers. - For driver software it is recommended to use the I2C control and - data register, because I2C bus timing is done by the ASIC and - an interrupt may be received when the I2C request is completed. - - Clock Rate Timing: MIN MAX generated by - VPD EEPROM: 50 kHz 100 kHz HW - LM80 over I2C Ctrl/Data reg. 50 kHz 100 kHz HW - LM80 over B2_I2C_SW register 0 400 kHz SW - - Note: The clock generated by the hardware is dependend on the - PCI clock. If the PCI bus clock is 33 MHz, the I2C/VPD - clock is 50 kHz. - */ -intro() -{} -#endif - -#ifdef SK_DIAG -/* - * I2C Fast Mode timing values used by the LM80. - * If new devices are added to the I2C bus the timing values have to be checked. - */ -#ifndef I2C_SLOW_TIMING -#define T_CLK_LOW 1300L /* clock low time in ns */ -#define T_CLK_HIGH 600L /* clock high time in ns */ -#define T_DATA_IN_SETUP 100L /* data in Set-up Time */ -#define T_START_HOLD 600L /* start condition hold time */ -#define T_START_SETUP 600L /* start condition Set-up time */ -#define T_STOP_SETUP 600L /* stop condition Set-up time */ -#define T_BUS_IDLE 1300L /* time the bus must free after Tx */ -#define T_CLK_2_DATA_OUT 900L /* max. clock low to data output valid */ -#else /* I2C_SLOW_TIMING */ -/* I2C Standard Mode Timing */ -#define T_CLK_LOW 4700L /* clock low time in ns */ -#define T_CLK_HIGH 4000L /* clock high time in ns */ -#define T_DATA_IN_SETUP 250L /* data in Set-up Time */ -#define T_START_HOLD 4000L /* start condition hold time */ -#define T_START_SETUP 4700L /* start condition Set-up time */ -#define T_STOP_SETUP 4000L /* stop condition Set-up time */ -#define T_BUS_IDLE 4700L /* time the bus must free after Tx */ -#endif /* !I2C_SLOW_TIMING */ - -#define NS2BCLK(x) (((x)*125)/10000) - -/* - * I2C Wire Operations - * - * About I2C_CLK_LOW(): - * - * The Data Direction bit (I2C_DATA_DIR) has to be set to input when setting - * clock to low, to prevent the ASIC and the I2C data client from driving the - * serial data line simultaneously (ASIC: last bit of a byte = '1', I2C client - * send an 'ACK'). See also Concentrator Bugreport No. 10192. - */ -#define I2C_DATA_HIGH(IoC) SK_I2C_SET_BIT(IoC, I2C_DATA) -#define I2C_DATA_LOW(IoC) SK_I2C_CLR_BIT(IoC, I2C_DATA) -#define I2C_DATA_OUT(IoC) SK_I2C_SET_BIT(IoC, I2C_DATA_DIR) -#define I2C_DATA_IN(IoC) SK_I2C_CLR_BIT(IoC, I2C_DATA_DIR | I2C_DATA) -#define I2C_CLK_HIGH(IoC) SK_I2C_SET_BIT(IoC, I2C_CLK) -#define I2C_CLK_LOW(IoC) SK_I2C_CLR_BIT(IoC, I2C_CLK | I2C_DATA_DIR) -#define I2C_START_COND(IoC) SK_I2C_CLR_BIT(IoC, I2C_CLK) - -#define NS2CLKT(x) ((x*125L)/10000) - -/*--------------- I2C Interface Register Functions --------------- */ - -/* - * sending one bit - */ -void SkI2cSndBit( -SK_IOC IoC, /* I/O Context */ -SK_U8 Bit) /* Bit to send */ -{ - I2C_DATA_OUT(IoC); - if (Bit) { - I2C_DATA_HIGH(IoC); - } - else { - I2C_DATA_LOW(IoC); - } - SkDgWaitTime(IoC, NS2BCLK(T_DATA_IN_SETUP)); - I2C_CLK_HIGH(IoC); - SkDgWaitTime(IoC, NS2BCLK(T_CLK_HIGH)); - I2C_CLK_LOW(IoC); -} /* SkI2cSndBit*/ - - -/* - * Signal a start to the I2C Bus. - * - * A start is signaled when data goes to low in a high clock cycle. - * - * Ends with Clock Low. - * - * Status: not tested - */ -void SkI2cStart( -SK_IOC IoC) /* I/O Context */ -{ - /* Init data and Clock to output lines */ - /* Set Data high */ - I2C_DATA_OUT(IoC); - I2C_DATA_HIGH(IoC); - /* Set Clock high */ - I2C_CLK_HIGH(IoC); - - SkDgWaitTime(IoC, NS2BCLK(T_START_SETUP)); - - /* Set Data Low */ - I2C_DATA_LOW(IoC); - - SkDgWaitTime(IoC, NS2BCLK(T_START_HOLD)); - - /* Clock low without Data to Input */ - I2C_START_COND(IoC); - - SkDgWaitTime(IoC, NS2BCLK(T_CLK_LOW)); -} /* SkI2cStart */ - - -void SkI2cStop( -SK_IOC IoC) /* I/O Context */ -{ - /* Init data and Clock to output lines */ - /* Set Data low */ - I2C_DATA_OUT(IoC); - I2C_DATA_LOW(IoC); - - SkDgWaitTime(IoC, NS2BCLK(T_CLK_2_DATA_OUT)); - - /* Set Clock high */ - I2C_CLK_HIGH(IoC); - - SkDgWaitTime(IoC, NS2BCLK(T_STOP_SETUP)); - - /* - * Set Data High: Do it by setting the Data Line to Input. - * Because of a pull up resistor the Data Line - * floods to high. - */ - I2C_DATA_IN(IoC); - - /* - * When I2C activity is stopped - * o DATA should be set to input and - * o CLOCK should be set to high! - */ - SkDgWaitTime(IoC, NS2BCLK(T_BUS_IDLE)); -} /* SkI2cStop */ - - -/* - * Receive just one bit via the I2C bus. - * - * Note: Clock must be set to LOW before calling this function. - * - * Returns The received bit. - */ -int SkI2cRcvBit( -SK_IOC IoC) /* I/O Context */ -{ - int Bit; - SK_U8 I2cSwCtrl; - - /* Init data as input line */ - I2C_DATA_IN(IoC); - - SkDgWaitTime(IoC, NS2BCLK(T_CLK_2_DATA_OUT)); - - I2C_CLK_HIGH(IoC); - - SkDgWaitTime(IoC, NS2BCLK(T_CLK_HIGH)); - - SK_I2C_GET_SW(IoC, &I2cSwCtrl); - - Bit = (I2cSwCtrl & I2C_DATA) ? 1 : 0; - - I2C_CLK_LOW(IoC); - SkDgWaitTime(IoC, NS2BCLK(T_CLK_LOW-T_CLK_2_DATA_OUT)); - - return(Bit); -} /* SkI2cRcvBit */ - - -/* - * Receive an ACK. - * - * returns 0 If acknowledged - * 1 in case of an error - */ -int SkI2cRcvAck( -SK_IOC IoC) /* I/O Context */ -{ - /* - * Received bit must be zero. - */ - return(SkI2cRcvBit(IoC) != 0); -} /* SkI2cRcvAck */ - - -/* - * Send an NACK. - */ -void SkI2cSndNAck( -SK_IOC IoC) /* I/O Context */ -{ - /* - * Received bit must be zero. - */ - SkI2cSndBit(IoC, 1); -} /* SkI2cSndNAck */ - - -/* - * Send an ACK. - */ -void SkI2cSndAck( -SK_IOC IoC) /* I/O Context */ -{ - /* - * Received bit must be zero. - */ - SkI2cSndBit(IoC, 0); -} /* SkI2cSndAck */ - - -/* - * Send one byte to the I2C device and wait for ACK. - * - * Return acknowleged status. - */ -int SkI2cSndByte( -SK_IOC IoC, /* I/O Context */ -int Byte) /* byte to send */ -{ - int i; - - for (i = 0; i < 8; i++) { - if (Byte & (1<<(7-i))) { - SkI2cSndBit(IoC, 1); - } - else { - SkI2cSndBit(IoC, 0); - } - } - - return(SkI2cRcvAck(IoC)); -} /* SkI2cSndByte */ - - -/* - * Receive one byte and ack it. - * - * Return byte. - */ -int SkI2cRcvByte( -SK_IOC IoC, /* I/O Context */ -int Last) /* Last Byte Flag */ -{ - int i; - int Byte = 0; - - for (i = 0; i < 8; i++) { - Byte <<= 1; - Byte |= SkI2cRcvBit(IoC); - } - - if (Last) { - SkI2cSndNAck(IoC); - } - else { - SkI2cSndAck(IoC); - } - - return(Byte); -} /* SkI2cRcvByte */ - - -/* - * Start dialog and send device address - * - * Return 0 if acknowleged, 1 in case of an error - */ -int SkI2cSndDev( -SK_IOC IoC, /* I/O Context */ -int Addr, /* Device Address */ -int Rw) /* Read / Write Flag */ -{ - SkI2cStart(IoC); - Rw = ~Rw; - Rw &= I2C_WRITE; - return(SkI2cSndByte(IoC, (Addr<<1) | Rw)); -} /* SkI2cSndDev */ - -#endif /* SK_DIAG */ - -/*----------------- I2C CTRL Register Functions ----------*/ - -/* - * waits for a completion of an I2C transfer - * - * returns 0: success, transfer completes - * 1: error, transfer does not complete, I2C transfer - * killed, wait loop terminated. - */ -int SkI2cWait( -SK_AC *pAC, /* Adapter Context */ -SK_IOC IoC, /* I/O Context */ -int Event) /* complete event to wait for (I2C_READ or I2C_WRITE) */ -{ - SK_U64 StartTime; - SK_U64 CurrentTime; - SK_U32 I2cCtrl; - - StartTime = SkOsGetTime(pAC); - - do { - CurrentTime = SkOsGetTime(pAC); - - if (CurrentTime - StartTime > SK_TICKS_PER_SEC / 8) { - - SK_I2C_STOP(IoC); -#ifndef SK_DIAG - SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_I2C_E002, SKERR_I2C_E002MSG); -#endif /* !SK_DIAG */ - return(1); - } - - SK_I2C_GET_CTL(IoC, &I2cCtrl); - -#ifdef xYUKON_DBG - printf("StartTime=%lu, CurrentTime=%lu\n", - StartTime, CurrentTime); - if (kbhit()) { - return(1); - } -#endif /* YUKON_DBG */ - - } while ((I2cCtrl & I2C_FLAG) == (SK_U32)Event << 31); - - return(0); -} /* SkI2cWait */ - - -/* - * waits for a completion of an I2C transfer - * - * Returns - * Nothing - */ -void SkI2cWaitIrq( -SK_AC *pAC, /* Adapter Context */ -SK_IOC IoC) /* I/O Context */ -{ - SK_SENSOR *pSen; - SK_U64 StartTime; - SK_U32 IrqSrc; - - pSen = &pAC->I2c.SenTable[pAC->I2c.CurrSens]; - - if (pSen->SenState == SK_SEN_IDLE) { - return; - } - - StartTime = SkOsGetTime(pAC); - - do { - if (SkOsGetTime(pAC) - StartTime > SK_TICKS_PER_SEC / 8) { - - SK_I2C_STOP(IoC); -#ifndef SK_DIAG - SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_I2C_E016, SKERR_I2C_E016MSG); -#endif /* !SK_DIAG */ - return; - } - - SK_IN32(IoC, B0_ISRC, &IrqSrc); - - } while ((IrqSrc & IS_I2C_READY) == 0); - - pSen->SenState = SK_SEN_IDLE; - return; -} /* SkI2cWaitIrq */ - -/* - * writes a single byte or 4 bytes into the I2C device - * - * returns 0: success - * 1: error - */ -int SkI2cWrite( -SK_AC *pAC, /* Adapter Context */ -SK_IOC IoC, /* I/O Context */ -SK_U32 I2cData, /* I2C Data to write */ -int I2cDev, /* I2C Device Address */ -int I2cDevSize, /* I2C Device Size (e.g. I2C_025K_DEV or I2C_2K_DEV) */ -int I2cReg, /* I2C Device Register Address */ -int I2cBurst) /* I2C Burst Flag */ -{ - SK_OUT32(IoC, B2_I2C_DATA, I2cData); - - SK_I2C_CTL(IoC, I2C_WRITE, I2cDev, I2cDevSize, I2cReg, I2cBurst); - - return(SkI2cWait(pAC, IoC, I2C_WRITE)); -} /* SkI2cWrite*/ - - -#ifdef SK_DIAG -/* - * reads a single byte or 4 bytes from the I2C device - * - * returns the word read - */ -SK_U32 SkI2cRead( -SK_AC *pAC, /* Adapter Context */ -SK_IOC IoC, /* I/O Context */ -int I2cDev, /* I2C Device Address */ -int I2cDevSize, /* I2C Device Size (e.g. I2C_025K_DEV or I2C_2K_DEV) */ -int I2cReg, /* I2C Device Register Address */ -int I2cBurst) /* I2C Burst Flag */ -{ - SK_U32 Data; - - SK_OUT32(IoC, B2_I2C_DATA, 0); - SK_I2C_CTL(IoC, I2C_READ, I2cDev, I2cDevSize, I2cReg, I2cBurst); - - if (SkI2cWait(pAC, IoC, I2C_READ) != 0) { - w_print("%s\n", SKERR_I2C_E002MSG); - } - - SK_IN32(IoC, B2_I2C_DATA, &Data); - - return(Data); -} /* SkI2cRead */ -#endif /* SK_DIAG */ - - -/* - * read a sensor's value - * - * This function reads a sensor's value from the I2C sensor chip. The sensor - * is defined by its index into the sensors database in the struct pAC points - * to. - * Returns - * 1 if the read is completed - * 0 if the read must be continued (I2C Bus still allocated) - */ -int SkI2cReadSensor( -SK_AC *pAC, /* Adapter Context */ -SK_IOC IoC, /* I/O Context */ -SK_SENSOR *pSen) /* Sensor to be read */ -{ - if (pSen->SenRead != NULL) { - return((*pSen->SenRead)(pAC, IoC, pSen)); - } - else { - return(0); /* no success */ - } -} /* SkI2cReadSensor */ - -/* - * Do the Init state 0 initialization - */ -static int SkI2cInit0( -SK_AC *pAC) /* Adapter Context */ -{ - int i; - - /* Begin with first sensor */ - pAC->I2c.CurrSens = 0; - - /* Begin with timeout control for state machine */ - pAC->I2c.TimerMode = SK_TIMER_WATCH_SM; - - /* Set sensor number to zero */ - pAC->I2c.MaxSens = 0; - -#ifndef SK_DIAG - /* Initialize Number of Dummy Reads */ - pAC->I2c.DummyReads = SK_MAX_SENSORS; -#endif - - for (i = 0; i < SK_MAX_SENSORS; i++) { - pAC->I2c.SenTable[i].SenDesc = "unknown"; - pAC->I2c.SenTable[i].SenType = SK_SEN_UNKNOWN; - pAC->I2c.SenTable[i].SenThreErrHigh = 0; - pAC->I2c.SenTable[i].SenThreErrLow = 0; - pAC->I2c.SenTable[i].SenThreWarnHigh = 0; - pAC->I2c.SenTable[i].SenThreWarnLow = 0; - pAC->I2c.SenTable[i].SenReg = LM80_FAN2_IN; - pAC->I2c.SenTable[i].SenInit = SK_SEN_DYN_INIT_NONE; - pAC->I2c.SenTable[i].SenValue = 0; - pAC->I2c.SenTable[i].SenErrFlag = SK_SEN_ERR_NOT_PRESENT; - pAC->I2c.SenTable[i].SenErrCts = 0; - pAC->I2c.SenTable[i].SenBegErrTS = 0; - pAC->I2c.SenTable[i].SenState = SK_SEN_IDLE; - pAC->I2c.SenTable[i].SenRead = NULL; - pAC->I2c.SenTable[i].SenDev = 0; - } - - /* Now we are "INIT data"ed */ - pAC->I2c.InitLevel = SK_INIT_DATA; - return(0); -} /* SkI2cInit0*/ - - -/* - * Do the init state 1 initialization - * - * initialize the following register of the LM80: - * Configuration register: - * - START, noINT, activeLOW, noINT#Clear, noRESET, noCI, noGPO#, noINIT - * - * Interrupt Mask Register 1: - * - all interrupts are Disabled (0xff) - * - * Interrupt Mask Register 2: - * - all interrupts are Disabled (0xff) Interrupt modi doesn't matter. - * - * Fan Divisor/RST_OUT register: - * - Divisors set to 1 (bits 00), all others 0s. - * - * OS# Configuration/Temperature resolution Register: - * - all 0s - * - */ -static int SkI2cInit1( -SK_AC *pAC, /* Adapter Context */ -SK_IOC IoC) /* I/O Context */ -{ - int i; - SK_U8 I2cSwCtrl; - SK_GEPORT *pPrt; /* GIni Port struct pointer */ - - if (pAC->I2c.InitLevel != SK_INIT_DATA) { - /* ReInit not needed in I2C module */ - return(0); - } - - /* Set the Direction of I2C-Data Pin to IN */ - SK_I2C_CLR_BIT(IoC, I2C_DATA_DIR | I2C_DATA); - /* Check for 32-Bit Yukon with Low at I2C-Data Pin */ - SK_I2C_GET_SW(IoC, &I2cSwCtrl); - - if ((I2cSwCtrl & I2C_DATA) == 0) { - /* this is a 32-Bit board */ - pAC->GIni.GIYukon32Bit = SK_TRUE; - return(0); - } - - /* Check for 64 Bit Yukon without sensors */ - if (SkI2cWrite(pAC, IoC, 0, LM80_ADDR, I2C_025K_DEV, LM80_CFG, 0) != 0) { - return(0); - } - - (void)SkI2cWrite(pAC, IoC, 0xffUL, LM80_ADDR, I2C_025K_DEV, LM80_IMSK_1, 0); - - (void)SkI2cWrite(pAC, IoC, 0xffUL, LM80_ADDR, I2C_025K_DEV, LM80_IMSK_2, 0); - - (void)SkI2cWrite(pAC, IoC, 0, LM80_ADDR, I2C_025K_DEV, LM80_FAN_CTRL, 0); - - (void)SkI2cWrite(pAC, IoC, 0, LM80_ADDR, I2C_025K_DEV, LM80_TEMP_CTRL, 0); - - (void)SkI2cWrite(pAC, IoC, (SK_U32)LM80_CFG_START, LM80_ADDR, I2C_025K_DEV, - LM80_CFG, 0); - - /* - * MaxSens has to be updated here, because PhyType is not - * set when performing Init Level 0 - */ - pAC->I2c.MaxSens = 5; - - pPrt = &pAC->GIni.GP[0]; - - if (pAC->GIni.GIGenesis) { - if (pPrt->PhyType == SK_PHY_BCOM) { - if (pAC->GIni.GIMacsFound == 1) { - pAC->I2c.MaxSens += 1; - } - else { - pAC->I2c.MaxSens += 3; - } - } - } - else { - pAC->I2c.MaxSens += 3; - } - - for (i = 0; i < pAC->I2c.MaxSens; i++) { - switch (i) { - case 0: - pAC->I2c.SenTable[i].SenDesc = "Temperature"; - pAC->I2c.SenTable[i].SenType = SK_SEN_TEMP; - pAC->I2c.SenTable[i].SenThreErrHigh = SK_SEN_TEMP_HIGH_ERR; - pAC->I2c.SenTable[i].SenThreWarnHigh = SK_SEN_TEMP_HIGH_WARN; - pAC->I2c.SenTable[i].SenThreWarnLow = SK_SEN_TEMP_LOW_WARN; - pAC->I2c.SenTable[i].SenThreErrLow = SK_SEN_TEMP_LOW_ERR; - pAC->I2c.SenTable[i].SenReg = LM80_TEMP_IN; - break; - case 1: - pAC->I2c.SenTable[i].SenDesc = "Voltage PCI"; - pAC->I2c.SenTable[i].SenType = SK_SEN_VOLT; - pAC->I2c.SenTable[i].SenThreErrHigh = SK_SEN_PCI_5V_HIGH_ERR; - pAC->I2c.SenTable[i].SenThreWarnHigh = SK_SEN_PCI_5V_HIGH_WARN; - pAC->I2c.SenTable[i].SenThreWarnLow = SK_SEN_PCI_5V_LOW_WARN; - pAC->I2c.SenTable[i].SenThreErrLow = SK_SEN_PCI_5V_LOW_ERR; - pAC->I2c.SenTable[i].SenReg = LM80_VT0_IN; - break; - case 2: - pAC->I2c.SenTable[i].SenDesc = "Voltage PCI-IO"; - pAC->I2c.SenTable[i].SenType = SK_SEN_VOLT; - pAC->I2c.SenTable[i].SenThreErrHigh = SK_SEN_PCI_IO_5V_HIGH_ERR; - pAC->I2c.SenTable[i].SenThreWarnHigh = SK_SEN_PCI_IO_5V_HIGH_WARN; - pAC->I2c.SenTable[i].SenThreWarnLow = SK_SEN_PCI_IO_3V3_LOW_WARN; - pAC->I2c.SenTable[i].SenThreErrLow = SK_SEN_PCI_IO_3V3_LOW_ERR; - pAC->I2c.SenTable[i].SenReg = LM80_VT1_IN; - pAC->I2c.SenTable[i].SenInit = SK_SEN_DYN_INIT_PCI_IO; - break; - case 3: - pAC->I2c.SenTable[i].SenDesc = "Voltage ASIC"; - pAC->I2c.SenTable[i].SenType = SK_SEN_VOLT; - pAC->I2c.SenTable[i].SenThreErrHigh = SK_SEN_VDD_HIGH_ERR; - pAC->I2c.SenTable[i].SenThreWarnHigh = SK_SEN_VDD_HIGH_WARN; - pAC->I2c.SenTable[i].SenThreWarnLow = SK_SEN_VDD_LOW_WARN; - pAC->I2c.SenTable[i].SenThreErrLow = SK_SEN_VDD_LOW_ERR; - pAC->I2c.SenTable[i].SenReg = LM80_VT2_IN; - break; - case 4: - if (pAC->GIni.GIGenesis) { - if (pPrt->PhyType == SK_PHY_BCOM) { - pAC->I2c.SenTable[i].SenDesc = "Voltage PHY A PLL"; - pAC->I2c.SenTable[i].SenThreErrHigh = SK_SEN_PLL_3V3_HIGH_ERR; - pAC->I2c.SenTable[i].SenThreWarnHigh = SK_SEN_PLL_3V3_HIGH_WARN; - pAC->I2c.SenTable[i].SenThreWarnLow = SK_SEN_PLL_3V3_LOW_WARN; - pAC->I2c.SenTable[i].SenThreErrLow = SK_SEN_PLL_3V3_LOW_ERR; - } - else { - pAC->I2c.SenTable[i].SenDesc = "Voltage PMA"; - pAC->I2c.SenTable[i].SenThreErrHigh = SK_SEN_PLL_3V3_HIGH_ERR; - pAC->I2c.SenTable[i].SenThreWarnHigh = SK_SEN_PLL_3V3_HIGH_WARN; - pAC->I2c.SenTable[i].SenThreWarnLow = SK_SEN_PLL_3V3_LOW_WARN; - pAC->I2c.SenTable[i].SenThreErrLow = SK_SEN_PLL_3V3_LOW_ERR; - } - } - else { - pAC->I2c.SenTable[i].SenDesc = "Voltage VAUX"; - pAC->I2c.SenTable[i].SenThreErrHigh = SK_SEN_VAUX_3V3_HIGH_ERR; - pAC->I2c.SenTable[i].SenThreWarnHigh = SK_SEN_VAUX_3V3_HIGH_WARN; - if (pAC->GIni.GIVauxAvail) { - pAC->I2c.SenTable[i].SenThreWarnLow = SK_SEN_VAUX_3V3_LOW_WARN; - pAC->I2c.SenTable[i].SenThreErrLow = SK_SEN_VAUX_3V3_LOW_ERR; - } - else { - pAC->I2c.SenTable[i].SenThreErrLow = SK_SEN_VAUX_0V_WARN_ERR; - pAC->I2c.SenTable[i].SenThreWarnLow = SK_SEN_VAUX_0V_WARN_ERR; - } - } - pAC->I2c.SenTable[i].SenType = SK_SEN_VOLT; - pAC->I2c.SenTable[i].SenReg = LM80_VT3_IN; - break; - case 5: - if (pAC->GIni.GIGenesis) { - pAC->I2c.SenTable[i].SenDesc = "Voltage PHY 2V5"; - pAC->I2c.SenTable[i].SenThreErrHigh = SK_SEN_PHY_2V5_HIGH_ERR; - pAC->I2c.SenTable[i].SenThreWarnHigh = SK_SEN_PHY_2V5_HIGH_WARN; - pAC->I2c.SenTable[i].SenThreWarnLow = SK_SEN_PHY_2V5_LOW_WARN; - pAC->I2c.SenTable[i].SenThreErrLow = SK_SEN_PHY_2V5_LOW_ERR; - } - else { - pAC->I2c.SenTable[i].SenDesc = "Voltage Core 1V5"; - pAC->I2c.SenTable[i].SenThreErrHigh = SK_SEN_CORE_1V5_HIGH_ERR; - pAC->I2c.SenTable[i].SenThreWarnHigh = SK_SEN_CORE_1V5_HIGH_WARN; - pAC->I2c.SenTable[i].SenThreWarnLow = SK_SEN_CORE_1V5_LOW_WARN; - pAC->I2c.SenTable[i].SenThreErrLow = SK_SEN_CORE_1V5_LOW_ERR; - } - pAC->I2c.SenTable[i].SenType = SK_SEN_VOLT; - pAC->I2c.SenTable[i].SenReg = LM80_VT4_IN; - break; - case 6: - if (pAC->GIni.GIGenesis) { - pAC->I2c.SenTable[i].SenDesc = "Voltage PHY B PLL"; - } - else { - pAC->I2c.SenTable[i].SenDesc = "Voltage PHY 3V3"; - } - pAC->I2c.SenTable[i].SenType = SK_SEN_VOLT; - pAC->I2c.SenTable[i].SenThreErrHigh = SK_SEN_PLL_3V3_HIGH_ERR; - pAC->I2c.SenTable[i].SenThreWarnHigh = SK_SEN_PLL_3V3_HIGH_WARN; - pAC->I2c.SenTable[i].SenThreWarnLow = SK_SEN_PLL_3V3_LOW_WARN; - pAC->I2c.SenTable[i].SenThreErrLow = SK_SEN_PLL_3V3_LOW_ERR; - pAC->I2c.SenTable[i].SenReg = LM80_VT5_IN; - break; - case 7: - if (pAC->GIni.GIGenesis) { - pAC->I2c.SenTable[i].SenDesc = "Speed Fan"; - pAC->I2c.SenTable[i].SenType = SK_SEN_FAN; - pAC->I2c.SenTable[i].SenThreErrHigh = SK_SEN_FAN_HIGH_ERR; - pAC->I2c.SenTable[i].SenThreWarnHigh = SK_SEN_FAN_HIGH_WARN; - pAC->I2c.SenTable[i].SenThreWarnLow = SK_SEN_FAN_LOW_WARN; - pAC->I2c.SenTable[i].SenThreErrLow = SK_SEN_FAN_LOW_ERR; - pAC->I2c.SenTable[i].SenReg = LM80_FAN2_IN; - } - else { - pAC->I2c.SenTable[i].SenDesc = "Voltage PHY 2V5"; - pAC->I2c.SenTable[i].SenType = SK_SEN_VOLT; - pAC->I2c.SenTable[i].SenThreErrHigh = SK_SEN_PHY_2V5_HIGH_ERR; - pAC->I2c.SenTable[i].SenThreWarnHigh = SK_SEN_PHY_2V5_HIGH_WARN; - pAC->I2c.SenTable[i].SenThreWarnLow = SK_SEN_PHY_2V5_LOW_WARN; - pAC->I2c.SenTable[i].SenThreErrLow = SK_SEN_PHY_2V5_LOW_ERR; - pAC->I2c.SenTable[i].SenReg = LM80_VT6_IN; - } - break; - default: - SK_ERR_LOG(pAC, SK_ERRCL_INIT | SK_ERRCL_SW, - SKERR_I2C_E001, SKERR_I2C_E001MSG); - break; - } - - pAC->I2c.SenTable[i].SenValue = 0; - pAC->I2c.SenTable[i].SenErrFlag = SK_SEN_ERR_OK; - pAC->I2c.SenTable[i].SenErrCts = 0; - pAC->I2c.SenTable[i].SenBegErrTS = 0; - pAC->I2c.SenTable[i].SenState = SK_SEN_IDLE; - pAC->I2c.SenTable[i].SenRead = SkLm80ReadSensor; - pAC->I2c.SenTable[i].SenDev = LM80_ADDR; - } - -#ifndef SK_DIAG - pAC->I2c.DummyReads = pAC->I2c.MaxSens; -#endif /* !SK_DIAG */ - - /* Clear I2C IRQ */ - SK_OUT32(IoC, B2_I2C_IRQ, I2C_CLR_IRQ); - - /* Now we are I/O initialized */ - pAC->I2c.InitLevel = SK_INIT_IO; - return(0); -} /* SkI2cInit1 */ - - -/* - * Init level 2: Start first sensor read. - */ -static int SkI2cInit2( -SK_AC *pAC, /* Adapter Context */ -SK_IOC IoC) /* I/O Context */ -{ - int ReadComplete; - SK_SENSOR *pSen; - - if (pAC->I2c.InitLevel != SK_INIT_IO) { - /* ReInit not needed in I2C module */ - /* Init0 and Init2 not permitted */ - return(0); - } - - pSen = &pAC->I2c.SenTable[pAC->I2c.CurrSens]; - ReadComplete = SkI2cReadSensor(pAC, IoC, pSen); - - if (ReadComplete) { - SK_ERR_LOG(pAC, SK_ERRCL_INIT, SKERR_I2C_E008, SKERR_I2C_E008MSG); - } - - /* Now we are correctly initialized */ - pAC->I2c.InitLevel = SK_INIT_RUN; - - return(0); -} /* SkI2cInit2*/ - - -/* - * Initialize I2C devices - * - * Get the first voltage value and discard it. - * Go into temperature read mode. A default pointer is not set. - * - * The things to be done depend on the init level in the parameter list: - * Level 0: - * Initialize only the data structures. Do NOT access hardware. - * Level 1: - * Initialize hardware through SK_IN / SK_OUT commands. Do NOT use interrupts. - * Level 2: - * Everything is possible. Interrupts may be used from now on. - * - * return: - * 0 = success - * other = error. - */ -int SkI2cInit( -SK_AC *pAC, /* Adapter Context */ -SK_IOC IoC, /* I/O Context needed in levels 1 and 2 */ -int Level) /* Init Level */ -{ - - switch (Level) { - case SK_INIT_DATA: - return(SkI2cInit0(pAC)); - case SK_INIT_IO: - return(SkI2cInit1(pAC, IoC)); - case SK_INIT_RUN: - return(SkI2cInit2(pAC, IoC)); - default: - break; - } - - return(0); -} /* SkI2cInit */ - - -#ifndef SK_DIAG - -/* - * Interrupt service function for the I2C Interface - * - * Clears the Interrupt source - * - * Reads the register and check it for sending a trap. - * - * Starts the timer if necessary. - */ -void SkI2cIsr( -SK_AC *pAC, /* Adapter Context */ -SK_IOC IoC) /* I/O Context */ -{ - SK_EVPARA Para; - - /* Clear I2C IRQ */ - SK_OUT32(IoC, B2_I2C_IRQ, I2C_CLR_IRQ); - - Para.Para64 = 0; - SkEventQueue(pAC, SKGE_I2C, SK_I2CEV_IRQ, Para); -} /* SkI2cIsr */ - - -/* - * Check this sensors Value against the threshold and send events. - */ -static void SkI2cCheckSensor( -SK_AC *pAC, /* Adapter Context */ -SK_SENSOR *pSen) -{ - SK_EVPARA ParaLocal; - SK_BOOL TooHigh; /* Is sensor too high? */ - SK_BOOL TooLow; /* Is sensor too low? */ - SK_U64 CurrTime; /* Current Time */ - SK_BOOL DoTrapSend; /* We need to send a trap */ - SK_BOOL DoErrLog; /* We need to log the error */ - SK_BOOL IsError; /* We need to log the error */ - - /* Check Dummy Reads first */ - if (pAC->I2c.DummyReads > 0) { - pAC->I2c.DummyReads--; - return; - } - - /* Get the current time */ - CurrTime = SkOsGetTime(pAC); - - /* Set para to the most useful setting: The current sensor. */ - ParaLocal.Para64 = (SK_U64)pAC->I2c.CurrSens; - - /* Check the Value against the thresholds. First: Error Thresholds */ - TooHigh = (pSen->SenValue > pSen->SenThreErrHigh); - TooLow = (pSen->SenValue < pSen->SenThreErrLow); - - IsError = SK_FALSE; - if (TooHigh || TooLow) { - /* Error condition is satisfied */ - DoTrapSend = SK_TRUE; - DoErrLog = SK_TRUE; - - /* Now error condition is satisfied */ - IsError = SK_TRUE; - - if (pSen->SenErrFlag == SK_SEN_ERR_ERR) { - /* This state is the former one */ - - /* So check first whether we have to send a trap */ - if (pSen->SenLastErrTrapTS + SK_SEN_ERR_TR_HOLD > - CurrTime) { - /* - * Do NOT send the Trap. The hold back time - * has to run out first. - */ - DoTrapSend = SK_FALSE; - } - - /* Check now whether we have to log an Error */ - if (pSen->SenLastErrLogTS + SK_SEN_ERR_LOG_HOLD > - CurrTime) { - /* - * Do NOT log the error. The hold back time - * has to run out first. - */ - DoErrLog = SK_FALSE; - } - } - else { - /* We came from a different state -> Set Begin Time Stamp */ - pSen->SenBegErrTS = CurrTime; - pSen->SenErrFlag = SK_SEN_ERR_ERR; - } - - if (DoTrapSend) { - /* Set current Time */ - pSen->SenLastErrTrapTS = CurrTime; - pSen->SenErrCts++; - - /* Queue PNMI Event */ - SkEventQueue(pAC, SKGE_PNMI, (TooHigh ? - SK_PNMI_EVT_SEN_ERR_UPP : - SK_PNMI_EVT_SEN_ERR_LOW), - ParaLocal); - } - - if (DoErrLog) { - /* Set current Time */ - pSen->SenLastErrLogTS = CurrTime; - - if (pSen->SenType == SK_SEN_TEMP) { - SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_I2C_E011, SKERR_I2C_E011MSG); - } - else if (pSen->SenType == SK_SEN_VOLT) { - SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_I2C_E012, SKERR_I2C_E012MSG); - } - else { - SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_I2C_E015, SKERR_I2C_E015MSG); - } - } - } - - /* Check the Value against the thresholds */ - /* 2nd: Warning thresholds */ - TooHigh = (pSen->SenValue > pSen->SenThreWarnHigh); - TooLow = (pSen->SenValue < pSen->SenThreWarnLow); - - if (!IsError && (TooHigh || TooLow)) { - /* Error condition is satisfied */ - DoTrapSend = SK_TRUE; - DoErrLog = SK_TRUE; - - if (pSen->SenErrFlag == SK_SEN_ERR_WARN) { - /* This state is the former one */ - - /* So check first whether we have to send a trap */ - if (pSen->SenLastWarnTrapTS + SK_SEN_WARN_TR_HOLD > CurrTime) { - /* - * Do NOT send the Trap. The hold back time - * has to run out first. - */ - DoTrapSend = SK_FALSE; - } - - /* Check now whether we have to log an Error */ - if (pSen->SenLastWarnLogTS + SK_SEN_WARN_LOG_HOLD > CurrTime) { - /* - * Do NOT log the error. The hold back time - * has to run out first. - */ - DoErrLog = SK_FALSE; - } - } - else { - /* We came from a different state -> Set Begin Time Stamp */ - pSen->SenBegWarnTS = CurrTime; - pSen->SenErrFlag = SK_SEN_ERR_WARN; - } - - if (DoTrapSend) { - /* Set current Time */ - pSen->SenLastWarnTrapTS = CurrTime; - pSen->SenWarnCts++; - - /* Queue PNMI Event */ - SkEventQueue(pAC, SKGE_PNMI, (TooHigh ? - SK_PNMI_EVT_SEN_WAR_UPP : - SK_PNMI_EVT_SEN_WAR_LOW), - ParaLocal); - } - - if (DoErrLog) { - /* Set current Time */ - pSen->SenLastWarnLogTS = CurrTime; - - if (pSen->SenType == SK_SEN_TEMP) { - SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_I2C_E009, SKERR_I2C_E009MSG); - } - else if (pSen->SenType == SK_SEN_VOLT) { - SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_I2C_E010, SKERR_I2C_E010MSG); - } - else { - SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_I2C_E014, SKERR_I2C_E014MSG); - } - } - } - - /* Check for NO error at all */ - if (!IsError && !TooHigh && !TooLow) { - /* Set o.k. Status if no error and no warning condition */ - pSen->SenErrFlag = SK_SEN_ERR_OK; - } - - /* End of check against the thresholds */ - - /* Bug fix AF: 16.Aug.2001: Correct the init base - * of LM80 sensor. - */ - if (pSen->SenInit == SK_SEN_DYN_INIT_PCI_IO) { - - pSen->SenInit = SK_SEN_DYN_INIT_NONE; - - if (pSen->SenValue > SK_SEN_PCI_IO_RANGE_LIMITER) { - /* 5V PCI-IO Voltage */ - pSen->SenThreWarnLow = SK_SEN_PCI_IO_5V_LOW_WARN; - pSen->SenThreErrLow = SK_SEN_PCI_IO_5V_LOW_ERR; - } - else { - /* 3.3V PCI-IO Voltage */ - pSen->SenThreWarnHigh = SK_SEN_PCI_IO_3V3_HIGH_WARN; - pSen->SenThreErrHigh = SK_SEN_PCI_IO_3V3_HIGH_ERR; - } - } - -#ifdef TEST_ONLY - /* Dynamic thresholds also for VAUX of LM80 sensor */ - if (pSen->SenInit == SK_SEN_DYN_INIT_VAUX) { - - pSen->SenInit = SK_SEN_DYN_INIT_NONE; - - /* 3.3V VAUX Voltage */ - if (pSen->SenValue > SK_SEN_VAUX_RANGE_LIMITER) { - pSen->SenThreWarnLow = SK_SEN_VAUX_3V3_LOW_WARN; - pSen->SenThreErrLow = SK_SEN_VAUX_3V3_LOW_ERR; - } - /* 0V VAUX Voltage */ - else { - pSen->SenThreWarnHigh = SK_SEN_VAUX_0V_WARN_ERR; - pSen->SenThreErrHigh = SK_SEN_VAUX_0V_WARN_ERR; - } - } - - /* - * Check initialization state: - * The VIO Thresholds need adaption - */ - if (!pSen->SenInit && pSen->SenReg == LM80_VT1_IN && - pSen->SenValue > SK_SEN_WARNLOW2C && - pSen->SenValue < SK_SEN_WARNHIGH2) { - pSen->SenThreErrLow = SK_SEN_ERRLOW2C; - pSen->SenThreWarnLow = SK_SEN_WARNLOW2C; - pSen->SenInit = SK_TRUE; - } - - if (!pSen->SenInit && pSen->SenReg == LM80_VT1_IN && - pSen->SenValue > SK_SEN_WARNLOW2 && - pSen->SenValue < SK_SEN_WARNHIGH2C) { - pSen->SenThreErrHigh = SK_SEN_ERRHIGH2C; - pSen->SenThreWarnHigh = SK_SEN_WARNHIGH2C; - pSen->SenInit = SK_TRUE; - } -#endif - - if (pSen->SenInit != SK_SEN_DYN_INIT_NONE) { - SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_I2C_E013, SKERR_I2C_E013MSG); - } -} /* SkI2cCheckSensor */ - - -/* - * The only Event to be served is the timeout event - * - */ -int SkI2cEvent( -SK_AC *pAC, /* Adapter Context */ -SK_IOC IoC, /* I/O Context */ -SK_U32 Event, /* Module specific Event */ -SK_EVPARA Para) /* Event specific Parameter */ -{ - int ReadComplete; - SK_SENSOR *pSen; - SK_U32 Time; - SK_EVPARA ParaLocal; - int i; - - /* New case: no sensors */ - if (pAC->I2c.MaxSens == 0) { - return(0); - } - - switch (Event) { - case SK_I2CEV_IRQ: - pSen = &pAC->I2c.SenTable[pAC->I2c.CurrSens]; - ReadComplete = SkI2cReadSensor(pAC, IoC, pSen); - - if (ReadComplete) { - /* Check sensor against defined thresholds */ - SkI2cCheckSensor(pAC, pSen); - - /* Increment Current sensor and set appropriate Timeout */ - pAC->I2c.CurrSens++; - if (pAC->I2c.CurrSens >= pAC->I2c.MaxSens) { - pAC->I2c.CurrSens = 0; - Time = SK_I2C_TIM_LONG; - } - else { - Time = SK_I2C_TIM_SHORT; - } - - /* Start Timer */ - ParaLocal.Para64 = (SK_U64)0; - - pAC->I2c.TimerMode = SK_TIMER_NEW_GAUGING; - - SkTimerStart(pAC, IoC, &pAC->I2c.SenTimer, Time, - SKGE_I2C, SK_I2CEV_TIM, ParaLocal); - } - else { - /* Start Timer */ - ParaLocal.Para64 = (SK_U64)0; - - pAC->I2c.TimerMode = SK_TIMER_WATCH_SM; - - SkTimerStart(pAC, IoC, &pAC->I2c.SenTimer, SK_I2C_TIM_WATCH, - SKGE_I2C, SK_I2CEV_TIM, ParaLocal); - } - break; - case SK_I2CEV_TIM: - if (pAC->I2c.TimerMode == SK_TIMER_NEW_GAUGING) { - - ParaLocal.Para64 = (SK_U64)0; - SkTimerStop(pAC, IoC, &pAC->I2c.SenTimer); - - pSen = &pAC->I2c.SenTable[pAC->I2c.CurrSens]; - ReadComplete = SkI2cReadSensor(pAC, IoC, pSen); - - if (ReadComplete) { - /* Check sensor against defined thresholds */ - SkI2cCheckSensor(pAC, pSen); - - /* Increment Current sensor and set appropriate Timeout */ - pAC->I2c.CurrSens++; - if (pAC->I2c.CurrSens == pAC->I2c.MaxSens) { - pAC->I2c.CurrSens = 0; - Time = SK_I2C_TIM_LONG; - } - else { - Time = SK_I2C_TIM_SHORT; - } - - /* Start Timer */ - ParaLocal.Para64 = (SK_U64)0; - - pAC->I2c.TimerMode = SK_TIMER_NEW_GAUGING; - - SkTimerStart(pAC, IoC, &pAC->I2c.SenTimer, Time, - SKGE_I2C, SK_I2CEV_TIM, ParaLocal); - } - } - else { - pSen = &pAC->I2c.SenTable[pAC->I2c.CurrSens]; - pSen->SenErrFlag = SK_SEN_ERR_FAULTY; - SK_I2C_STOP(IoC); - - /* Increment Current sensor and set appropriate Timeout */ - pAC->I2c.CurrSens++; - if (pAC->I2c.CurrSens == pAC->I2c.MaxSens) { - pAC->I2c.CurrSens = 0; - Time = SK_I2C_TIM_LONG; - } - else { - Time = SK_I2C_TIM_SHORT; - } - - /* Start Timer */ - ParaLocal.Para64 = (SK_U64)0; - - pAC->I2c.TimerMode = SK_TIMER_NEW_GAUGING; - - SkTimerStart(pAC, IoC, &pAC->I2c.SenTimer, Time, - SKGE_I2C, SK_I2CEV_TIM, ParaLocal); - } - break; - case SK_I2CEV_CLEAR: - for (i = 0; i < SK_MAX_SENSORS; i++) { - pAC->I2c.SenTable[i].SenErrFlag = SK_SEN_ERR_OK; - pAC->I2c.SenTable[i].SenErrCts = 0; - pAC->I2c.SenTable[i].SenWarnCts = 0; - pAC->I2c.SenTable[i].SenBegErrTS = 0; - pAC->I2c.SenTable[i].SenBegWarnTS = 0; - pAC->I2c.SenTable[i].SenLastErrTrapTS = (SK_U64)0; - pAC->I2c.SenTable[i].SenLastErrLogTS = (SK_U64)0; - pAC->I2c.SenTable[i].SenLastWarnTrapTS = (SK_U64)0; - pAC->I2c.SenTable[i].SenLastWarnLogTS = (SK_U64)0; - } - break; - default: - SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_I2C_E006, SKERR_I2C_E006MSG); - } - - return(0); -} /* SkI2cEvent*/ - -#endif /* !SK_DIAG */ diff -urN linux-2.4.32-600/drivers/net/sk98lin/sklm80.c linux-2.4.32-600-sk98_831/drivers/net/sk98lin/sklm80.c --- linux-2.4.32-600/drivers/net/sk98lin/sklm80.c Sat Mar 20 10:08:19 2004 +++ linux-2.4.32-600-sk98_831/drivers/net/sk98lin/sklm80.c Sun Feb 26 11:12:56 2006 @@ -2,6 +2,8 @@ * * Name: sklm80.c * Project: Gigabit Ethernet Adapters, TWSI-Module + * Version: $Revision: 1.1 $ + * Date: $Date: 2003/12/19 14:02:31 $ * Purpose: Functions to access Voltage and Temperature Sensor (LM80) * ******************************************************************************/ @@ -25,7 +27,7 @@ */ #if (defined(DEBUG) || ((!defined(LINT)) && (!defined(SK_SLIM)))) static const char SysKonnectFileId[] = - "@(#) $Id: sklm80.c,v 1.22 2003/10/20 09:08:21 rschmidt Exp $ (C) Marvell. "; + "@(#) $Id: sklm80.c,v 1.1 2003/12/19 14:02:31 mschmid Exp $ (C) Marvell. "; #endif #include "h/skdrv1st.h" /* Driver Specific Definitions */ @@ -109,12 +111,12 @@ /* * read a sensors value (LM80 specific) * - * This function reads a sensors value from the I2C sensor chip LM80. + * This function reads a sensors value from the TWSI sensor chip LM80. * The sensor is defined by its index into the sensors database in the struct * pAC points to. * * Returns 1 if the read is completed - * 0 if the read must be continued (I2C Bus still allocated) + * 0 if the read must be continued (TWSI Bus still allocated) */ int SkLm80ReadSensor( SK_AC *pAC, /* Adapter Context */ diff -urN linux-2.4.32-600/drivers/net/sk98lin/skproc.c linux-2.4.32-600-sk98_831/drivers/net/sk98lin/skproc.c --- linux-2.4.32-600/drivers/net/sk98lin/skproc.c Sat Mar 20 10:08:19 2004 +++ linux-2.4.32-600-sk98_831/drivers/net/sk98lin/skproc.c Sun Feb 26 11:12:56 2006 @@ -2,26 +2,33 @@ * * Name: skproc.c * Project: GEnesis, PCI Gigabit Ethernet Adapter - * Purpose: Funktions to display statictic data + * Version: $Revision: 1.14.2.4 $ + * Date: $Date: 2005/05/23 13:47:33 $ + * Purpose: Functions to display statictic data * ******************************************************************************/ /****************************************************************************** * * (C)Copyright 1998-2002 SysKonnect GmbH. - * (C)Copyright 2002-2003 Marvell. + * (C)Copyright 2002-2005 Marvell. + * + * Driver for Marvell Yukon/2 chipset and SysKonnect Gigabit Ethernet + * Server Adapters. + * + * Author: Ralph Roesler (rroesler@syskonnect.de) + * Mirko Lindner (mlindner@syskonnect.de) + * + * Address all question to: linux@syskonnect.de * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * - * Created 22-Nov-2000 - * Author: Mirko Lindner (mlindner@syskonnect.de) - * * The information in this file is provided "AS IS" without warranty. * - ******************************************************************************/ + *****************************************************************************/ #include @@ -30,9 +37,16 @@ #include "h/skversion.h" extern struct SK_NET_DEVICE *SkGeRootDev; + +/****************************************************************************** + * + * Local Function Prototypes and Local Variables + * + *****************************************************************************/ + static int sk_proc_print(void *writePtr, char *format, ...); static void sk_gen_browse(void *buffer); -int len; +static int len; struct proc_dir_entry *file = NULL; @@ -41,19 +55,21 @@ * sk_proc_read - show proc information of a particular adapter * * Description: - * This function fills the proc entry with statistic data about - * the ethernet device. It invokes the generic sk_gen_browse() to - * print out all items one per one. + * This function fills the proc entry with statistic data about + * the ethernet device. It invokes the generic sk_gen_browse() to + * print out all items one per one. * - * Returns: number of bytes written + * Returns: + * the number of bytes written * */ -int sk_proc_read(char *buffer, - char **buffer_location, - off_t offset, - int buffer_length, - int *eof, - void *data) +int sk_proc_read( +char *buffer, /* the buffer holding the display results */ +char **buffer_location, /* the buffer location */ +off_t offset, /* additional offset */ +int buffer_length, /* total buffer length */ +int *eof, /* End Of File (EOF) indication */ +void *data) /* the data pointer */ { void *castedBuffer = (void *) buffer; file = (struct proc_dir_entry*) data; @@ -77,16 +93,18 @@ * sk_gen_browse -generic print "summaries" entry * * Description: - * This function fills the proc entry with statistic data about - * the ethernet device. + * This function fills the proc entry with statistic data about + * the ethernet device. * - * Returns: - + * Returns: N/A * */ -static void sk_gen_browse(void *buffer) +static void sk_gen_browse( +void *buffer) /* buffer where the statistics will be stored in */ { struct SK_NET_DEVICE *SkgeProcDev = SkGeRootDev; struct SK_NET_DEVICE *next; + SK_BOOL DisableStatistic = 0; SK_PNMI_STRUCT_DATA *pPnmiStruct; SK_PNMI_STAT *pPnmiStat; unsigned long Flags; @@ -94,6 +112,7 @@ DEV_NET *pNet; SK_AC *pAC; char sens_msg[50]; + int card_type; int MaxSecurityCount = 0; int t; int i; @@ -116,7 +135,7 @@ spin_lock_irqsave(&pAC->SlowPathLock, Flags); Size = SK_PNMI_STRUCT_SIZE; -#ifdef SK_DIAG_SUPPORT + DisableStatistic = 0; if (pAC->BoardLevel == SK_INIT_DATA) { SK_MEMCPY(&(pAC->PnmiStruct), &(pAC->PnmiBackup), sizeof(SK_PNMI_STRUCT_DATA)); if (pAC->DiagModeActive == DIAG_NOTACTIVE) { @@ -125,13 +144,13 @@ } else { SkPnmiGetStruct(pAC, pAC->IoBase, pPnmiStruct, &Size, t-1); } -#else - SkPnmiGetStruct(pAC, pAC->IoBase, - pPnmiStruct, &Size, t-1); -#endif spin_unlock_irqrestore(&pAC->SlowPathLock, Flags); - if (strcmp(pAC->dev[t-1]->name, file->name) == 0) { + if (!pAC->GIni.GIYukon32Bit) + card_type = 64; + else + card_type = 32; + pPnmiStat = &pPnmiStruct->Stat[0]; len = sk_proc_print(buffer, "\nDetailed statistic for device %s\n", @@ -143,6 +162,17 @@ len += sk_proc_print(buffer, "\nBoard statistics\n\n"); len += sk_proc_print(buffer, + "Card name %s\n", + pAC->DeviceStr); + len += sk_proc_print(buffer, + "Vendor/Device ID %x/%x\n", + pAC->PciDev->vendor, + pAC->PciDev->device); + len += sk_proc_print(buffer, + "Card type (Bit) %d\n", + card_type); + + len += sk_proc_print(buffer, "Active Port %c\n", 'A' + pAC->Rlmt.Net[t-1].Port[pAC->Rlmt. Net[t-1].PrefPort]->PortNumber); @@ -151,177 +181,239 @@ 'A' + pAC->Rlmt.Net[t-1].Port[pAC->Rlmt. Net[t-1].PrefPort]->PortNumber); - len += sk_proc_print(buffer, - "Bus speed (MHz) %d\n", - pPnmiStruct->BusSpeed); - - len += sk_proc_print(buffer, - "Bus width (Bit) %d\n", - pPnmiStruct->BusWidth); - len += sk_proc_print(buffer, - "Driver version %s\n", - VER_STRING); - len += sk_proc_print(buffer, - "Hardware revision v%d.%d\n", - (pAC->GIni.GIPciHwRev >> 4) & 0x0F, - pAC->GIni.GIPciHwRev & 0x0F); - - /* Print sensor informations */ - for (i=0; i < pAC->I2c.MaxSens; i ++) { - /* Check type */ - switch (pAC->I2c.SenTable[i].SenType) { - case 1: - strcpy(sens_msg, pAC->I2c.SenTable[i].SenDesc); - strcat(sens_msg, " (C)"); - len += sk_proc_print(buffer, - "%-25s %d.%02d\n", - sens_msg, - pAC->I2c.SenTable[i].SenValue / 10, - pAC->I2c.SenTable[i].SenValue % 10); + if (pAC->DynIrqModInfo.IntModTypeSelect == C_INT_MOD_STATIC) { + len += sk_proc_print(buffer, + "Interrupt Moderation static (%d ints/sec)\n", + pAC->DynIrqModInfo.MaxModIntsPerSec); + } else if (pAC->DynIrqModInfo.IntModTypeSelect == C_INT_MOD_DYNAMIC) { + len += sk_proc_print(buffer, + "Interrupt Moderation dynamic (%d ints/sec)\n", + pAC->DynIrqModInfo.MaxModIntsPerSec); + } else { + len += sk_proc_print(buffer, + "Interrupt Moderation disabled\n"); + } - strcpy(sens_msg, pAC->I2c.SenTable[i].SenDesc); - strcat(sens_msg, " (F)"); + if (pAC->GIni.GIPciBus == SK_PEX_BUS) { + len += sk_proc_print(buffer, + "Bus type PCI-Express\n"); + len += sk_proc_print(buffer, + "Bus width (Lanes) %d\n", + pAC->GIni.GIPexWidth); + } else { + if (pAC->GIni.GIPciBus == SK_PCIX_BUS) { len += sk_proc_print(buffer, - "%-25s %d.%02d\n", - sens_msg, - ((((pAC->I2c.SenTable[i].SenValue) - *10)*9)/5 + 3200)/100, - ((((pAC->I2c.SenTable[i].SenValue) - *10)*9)/5 + 3200) % 10); - break; - case 2: - strcpy(sens_msg, pAC->I2c.SenTable[i].SenDesc); - strcat(sens_msg, " (V)"); + "Bus type PCI-X\n"); + if (pAC->GIni.GIPciMode == PCI_OS_SPD_X133) { + len += sk_proc_print(buffer, + "Bus speed (MHz) 133\n"); + } else if (pAC->GIni.GIPciMode == PCI_OS_SPD_X100) { + len += sk_proc_print(buffer, + "Bus speed (MHz) 100\n"); + } else if (pAC->GIni.GIPciMode == PCI_OS_SPD_X66) { + len += sk_proc_print(buffer, + "Bus speed (MHz) 66\n"); + } else { + len += sk_proc_print(buffer, + "Bus speed (MHz) 33\n"); + } + } else { len += sk_proc_print(buffer, - "%-25s %d.%03d\n", - sens_msg, - pAC->I2c.SenTable[i].SenValue / 1000, - pAC->I2c.SenTable[i].SenValue % 1000); - break; - case 3: - strcpy(sens_msg, pAC->I2c.SenTable[i].SenDesc); - strcat(sens_msg, " (rpm)"); + "Bus type PCI\n"); len += sk_proc_print(buffer, - "%-25s %d\n", - sens_msg, - pAC->I2c.SenTable[i].SenValue); - break; - default: - break; + "Bus speed (MHz) %d\n", + pPnmiStruct->BusSpeed); } + len += sk_proc_print(buffer, + "Bus width (Bit) %d\n", + pPnmiStruct->BusWidth); } - - /*Receive statistics */ - len += sk_proc_print(buffer, - "\nReceive statistics\n\n"); len += sk_proc_print(buffer, - "Received bytes %Lu\n", - (unsigned long long) pPnmiStat->StatRxOctetsOkCts); - len += sk_proc_print(buffer, - "Received packets %Lu\n", - (unsigned long long) pPnmiStat->StatRxOkCts); -#if 0 - if (pAC->GIni.GP[0].PhyType == SK_PHY_XMAC && - pAC->HWRevision < 12) { - pPnmiStruct->InErrorsCts = pPnmiStruct->InErrorsCts - - pPnmiStat->StatRxShortsCts; - pPnmiStat->StatRxShortsCts = 0; - } -#endif - if (pNet->Mtu > 1500) - pPnmiStruct->InErrorsCts = pPnmiStruct->InErrorsCts - - pPnmiStat->StatRxTooLongCts; - - len += sk_proc_print(buffer, - "Receive errors %Lu\n", - (unsigned long long) pPnmiStruct->InErrorsCts); - len += sk_proc_print(buffer, - "Receive dropped %Lu\n", - (unsigned long long) pPnmiStruct->RxNoBufCts); + "Driver version %s (%s)\n", + VER_STRING, PATCHLEVEL); len += sk_proc_print(buffer, - "Received multicast %Lu\n", - (unsigned long long) pPnmiStat->StatRxMulticastOkCts); + "Driver release date %s\n", + pAC->Pnmi.pDriverReleaseDate); len += sk_proc_print(buffer, - "Receive error types\n"); - len += sk_proc_print(buffer, - " length %Lu\n", - (unsigned long long) pPnmiStat->StatRxRuntCts); - len += sk_proc_print(buffer, - " buffer overflow %Lu\n", - (unsigned long long) pPnmiStat->StatRxFifoOverflowCts); - len += sk_proc_print(buffer, - " bad crc %Lu\n", - (unsigned long long) pPnmiStat->StatRxFcsCts); - len += sk_proc_print(buffer, - " framing %Lu\n", - (unsigned long long) pPnmiStat->StatRxFramingCts); - len += sk_proc_print(buffer, - " missed frames %Lu\n", - (unsigned long long) pPnmiStat->StatRxMissedCts); - - if (pNet->Mtu > 1500) - pPnmiStat->StatRxTooLongCts = 0; + "Hardware revision v%d.%d\n", + (pAC->GIni.GIPciHwRev >> 4) & 0x0F, + pAC->GIni.GIPciHwRev & 0x0F); - len += sk_proc_print(buffer, - " too long %Lu\n", - (unsigned long long) pPnmiStat->StatRxTooLongCts); - len += sk_proc_print(buffer, - " carrier extension %Lu\n", - (unsigned long long) pPnmiStat->StatRxCextCts); - len += sk_proc_print(buffer, - " too short %Lu\n", - (unsigned long long) pPnmiStat->StatRxShortsCts); - len += sk_proc_print(buffer, - " symbol %Lu\n", - (unsigned long long) pPnmiStat->StatRxSymbolCts); - len += sk_proc_print(buffer, - " LLC MAC size %Lu\n", - (unsigned long long) pPnmiStat->StatRxIRLengthCts); - len += sk_proc_print(buffer, - " carrier event %Lu\n", - (unsigned long long) pPnmiStat->StatRxCarrierCts); - len += sk_proc_print(buffer, - " jabber %Lu\n", - (unsigned long long) pPnmiStat->StatRxJabberCts); + if (!netif_running(pAC->dev[t-1])) { + len += sk_proc_print(buffer, + "\n Device %s is down.\n" + " Therefore no statistics are available.\n" + " After bringing the device up (ifconfig)" + " statistics will\n" + " be displayed.\n", + pAC->dev[t-1]->name); + DisableStatistic = 1; + } + /* Display only if statistic info available */ + /* Print sensor informations */ + if (!DisableStatistic) { + for (i=0; i < pAC->I2c.MaxSens; i ++) { + /* Check type */ + switch (pAC->I2c.SenTable[i].SenType) { + case 1: + strcpy(sens_msg, pAC->I2c.SenTable[i].SenDesc); + strcat(sens_msg, " (C)"); + len += sk_proc_print(buffer, + "%-25s %d.%02d\n", + sens_msg, + pAC->I2c.SenTable[i].SenValue / 10, + pAC->I2c.SenTable[i].SenValue % + 10); + + strcpy(sens_msg, pAC->I2c.SenTable[i].SenDesc); + strcat(sens_msg, " (F)"); + len += sk_proc_print(buffer, + "%-25s %d.%02d\n", + sens_msg, + ((((pAC->I2c.SenTable[i].SenValue) + *10)*9)/5 + 3200)/100, + ((((pAC->I2c.SenTable[i].SenValue) + *10)*9)/5 + 3200) % 10); + break; + case 2: + strcpy(sens_msg, pAC->I2c.SenTable[i].SenDesc); + strcat(sens_msg, " (V)"); + len += sk_proc_print(buffer, + "%-25s %d.%03d\n", + sens_msg, + pAC->I2c.SenTable[i].SenValue / 1000, + pAC->I2c.SenTable[i].SenValue % 1000); + break; + case 3: + strcpy(sens_msg, pAC->I2c.SenTable[i].SenDesc); + strcat(sens_msg, " (rpm)"); + len += sk_proc_print(buffer, + "%-25s %d\n", + sens_msg, + pAC->I2c.SenTable[i].SenValue); + break; + default: + break; + } + } + + /*Receive statistics */ + len += sk_proc_print(buffer, + "\nReceive statistics\n\n"); + + len += sk_proc_print(buffer, + "Received bytes %Lu\n", + (unsigned long long) pPnmiStat->StatRxOctetsOkCts); + len += sk_proc_print(buffer, + "Received packets %Lu\n", + (unsigned long long) pPnmiStat->StatRxOkCts); +#if 0 + if (pAC->GIni.GP[0].PhyType == SK_PHY_XMAC && + pAC->HWRevision < 12) { + pPnmiStruct->InErrorsCts = pPnmiStruct->InErrorsCts - + pPnmiStat->StatRxShortsCts; + pPnmiStat->StatRxShortsCts = 0; + } +#endif + if (pAC->dev[t-1]->mtu > 1500) + pPnmiStruct->InErrorsCts = pPnmiStruct->InErrorsCts - + pPnmiStat->StatRxTooLongCts; + + len += sk_proc_print(buffer, + "Receive errors %Lu\n", + (unsigned long long) pPnmiStruct->InErrorsCts); + len += sk_proc_print(buffer, + "Receive dropped %Lu\n", + (unsigned long long) pPnmiStruct->RxNoBufCts); + len += sk_proc_print(buffer, + "Received multicast %Lu\n", + (unsigned long long) pPnmiStat->StatRxMulticastOkCts); +#ifdef ADVANCED_STATISTIC_OUTPUT + len += sk_proc_print(buffer, + "Receive error types\n"); + len += sk_proc_print(buffer, + " length %Lu\n", + (unsigned long long) pPnmiStat->StatRxRuntCts); + len += sk_proc_print(buffer, + " buffer overflow %Lu\n", + (unsigned long long) pPnmiStat->StatRxFifoOverflowCts); + len += sk_proc_print(buffer, + " bad crc %Lu\n", + (unsigned long long) pPnmiStat->StatRxFcsCts); + len += sk_proc_print(buffer, + " framing %Lu\n", + (unsigned long long) pPnmiStat->StatRxFramingCts); + len += sk_proc_print(buffer, + " missed frames %Lu\n", + (unsigned long long) pPnmiStat->StatRxMissedCts); + + if (pAC->dev[t-1]->mtu > 1500) + pPnmiStat->StatRxTooLongCts = 0; + + len += sk_proc_print(buffer, + " too long %Lu\n", + (unsigned long long) pPnmiStat->StatRxTooLongCts); + len += sk_proc_print(buffer, + " carrier extension %Lu\n", + (unsigned long long) pPnmiStat->StatRxCextCts); + len += sk_proc_print(buffer, + " too short %Lu\n", + (unsigned long long) pPnmiStat->StatRxShortsCts); + len += sk_proc_print(buffer, + " symbol %Lu\n", + (unsigned long long) pPnmiStat->StatRxSymbolCts); + len += sk_proc_print(buffer, + " LLC MAC size %Lu\n", + (unsigned long long) pPnmiStat->StatRxIRLengthCts); + len += sk_proc_print(buffer, + " carrier event %Lu\n", + (unsigned long long) pPnmiStat->StatRxCarrierCts); + len += sk_proc_print(buffer, + " jabber %Lu\n", + (unsigned long long) pPnmiStat->StatRxJabberCts); +#endif - /*Transmit statistics */ - len += sk_proc_print(buffer, - "\nTransmit statistics\n\n"); + /*Transmit statistics */ + len += sk_proc_print(buffer, + "\nTransmit statistics\n\n"); - len += sk_proc_print(buffer, - "Transmited bytes %Lu\n", - (unsigned long long) pPnmiStat->StatTxOctetsOkCts); - len += sk_proc_print(buffer, - "Transmited packets %Lu\n", - (unsigned long long) pPnmiStat->StatTxOkCts); - len += sk_proc_print(buffer, - "Transmit errors %Lu\n", - (unsigned long long) pPnmiStat->StatTxSingleCollisionCts); - len += sk_proc_print(buffer, - "Transmit dropped %Lu\n", - (unsigned long long) pPnmiStruct->TxNoBufCts); - len += sk_proc_print(buffer, - "Transmit collisions %Lu\n", - (unsigned long long) pPnmiStat->StatTxSingleCollisionCts); - len += sk_proc_print(buffer, - "Transmit error types\n"); - len += sk_proc_print(buffer, - " excessive collision %ld\n", - pAC->stats.tx_aborted_errors); - len += sk_proc_print(buffer, - " carrier %Lu\n", - (unsigned long long) pPnmiStat->StatTxCarrierCts); - len += sk_proc_print(buffer, - " fifo underrun %Lu\n", - (unsigned long long) pPnmiStat->StatTxFifoUnderrunCts); - len += sk_proc_print(buffer, - " heartbeat %Lu\n", - (unsigned long long) pPnmiStat->StatTxCarrierCts); - len += sk_proc_print(buffer, - " window %ld\n", - pAC->stats.tx_window_errors); + len += sk_proc_print(buffer, + "Transmitted bytes %Lu\n", + (unsigned long long) pPnmiStat->StatTxOctetsOkCts); + len += sk_proc_print(buffer, + "Transmitted packets %Lu\n", + (unsigned long long) pPnmiStat->StatTxOkCts); + len += sk_proc_print(buffer, + "Transmit errors %Lu\n", + (unsigned long long) pPnmiStat->StatTxSingleCollisionCts); + len += sk_proc_print(buffer, + "Transmit dropped %Lu\n", + (unsigned long long) pPnmiStruct->TxNoBufCts); + len += sk_proc_print(buffer, + "Transmit collisions %Lu\n", + (unsigned long long) pPnmiStat->StatTxSingleCollisionCts); +#ifdef ADVANCED_STATISTIC_OUTPUT + len += sk_proc_print(buffer, + "Transmit error types\n"); + len += sk_proc_print(buffer, + " excessive collision %ld\n", + pAC->stats.tx_aborted_errors); + len += sk_proc_print(buffer, + " carrier %Lu\n", + (unsigned long long) pPnmiStat->StatTxCarrierCts); + len += sk_proc_print(buffer, + " fifo underrun %Lu\n", + (unsigned long long) pPnmiStat->StatTxFifoUnderrunCts); + len += sk_proc_print(buffer, + " heartbeat %Lu\n", + (unsigned long long) pPnmiStat->StatTxCarrierCts); + len += sk_proc_print(buffer, + " window %ld\n", + pAC->stats.tx_window_errors); +#endif + } /* if (!DisableStatistic) */ } /* if (strcmp(pACname, currDeviceName) == 0) */ } @@ -331,16 +423,20 @@ /***************************************************************************** * - * sk_proc_print -generic line print + * sk_proc_print - generic line print * * Description: - * This function fills the proc entry with statistic data about - * the ethernet device. + * This function fills the proc entry with statistic data about the + * ethernet device. * - * Returns: number of bytes written + * Returns: + * the number of bytes written * */ -static int sk_proc_print(void *writePtr, char *format, ...) +static int sk_proc_print( +void *writePtr, /* the buffer pointer */ +char *format, /* the format of the string */ +...) /* variable list of arguments */ { #define MAX_LEN_SINGLE_LINE 256 char str[MAX_LEN_SINGLE_LINE]; diff -urN linux-2.4.32-600/drivers/net/sk98lin/skqueue.c linux-2.4.32-600-sk98_831/drivers/net/sk98lin/skqueue.c --- linux-2.4.32-600/drivers/net/sk98lin/skqueue.c Sat Mar 20 10:08:19 2004 +++ linux-2.4.32-600-sk98_831/drivers/net/sk98lin/skqueue.c Sun Feb 26 11:12:56 2006 @@ -2,6 +2,8 @@ * * Name: skqueue.c * Project: Gigabit Ethernet Adapters, Event Scheduler Module + * Version: $Revision: 2.3 $ + * Date: $Date: 2004/05/14 13:28:18 $ * Purpose: Management of an event queue. * ******************************************************************************/ @@ -20,12 +22,13 @@ * ******************************************************************************/ + /* * Event queue and dispatcher */ #if (defined(DEBUG) || ((!defined(LINT)) && (!defined(SK_SLIM)))) static const char SysKonnectFileId[] = - "@(#) $Id: skqueue.c,v 1.20 2003/09/16 13:44:00 rschmidt Exp $ (C) Marvell."; + "@(#) $Id: skqueue.c,v 2.3 2004/05/14 13:28:18 malthoff Exp $ (C) Marvell."; #endif #include "h/skdrv1st.h" /* Driver Specific Definitions */ @@ -45,10 +48,16 @@ #define PRINTF(a,b,c) -/* - * init event queue management +/****************************************************************************** * - * Must be called during init level 0. + * SkEventInit() - init event queue management + * + * Description: + * This function initializes event queue management. + * It must be called during init level 0. + * + * Returns: + * nothing */ void SkEventInit( SK_AC *pAC, /* Adapter context */ @@ -64,8 +73,17 @@ } } -/* - * add event to queue +/****************************************************************************** + * + * SkEventQueue() - add event to queue + * + * Description: + * This function adds an event to the event queue. + * At least Init Level 1 is required to queue events, + * but will be scheduled add Init Level 2. + * + * returns: + * nothing */ void SkEventQueue( SK_AC *pAC, /* Adapters context */ @@ -73,26 +91,45 @@ SK_U32 Event, /* Event to be queued */ SK_EVPARA Para) /* Event parameter */ { - pAC->Event.EvPut->Class = Class; - pAC->Event.EvPut->Event = Event; - pAC->Event.EvPut->Para = Para; + + if (pAC->GIni.GILevel == SK_INIT_DATA) { + SK_ERR_LOG(pAC, SK_ERRCL_NORES, SKERR_Q_E003, SKERR_Q_E003MSG); + } + else { + pAC->Event.EvPut->Class = Class; + pAC->Event.EvPut->Event = Event; + pAC->Event.EvPut->Para = Para; - if (++pAC->Event.EvPut == &pAC->Event.EvQueue[SK_MAX_EVENT]) - pAC->Event.EvPut = pAC->Event.EvQueue; + if (++pAC->Event.EvPut == &pAC->Event.EvQueue[SK_MAX_EVENT]) + pAC->Event.EvPut = pAC->Event.EvQueue; - if (pAC->Event.EvPut == pAC->Event.EvGet) { - SK_ERR_LOG(pAC, SK_ERRCL_NORES, SKERR_Q_E001, SKERR_Q_E001MSG); + if (pAC->Event.EvPut == pAC->Event.EvGet) { + SK_ERR_LOG(pAC, SK_ERRCL_NORES, SKERR_Q_E001, SKERR_Q_E001MSG); + } } } -/* - * event dispatcher - * while event queue is not empty - * get event from queue - * send command to state machine - * end - * return error reported by individual Event function - * 0 if no error occured. +/****************************************************************************** + * + * SkEventDispatcher() - Event Dispatcher + * + * Description: + * The event dispatcher performs the following operations: + * o while event queue is not empty + * - get event from queue + * - send event to state machine + * end + * + * CAUTION: + * The event functions MUST report an error if performing a reinitialization + * of the event queue, e.g. performing level Init 0..2 while in dispatcher + * call! + * ANY OTHER return value delays scheduling the other events in the + * queue. In this case the event blocks the queue until + * the error condition is cleared! + * + * Returns: + * The return value error reported by individual event function */ int SkEventDispatcher( SK_AC *pAC, /* Adapters Context */ @@ -102,6 +139,10 @@ SK_U32 Class; int Rtv; + if (pAC->GIni.GILevel != SK_INIT_RUN) { + SK_ERR_LOG(pAC, SK_ERRCL_NORES, SKERR_Q_E005, SKERR_Q_E005MSG); + } + pEv = pAC->Event.EvGet; PRINTF("dispatch get %x put %x\n", pEv, pAC->Event.ev_put); @@ -149,6 +190,11 @@ Rtv = SkFdEvent(pAC, Ioc, pEv->Event, pEv->Para); break; #endif /* SK_USE_LAC_EV */ +#ifdef SK_ASF + case SKGE_ASF : + Rtv = SkAsfEvent(pAC,Ioc,pEv->Event,pEv->Para); + break ; +#endif #ifdef SK_USE_CSUM case SKGE_CSUM : Rtv = SkCsEvent(pAC, Ioc, pEv->Event, pEv->Para); @@ -160,6 +206,20 @@ } if (Rtv != 0) { + /* + * Special Case: See CAUTION statement above. + * We assume the event queue is reset. + */ + if (pAC->Event.EvGet != pAC->Event.EvQueue && + pAC->Event.EvGet != pEv) { + /* + * Create an error log entry if the + * event queue isn't reset. + * In this case it may be blocked. + */ + SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_Q_E004, SKERR_Q_E004MSG); + } + return(Rtv); } diff -urN linux-2.4.32-600/drivers/net/sk98lin/skrlmt.c linux-2.4.32-600-sk98_831/drivers/net/sk98lin/skrlmt.c --- linux-2.4.32-600/drivers/net/sk98lin/skrlmt.c Sat Mar 20 10:08:19 2004 +++ linux-2.4.32-600-sk98_831/drivers/net/sk98lin/skrlmt.c Sun Feb 26 11:12:56 2006 @@ -2,6 +2,8 @@ * * Name: skrlmt.c * Project: GEnesis, PCI Gigabit Ethernet Adapter + * Version: $Revision: 2.3 $ + * Date: $Date: 2005/05/04 09:47:53 $ * Purpose: Manage links on SK-NET Adapters, esp. redundant ones. * ******************************************************************************/ @@ -37,7 +39,7 @@ #ifndef lint static const char SysKonnectFileId[] = - "@(#) $Id: skrlmt.c,v 1.69 2003/04/15 09:39:22 tschilli Exp $ (C) Marvell."; + "@(#) $Id: skrlmt.c,v 2.3 2005/05/04 09:47:53 tschilli Exp $ (C) Marvell."; #endif /* !defined(lint) */ #define __SKRLMT_C @@ -348,7 +350,7 @@ SK_BOOL PhysicalAMacAddressSet; SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_INIT, - ("RLMT Init level %d.\n", Level)) + ("RLMT Init level %d.\n", Level)); switch (Level) { case SK_INIT_DATA: /* Initialize data structures. */ @@ -388,7 +390,7 @@ case SK_INIT_IO: /* GIMacsFound first available here. */ SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_INIT, - ("RLMT: %d MACs were detected.\n", pAC->GIni.GIMacsFound)) + ("RLMT: %d MACs were detected.\n", pAC->GIni.GIMacsFound)); pAC->Rlmt.Net[0].NumPorts = pAC->GIni.GIMacsFound; @@ -510,7 +512,7 @@ } SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, - ("SkRlmtBuildCheckChain.\n")) + ("SkRlmtBuildCheckChain.\n")); NumMacsUp = 0; @@ -556,7 +558,7 @@ SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, ("Port %d checks %d other ports: %2X.\n", i, pAC->Rlmt.Net[NetIdx].Port[i]->PortsChecked, - pAC->Rlmt.Net[NetIdx].Port[i]->PortCheck[0].CheckAddr.a[5])) + pAC->Rlmt.Net[NetIdx].Port[i]->PortCheck[0].CheckAddr.a[5])); } #endif /* DEBUG */ @@ -602,7 +604,7 @@ if ((CheckSrc == 0) || (CheckDest == 0)) { SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_ERR, ("SkRlmtBuildPacket: Invalid %s%saddr.\n", - (CheckSrc == 0 ? "Src" : ""), (CheckDest == 0 ? "Dest" : ""))) + (CheckSrc == 0 ? "Src" : ""), (CheckDest == 0 ? "Dest" : ""))); } #endif @@ -794,7 +796,7 @@ SkEventQueue(pAC, SKGE_DRV, SK_DRV_RLMT_SEND, Para); SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_TX, - ("SkRlmtSend: BPDU Packet on Port %u.\n", PortNumber)) + ("SkRlmtSend: BPDU Packet on Port %u.\n", PortNumber)); } } return; @@ -833,7 +835,7 @@ * Bring it up. */ SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_RX, - ("SkRlmtPacketReceive: Received on PortDown.\n")) + ("SkRlmtPacketReceive: Received on PortDown.\n")); pRPort->PortState = SK_RLMT_PS_GOING_UP; pRPort->GuTimeStamp = SkOsGetTime(pAC); @@ -847,7 +849,7 @@ } /* PortDown && !SuspectTx */ else if (pRPort->CheckingState & SK_RLMT_PCS_RX) { SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_RX, - ("SkRlmtPacketReceive: Stop bringing port down.\n")) + ("SkRlmtPacketReceive: Stop bringing port down.\n")); SkTimerStop(pAC, IoC, &pRPort->DownRxTimer); pRPort->CheckingState &= ~SK_RLMT_PCS_RX; /* pAC->Rlmt.CheckSwitch = SK_TRUE; */ @@ -894,7 +896,7 @@ pRPort = &pAC->Rlmt.Port[PortNumber]; SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_RX, - ("SkRlmtPacketReceive: PortNumber == %d.\n", PortNumber)) + ("SkRlmtPacketReceive: PortNumber == %d.\n", PortNumber)); pRPacket = (SK_RLMT_PACKET*)pMb->pData; pSPacket = (SK_SPTREE_PACKET*)pRPacket; @@ -915,7 +917,7 @@ /* Not sent to current MAC or registered MC address => Trash it. */ SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_RX, - ("SkRlmtPacketReceive: Not for me.\n")) + ("SkRlmtPacketReceive: Not for me.\n")); SkDrvFreeRlmtMbuf(pAC, IoC, pMb); return; @@ -953,7 +955,7 @@ pRPacket->Indicator[5] == SK_RLMT_INDICATOR5 && pRPacket->Indicator[6] == SK_RLMT_INDICATOR6) { SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_RX, - ("SkRlmtPacketReceive: Duplicate MAC Address.\n")) + ("SkRlmtPacketReceive: Duplicate MAC Address.\n")); /* Error Log entry. */ SK_ERR_LOG(pAC, SK_ERRCL_COMM, SKERR_RLMT_E006, SKERR_RLMT_E006_MSG); @@ -961,7 +963,7 @@ else { /* Simply trash it. */ SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_RX, - ("SkRlmtPacketReceive: Sent by me.\n")) + ("SkRlmtPacketReceive: Sent by me.\n")); } SkDrvFreeRlmtMbuf(pAC, IoC, pMb); @@ -1005,7 +1007,7 @@ #endif /* 0 */ SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_RX, - ("SkRlmtPacketReceive: Announce.\n")) + ("SkRlmtPacketReceive: Announce.\n")); SkDrvFreeRlmtMbuf(pAC, IoC, pMb); break; @@ -1013,7 +1015,7 @@ case SK_PACKET_ALIVE: if (pRPacket->SSap & LLC_COMMAND_RESPONSE_BIT) { SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_RX, - ("SkRlmtPacketReceive: Alive Reply.\n")) + ("SkRlmtPacketReceive: Alive Reply.\n")); if (!(pAC->Addr.Port[PortNumber].PromMode & SK_PROM_MODE_LLC) || SK_ADDR_EQUAL( @@ -1044,7 +1046,7 @@ } else { /* Alive Request Packet. */ SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_RX, - ("SkRlmtPacketReceive: Alive Request.\n")) + ("SkRlmtPacketReceive: Alive Request.\n")); pRPort->RxHelloCts++; @@ -1063,7 +1065,7 @@ case SK_PACKET_CHECK_TX: SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_RX, - ("SkRlmtPacketReceive: Check your tx line.\n")) + ("SkRlmtPacketReceive: Check your tx line.\n")); /* A port checking us requests us to check our tx line. */ pRPort->CheckingState |= SK_RLMT_PCS_TX; @@ -1086,7 +1088,7 @@ case SK_PACKET_ADDR_CHANGED: SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_RX, - ("SkRlmtPacketReceive: Address Change.\n")) + ("SkRlmtPacketReceive: Address Change.\n")); /* Build the check chain. */ SkRlmtBuildCheckChain(pAC, pRPort->Net->NetNumber); @@ -1095,7 +1097,7 @@ default: SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_RX, - ("SkRlmtPacketReceive: Unknown RLMT packet.\n")) + ("SkRlmtPacketReceive: Unknown RLMT packet.\n")); /* RA;:;: ??? */ SkDrvFreeRlmtMbuf(pAC, IoC, pMb); @@ -1105,7 +1107,7 @@ pSPacket->Ctrl == SK_RLMT_SPT_CTRL && (pSPacket->SSap & ~LLC_COMMAND_RESPONSE_BIT) == SK_RLMT_SPT_SSAP) { SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_RX, - ("SkRlmtPacketReceive: BPDU Packet.\n")) + ("SkRlmtPacketReceive: BPDU Packet.\n")); /* Spanning Tree packet. */ pRPort->RxSpHelloCts++; @@ -1137,7 +1139,7 @@ pRPort->Root.Id[0], pRPort->Root.Id[1], pRPort->Root.Id[2], pRPort->Root.Id[3], pRPort->Root.Id[4], pRPort->Root.Id[5], - pRPort->Root.Id[6], pRPort->Root.Id[7])) + pRPort->Root.Id[6], pRPort->Root.Id[7])); } SkDrvFreeRlmtMbuf(pAC, IoC, pMb); @@ -1148,7 +1150,7 @@ } else { SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_RX, - ("SkRlmtPacketReceive: Unknown Packet Type.\n")) + ("SkRlmtPacketReceive: Unknown Packet Type.\n")); /* Unknown packet. */ SkDrvFreeRlmtMbuf(pAC, IoC, pMb); @@ -1230,7 +1232,7 @@ if ((pRPort->PacketsPerTimeSlot - pRPort->BpduPacketsPerTimeSlot) == 0) { SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, ("SkRlmtCheckPort %d: No (%d) receives in last time slot.\n", - PortNumber, pRPort->PacketsPerTimeSlot)) + PortNumber, pRPort->PacketsPerTimeSlot)); /* * Check segmentation if there was no receive at least twice @@ -1247,7 +1249,7 @@ SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, ("SkRlmtCheckPort: PortsSuspect %d, PcsRx %d.\n", - pRPort->PortsSuspect, pRPort->CheckingState & SK_RLMT_PCS_RX)) + pRPort->PortsSuspect, pRPort->CheckingState & SK_RLMT_PCS_RX)); if (pRPort->PortState != SK_RLMT_PS_DOWN) { NewTimeout = TO_SHORTEN(pAC->Rlmt.Port[PortNumber].Net->TimeoutValue); @@ -1293,7 +1295,7 @@ ("SkRlmtCheckPort %d: %d (%d) receives in last time slot.\n", PortNumber, pRPort->PacketsPerTimeSlot - pRPort->BpduPacketsPerTimeSlot, - pRPort->PacketsPerTimeSlot)) + pRPort->PacketsPerTimeSlot)); SkRlmtPortReceives(pAC, IoC, PortNumber); if (pAC->Rlmt.CheckSwitch) { @@ -1343,7 +1345,7 @@ i, pAC->Rlmt.Port[i].PortDown, pAC->Rlmt.Port[i].PortNoRx, *((SK_U32*)(&pAC->Rlmt.Port[i].BcTimeStamp) + OFFS_HI32), - *((SK_U32*)(&pAC->Rlmt.Port[i].BcTimeStamp) + OFFS_LO32))) + *((SK_U32*)(&pAC->Rlmt.Port[i].BcTimeStamp) + OFFS_LO32))); if (!pAC->Rlmt.Port[i].PortDown && !pAC->Rlmt.Port[i].PortNoRx) { if (!PortFound || pAC->Rlmt.Port[i].BcTimeStamp > BcTimeStamp) { @@ -1356,7 +1358,7 @@ if (PortFound) { SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, - ("Port %d received the last broadcast.\n", *pSelect)) + ("Port %d received the last broadcast.\n", *pSelect)); /* Look if another port's time stamp is similar. */ for (i = 0; i < (SK_U32)pAC->GIni.GIMacsFound; i++) { @@ -1371,7 +1373,7 @@ PortFound = SK_FALSE; SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, - ("Port %d received a broadcast at a similar time.\n", i)) + ("Port %d received a broadcast at a similar time.\n", i)); break; } } @@ -1383,7 +1385,7 @@ ("SK_RLMT_SELECT_BCRX found Port %d receiving the substantially " "latest broadcast (%u).\n", *pSelect, - BcTimeStamp - pAC->Rlmt.Port[1 - *pSelect].BcTimeStamp)) + BcTimeStamp - pAC->Rlmt.Port[1 - *pSelect].BcTimeStamp)); } #endif /* DEBUG */ @@ -1432,7 +1434,7 @@ PortFound = SK_TRUE; SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, ("SK_RLMT_SELECT_NOTSUSPECT found Port %d up and not check RX.\n", - *pSelect)) + *pSelect)); break; } } @@ -1481,7 +1483,7 @@ } PortFound = SK_TRUE; SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, - ("SK_RLMT_SELECT_UP found Port %d up.\n", *pSelect)) + ("SK_RLMT_SELECT_UP found Port %d up.\n", *pSelect)); break; } } @@ -1542,7 +1544,7 @@ } SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, - ("SK_RLMT_SELECT_GOINGUP found Port %d going up.\n", *pSelect)) + ("SK_RLMT_SELECT_GOINGUP found Port %d going up.\n", *pSelect)); return (SK_TRUE); } /* SkRlmtSelectGoingUp */ @@ -1588,7 +1590,7 @@ } PortFound = SK_TRUE; SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, - ("SK_RLMT_SELECT_DOWN found Port %d down.\n", *pSelect)) + ("SK_RLMT_SELECT_DOWN found Port %d down.\n", *pSelect)); break; } } @@ -1678,16 +1680,19 @@ Para.Para32[1] = NetIdx; SkEventQueue(pAC, SKGE_DRV, SK_DRV_NET_UP, Para); - if ((pAC->Rlmt.Net[NetIdx].RlmtMode & SK_RLMT_TRANSPARENT) == 0 && - (Para.pParaPtr = SkRlmtBuildPacket(pAC, IoC, - pAC->Rlmt.Net[NetIdx].Port[i]->PortNumber, - SK_PACKET_ANNOUNCE, &pAC->Addr.Net[NetIdx]. - CurrentMacAddress, &SkRlmtMcAddr)) != NULL) { - /* - * Send announce packet to RLMT multicast address to force - * switches to learn the new location of the logical MAC address. - */ - SkEventQueue(pAC, SKGE_DRV, SK_DRV_RLMT_SEND, Para); + if (pAC->Rlmt.NumNets == 1) { + if ((pAC->Rlmt.Net[NetIdx].RlmtMode & SK_RLMT_TRANSPARENT) == 0 && + (Para.pParaPtr = SkRlmtBuildPacket(pAC, IoC, + pAC->Rlmt.Net[NetIdx].Port[i]->PortNumber, + SK_PACKET_ANNOUNCE, &pAC->Addr.Net[NetIdx]. + CurrentMacAddress, &SkRlmtMcAddr)) != NULL) { + + /* + * Send announce packet to RLMT multicast address to force + * switches to learn the new location of the logical MAC address. + */ + SkEventQueue(pAC, SKGE_DRV, SK_DRV_RLMT_SEND, Para); + } } } else { @@ -1786,7 +1791,7 @@ if (Para.Para32[1] != Active) { SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, - ("Active: %d, Para1: %d.\n", Active, Para.Para32[1])) + ("Active: %d, Para1: %d.\n", Active, Para.Para32[1])); pAC->Rlmt.Net[NetIdx].ActivePort = Para.Para32[1]; Para.Para32[0] = pAC->Rlmt.Net[NetIdx]. Port[Para.Para32[0]]->PortNumber; @@ -1866,7 +1871,7 @@ pNet->Port[i]->Root.Id[0], pNet->Port[i]->Root.Id[1], pNet->Port[i]->Root.Id[2], pNet->Port[i]->Root.Id[3], pNet->Port[i]->Root.Id[4], pNet->Port[i]->Root.Id[5], - pNet->Port[i]->Root.Id[6], pNet->Port[i]->Root.Id[7])) + pNet->Port[i]->Root.Id[6], pNet->Port[i]->Root.Id[7])); if (!pNet->RootIdSet) { pNet->Root = pNet->Port[i]->Root; @@ -1961,13 +1966,13 @@ SK_U32 i; SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, - ("SK_RLMT_PORTSTART_TIMEOUT Port %d Event BEGIN.\n", Para.Para32[0])) + ("SK_RLMT_PORTSTART_TIMEOUT Port %d Event BEGIN.\n", Para.Para32[0])); if (Para.Para32[1] != (SK_U32)-1) { SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, - ("Bad Parameter.\n")) + ("Bad Parameter.\n")); SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, - ("SK_RLMT_PORTSTART_TIMEOUT Event EMPTY.\n")) + ("SK_RLMT_PORTSTART_TIMEOUT Event EMPTY.\n")); return; } @@ -1988,7 +1993,7 @@ } SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, - ("SK_RLMT_PORTSTART_TIMEOUT Event END.\n")) + ("SK_RLMT_PORTSTART_TIMEOUT Event END.\n")); } /* SkRlmtEvtPortStartTim */ @@ -2016,21 +2021,21 @@ SK_EVPARA Para2; SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, - ("SK_RLMT_LINK_UP Port %d Event BEGIN.\n", Para.Para32[0])) + ("SK_RLMT_LINK_UP Port %d Event BEGIN.\n", Para.Para32[0])); pRPort = &pAC->Rlmt.Port[Para.Para32[0]]; if (!pRPort->PortStarted) { SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_RLMT_E008, SKERR_RLMT_E008_MSG); SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, - ("SK_RLMT_LINK_UP Event EMPTY.\n")) + ("SK_RLMT_LINK_UP Event EMPTY.\n")); return; } if (!pRPort->LinkDown) { /* RA;:;: Any better solution? */ SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, - ("SK_RLMT_LINK_UP Event EMPTY.\n")) + ("SK_RLMT_LINK_UP Event EMPTY.\n")); return; } @@ -2080,16 +2085,19 @@ Para2.Para32[1] = (SK_U32)-1; SkTimerStart(pAC, IoC, &pRPort->UpTimer, SK_RLMT_PORTUP_TIM_VAL, SKGE_RLMT, SK_RLMT_PORTUP_TIM, Para2); - + /* Later: if (pAC->Rlmt.RlmtMode & SK_RLMT_CHECK_LOC_LINK) && */ - if ((pRPort->Net->RlmtMode & SK_RLMT_TRANSPARENT) == 0 && - (pRPort->Net->RlmtMode & SK_RLMT_CHECK_LINK) != 0 && - (Para2.pParaPtr = - SkRlmtBuildPacket(pAC, IoC, Para.Para32[0], SK_PACKET_ANNOUNCE, - &pAC->Addr.Port[Para.Para32[0]].CurrentMacAddress, &SkRlmtMcAddr) - ) != NULL) { - /* Send "new" packet to RLMT multicast address. */ - SkEventQueue(pAC, SKGE_DRV, SK_DRV_RLMT_SEND, Para2); + if (pAC->Rlmt.NumNets == 1) { + if ((pRPort->Net->RlmtMode & SK_RLMT_TRANSPARENT) == 0 && + (pRPort->Net->RlmtMode & SK_RLMT_CHECK_LINK) != 0 && + (Para2.pParaPtr = + SkRlmtBuildPacket(pAC, IoC, Para.Para32[0], SK_PACKET_ANNOUNCE, + &pAC->Addr.Port[Para.Para32[0]].CurrentMacAddress, &SkRlmtMcAddr) + ) != NULL) { + + /* Send "new" packet to RLMT multicast address. */ + SkEventQueue(pAC, SKGE_DRV, SK_DRV_RLMT_SEND, Para2); + } } if (pRPort->Net->RlmtMode & SK_RLMT_CHECK_SEG) { @@ -2108,7 +2116,7 @@ } SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, - ("SK_RLMT_LINK_UP Event END.\n")) + ("SK_RLMT_LINK_UP Event END.\n")); } /* SkRlmtEvtLinkUp */ @@ -2134,20 +2142,20 @@ SK_RLMT_PORT *pRPort; SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, - ("SK_RLMT_PORTUP_TIM Port %d Event BEGIN.\n", Para.Para32[0])) + ("SK_RLMT_PORTUP_TIM Port %d Event BEGIN.\n", Para.Para32[0])); if (Para.Para32[1] != (SK_U32)-1) { SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, - ("Bad Parameter.\n")) + ("Bad Parameter.\n")); SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, - ("SK_RLMT_PORTUP_TIM Event EMPTY.\n")) + ("SK_RLMT_PORTUP_TIM Event EMPTY.\n")); return; } pRPort = &pAC->Rlmt.Port[Para.Para32[0]]; if (pRPort->LinkDown || (pRPort->PortState == SK_RLMT_PS_UP)) { SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, - ("SK_RLMT_PORTUP_TIM Port %d Event EMPTY.\n", Para.Para32[0])) + ("SK_RLMT_PORTUP_TIM Port %d Event EMPTY.\n", Para.Para32[0])); return; } @@ -2162,7 +2170,7 @@ } SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, - ("SK_RLMT_PORTUP_TIM Event END.\n")) + ("SK_RLMT_PORTUP_TIM Event END.\n")); } /* SkRlmtEvtPortUpTim */ @@ -2190,13 +2198,13 @@ SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, ("SK_RLMT_PORTDOWN* Port %d Event (%d) BEGIN.\n", - Para.Para32[0], Event)) + Para.Para32[0], Event)); if (Para.Para32[1] != (SK_U32)-1) { SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, - ("Bad Parameter.\n")) + ("Bad Parameter.\n")); SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, - ("SK_RLMT_PORTDOWN* Event EMPTY.\n")) + ("SK_RLMT_PORTDOWN* Event EMPTY.\n")); return; } @@ -2204,7 +2212,7 @@ if (!pRPort->PortStarted || (Event == SK_RLMT_PORTDOWN_TX_TIM && !(pRPort->CheckingState & SK_RLMT_PCS_TX))) { SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, - ("SK_RLMT_PORTDOWN* Event (%d) EMPTY.\n", Event)) + ("SK_RLMT_PORTDOWN* Event (%d) EMPTY.\n", Event)); return; } @@ -2241,7 +2249,7 @@ } SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, - ("SK_RLMT_PORTDOWN* Event (%d) END.\n", Event)) + ("SK_RLMT_PORTDOWN* Event (%d) END.\n", Event)); } /* SkRlmtEvtPortDownX */ @@ -2268,7 +2276,7 @@ pRPort = &pAC->Rlmt.Port[Para.Para32[0]]; SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, - ("SK_RLMT_LINK_DOWN Port %d Event BEGIN.\n", Para.Para32[0])) + ("SK_RLMT_LINK_DOWN Port %d Event BEGIN.\n", Para.Para32[0])); if (!pAC->Rlmt.Port[Para.Para32[0]].LinkDown) { pRPort->Net->LinksUp--; @@ -2287,7 +2295,7 @@ } SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, - ("SK_RLMT_LINK_DOWN Event END.\n")) + ("SK_RLMT_LINK_DOWN Event END.\n")); } /* SkRlmtEvtLinkDown */ @@ -2316,13 +2324,13 @@ SK_MAC_ADDR *pNewMacAddr; SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, - ("SK_RLMT_PORT_ADDR Port %d Event BEGIN.\n", Para.Para32[0])) + ("SK_RLMT_PORT_ADDR Port %d Event BEGIN.\n", Para.Para32[0])); if (Para.Para32[1] != (SK_U32)-1) { SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, - ("Bad Parameter.\n")) + ("Bad Parameter.\n")); SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, - ("SK_RLMT_PORT_ADDR Event EMPTY.\n")) + ("SK_RLMT_PORT_ADDR Event EMPTY.\n")); return; } @@ -2346,7 +2354,7 @@ } SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, - ("SK_RLMT_PORT_ADDR Event END.\n")) + ("SK_RLMT_PORT_ADDR Event END.\n")); } /* SkRlmtEvtPortAddr */ @@ -2374,35 +2382,35 @@ SK_U32 PortNumber; SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, - ("SK_RLMT_START Net %d Event BEGIN.\n", Para.Para32[0])) + ("SK_RLMT_START Net %d Event BEGIN.\n", Para.Para32[0])); if (Para.Para32[1] != (SK_U32)-1) { SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, - ("Bad Parameter.\n")) + ("Bad Parameter.\n")); SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, - ("SK_RLMT_START Event EMPTY.\n")) + ("SK_RLMT_START Event EMPTY.\n")); return; } if (Para.Para32[0] >= pAC->Rlmt.NumNets) { SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, - ("Bad NetNumber %d.\n", Para.Para32[0])) + ("Bad NetNumber %d.\n", Para.Para32[0])); SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, - ("SK_RLMT_START Event EMPTY.\n")) + ("SK_RLMT_START Event EMPTY.\n")); return; } if (pAC->Rlmt.Net[Para.Para32[0]].RlmtState != SK_RLMT_RS_INIT) { SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, - ("SK_RLMT_START Event EMPTY.\n")) + ("SK_RLMT_START Event EMPTY.\n")); return; } if (pAC->Rlmt.NetsStarted >= pAC->Rlmt.NumNets) { SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, - ("All nets should have been started.\n")) + ("All nets should have been started.\n")); SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, - ("SK_RLMT_START Event EMPTY.\n")) + ("SK_RLMT_START Event EMPTY.\n")); return; } @@ -2436,7 +2444,7 @@ pAC->Rlmt.NetsStarted++; SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, - ("SK_RLMT_START Event END.\n")) + ("SK_RLMT_START Event END.\n")); } /* SkRlmtEvtStart */ @@ -2464,35 +2472,35 @@ SK_U32 i; SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, - ("SK_RLMT_STOP Net %d Event BEGIN.\n", Para.Para32[0])) + ("SK_RLMT_STOP Net %d Event BEGIN.\n", Para.Para32[0])); if (Para.Para32[1] != (SK_U32)-1) { SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, - ("Bad Parameter.\n")) + ("Bad Parameter.\n")); SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, - ("SK_RLMT_STOP Event EMPTY.\n")) + ("SK_RLMT_STOP Event EMPTY.\n")); return; } if (Para.Para32[0] >= pAC->Rlmt.NumNets) { SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, - ("Bad NetNumber %d.\n", Para.Para32[0])) + ("Bad NetNumber %d.\n", Para.Para32[0])); SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, - ("SK_RLMT_STOP Event EMPTY.\n")) + ("SK_RLMT_STOP Event EMPTY.\n")); return; } if (pAC->Rlmt.Net[Para.Para32[0]].RlmtState == SK_RLMT_RS_INIT) { SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, - ("SK_RLMT_STOP Event EMPTY.\n")) + ("SK_RLMT_STOP Event EMPTY.\n")); return; } if (pAC->Rlmt.NetsStarted == 0) { SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, - ("All nets are stopped.\n")) + ("All nets are stopped.\n")); SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, - ("SK_RLMT_STOP Event EMPTY.\n")) + ("SK_RLMT_STOP Event EMPTY.\n")); return; } @@ -2527,7 +2535,7 @@ pAC->Rlmt.NetsStarted--; SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, - ("SK_RLMT_STOP Event END.\n")) + ("SK_RLMT_STOP Event END.\n")); } /* SkRlmtEvtStop */ @@ -2557,13 +2565,13 @@ SK_U32 i; SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, - ("SK_RLMT_TIM Event BEGIN.\n")) + ("SK_RLMT_TIM Event BEGIN.\n")); if (Para.Para32[1] != (SK_U32)-1) { SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, - ("Bad Parameter.\n")) + ("Bad Parameter.\n")); SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, - ("SK_RLMT_TIM Event EMPTY.\n")) + ("SK_RLMT_TIM Event EMPTY.\n")); return; } @@ -2635,7 +2643,7 @@ } SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, - ("SK_RLMT_TIM Event END.\n")) + ("SK_RLMT_TIM Event END.\n")); } /* SkRlmtEvtTim */ @@ -2663,13 +2671,13 @@ #endif /* DEBUG */ SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, - ("SK_RLMT_SEG_TIM Event BEGIN.\n")) + ("SK_RLMT_SEG_TIM Event BEGIN.\n")); if (Para.Para32[1] != (SK_U32)-1) { SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, - ("Bad Parameter.\n")) + ("Bad Parameter.\n")); SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, - ("SK_RLMT_SEG_TIM Event EMPTY.\n")) + ("SK_RLMT_SEG_TIM Event EMPTY.\n")); return; } @@ -2693,7 +2701,7 @@ InAddr8[3], InAddr8[4], InAddr8[5], pAPort->Exact[k].a[0], pAPort->Exact[k].a[1], pAPort->Exact[k].a[2], pAPort->Exact[k].a[3], - pAPort->Exact[k].a[4], pAPort->Exact[k].a[5])) + pAPort->Exact[k].a[4], pAPort->Exact[k].a[5])); } } #endif /* xDEBUG */ @@ -2701,7 +2709,7 @@ SkRlmtCheckSeg(pAC, IoC, Para.Para32[0]); SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, - ("SK_RLMT_SEG_TIM Event END.\n")) + ("SK_RLMT_SEG_TIM Event END.\n")); } /* SkRlmtEvtSegTim */ @@ -2730,18 +2738,18 @@ SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, - ("SK_RLMT_PACKET_RECEIVED Event BEGIN.\n")) + ("SK_RLMT_PACKET_RECEIVED Event BEGIN.\n")); /* Should we ignore frames during port switching? */ #ifdef DEBUG pMb = Para.pParaPtr; if (pMb == NULL) { - SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, ("No mbuf.\n")) + SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, ("No mbuf.\n")); } else if (pMb->pNext != NULL) { SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, - ("More than one mbuf or pMb->pNext not set.\n")) + ("More than one mbuf or pMb->pNext not set.\n")); } #endif /* DEBUG */ @@ -2759,7 +2767,7 @@ } SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, - ("SK_RLMT_PACKET_RECEIVED Event END.\n")) + ("SK_RLMT_PACKET_RECEIVED Event END.\n")); } /* SkRlmtEvtPacketRx */ @@ -2786,21 +2794,21 @@ SK_RLMT_PORT *pRPort; SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, - ("SK_RLMT_STATS_CLEAR Event BEGIN.\n")) + ("SK_RLMT_STATS_CLEAR Event BEGIN.\n")); if (Para.Para32[1] != (SK_U32)-1) { SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, - ("Bad Parameter.\n")) + ("Bad Parameter.\n")); SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, - ("SK_RLMT_STATS_CLEAR Event EMPTY.\n")) + ("SK_RLMT_STATS_CLEAR Event EMPTY.\n")); return; } if (Para.Para32[0] >= pAC->Rlmt.NumNets) { SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, - ("Bad NetNumber %d.\n", Para.Para32[0])) + ("Bad NetNumber %d.\n", Para.Para32[0])); SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, - ("SK_RLMT_STATS_CLEAR Event EMPTY.\n")) + ("SK_RLMT_STATS_CLEAR Event EMPTY.\n")); return; } @@ -2815,7 +2823,7 @@ } SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, - ("SK_RLMT_STATS_CLEAR Event END.\n")) + ("SK_RLMT_STATS_CLEAR Event END.\n")); } /* SkRlmtEvtStatsClear */ @@ -2839,28 +2847,28 @@ SK_EVPARA Para) /* SK_U32 NetNumber; SK_U32 -1 */ { SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, - ("SK_RLMT_STATS_UPDATE Event BEGIN.\n")) + ("SK_RLMT_STATS_UPDATE Event BEGIN.\n")); if (Para.Para32[1] != (SK_U32)-1) { SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, - ("Bad Parameter.\n")) + ("Bad Parameter.\n")); SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, - ("SK_RLMT_STATS_UPDATE Event EMPTY.\n")) + ("SK_RLMT_STATS_UPDATE Event EMPTY.\n")); return; } if (Para.Para32[0] >= pAC->Rlmt.NumNets) { SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, - ("Bad NetNumber %d.\n", Para.Para32[0])) + ("Bad NetNumber %d.\n", Para.Para32[0])); SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, - ("SK_RLMT_STATS_UPDATE Event EMPTY.\n")) + ("SK_RLMT_STATS_UPDATE Event EMPTY.\n")); return; } /* Update statistics - currently always up-to-date. */ SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, - ("SK_RLMT_STATS_UPDATE Event END.\n")) + ("SK_RLMT_STATS_UPDATE Event END.\n")); } /* SkRlmtEvtStatsUpdate */ @@ -2884,13 +2892,13 @@ SK_EVPARA Para) /* SK_U32 PortIndex; SK_U32 NetNumber */ { SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, - ("SK_RLMT_PREFPORT_CHANGE to Port %d Event BEGIN.\n", Para.Para32[0])) + ("SK_RLMT_PREFPORT_CHANGE to Port %d Event BEGIN.\n", Para.Para32[0])); if (Para.Para32[1] >= pAC->Rlmt.NumNets) { SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, - ("Bad NetNumber %d.\n", Para.Para32[1])) + ("Bad NetNumber %d.\n", Para.Para32[1])); SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, - ("SK_RLMT_PREFPORT_CHANGE Event EMPTY.\n")) + ("SK_RLMT_PREFPORT_CHANGE Event EMPTY.\n")); return; } @@ -2903,7 +2911,7 @@ SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_RLMT_E010, SKERR_RLMT_E010_MSG); SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, - ("SK_RLMT_PREFPORT_CHANGE Event EMPTY.\n")) + ("SK_RLMT_PREFPORT_CHANGE Event EMPTY.\n")); return; } @@ -2917,7 +2925,7 @@ } SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, - ("SK_RLMT_PREFPORT_CHANGE Event END.\n")) + ("SK_RLMT_PREFPORT_CHANGE Event END.\n")); } /* SkRlmtEvtPrefportChange */ @@ -2943,37 +2951,37 @@ int i; SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, - ("SK_RLMT_SET_NETS Event BEGIN.\n")) + ("SK_RLMT_SET_NETS Event BEGIN.\n")); if (Para.Para32[1] != (SK_U32)-1) { SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, - ("Bad Parameter.\n")) + ("Bad Parameter.\n")); SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, - ("SK_RLMT_SET_NETS Event EMPTY.\n")) + ("SK_RLMT_SET_NETS Event EMPTY.\n")); return; } if (Para.Para32[0] == 0 || Para.Para32[0] > SK_MAX_NETS || Para.Para32[0] > (SK_U32)pAC->GIni.GIMacsFound) { SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, - ("Bad number of nets: %d.\n", Para.Para32[0])) + ("Bad number of nets: %d.\n", Para.Para32[0])); SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, - ("SK_RLMT_SET_NETS Event EMPTY.\n")) + ("SK_RLMT_SET_NETS Event EMPTY.\n")); return; } if (Para.Para32[0] == pAC->Rlmt.NumNets) { /* No change. */ SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, - ("SK_RLMT_SET_NETS Event EMPTY.\n")) + ("SK_RLMT_SET_NETS Event EMPTY.\n")); return; } /* Entering and leaving dual mode only allowed while nets are stopped. */ if (pAC->Rlmt.NetsStarted > 0) { SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, - ("Changing dual mode only allowed while all nets are stopped.\n")) + ("Changing dual mode only allowed while all nets are stopped.\n")); SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, - ("SK_RLMT_SET_NETS Event EMPTY.\n")) + ("SK_RLMT_SET_NETS Event EMPTY.\n")); return; } @@ -3004,9 +3012,10 @@ SkEventQueue(pAC, SKGE_PNMI, SK_PNMI_EVT_RLMT_SET_NETS, Para); SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, - ("RLMT: Changed to one net with two ports.\n")) + ("RLMT: Changed to one net with two ports.\n")); } else if (Para.Para32[0] == 2) { + pAC->Rlmt.RlmtOff = SK_TRUE; pAC->Rlmt.Port[1].Net= &pAC->Rlmt.Net[1]; pAC->Rlmt.Net[1].NumPorts = pAC->GIni.GIMacsFound - 1; pAC->Rlmt.Net[0].NumPorts = @@ -3033,19 +3042,19 @@ SkEventQueue(pAC, SKGE_PNMI, SK_PNMI_EVT_RLMT_SET_NETS, Para); SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, - ("RLMT: Changed to two nets with one port each.\n")) + ("RLMT: Changed to two nets with one port each.\n")); } else { /* Not implemented for more than two nets. */ SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, - ("SetNets not implemented for more than two nets.\n")) + ("SetNets not implemented for more than two nets.\n")); SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, - ("SK_RLMT_SET_NETS Event EMPTY.\n")) + ("SK_RLMT_SET_NETS Event EMPTY.\n")); return; } SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, - ("SK_RLMT_SET_NETS Event END.\n")) + ("SK_RLMT_SET_NETS Event END.\n")); } /* SkRlmtSetNets */ @@ -3073,13 +3082,13 @@ SK_U32 PrevRlmtMode; SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, - ("SK_RLMT_MODE_CHANGE Event BEGIN.\n")) + ("SK_RLMT_MODE_CHANGE Event BEGIN.\n")); if (Para.Para32[1] >= pAC->Rlmt.NumNets) { SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, - ("Bad NetNumber %d.\n", Para.Para32[1])) + ("Bad NetNumber %d.\n", Para.Para32[1])); SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, - ("SK_RLMT_MODE_CHANGE Event EMPTY.\n")) + ("SK_RLMT_MODE_CHANGE Event EMPTY.\n")); return; } @@ -3089,9 +3098,9 @@ Para.Para32[0] != SK_RLMT_MODE_CLS) { pAC->Rlmt.Net[Para.Para32[1]].RlmtMode = SK_RLMT_MODE_CLS; SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, - ("Forced RLMT mode to CLS on single port net.\n")) + ("Forced RLMT mode to CLS on single port net.\n")); SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, - ("SK_RLMT_MODE_CHANGE Event EMPTY.\n")) + ("SK_RLMT_MODE_CHANGE Event EMPTY.\n")); return; } @@ -3157,7 +3166,7 @@ } /* SK_RLMT_CHECK_SEG bit changed. */ SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, - ("SK_RLMT_MODE_CHANGE Event END.\n")) + ("SK_RLMT_MODE_CHANGE Event END.\n")); } /* SkRlmtEvtModeChange */ @@ -3243,7 +3252,7 @@ default: /* Create error log entry. */ SK_DBG_MSG(pAC, SK_DBGMOD_RLMT, SK_DBGCAT_CTRL, - ("Unknown RLMT Event %d.\n", Event)) + ("Unknown RLMT Event %d.\n", Event)); SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_RLMT_E003, SKERR_RLMT_E003_MSG); break; } /* switch() */ diff -urN linux-2.4.32-600/drivers/net/sk98lin/sktimer.c linux-2.4.32-600-sk98_831/drivers/net/sk98lin/sktimer.c --- linux-2.4.32-600/drivers/net/sk98lin/sktimer.c Sat Mar 20 10:08:19 2004 +++ linux-2.4.32-600-sk98_831/drivers/net/sk98lin/sktimer.c Sun Feb 26 11:12:56 2006 @@ -2,6 +2,8 @@ * * Name: sktimer.c * Project: Gigabit Ethernet Adapters, Event Scheduler Module + * Version: $Revision: 2.2 $ + * Date: $Date: 2004/05/28 13:44:39 $ * Purpose: High level timer functions. * ******************************************************************************/ @@ -9,7 +11,7 @@ /****************************************************************************** * * (C)Copyright 1998-2002 SysKonnect GmbH. - * (C)Copyright 2002-2003 Marvell. + * (C)Copyright 2002-2004 Marvell. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -25,7 +27,7 @@ */ #if (defined(DEBUG) || ((!defined(LINT)) && (!defined(SK_SLIM)))) static const char SysKonnectFileId[] = - "@(#) $Id: sktimer.c,v 1.14 2003/09/16 13:46:51 rschmidt Exp $ (C) Marvell."; + "@(#) $Id: sktimer.c,v 2.2 2004/05/28 13:44:39 rschmidt Exp $ (C) Marvell."; #endif #include "h/skdrv1st.h" /* Driver Specific Definitions */ @@ -82,22 +84,20 @@ SK_TIMER **ppTimPrev; SK_TIMER *pTm; - /* - * remove timer from queue - */ + /* remove timer from queue */ pTimer->TmActive = SK_FALSE; - + if (pAC->Tim.StQueue == pTimer && !pTimer->TmNext) { SkHwtStop(pAC, Ioc); } - + for (ppTimPrev = &pAC->Tim.StQueue; (pTm = *ppTimPrev); ppTimPrev = &pTm->TmNext ) { - + if (pTm == pTimer) { /* * Timer found in queue - * - dequeue it and + * - dequeue it * - correct delta of the next timer */ *ppTimPrev = pTm->TmNext; @@ -118,7 +118,7 @@ SK_AC *pAC, /* Adapters context */ SK_IOC Ioc, /* IoContext */ SK_TIMER *pTimer, /* Timer Pointer to be started */ -SK_U32 Time, /* Time value */ +SK_U32 Time, /* Time Value (in microsec.) */ SK_U32 Class, /* Event Class for this timer */ SK_U32 Event, /* Event Value for this timer */ SK_EVPARA Para) /* Event Parameter for this timer */ @@ -127,11 +127,6 @@ SK_TIMER *pTm; SK_U32 Delta; - Time /= 16; /* input is uS, clock ticks are 16uS */ - - if (!Time) - Time = 1; - SkTimerStop(pAC, Ioc, pTimer); pTimer->TmClass = Class; @@ -140,31 +135,26 @@ pTimer->TmActive = SK_TRUE; if (!pAC->Tim.StQueue) { - /* First Timer to be started */ + /* first Timer to be started */ pAC->Tim.StQueue = pTimer; pTimer->TmNext = 0; pTimer->TmDelta = Time; - + SkHwtStart(pAC, Ioc, Time); - + return; } - /* - * timer correction - */ + /* timer correction */ timer_done(pAC, Ioc, 0); - /* - * find position in queue - */ + /* find position in queue */ Delta = 0; for (ppTimPrev = &pAC->Tim.StQueue; (pTm = *ppTimPrev); ppTimPrev = &pTm->TmNext ) { - + if (Delta + pTm->TmDelta > Time) { - /* Position found */ - /* Here the timer needs to be inserted. */ + /* the timer needs to be inserted here */ break; } Delta += pTm->TmDelta; @@ -176,9 +166,7 @@ pTimer->TmDelta = Time - Delta; if (pTm) { - /* There is a next timer - * -> correct its Delta value. - */ + /* there is a next timer: correct its Delta value */ pTm->TmDelta -= pTimer->TmDelta; } @@ -207,7 +195,7 @@ int Done = 0; Delta = SkHwtRead(pAC, Ioc); - + ppLast = &pAC->Tim.StQueue; pTm = pAC->Tim.StQueue; while (pTm && !Done) { @@ -231,7 +219,7 @@ * StQueue points to the first Timer that run out. */ - for ( pTComp = pAC->Tim.StQueue; pTComp; pTComp = pTComp->TmNext) { + for (pTComp = pAC->Tim.StQueue; pTComp; pTComp = pTComp->TmNext) { SkEventQueue(pAC,pTComp->TmClass, pTComp->TmEvent, pTComp->TmPara); } diff -urN linux-2.4.32-600/drivers/net/sk98lin/sktwsi.c linux-2.4.32-600-sk98_831/drivers/net/sk98lin/sktwsi.c --- linux-2.4.32-600/drivers/net/sk98lin/sktwsi.c Thu Jan 1 01:00:00 1970 +++ linux-2.4.32-600-sk98_831/drivers/net/sk98lin/sktwsi.c Sun Feb 26 11:12:56 2006 @@ -0,0 +1,1359 @@ +/****************************************************************************** + * + * Name: sktwsi.c + * Project: Gigabit Ethernet Adapters, TWSI-Module + * Version: $Revision: 1.10 $ + * Date: $Date: 2005/08/03 09:45:32 $ + * Purpose: Functions to access Voltage and Temperature Sensor + * + ******************************************************************************/ + +/****************************************************************************** + * + * (C)Copyright 1998-2002 SysKonnect. + * (C)Copyright 2002-2005 Marvell. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * The information in this file is provided "AS IS" without warranty. + * + ******************************************************************************/ + +/* + * TWSI Protocol + */ +#if (defined(DEBUG) || ((!defined(LINT)) && (!defined(SK_SLIM)))) +static const char SysKonnectFileId[] = + "@(#) $Id: sktwsi.c,v 1.10 2005/08/03 09:45:32 rschmidt Exp $ (C) Marvell."; +#endif + +#include "h/skdrv1st.h" /* Driver Specific Definitions */ +#include "h/lm80.h" +#include "h/skdrv2nd.h" /* Adapter Control- and Driver specific Def. */ + +#ifdef __C2MAN__ +/* + TWSI protocol implementation. + + General Description: + + The TWSI protocol is used for the temperature sensors and for + the serial EEPROM which hold the configuration. + + This file covers functions that allow to read write and do + some bulk requests a specified TWSI address. + + The Genesis has 2 TWSI buses. One for the EEPROM which holds + the VPD Data and one for temperature and voltage sensor. + The following picture shows the TWSI buses, TWSI devices and + their control registers. + + Note: The VPD functions are in skvpd.c +. +. PCI Config TWSI Bus for VPD Data: +. +. +------------+ +. | VPD EEPROM | +. +------------+ +. | +. | <-- TWSI +. | +. +-----------+-----------+ +. | | +. +-----------------+ +-----------------+ +. | PCI_VPD_ADR_REG | | PCI_VPD_DAT_REG | +. +-----------------+ +-----------------+ +. +. +. TWSI Bus for LM80 sensor: +. +. +-----------------+ +. | Temperature and | +. | Voltage Sensor | +. | LM80 | +. +-----------------+ +. | +. | +. TWSI --> | +. | +. +----+ +. +-------------->| OR |<--+ +. | +----+ | +. +------+------+ | +. | | | +. +--------+ +--------+ +----------+ +. | B2_I2C | | B2_I2C | | B2_I2C | +. | _CTRL | | _DATA | | _SW | +. +--------+ +--------+ +----------+ +. + The TWSI bus may be driven by the B2_I2C_SW or by the B2_I2C_CTRL + and B2_I2C_DATA registers. + For driver software it is recommended to use the TWSI control and + data register, because TWSI bus timing is done by the ASIC and + an interrupt may be received when the TWSI request is completed. + + Clock Rate Timing: MIN MAX generated by + VPD EEPROM: 50 kHz 100 kHz HW + LM80 over TWSI Ctrl/Data reg. 50 kHz 100 kHz HW + LM80 over B2_I2C_SW register 0 400 kHz SW + + Note: The clock generated by the hardware is dependend on the + PCI clock. If the PCI bus clock is 33 MHz, the I2C/VPD + clock is 50 kHz. + */ +intro() +{} +#endif + +#ifdef SK_DIAG +/* + * TWSI Fast Mode timing values used by the LM80. + * If new devices are added to the TWSI bus the timing values have to be checked. + */ +#ifndef I2C_SLOW_TIMING +#define T_CLK_LOW 1300L /* clock low time in ns */ +#define T_CLK_HIGH 600L /* clock high time in ns */ +#define T_DATA_IN_SETUP 100L /* data in Set-up Time */ +#define T_START_HOLD 600L /* start condition hold time */ +#define T_START_SETUP 600L /* start condition Set-up time */ +#define T_STOP_SETUP 600L /* stop condition Set-up time */ +#define T_BUS_IDLE 1300L /* time the bus must free after Tx */ +#define T_CLK_2_DATA_OUT 900L /* max. clock low to data output valid */ +#else /* I2C_SLOW_TIMING */ +/* TWSI Standard Mode Timing */ +#define T_CLK_LOW 4700L /* clock low time in ns */ +#define T_CLK_HIGH 4000L /* clock high time in ns */ +#define T_DATA_IN_SETUP 250L /* data in Set-up Time */ +#define T_START_HOLD 4000L /* start condition hold time */ +#define T_START_SETUP 4700L /* start condition Set-up time */ +#define T_STOP_SETUP 4000L /* stop condition Set-up time */ +#define T_BUS_IDLE 4700L /* time the bus must free after Tx */ +#endif /* !I2C_SLOW_TIMING */ + +#define NS2BCLK(x) (((x)*125)/10000) + +/* + * TWSI Wire Operations + * + * About I2C_CLK_LOW(): + * + * The Data Direction bit (I2C_DATA_DIR) has to be set to input when setting + * clock to low, to prevent the ASIC and the TWSI data client from driving the + * serial data line simultaneously (ASIC: last bit of a byte = '1', TWSI client + * send an 'ACK'). See also Concentrator Bugreport No. 10192. + */ +#define I2C_DATA_HIGH(IoC) SK_I2C_SET_BIT(IoC, I2C_DATA) +#define I2C_DATA_LOW(IoC) SK_I2C_CLR_BIT(IoC, I2C_DATA) +#define I2C_DATA_OUT(IoC) SK_I2C_SET_BIT(IoC, I2C_DATA_DIR) +#define I2C_DATA_IN(IoC) SK_I2C_CLR_BIT(IoC, I2C_DATA_DIR | I2C_DATA) +#define I2C_CLK_HIGH(IoC) SK_I2C_SET_BIT(IoC, I2C_CLK) +#define I2C_CLK_LOW(IoC) SK_I2C_CLR_BIT(IoC, I2C_CLK | I2C_DATA_DIR) +#define I2C_START_COND(IoC) SK_I2C_CLR_BIT(IoC, I2C_CLK) + +#define NS2CLKT(x) ((x*125L)/10000) + +/*--------------- TWSI Interface Register Functions --------------- */ + +/* + * sending one bit + */ +void SkI2cSndBit( +SK_IOC IoC, /* I/O Context */ +SK_U8 Bit) /* Bit to send */ +{ + I2C_DATA_OUT(IoC); + if (Bit) { + I2C_DATA_HIGH(IoC); + } + else { + I2C_DATA_LOW(IoC); + } + SkDgWaitTime(IoC, NS2BCLK(T_DATA_IN_SETUP)); + I2C_CLK_HIGH(IoC); + SkDgWaitTime(IoC, NS2BCLK(T_CLK_HIGH)); + I2C_CLK_LOW(IoC); +} /* SkI2cSndBit*/ + + +/* + * Signal a start to the TWSI Bus. + * + * A start is signaled when data goes to low in a high clock cycle. + * + * Ends with Clock Low. + * + * Status: not tested + */ +void SkI2cStart( +SK_IOC IoC) /* I/O Context */ +{ + /* Init data and Clock to output lines */ + /* Set Data high */ + I2C_DATA_OUT(IoC); + I2C_DATA_HIGH(IoC); + /* Set Clock high */ + I2C_CLK_HIGH(IoC); + + SkDgWaitTime(IoC, NS2BCLK(T_START_SETUP)); + + /* Set Data Low */ + I2C_DATA_LOW(IoC); + + SkDgWaitTime(IoC, NS2BCLK(T_START_HOLD)); + + /* Clock low without Data to Input */ + I2C_START_COND(IoC); + + SkDgWaitTime(IoC, NS2BCLK(T_CLK_LOW)); +} /* SkI2cStart */ + + +void SkI2cStop( +SK_IOC IoC) /* I/O Context */ +{ + /* Init data and Clock to output lines */ + /* Set Data low */ + I2C_DATA_OUT(IoC); + I2C_DATA_LOW(IoC); + + SkDgWaitTime(IoC, NS2BCLK(T_CLK_2_DATA_OUT)); + + /* Set Clock high */ + I2C_CLK_HIGH(IoC); + + SkDgWaitTime(IoC, NS2BCLK(T_STOP_SETUP)); + + /* + * Set Data High: Do it by setting the Data Line to Input. + * Because of a pull up resistor the Data Line + * floods to high. + */ + I2C_DATA_IN(IoC); + + /* + * When TWSI activity is stopped + * o DATA should be set to input and + * o CLOCK should be set to high! + */ + SkDgWaitTime(IoC, NS2BCLK(T_BUS_IDLE)); +} /* SkI2cStop */ + + +/* + * Receive just one bit via the TWSI bus. + * + * Note: Clock must be set to LOW before calling this function. + * + * Returns The received bit. + */ +int SkI2cRcvBit( +SK_IOC IoC) /* I/O Context */ +{ + int Bit; + SK_U8 I2cSwCtrl; + + /* Init data as input line */ + I2C_DATA_IN(IoC); + + SkDgWaitTime(IoC, NS2BCLK(T_CLK_2_DATA_OUT)); + + I2C_CLK_HIGH(IoC); + + SkDgWaitTime(IoC, NS2BCLK(T_CLK_HIGH)); + + SK_I2C_GET_SW(IoC, &I2cSwCtrl); + + Bit = (I2cSwCtrl & I2C_DATA) ? 1 : 0; + + I2C_CLK_LOW(IoC); + SkDgWaitTime(IoC, NS2BCLK(T_CLK_LOW-T_CLK_2_DATA_OUT)); + + return(Bit); +} /* SkI2cRcvBit */ + + +/* + * Receive an ACK. + * + * returns 0 If acknowledged + * 1 in case of an error + */ +int SkI2cRcvAck( +SK_IOC IoC) /* I/O Context */ +{ + /* + * Received bit must be zero. + */ + return(SkI2cRcvBit(IoC) != 0); +} /* SkI2cRcvAck */ + + +/* + * Send an NACK. + */ +void SkI2cSndNAck( +SK_IOC IoC) /* I/O Context */ +{ + /* + * Received bit must be zero. + */ + SkI2cSndBit(IoC, 1); +} /* SkI2cSndNAck */ + + +/* + * Send an ACK. + */ +void SkI2cSndAck( +SK_IOC IoC) /* I/O Context */ +{ + /* + * Received bit must be zero. + */ + SkI2cSndBit(IoC, 0); +} /* SkI2cSndAck */ + + +/* + * Send one byte to the TWSI device and wait for ACK. + * + * Return acknowleged status. + */ +int SkI2cSndByte( +SK_IOC IoC, /* I/O Context */ +int Byte) /* byte to send */ +{ + int i; + + for (i = 0; i < 8; i++) { + if (Byte & (1<<(7-i))) { + SkI2cSndBit(IoC, 1); + } + else { + SkI2cSndBit(IoC, 0); + } + } + + return(SkI2cRcvAck(IoC)); +} /* SkI2cSndByte */ + + +/* + * Receive one byte and ack it. + * + * Return byte. + */ +int SkI2cRcvByte( +SK_IOC IoC, /* I/O Context */ +int Last) /* Last Byte Flag */ +{ + int i; + int Byte = 0; + + for (i = 0; i < 8; i++) { + Byte <<= 1; + Byte |= SkI2cRcvBit(IoC); + } + + if (Last) { + SkI2cSndNAck(IoC); + } + else { + SkI2cSndAck(IoC); + } + + return(Byte); +} /* SkI2cRcvByte */ + + +/* + * Start dialog and send device address + * + * Return 0 if acknowleged, 1 in case of an error + */ +int SkI2cSndDev( +SK_IOC IoC, /* I/O Context */ +int Addr, /* Device Address */ +int Rw) /* Read / Write Flag */ +{ + SkI2cStart(IoC); + Rw = ~Rw; + Rw &= I2C_WRITE; + return(SkI2cSndByte(IoC, (Addr << 1) | Rw)); +} /* SkI2cSndDev */ + +#endif /* SK_DIAG */ + +/*----------------- TWSI CTRL Register Functions ----------*/ + +/* + * waits for a completion of a TWSI transfer + * + * returns 0: success, transfer completes + * 1: error, transfer does not complete, TWSI transfer + * killed, wait loop terminated. + */ +int SkI2cWait( +SK_AC *pAC, /* Adapter Context */ +SK_IOC IoC, /* I/O Context */ +int Event) /* complete event to wait for (I2C_READ or I2C_WRITE) */ +{ + SK_U64 StartTime; + SK_U64 CurrentTime; + SK_U32 I2cCtrl; + + StartTime = SkOsGetTime(pAC); + + do { + CurrentTime = SkOsGetTime(pAC); + + if (CurrentTime - StartTime > SK_TICKS_PER_SEC / 8) { + + SK_I2C_STOP(IoC); +#ifndef SK_DIAG + if (pAC->I2c.InitLevel > SK_INIT_DATA) { + SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_I2C_E002, SKERR_I2C_E002MSG); + } +#endif /* !SK_DIAG */ + return(1); + } + + SK_I2C_GET_CTL(IoC, &I2cCtrl); + +#ifdef xYUKON_DBG + printf("StartTime=%lu, CurrentTime=%lu\n", + StartTime, CurrentTime); + if (kbhit()) { + return(1); + } +#endif /* YUKON_DBG */ + + } while ((I2cCtrl & I2C_FLAG) == (SK_U32)Event << 31); + + return(0); +} /* SkI2cWait */ + + +/* + * waits for a completion of a TWSI transfer + * + * Returns + * Nothing + */ +void SkI2cWaitIrq( +SK_AC *pAC, /* Adapter Context */ +SK_IOC IoC) /* I/O Context */ +{ + SK_SENSOR *pSen; + SK_U64 StartTime; + SK_U32 IrqSrc; + SK_U32 IsTwsiReadyBit; + + pSen = &pAC->I2c.SenTable[pAC->I2c.CurrSens]; + + if (pSen->SenState == SK_SEN_IDLE) { + return; + } + + IsTwsiReadyBit = CHIP_ID_YUKON_2(pAC) ? Y2_IS_TWSI_RDY : IS_I2C_READY; + + StartTime = SkOsGetTime(pAC); + + do { + if (SkOsGetTime(pAC) - StartTime > SK_TICKS_PER_SEC / 8) { + + SK_I2C_STOP(IoC); +#ifndef SK_DIAG + SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_I2C_E016, SKERR_I2C_E016MSG); +#endif /* !SK_DIAG */ + return; + } + + SK_IN32(IoC, B0_ISRC, &IrqSrc); + + } while ((IrqSrc & IsTwsiReadyBit) == 0); + + pSen->SenState = SK_SEN_IDLE; + return; +} /* SkI2cWaitIrq */ + +/* + * writes a single byte or 4 bytes into the TWSI device + * + * returns 0: success + * 1: error + */ +int SkI2cWrite( +SK_AC *pAC, /* Adapter Context */ +SK_IOC IoC, /* I/O Context */ +SK_U32 I2cData, /* TWSI Data to write */ +int I2cDev, /* TWSI Device Address */ +int I2cDevSize, /* TWSI Device Size (e.g. I2C_025K_DEV or I2C_2K_DEV) */ +int I2cReg, /* TWSI Device Register Address */ +int I2cBurst) /* TWSI Burst Flag */ +{ + SK_OUT32(IoC, B2_I2C_DATA, I2cData); + + SK_I2C_CTL(IoC, I2C_WRITE, I2cDev, I2cDevSize, I2cReg, I2cBurst); + + return(SkI2cWait(pAC, IoC, I2C_WRITE)); +} /* SkI2cWrite*/ + + +#ifdef SK_DIAG +/* + * reads a single byte or 4 bytes from the TWSI device + * + * returns the word read + */ +SK_U32 SkI2cRead( +SK_AC *pAC, /* Adapter Context */ +SK_IOC IoC, /* I/O Context */ +int I2cDev, /* TWSI Device Address */ +int I2cDevSize, /* TWSI Device Size (e.g. I2C_025K_DEV or I2C_2K_DEV) */ +int I2cReg, /* TWSI Device Register Address */ +int I2cBurst) /* TWSI Burst Flag */ +{ + SK_U32 Data; + + SK_OUT32(IoC, B2_I2C_DATA, 0); + + SK_I2C_CTL(IoC, I2C_READ, I2cDev, I2cDevSize, I2cReg, I2cBurst); + + if (SkI2cWait(pAC, IoC, I2C_READ) != 0) { + w_print("%s\n", SKERR_I2C_E002MSG); + } + + SK_IN32(IoC, B2_I2C_DATA, &Data); + + return(Data); +} /* SkI2cRead */ +#endif /* SK_DIAG */ + + +/* + * read a sensor's value + * + * This function reads a sensor's value from the TWSI sensor chip. The sensor + * is defined by its index into the sensors database in the struct pAC points + * to. + * Returns + * 1 if the read is completed + * 0 if the read must be continued (TWSI Bus still allocated) + */ +int SkI2cReadSensor( +SK_AC *pAC, /* Adapter Context */ +SK_IOC IoC, /* I/O Context */ +SK_SENSOR *pSen) /* Sensor to be read */ +{ + if (pSen->SenRead != NULL) { + return((*pSen->SenRead)(pAC, IoC, pSen)); + } + + return(0); /* no success */ +} /* SkI2cReadSensor */ + +/* + * Do the Init state 0 initialization + */ +static int SkI2cInit0( +SK_AC *pAC) /* Adapter Context */ +{ + int i; + SK_SENSOR *pSen; + + /* Begin with first sensor */ + pAC->I2c.CurrSens = 0; + + /* Begin with timeout control for state machine */ + pAC->I2c.TimerMode = SK_TIMER_WATCH_SM; + + /* Set sensor number to zero */ + pAC->I2c.MaxSens = 0; + +#ifndef SK_DIAG + /* Initialize Number of Dummy Reads */ + pAC->I2c.DummyReads = SK_MAX_SENSORS; +#endif /* !SK_DIAG */ + + for (i = 0; i < SK_MAX_SENSORS; i++) { + pSen = &pAC->I2c.SenTable[i]; + + pSen->SenDesc = "unknown"; + pSen->SenType = SK_SEN_UNKNOWN; + pSen->SenThreErrHigh = 0; + pSen->SenThreErrLow = 0; + pSen->SenThreWarnHigh = 0; + pSen->SenThreWarnLow = 0; + pSen->SenReg = LM80_FAN2_IN; + pSen->SenInit = SK_SEN_DYN_INIT_NONE; + pSen->SenValue = 0; + pSen->SenErrFlag = SK_SEN_ERR_NOT_PRESENT; + pSen->SenErrCts = 0; + pSen->SenBegErrTS = 0; + pSen->SenState = SK_SEN_IDLE; + pSen->SenRead = NULL; + pSen->SenDev = 0; + } + + /* Now we are "INIT data"ed */ + pAC->I2c.InitLevel = SK_INIT_DATA; + return(0); +} /* SkI2cInit0*/ + + +/* + * Do the init state 1 initialization + * + * initialize the following register of the LM80: + * Configuration register: + * - START, noINT, activeLOW, noINT#Clear, noRESET, noCI, noGPO#, noINIT + * + * Interrupt Mask Register 1: + * - all interrupts are Disabled (0xff) + * + * Interrupt Mask Register 2: + * - all interrupts are Disabled (0xff) Interrupt modi doesn't matter. + * + * Fan Divisor/RST_OUT register: + * - Divisors set to 1 (bits 00), all others 0s. + * + * OS# Configuration/Temperature resolution Register: + * - all 0s + * + */ +static int SkI2cInit1( +SK_AC *pAC, /* Adapter Context */ +SK_IOC IoC) /* I/O Context */ +{ + int i; + SK_U8 I2cSwCtrl; + SK_GEPORT *pPrt; /* GIni Port struct pointer */ + SK_SENSOR *pSen; + + if (pAC->I2c.InitLevel != SK_INIT_DATA) { + /* Re-init not needed in TWSI module */ + return(0); + } + + if (pAC->GIni.GIChipId == CHIP_ID_YUKON_EC || + pAC->GIni.GIChipId == CHIP_ID_YUKON_FE) { + /* No sensors on Yukon-EC and Yukon-FE */ + return(0); + } + + /* Set the Direction of TWSI-Data Pin to IN */ + SK_I2C_CLR_BIT(IoC, I2C_DATA_DIR | I2C_DATA); + + /* Check for 32-Bit Yukon with Low at TWSI-Data Pin */ + SK_I2C_GET_SW(IoC, &I2cSwCtrl); + + if ((I2cSwCtrl & I2C_DATA) == 0) { + /* this is a 32-Bit board */ + pAC->GIni.GIYukon32Bit = SK_TRUE; + return(0); + } + + /* Check for 64 Bit Yukon without sensors */ + if (SkI2cWrite(pAC, IoC, 0, LM80_ADDR, I2C_025K_DEV, LM80_CFG, 0) != 0) { + return(0); + } + + (void)SkI2cWrite(pAC, IoC, 0xffUL, LM80_ADDR, I2C_025K_DEV, LM80_IMSK_1, 0); + + (void)SkI2cWrite(pAC, IoC, 0xffUL, LM80_ADDR, I2C_025K_DEV, LM80_IMSK_2, 0); + + (void)SkI2cWrite(pAC, IoC, 0, LM80_ADDR, I2C_025K_DEV, LM80_FAN_CTRL, 0); + + (void)SkI2cWrite(pAC, IoC, 0, LM80_ADDR, I2C_025K_DEV, LM80_TEMP_CTRL, 0); + + (void)SkI2cWrite(pAC, IoC, (SK_U32)LM80_CFG_START, LM80_ADDR, I2C_025K_DEV, + LM80_CFG, 0); + + /* + * MaxSens has to be updated here, because PhyType is not + * set when performing Init Level 0 + */ + pAC->I2c.MaxSens = 5; + + pPrt = &pAC->GIni.GP[0]; + + if (pAC->GIni.GIGenesis) { + if (pPrt->PhyType == SK_PHY_BCOM) { + if (pAC->GIni.GIMacsFound == 1) { + pAC->I2c.MaxSens += 1; + } + else { + pAC->I2c.MaxSens += 3; + } + } + } + else { + pAC->I2c.MaxSens += 3; + } + + for (i = 0; i < pAC->I2c.MaxSens; i++) { + pSen = &pAC->I2c.SenTable[i]; + switch (i) { + case 0: + pSen->SenDesc = "Temperature"; + pSen->SenType = SK_SEN_TEMP; + pSen->SenThreErrHigh = SK_SEN_TEMP_HIGH_ERR; + pSen->SenThreWarnHigh = SK_SEN_TEMP_HIGH_WARN; + pSen->SenThreWarnLow = SK_SEN_TEMP_LOW_WARN; + pSen->SenThreErrLow = SK_SEN_TEMP_LOW_ERR; + pSen->SenReg = LM80_TEMP_IN; + break; + case 1: + pSen->SenDesc = "Voltage PCI"; + pSen->SenType = SK_SEN_VOLT; + pSen->SenThreErrHigh = SK_SEN_PCI_5V_HIGH_ERR; + pSen->SenThreWarnHigh = SK_SEN_PCI_5V_HIGH_WARN; + if (pAC->GIni.GIPciBus != SK_PEX_BUS) { + pSen->SenThreWarnLow = SK_SEN_PCI_5V_LOW_WARN; + pSen->SenThreErrLow = SK_SEN_PCI_5V_LOW_ERR; + } + else { + pSen->SenThreWarnLow = 0; + pSen->SenThreErrLow = 0; + } + pSen->SenReg = LM80_VT0_IN; + break; + case 2: + pSen->SenDesc = "Voltage PCI-IO"; + pSen->SenType = SK_SEN_VOLT; + pSen->SenThreErrHigh = SK_SEN_PCI_IO_5V_HIGH_ERR; + pSen->SenThreWarnHigh = SK_SEN_PCI_IO_5V_HIGH_WARN; + if (pAC->GIni.GIPciBus != SK_PEX_BUS) { + pSen->SenThreWarnLow = SK_SEN_PCI_IO_3V3_LOW_WARN; + pSen->SenThreErrLow = SK_SEN_PCI_IO_3V3_LOW_ERR; + } + else { + pSen->SenThreWarnLow = 0; + pSen->SenThreErrLow = 0; + } + pSen->SenReg = LM80_VT1_IN; + pSen->SenInit = SK_SEN_DYN_INIT_PCI_IO; + break; + case 3: + if (pAC->GIni.GIGenesis) { + pSen->SenDesc = "Voltage ASIC"; + } + else { + pSen->SenDesc = "Voltage VMAIN"; + } + pSen->SenType = SK_SEN_VOLT; + pSen->SenThreErrHigh = SK_SEN_VDD_HIGH_ERR; + pSen->SenThreWarnHigh = SK_SEN_VDD_HIGH_WARN; + pSen->SenThreWarnLow = SK_SEN_VDD_LOW_WARN; + pSen->SenThreErrLow = SK_SEN_VDD_LOW_ERR; + pSen->SenReg = LM80_VT2_IN; + break; + case 4: + if (pAC->GIni.GIGenesis) { + if (pPrt->PhyType == SK_PHY_BCOM) { + pSen->SenDesc = "Voltage PHY A PLL"; + pSen->SenThreErrHigh = SK_SEN_PLL_3V3_HIGH_ERR; + pSen->SenThreWarnHigh = SK_SEN_PLL_3V3_HIGH_WARN; + pSen->SenThreWarnLow = SK_SEN_PLL_3V3_LOW_WARN; + pSen->SenThreErrLow = SK_SEN_PLL_3V3_LOW_ERR; + } + else { + pSen->SenDesc = "Voltage PMA"; + pSen->SenThreErrHigh = SK_SEN_PLL_3V3_HIGH_ERR; + pSen->SenThreWarnHigh = SK_SEN_PLL_3V3_HIGH_WARN; + pSen->SenThreWarnLow = SK_SEN_PLL_3V3_LOW_WARN; + pSen->SenThreErrLow = SK_SEN_PLL_3V3_LOW_ERR; + } + } + else { + pSen->SenDesc = "Voltage VAUX"; + pSen->SenThreErrHigh = SK_SEN_VAUX_3V3_HIGH_ERR; + pSen->SenThreWarnHigh = SK_SEN_VAUX_3V3_HIGH_WARN; + if (pAC->GIni.GIVauxAvail) { + pSen->SenThreWarnLow = SK_SEN_VAUX_3V3_LOW_WARN; + pSen->SenThreErrLow = SK_SEN_VAUX_3V3_LOW_ERR; + } + else { + pSen->SenThreErrLow = 0; + pSen->SenThreWarnLow = 0; + } + } + pSen->SenType = SK_SEN_VOLT; + pSen->SenReg = LM80_VT3_IN; + break; + case 5: + if (CHIP_ID_YUKON_2(pAC)) { + if (pAC->GIni.GIChipRev == 0) { + pSen->SenDesc = "Voltage Core 1V3"; + pSen->SenThreErrHigh = SK_SEN_CORE_1V3_HIGH_ERR; + pSen->SenThreWarnHigh = SK_SEN_CORE_1V3_HIGH_WARN; + pSen->SenThreWarnLow = SK_SEN_CORE_1V3_LOW_WARN; + pSen->SenThreErrLow = SK_SEN_CORE_1V3_LOW_ERR; + } + else { + pSen->SenDesc = "Voltage Core 1V2"; + pSen->SenThreErrHigh = SK_SEN_CORE_1V2_HIGH_ERR; + pSen->SenThreWarnHigh = SK_SEN_CORE_1V2_HIGH_WARN; + pSen->SenThreWarnLow = SK_SEN_CORE_1V2_LOW_WARN; + pSen->SenThreErrLow = SK_SEN_CORE_1V2_LOW_ERR; + } + } + else { + if (pAC->GIni.GIGenesis) { + pSen->SenDesc = "Voltage PHY 2V5"; + pSen->SenThreErrHigh = SK_SEN_PHY_2V5_HIGH_ERR; + pSen->SenThreWarnHigh = SK_SEN_PHY_2V5_HIGH_WARN; + pSen->SenThreWarnLow = SK_SEN_PHY_2V5_LOW_WARN; + pSen->SenThreErrLow = SK_SEN_PHY_2V5_LOW_ERR; + } + else { + pSen->SenDesc = "Voltage Core 1V5"; + pSen->SenThreErrHigh = SK_SEN_CORE_1V5_HIGH_ERR; + pSen->SenThreWarnHigh = SK_SEN_CORE_1V5_HIGH_WARN; + pSen->SenThreWarnLow = SK_SEN_CORE_1V5_LOW_WARN; + pSen->SenThreErrLow = SK_SEN_CORE_1V5_LOW_ERR; + } + } + pSen->SenType = SK_SEN_VOLT; + pSen->SenReg = LM80_VT4_IN; + break; + case 6: + if (CHIP_ID_YUKON_2(pAC)) { + pSen->SenDesc = "Voltage PHY 1V5"; + pSen->SenThreErrHigh = SK_SEN_CORE_1V5_HIGH_ERR; + pSen->SenThreWarnHigh = SK_SEN_CORE_1V5_HIGH_WARN; + if (pAC->GIni.GIPciBus == SK_PEX_BUS) { + pSen->SenThreWarnLow = SK_SEN_CORE_1V5_LOW_WARN; + pSen->SenThreErrLow = SK_SEN_CORE_1V5_LOW_ERR; + } + else { + pSen->SenThreWarnLow = 0; + pSen->SenThreErrLow = 0; + } + } + else { + if (pAC->GIni.GIGenesis) { + pSen->SenDesc = "Voltage PHY B PLL"; + } + else { + pSen->SenDesc = "Voltage PHY 3V3"; + } + pSen->SenThreErrHigh = SK_SEN_PLL_3V3_HIGH_ERR; + pSen->SenThreWarnHigh = SK_SEN_PLL_3V3_HIGH_WARN; + pSen->SenThreWarnLow = SK_SEN_PLL_3V3_LOW_WARN; + pSen->SenThreErrLow = SK_SEN_PLL_3V3_LOW_ERR; + } + pSen->SenType = SK_SEN_VOLT; + pSen->SenReg = LM80_VT5_IN; + break; + case 7: + if (pAC->GIni.GIGenesis) { + pSen->SenDesc = "Speed Fan"; + pSen->SenType = SK_SEN_FAN; + pSen->SenThreErrHigh = SK_SEN_FAN_HIGH_ERR; + pSen->SenThreWarnHigh = SK_SEN_FAN_HIGH_WARN; + pSen->SenThreWarnLow = SK_SEN_FAN_LOW_WARN; + pSen->SenThreErrLow = SK_SEN_FAN_LOW_ERR; + pSen->SenReg = LM80_FAN2_IN; + } + else { + pSen->SenDesc = "Voltage PHY 2V5"; + pSen->SenType = SK_SEN_VOLT; + pSen->SenThreErrHigh = SK_SEN_PHY_2V5_HIGH_ERR; + pSen->SenThreWarnHigh = SK_SEN_PHY_2V5_HIGH_WARN; + pSen->SenThreWarnLow = SK_SEN_PHY_2V5_LOW_WARN; + pSen->SenThreErrLow = SK_SEN_PHY_2V5_LOW_ERR; + pSen->SenReg = LM80_VT6_IN; + } + break; + default: + SK_ERR_LOG(pAC, SK_ERRCL_INIT | SK_ERRCL_SW, + SKERR_I2C_E001, SKERR_I2C_E001MSG); + break; + } + + pSen->SenValue = 0; + pSen->SenErrFlag = SK_SEN_ERR_OK; + pSen->SenErrCts = 0; + pSen->SenBegErrTS = 0; + pSen->SenState = SK_SEN_IDLE; + if (pSen->SenThreWarnLow != 0) { + pSen->SenRead = SkLm80ReadSensor; + } + pSen->SenDev = LM80_ADDR; + } + +#ifndef SK_DIAG + pAC->I2c.DummyReads = pAC->I2c.MaxSens; +#endif /* !SK_DIAG */ + + /* Clear TWSI IRQ */ + SK_OUT32(IoC, B2_I2C_IRQ, I2C_CLR_IRQ); + + /* Now we are I/O initialized */ + pAC->I2c.InitLevel = SK_INIT_IO; + return(0); +} /* SkI2cInit1 */ + + +/* + * Init level 2: Start first sensor read. + */ +static int SkI2cInit2( +SK_AC *pAC, /* Adapter Context */ +SK_IOC IoC) /* I/O Context */ +{ + int ReadComplete; + SK_SENSOR *pSen; + + if (pAC->I2c.InitLevel != SK_INIT_IO) { + /* ReInit not needed in TWSI module */ + /* Init0 and Init2 not permitted */ + return(0); + } + + pSen = &pAC->I2c.SenTable[pAC->I2c.CurrSens]; + + ReadComplete = SkI2cReadSensor(pAC, IoC, pSen); + + if (ReadComplete) { + SK_ERR_LOG(pAC, SK_ERRCL_INIT, SKERR_I2C_E008, SKERR_I2C_E008MSG); + } + + /* Now we are correctly initialized */ + pAC->I2c.InitLevel = SK_INIT_RUN; + + return(0); +} /* SkI2cInit2*/ + + +/* + * Initialize TWSI devices + * + * Get the first voltage value and discard it. + * Go into temperature read mode. A default pointer is not set. + * + * The things to be done depend on the init level in the parameter list: + * Level 0: + * Initialize only the data structures. Do NOT access hardware. + * Level 1: + * Initialize hardware through SK_IN / SK_OUT commands. Do NOT use interrupts. + * Level 2: + * Everything is possible. Interrupts may be used from now on. + * + * return: + * 0 = success + * other = error. + */ +int SkI2cInit( +SK_AC *pAC, /* Adapter Context */ +SK_IOC IoC, /* I/O Context needed in levels 1 and 2 */ +int Level) /* Init Level */ +{ + + switch (Level) { + case SK_INIT_DATA: + return(SkI2cInit0(pAC)); + case SK_INIT_IO: + return(SkI2cInit1(pAC, IoC)); + case SK_INIT_RUN: + return(SkI2cInit2(pAC, IoC)); + default: + break; + } + + return(0); +} /* SkI2cInit */ + + +#ifndef SK_DIAG +/* + * Interrupt service function for the TWSI Interface + * + * Clears the Interrupt source + * + * Reads the register and check it for sending a trap. + * + * Starts the timer if necessary. + */ +void SkI2cIsr( +SK_AC *pAC, /* Adapter Context */ +SK_IOC IoC) /* I/O Context */ +{ + SK_EVPARA Para; + + /* Clear TWSI IRQ */ + SK_OUT32(IoC, B2_I2C_IRQ, I2C_CLR_IRQ); + + Para.Para64 = 0; + SkEventQueue(pAC, SKGE_I2C, SK_I2CEV_IRQ, Para); +} /* SkI2cIsr */ + + +/* + * Check this sensors Value against the threshold and send events. + */ +static void SkI2cCheckSensor( +SK_AC *pAC, /* Adapter Context */ +SK_SENSOR *pSen) +{ + SK_EVPARA ParaLocal; + SK_BOOL TooHigh; /* Is sensor too high? */ + SK_BOOL TooLow; /* Is sensor too low? */ + SK_U64 CurrTime; /* Current Time */ + SK_BOOL DoTrapSend; /* We need to send a trap */ + SK_BOOL DoErrLog; /* We need to log the error */ + SK_BOOL IsError; /* Error occured */ + + /* Check Dummy Reads first */ + if (pAC->I2c.DummyReads > 0) { + pAC->I2c.DummyReads--; + return; + } + + /* Get the current time */ + CurrTime = SkOsGetTime(pAC); + + /* Set para to the most useful setting: The current sensor. */ + ParaLocal.Para64 = (SK_U64)pAC->I2c.CurrSens; + + /* Check the Value against the thresholds. First: Error Thresholds */ + TooHigh = pSen->SenValue > pSen->SenThreErrHigh; + TooLow = pSen->SenValue < pSen->SenThreErrLow; + + IsError = SK_FALSE; + + if (TooHigh || TooLow) { + /* Error condition is satisfied */ + DoTrapSend = SK_TRUE; + DoErrLog = SK_TRUE; + + /* Now error condition is satisfied */ + IsError = SK_TRUE; + + if (pSen->SenErrFlag == SK_SEN_ERR_ERR) { + /* This state is the former one */ + + /* So check first whether we have to send a trap */ + if (pSen->SenLastErrTrapTS + SK_SEN_ERR_TR_HOLD > CurrTime) { + /* + * Do NOT send the Trap. The hold back time + * has to run out first. + */ + DoTrapSend = SK_FALSE; + } + + /* Check now whether we have to log an Error */ + if (pSen->SenLastErrLogTS + SK_SEN_ERR_LOG_HOLD > CurrTime) { + /* + * Do NOT log the error. The hold back time + * has to run out first. + */ + DoErrLog = SK_FALSE; + } + } + else { + /* We came from a different state -> Set Begin Time Stamp */ + pSen->SenBegErrTS = CurrTime; + pSen->SenErrFlag = SK_SEN_ERR_ERR; + } + + if (DoTrapSend) { + /* Set current Time */ + pSen->SenLastErrTrapTS = CurrTime; + pSen->SenErrCts++; + + /* Queue PNMI Event */ + SkEventQueue(pAC, SKGE_PNMI, TooHigh ? + SK_PNMI_EVT_SEN_ERR_UPP : SK_PNMI_EVT_SEN_ERR_LOW, + ParaLocal); + } + + if (DoErrLog) { + /* Set current Time */ + pSen->SenLastErrLogTS = CurrTime; + + if (pSen->SenType == SK_SEN_TEMP) { + SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_I2C_E011, SKERR_I2C_E011MSG); + } + else if (pSen->SenType == SK_SEN_VOLT) { + SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_I2C_E012, SKERR_I2C_E012MSG); + } + else { + SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_I2C_E015, SKERR_I2C_E015MSG); + } + } + } + + /* Check the Value against the thresholds */ + /* 2nd: Warning thresholds */ + TooHigh = pSen->SenValue > pSen->SenThreWarnHigh; + TooLow = pSen->SenValue < pSen->SenThreWarnLow; + + if (!IsError && (TooHigh || TooLow)) { + /* Error condition is satisfied */ + DoTrapSend = SK_TRUE; + DoErrLog = SK_TRUE; + + if (pSen->SenErrFlag == SK_SEN_ERR_WARN) { + /* This state is the former one */ + + /* So check first whether we have to send a trap */ + if (pSen->SenLastWarnTrapTS + SK_SEN_WARN_TR_HOLD > CurrTime) { + /* + * Do NOT send the Trap. The hold back time + * has to run out first. + */ + DoTrapSend = SK_FALSE; + } + + /* Check now whether we have to log an Error */ + if (pSen->SenLastWarnLogTS + SK_SEN_WARN_LOG_HOLD > CurrTime) { + /* + * Do NOT log the error. The hold back time + * has to run out first. + */ + DoErrLog = SK_FALSE; + } + } + else { + /* We came from a different state -> Set Begin Time Stamp */ + pSen->SenBegWarnTS = CurrTime; + pSen->SenErrFlag = SK_SEN_ERR_WARN; + } + + if (DoTrapSend) { + /* Set current Time */ + pSen->SenLastWarnTrapTS = CurrTime; + pSen->SenWarnCts++; + + /* Queue PNMI Event */ + SkEventQueue(pAC, SKGE_PNMI, TooHigh ? + SK_PNMI_EVT_SEN_WAR_UPP : SK_PNMI_EVT_SEN_WAR_LOW, ParaLocal); + } + + if (DoErrLog) { + /* Set current Time */ + pSen->SenLastWarnLogTS = CurrTime; + + if (pSen->SenType == SK_SEN_TEMP) { + SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_I2C_E009, SKERR_I2C_E009MSG); + } + else if (pSen->SenType == SK_SEN_VOLT) { + SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_I2C_E010, SKERR_I2C_E010MSG); + } + else { + SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_I2C_E014, SKERR_I2C_E014MSG); + } + } + } + + /* Check for NO error at all */ + if (!IsError && !TooHigh && !TooLow) { + /* Set o.k. Status if no error and no warning condition */ + pSen->SenErrFlag = SK_SEN_ERR_OK; + } + + /* End of check against the thresholds */ + + if (pSen->SenInit == SK_SEN_DYN_INIT_PCI_IO) { + /* Bug fix AF: 16.Aug.2001: Correct the init base of LM80 sensor */ + pSen->SenInit = SK_SEN_DYN_INIT_NONE; + + if (pSen->SenValue > SK_SEN_PCI_IO_RANGE_LIMITER) { + /* 5V PCI-IO Voltage */ + pSen->SenThreWarnLow = SK_SEN_PCI_IO_5V_LOW_WARN; + pSen->SenThreErrLow = SK_SEN_PCI_IO_5V_LOW_ERR; + } + else { + /* 3.3V PCI-IO Voltage */ + pSen->SenThreWarnHigh = SK_SEN_PCI_IO_3V3_HIGH_WARN; + pSen->SenThreErrHigh = SK_SEN_PCI_IO_3V3_HIGH_ERR; + } + } + +#ifdef TEST_ONLY + /* Dynamic thresholds also for VAUX of LM80 sensor */ + if (pSen->SenInit == SK_SEN_DYN_INIT_VAUX) { + + pSen->SenInit = SK_SEN_DYN_INIT_NONE; + + /* 3.3V VAUX Voltage */ + if (pSen->SenValue > SK_SEN_VAUX_RANGE_LIMITER) { + pSen->SenThreWarnLow = SK_SEN_VAUX_3V3_LOW_WARN; + pSen->SenThreErrLow = SK_SEN_VAUX_3V3_LOW_ERR; + } + /* 0V VAUX Voltage */ + else { + pSen->SenThreWarnHigh = SK_SEN_VAUX_0V_WARN_ERR; + pSen->SenThreErrHigh = SK_SEN_VAUX_0V_WARN_ERR; + } + } + + /* Check initialization state: the VIO Thresholds need adaption */ + if (!pSen->SenInit && pSen->SenReg == LM80_VT1_IN && + pSen->SenValue > SK_SEN_WARNLOW2C && + pSen->SenValue < SK_SEN_WARNHIGH2) { + + pSen->SenThreErrLow = SK_SEN_ERRLOW2C; + pSen->SenThreWarnLow = SK_SEN_WARNLOW2C; + pSen->SenInit = SK_TRUE; + } + + if (!pSen->SenInit && pSen->SenReg == LM80_VT1_IN && + pSen->SenValue > SK_SEN_WARNLOW2 && + pSen->SenValue < SK_SEN_WARNHIGH2C) { + + pSen->SenThreErrHigh = SK_SEN_ERRHIGH2C; + pSen->SenThreWarnHigh = SK_SEN_WARNHIGH2C; + pSen->SenInit = SK_TRUE; + } +#endif + + if (pSen->SenInit != SK_SEN_DYN_INIT_NONE) { + SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_I2C_E013, SKERR_I2C_E013MSG); + } +} /* SkI2cCheckSensor */ + + +/* + * The only Event to be served is the timeout event + * + */ +int SkI2cEvent( +SK_AC *pAC, /* Adapter Context */ +SK_IOC IoC, /* I/O Context */ +SK_U32 Event, /* Module specific Event */ +SK_EVPARA Para) /* Event specific Parameter */ +{ + int ReadComplete; + SK_SENSOR *pSen; + SK_U32 Time; + SK_EVPARA ParaLocal; + int i; + + /* New case: no sensors */ + if (pAC->I2c.MaxSens == 0) { + return(0); + } + + switch (Event) { + case SK_I2CEV_IRQ: + pSen = &pAC->I2c.SenTable[pAC->I2c.CurrSens]; + ReadComplete = SkI2cReadSensor(pAC, IoC, pSen); + + if (ReadComplete) { + /* Check sensor against defined thresholds */ + SkI2cCheckSensor(pAC, pSen); + + /* Increment Current sensor and set appropriate Timeout */ + pAC->I2c.CurrSens++; + if (pAC->I2c.CurrSens >= pAC->I2c.MaxSens) { + pAC->I2c.CurrSens = 0; + Time = SK_I2C_TIM_LONG; + } + else { + Time = SK_I2C_TIM_SHORT; + } + + /* Start Timer */ + ParaLocal.Para64 = (SK_U64)0; + + pAC->I2c.TimerMode = SK_TIMER_NEW_GAUGING; + + SkTimerStart(pAC, IoC, &pAC->I2c.SenTimer, Time, + SKGE_I2C, SK_I2CEV_TIM, ParaLocal); + } + else { + /* Start Timer */ + ParaLocal.Para64 = (SK_U64)0; + + pAC->I2c.TimerMode = SK_TIMER_WATCH_SM; + + SkTimerStart(pAC, IoC, &pAC->I2c.SenTimer, SK_I2C_TIM_WATCH, + SKGE_I2C, SK_I2CEV_TIM, ParaLocal); + } + break; + case SK_I2CEV_TIM: + if (pAC->I2c.TimerMode == SK_TIMER_NEW_GAUGING) { + + ParaLocal.Para64 = (SK_U64)0; + SkTimerStop(pAC, IoC, &pAC->I2c.SenTimer); + + pSen = &pAC->I2c.SenTable[pAC->I2c.CurrSens]; + ReadComplete = SkI2cReadSensor(pAC, IoC, pSen); + + if (ReadComplete) { + /* Check sensor against defined thresholds */ + SkI2cCheckSensor(pAC, pSen); + + /* Increment Current sensor and set appropriate Timeout */ + pAC->I2c.CurrSens++; + if (pAC->I2c.CurrSens == pAC->I2c.MaxSens) { + pAC->I2c.CurrSens = 0; + Time = SK_I2C_TIM_LONG; + } + else { + Time = SK_I2C_TIM_SHORT; + } + + /* Start Timer */ + ParaLocal.Para64 = (SK_U64)0; + + pAC->I2c.TimerMode = SK_TIMER_NEW_GAUGING; + + SkTimerStart(pAC, IoC, &pAC->I2c.SenTimer, Time, + SKGE_I2C, SK_I2CEV_TIM, ParaLocal); + } + } + else { + pSen = &pAC->I2c.SenTable[pAC->I2c.CurrSens]; + pSen->SenErrFlag = SK_SEN_ERR_FAULTY; + SK_I2C_STOP(IoC); + + /* Increment Current sensor and set appropriate Timeout */ + pAC->I2c.CurrSens++; + if (pAC->I2c.CurrSens == pAC->I2c.MaxSens) { + pAC->I2c.CurrSens = 0; + Time = SK_I2C_TIM_LONG; + } + else { + Time = SK_I2C_TIM_SHORT; + } + + /* Start Timer */ + ParaLocal.Para64 = (SK_U64)0; + + pAC->I2c.TimerMode = SK_TIMER_NEW_GAUGING; + + SkTimerStart(pAC, IoC, &pAC->I2c.SenTimer, Time, + SKGE_I2C, SK_I2CEV_TIM, ParaLocal); + } + break; + case SK_I2CEV_CLEAR: + for (i = 0; i < SK_MAX_SENSORS; i++) { + pSen = &pAC->I2c.SenTable[i]; + + pSen->SenErrFlag = SK_SEN_ERR_OK; + pSen->SenErrCts = 0; + pSen->SenWarnCts = 0; + pSen->SenBegErrTS = 0; + pSen->SenBegWarnTS = 0; + pSen->SenLastErrTrapTS = (SK_U64)0; + pSen->SenLastErrLogTS = (SK_U64)0; + pSen->SenLastWarnTrapTS = (SK_U64)0; + pSen->SenLastWarnLogTS = (SK_U64)0; + } + break; + default: + SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_I2C_E006, SKERR_I2C_E006MSG); + } + + return(0); +} /* SkI2cEvent*/ + +#endif /* !SK_DIAG */ + diff -urN linux-2.4.32-600/drivers/net/sk98lin/skvpd.c linux-2.4.32-600-sk98_831/drivers/net/sk98lin/skvpd.c --- linux-2.4.32-600/drivers/net/sk98lin/skvpd.c Sun Apr 17 15:32:23 2005 +++ linux-2.4.32-600-sk98_831/drivers/net/sk98lin/skvpd.c Sun Feb 26 11:12:56 2006 @@ -1,20 +1,22 @@ /****************************************************************************** * * Name: skvpd.c - * Project: GEnesis, PCI Gigabit Ethernet Adapter - * Purpose: Shared software to read and write VPD data + * Project: Gigabit Ethernet Adapters, VPD-Module + * Version: $Revision: 2.6 $ + * Date: $Date: 2004/11/02 10:47:39 $ + * Purpose: Shared software to read and write VPD * ******************************************************************************/ /****************************************************************************** * - * (C)Copyright 1998-2003 SysKonnect GmbH. + * (C)Copyright 1998-2002 SysKonnect. + * (C)Copyright 2002-2004 Marvell. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. - * * The information in this file is provided "AS IS" without warranty. * ******************************************************************************/ @@ -23,7 +25,7 @@ Please refer skvpd.txt for infomation how to include this module */ static const char SysKonnectFileId[] = - "@(#)$Id: skvpd.c,v 1.37 2003/01/13 10:42:45 rschmidt Exp $ (C) SK"; + "@(#) $Id: skvpd.c,v 2.6 2004/11/02 10:47:39 rschmidt Exp $ (C) Marvell."; #include "h/skdrv1st.h" #include "h/sktypes.h" @@ -57,9 +59,10 @@ SK_U64 start_time; SK_U16 state; - SK_DBG_MSG(pAC,SK_DBGMOD_VPD, SK_DBGCAT_CTRL, + SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_CTRL, ("VPD wait for %s\n", event?"Write":"Read")); start_time = SkOsGetTime(pAC); + do { if (SkOsGetTime(pAC) - start_time > SK_TICKS_PER_SEC) { @@ -79,17 +82,18 @@ ("ERROR:VPD wait timeout\n")); return(1); } - + VPD_IN16(pAC, IoC, PCI_VPD_ADR_REG, &state); - + SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_CTRL, ("state = %x, event %x\n",state,event)); - } while((int)(state & PCI_VPD_FLAG) == event); + } while ((int)(state & PCI_VPD_FLAG) == event); return(0); } -#ifdef SKDIAG + +#ifdef SK_DIAG /* * Read the dword at address 'addr' from the VPD EEPROM. @@ -122,16 +126,15 @@ Rtv = 0; VPD_IN32(pAC, IoC, PCI_VPD_DAT_REG, &Rtv); - + SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_CTRL, ("VPD read dword data = 0x%x\n",Rtv)); return(Rtv); } +#endif /* SK_DIAG */ -#endif /* SKDIAG */ - -#if 0 +#ifdef XXX /* Write the dword 'data' at address 'addr' into the VPD EEPROM, and verify that the data is written. @@ -149,7 +152,6 @@ . over all 3.8 ms 13.2 ms . - Returns 0: success 1: error, I2C transfer does not terminate 2: error, data verify error @@ -187,7 +189,8 @@ return(0); } /* VpdWriteDWord */ -#endif /* 0 */ +#endif /* XXX */ + /* * Read one Stream of 'len' bytes of VPD data, starting at 'addr' from @@ -213,7 +216,7 @@ pComp = (SK_U8 *) buf; for (i = 0; i < Len; i++, buf++) { - if ((i%sizeof(SK_U32)) == 0) { + if ((i % SZ_LONG) == 0) { /* * At the begin of each cycle read the Data Reg * So it is initialized even if only a few bytes @@ -231,14 +234,13 @@ } } - /* Write current Byte */ - VPD_OUT8(pAC, IoC, PCI_VPD_DAT_REG + (i%sizeof(SK_U32)), - *(SK_U8*)buf); + /* Write current byte */ + VPD_OUT8(pAC, IoC, PCI_VPD_DAT_REG + (i % SZ_LONG), *(SK_U8*)buf); - if (((i%sizeof(SK_U32)) == 3) || (i == (Len - 1))) { + if (((i % SZ_LONG) == 3) || (i == (Len - 1))) { /* New Address needs to be written to VPD_ADDR reg */ AdrReg = (SK_U16) Addr; - Addr += sizeof(SK_U32); + Addr += SZ_LONG; AdrReg |= VPD_WRITE; /* WRITE operation */ VPD_OUT16(pAC, IoC, PCI_VPD_ADR_REG, AdrReg); @@ -248,7 +250,7 @@ if (Rtv != 0) { SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR, ("Write Timed Out\n")); - return(i - (i%sizeof(SK_U32))); + return(i - (i % SZ_LONG)); } /* @@ -263,18 +265,18 @@ if (Rtv != 0) { SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR, ("Verify Timed Out\n")); - return(i - (i%sizeof(SK_U32))); + return(i - (i % SZ_LONG)); } - for (j = 0; j <= (int)(i%sizeof(SK_U32)); j++, pComp++) { - + for (j = 0; j <= (int)(i % SZ_LONG); j++, pComp++) { + VPD_IN8(pAC, IoC, PCI_VPD_DAT_REG + j, &Data); - + if (Data != *pComp) { /* Verify Error */ SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR, ("WriteStream Verify Error\n")); - return(i - (i%sizeof(SK_U32)) + j); + return(i - (i % SZ_LONG) + j); } } } @@ -282,7 +284,7 @@ return(Len); } - + /* * Read one Stream of 'len' bytes of VPD data, starting at 'addr' from @@ -302,10 +304,10 @@ int Rtv; for (i = 0; i < Len; i++, buf++) { - if ((i%sizeof(SK_U32)) == 0) { + if ((i % SZ_LONG) == 0) { /* New Address needs to be written to VPD_ADDR reg */ AdrReg = (SK_U16) Addr; - Addr += sizeof(SK_U32); + Addr += SZ_LONG; AdrReg &= ~VPD_WRITE; /* READ operation */ VPD_OUT16(pAC, IoC, PCI_VPD_ADR_REG, AdrReg); @@ -316,13 +318,13 @@ return(i); } } - VPD_IN8(pAC, IoC, PCI_VPD_DAT_REG + (i%sizeof(SK_U32)), - (SK_U8 *)buf); + VPD_IN8(pAC, IoC, PCI_VPD_DAT_REG + (i % SZ_LONG), (SK_U8 *)buf); } return(Len); } + /* * Read ore writes 'len' bytes of VPD data, starting at 'addr' from * or to the I2C EEPROM. @@ -348,14 +350,14 @@ return(0); vpd_rom_size = pAC->vpd.rom_size; - + if (addr > vpd_rom_size - 4) { SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR | SK_DBGCAT_FATAL, ("Address error: 0x%x, exp. < 0x%x\n", addr, vpd_rom_size - 4)); return(0); } - + if (addr + len > vpd_rom_size) { len = vpd_rom_size - addr; SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR, @@ -372,8 +374,8 @@ return(Rtv); } -#ifdef SKDIAG +#if defined (SK_DIAG) || defined (SK_ASF) /* * Read 'len' bytes of VPD data, starting at 'addr'. * @@ -389,6 +391,7 @@ return(VpdTransferBlock(pAC, IoC, buf, addr, len, VPD_READ)); } + /* * Write 'len' bytes of *but to the VPD EEPROM, starting at 'addr'. * @@ -403,18 +406,27 @@ { return(VpdTransferBlock(pAC, IoC, buf, addr, len, VPD_WRITE)); } -#endif /* SKDIAG */ +#endif /* SK_DIAG */ -/* - * (re)initialize the VPD buffer + +/****************************************************************************** * - * Reads the VPD data from the EEPROM into the VPD buffer. - * Get the remaining read only and read / write space. + * VpdInit() - (re)initialize the VPD buffer * - * return 0: success - * 1: fatal VPD error + * Description: + * Reads the VPD data from the EEPROM into the VPD buffer. + * Get the remaining read only and read / write space. + * + * Note: + * This is a local function and should be used locally only. + * However, the ASF module needs to use this function also. + * Therfore it has been published. + * + * Returns: + * 0: success + * 1: fatal VPD error */ -static int VpdInit( +int VpdInit( SK_AC *pAC, /* Adapters context */ SK_IOC IoC) /* IO Context */ { @@ -425,14 +437,14 @@ SK_U16 dev_id; SK_U32 our_reg2; - SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_INIT, ("VpdInit .. ")); - + SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_INIT, ("VpdInit ... ")); + VPD_IN16(pAC, IoC, PCI_DEVICE_ID, &dev_id); - + VPD_IN32(pAC, IoC, PCI_OUR_REG_2, &our_reg2); - + pAC->vpd.rom_size = 256 << ((our_reg2 & PCI_VPD_ROM_SZ) >> 14); - + /* * this function might get used before the hardware is initialized * therefore we cannot always trust in GIChipId @@ -463,16 +475,14 @@ ("Block Read Error\n")); return(1); } - + pAC->vpd.vpd_size = vpd_size; /* Asus K8V Se Deluxe bugfix. Correct VPD content */ - /* MBo April 2004 */ - if( ((unsigned char)pAC->vpd.vpd_buf[0x3f] == 0x38) && - ((unsigned char)pAC->vpd.vpd_buf[0x40] == 0x3c) && - ((unsigned char)pAC->vpd.vpd_buf[0x41] == 0x45) ) { - printk(KERN_INFO "sk98lin : humm... Asus mainboard with buggy VPD ? correcting data.\n"); - (unsigned char)pAC->vpd.vpd_buf[0x40] = 0x38; + i = 62; + if (!SK_STRNCMP(pAC->vpd.vpd_buf + i, " 8vpd.vpd_buf[i + 2] = '8'; } /* find the end tag of the RO area */ @@ -481,9 +491,9 @@ ("Encoding Error: RV Tag not found\n")); return(1); } - + if (r->p_val + r->p_len > pAC->vpd.vpd_buf + vpd_size/2) { - SK_DBG_MSG(pAC,SK_DBGMOD_VPD,SK_DBGCAT_ERR | SK_DBGCAT_FATAL, + SK_DBG_MSG(pAC, SK_DBGMOD_VPD,SK_DBGCAT_ERR | SK_DBGCAT_FATAL, ("Encoding Error: Invalid VPD struct size\n")); return(1); } @@ -493,7 +503,7 @@ for (i = 0, x = 0; (unsigned)i <= (unsigned)vpd_size/2 - r->p_len; i++) { x += pAC->vpd.vpd_buf[i]; } - + if (x != 0) { /* checksum error */ SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR | SK_DBGCAT_FATAL, @@ -507,7 +517,7 @@ ("Encoding Error: RV Tag not found\n")); return(1); } - + if (r->p_val < pAC->vpd.vpd_buf + vpd_size/2) { SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR | SK_DBGCAT_FATAL, ("Encoding Error: Invalid VPD struct size\n")); @@ -527,6 +537,7 @@ return(0); } + /* * find the Keyword 'key' in the VPD buffer and fills the * parameter struct 'p' with it's values @@ -537,7 +548,7 @@ static SK_VPD_PARA *vpd_find_para( SK_AC *pAC, /* common data base */ const char *key, /* keyword to find (e.g. "MN") */ -SK_VPD_PARA *p) /* parameter description struct */ +SK_VPD_PARA *p) /* parameter description struct */ { char *v ; /* points to VPD buffer */ int max; /* Maximum Number of Iterations */ @@ -555,7 +566,7 @@ return(0); } - if (strcmp(key, VPD_NAME) == 0) { + if (SK_STRCMP(key, VPD_NAME) == 0) { p->p_len = VPD_GET_RES_LEN(v); p->p_val = VPD_GET_VAL(v); SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_CTRL, @@ -565,7 +576,7 @@ v += 3 + VPD_GET_RES_LEN(v) + 3; for (;; ) { - if (SK_MEMCMP(key,v,2) == 0) { + if (SK_MEMCMP(key, v, 2) == 0) { p->p_len = VPD_GET_VPD_LEN(v); p->p_val = VPD_GET_VAL(v); SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_CTRL, @@ -575,11 +586,11 @@ /* exit when reaching the "RW" Tag or the maximum of itera. */ max--; - if (SK_MEMCMP(VPD_RW,v,2) == 0 || max == 0) { + if (SK_MEMCMP(VPD_RW, v, 2) == 0 || max == 0) { break; } - if (SK_MEMCMP(VPD_RV,v,2) == 0) { + if (SK_MEMCMP(VPD_RV, v, 2) == 0) { v += 3 + VPD_GET_VPD_LEN(v) + 3; /* skip VPD-W */ } else { @@ -599,6 +610,7 @@ return(0); } + /* * Move 'n' bytes. Begin with the last byte if 'n' is > 0, * Start with the last byte if n is < 0. @@ -633,6 +645,7 @@ } } + /* * setup the VPD keyword 'key' at 'ip'. * @@ -649,10 +662,11 @@ p = (SK_VPD_KEY *) ip; p->p_key[0] = key[0]; p->p_key[1] = key[1]; - p->p_len = (unsigned char) len; - SK_MEMCPY(&p->p_val,buf,len); + p->p_len = (unsigned char)len; + SK_MEMCPY(&p->p_val, buf, len); } + /* * Setup the VPD end tag "RV" / "RW". * Also correct the remaining space variables vpd_free_ro / vpd_free_rw. @@ -678,7 +692,7 @@ if (p->p_key[0] != 'R' || (p->p_key[1] != 'V' && p->p_key[1] != 'W')) { /* something wrong here, encoding error */ - SK_DBG_MSG(pAC,SK_DBGMOD_VPD,SK_DBGCAT_ERR | SK_DBGCAT_FATAL, + SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR | SK_DBGCAT_FATAL, ("Encoding Error: invalid end tag\n")); return(1); } @@ -710,6 +724,7 @@ return(0); } + /* * Insert a VPD keyword into the VPD buffer. * @@ -743,7 +758,7 @@ SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_CTRL, ("VPD setup para key = %s, val = %s\n",key,buf)); - + vpd_size = pAC->vpd.vpd_size; rtv = 0; @@ -871,18 +886,18 @@ } } - if ((signed)strlen(VPD_NAME) + 1 <= *len) { + if ((signed)SK_STRLEN(VPD_NAME) + 1 <= *len) { v = pAC->vpd.vpd_buf; - strcpy(buf,VPD_NAME); - n = strlen(VPD_NAME) + 1; + SK_STRCPY(buf, VPD_NAME); + n = SK_STRLEN(VPD_NAME) + 1; buf += n; *elements = 1; SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_RX, - ("'%c%c' ",v[0],v[1])); + ("'%c%c' ", v[0], v[1])); } else { *len = 0; - SK_DBG_MSG(pAC,SK_DBGMOD_VPD,SK_DBGCAT_ERR, + SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR, ("buffer overflow\n")); return(2); } @@ -890,17 +905,17 @@ v += 3 + VPD_GET_RES_LEN(v) + 3; for (;; ) { /* exit when reaching the "RW" Tag */ - if (SK_MEMCMP(VPD_RW,v,2) == 0) { + if (SK_MEMCMP(VPD_RW, v, 2) == 0) { break; } - if (SK_MEMCMP(VPD_RV,v,2) == 0) { + if (SK_MEMCMP(VPD_RV, v, 2) == 0) { v += 3 + VPD_GET_VPD_LEN(v) + 3; /* skip VPD-W */ continue; } if (n+3 <= *len) { - SK_MEMCPY(buf,v,2); + SK_MEMCPY(buf, v, 2); buf += 2; *buf++ = '\0'; n += 3; @@ -987,13 +1002,14 @@ { if ((*key != 'Y' && *key != 'V') || key[1] < '0' || key[1] > 'Z' || - (key[1] > '9' && key[1] < 'A') || strlen(key) != 2) { + (key[1] > '9' && key[1] < 'A') || SK_STRLEN(key) != 2) { return(SK_FALSE); } return(SK_TRUE); } + /* * Read the contents of the VPD EEPROM and copy it to the VPD * buffer if not already done. Insert/overwrite the keyword 'key' @@ -1022,7 +1038,7 @@ if ((*key != 'Y' && *key != 'V') || key[1] < '0' || key[1] > 'Z' || - (key[1] > '9' && key[1] < 'A') || strlen(key) != 2) { + (key[1] > '9' && key[1] < 'A') || SK_STRLEN(key) != 2) { SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR, ("illegal key tag, keyword not written\n")); @@ -1038,13 +1054,13 @@ } rtv = 0; - len = strlen(buf); + len = SK_STRLEN(buf); if (len > VPD_MAX_LEN) { /* cut it */ len = VPD_MAX_LEN; rtv = 2; SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR, - ("keyword too long, cut after %d bytes\n",VPD_MAX_LEN)); + ("keyword too long, cut after %d bytes\n", VPD_MAX_LEN)); } if ((rtv2 = VpdSetupPara(pAC, key, buf, len, VPD_RW_KEY, OWR_KEY)) != 0) { SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR, @@ -1055,6 +1071,7 @@ return(rtv); } + /* * Read the contents of the VPD EEPROM and copy it to the * VPD buffer if not already done. Remove the VPD keyword @@ -1078,7 +1095,7 @@ vpd_size = pAC->vpd.vpd_size; - SK_DBG_MSG(pAC,SK_DBGMOD_VPD,SK_DBGCAT_TX,("VPD delete key %s\n",key)); + SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_TX, ("VPD delete key %s\n", key)); if ((pAC->vpd.v.vpd_status & VPD_VALID) == 0) { if (VpdInit(pAC, IoC) != 0) { SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR, @@ -1115,6 +1132,7 @@ return(0); } + /* * If the VPD buffer contains valid data write the VPD * read/write area back to the VPD EEPROM. @@ -1145,7 +1163,6 @@ } - /* * Read the contents of the VPD EEPROM and copy it to the VPD buffer * if not already done. If the keyword "VF" is not present it will be @@ -1174,7 +1191,7 @@ } } - len = strlen(msg); + len = SK_STRLEN(msg); if (len > VPD_MAX_LEN) { /* cut it */ len = VPD_MAX_LEN; diff -urN linux-2.4.32-600/drivers/net/sk98lin/skxmac2.c linux-2.4.32-600-sk98_831/drivers/net/sk98lin/skxmac2.c --- linux-2.4.32-600/drivers/net/sk98lin/skxmac2.c Sat Mar 20 10:08:19 2004 +++ linux-2.4.32-600-sk98_831/drivers/net/sk98lin/skxmac2.c Sun Feb 26 11:13:02 2006 @@ -2,21 +2,24 @@ * * Name: skxmac2.c * Project: Gigabit Ethernet Adapters, Common Modules + * Version: $Revision: 2.52 $ + * Date: $Date: 2005/12/14 16:11:35 $ * Purpose: Contains functions to initialize the MACs and PHYs * ******************************************************************************/ /****************************************************************************** * + * LICENSE: * (C)Copyright 1998-2002 SysKonnect. - * (C)Copyright 2002-2003 Marvell. + * (C)Copyright 2002-2005 Marvell. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. - * * The information in this file is provided "AS IS" without warranty. + * /LICENSE * ******************************************************************************/ @@ -35,7 +38,7 @@ #if (defined(DEBUG) || ((!defined(LINT)) && (!defined(SK_SLIM)))) static const char SysKonnectFileId[] = - "@(#) $Id: skxmac2.c,v 1.102 2003/10/02 16:53:58 rschmidt Exp $ (C) Marvell."; + "@(#) $Id: skxmac2.c,v 2.52 2005/12/14 16:11:35 ibrueder Exp $ (C) Marvell."; #endif #ifdef GENESIS @@ -81,7 +84,7 @@ * Returns: * nothing */ -void SkXmPhyRead( +int SkXmPhyRead( SK_AC *pAC, /* Adapter Context */ SK_IOC IoC, /* I/O Context */ int Port, /* Port Index (MAC_1 + n) */ @@ -92,13 +95,13 @@ SK_GEPORT *pPrt; pPrt = &pAC->GIni.GP[Port]; - + /* write the PHY register's address */ XM_OUT16(IoC, Port, XM_PHY_ADDR, PhyReg | pPrt->PhyAddr); - + /* get the PHY register's value */ XM_IN16(IoC, Port, XM_PHY_DATA, pVal); - + if (pPrt->PhyType != SK_PHY_XMAC) { do { XM_IN16(IoC, Port, XM_MMU_CMD, &Mmu); @@ -108,6 +111,8 @@ /* get the PHY register's value */ XM_IN16(IoC, Port, XM_PHY_DATA, pVal); } + + return(0); } /* SkXmPhyRead */ @@ -120,7 +125,7 @@ * Returns: * nothing */ -void SkXmPhyWrite( +int SkXmPhyWrite( SK_AC *pAC, /* Adapter Context */ SK_IOC IoC, /* I/O Context */ int Port, /* Port Index (MAC_1 + n) */ @@ -131,26 +136,28 @@ SK_GEPORT *pPrt; pPrt = &pAC->GIni.GP[Port]; - + if (pPrt->PhyType != SK_PHY_XMAC) { do { XM_IN16(IoC, Port, XM_MMU_CMD, &Mmu); /* wait until 'Busy' is cleared */ } while ((Mmu & XM_MMU_PHY_BUSY) != 0); } - + /* write the PHY register's address */ XM_OUT16(IoC, Port, XM_PHY_ADDR, PhyReg | pPrt->PhyAddr); - + /* write the PHY register's value */ XM_OUT16(IoC, Port, XM_PHY_DATA, Val); - + if (pPrt->PhyType != SK_PHY_XMAC) { do { XM_IN16(IoC, Port, XM_MMU_CMD, &Mmu); /* wait until 'Busy' is cleared */ } while ((Mmu & XM_MMU_PHY_BUSY) != 0); } + + return(0); } /* SkXmPhyWrite */ #endif /* GENESIS */ @@ -163,63 +170,97 @@ * Description: reads a 16-bit word from GPHY through MDIO * * Returns: - * nothing + * 0 o.k. + * 1 error during MDIO read + * 2 timeout */ -void SkGmPhyRead( +int SkGmPhyRead( SK_AC *pAC, /* Adapter Context */ SK_IOC IoC, /* I/O Context */ int Port, /* Port Index (MAC_1 + n) */ int PhyReg, /* Register Address (Offset) */ SK_U16 SK_FAR *pVal) /* Pointer to Value */ { + SK_U16 Word; SK_U16 Ctrl; SK_GEPORT *pPrt; -#ifdef VCPU - u_long SimCyle; - u_long SimLowTime; - - VCPUgetTime(&SimCyle, &SimLowTime); - VCPUprintf(0, "SkGmPhyRead(%u), SimCyle=%u, SimLowTime=%u\n", - PhyReg, SimCyle, SimLowTime); -#endif /* VCPU */ - + SK_U32 StartTime; + SK_U32 CurrTime; + SK_U32 Delta; + SK_U32 TimeOut; + int Rtv; + + Rtv = 0; + + *pVal = 0xffff; + pPrt = &pAC->GIni.GP[Port]; - + /* set PHY-Register offset and 'Read' OpCode (= 1) */ - *pVal = (SK_U16)(GM_SMI_CT_PHY_AD(pPrt->PhyAddr) | + Word = (SK_U16)(GM_SMI_CT_PHY_AD(pPrt->PhyAddr) | GM_SMI_CT_REG_AD(PhyReg) | GM_SMI_CT_OP_RD); - GM_OUT16(IoC, Port, GM_SMI_CTRL, *pVal); + GM_OUT16(IoC, Port, GM_SMI_CTRL, Word); - GM_IN16(IoC, Port, GM_SMI_CTRL, &Ctrl); - /* additional check for MDC/MDIO activity */ - if ((Ctrl & GM_SMI_CT_BUSY) == 0) { - *pVal = 0; - return; + GM_IN16(IoC, Port, GM_SMI_CTRL, &Ctrl); + + if (Ctrl == 0xffff || (Ctrl & GM_SMI_CT_OP_RD) == 0) { + + SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_ERR, + ("PHY read impossible on Port %d (Ctrl=0x%04x)\n", Port, Ctrl)); + + return(1); } - *pVal |= GM_SMI_CT_BUSY; - - do { + Word |= GM_SMI_CT_BUSY; + + SK_IN32(IoC, GMAC_TI_ST_VAL, &StartTime); + + /* set timeout to 10 ms */ + TimeOut = HW_MS_TO_TICKS(pAC, 10); + + do { /* wait until 'Busy' is cleared and 'ReadValid' is set */ #ifdef VCPU VCPUwaitTime(1000); #endif /* VCPU */ + SK_IN32(IoC, GMAC_TI_ST_VAL, &CurrTime); + + if (CurrTime >= StartTime) { + Delta = CurrTime - StartTime; + } + else { + Delta = CurrTime + ~StartTime + 1; + } + + if (Delta > TimeOut) { + + SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_ERR, + ("PHY read timeout on Port %d (Ctrl=0x%04x)\n", Port, Ctrl)); + Rtv = 2; + break; + } + GM_IN16(IoC, Port, GM_SMI_CTRL, &Ctrl); - /* wait until 'ReadValid' is set */ - } while (Ctrl == *pVal); - - /* get the PHY register's value */ + /* Error on reading SMI Control Register */ + if (Ctrl == 0xffff) { + return(1); + } + + } while ((Ctrl ^ Word) != (GM_SMI_CT_RD_VAL | GM_SMI_CT_BUSY)); + GM_IN16(IoC, Port, GM_SMI_DATA, pVal); -#ifdef VCPU - VCPUgetTime(&SimCyle, &SimLowTime); - VCPUprintf(0, "VCPUgetTime(), SimCyle=%u, SimLowTime=%u\n", - SimCyle, SimLowTime); -#endif /* VCPU */ + /* dummy read after GM_IN16() */ + SK_IN32(IoC, GMAC_TI_ST_VAL, &CurrTime); + SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, + ("SkGmPhyRead Port:%d, Reg=%d, Val = 0x%04X\n", + Port, PhyReg, *pVal)); + + return(Rtv); } /* SkGmPhyRead */ @@ -230,9 +271,11 @@ * Description: writes a 16-bit word to GPHY through MDIO * * Returns: - * nothing + * 0 o.k. + * 1 error during MDIO read + * 2 timeout */ -void SkGmPhyWrite( +int SkGmPhyWrite( SK_AC *pAC, /* Adapter Context */ SK_IOC IoC, /* I/O Context */ int Port, /* Port Index (MAC_1 + n) */ @@ -241,54 +284,78 @@ { SK_U16 Ctrl; SK_GEPORT *pPrt; -#ifdef VCPU - SK_U32 DWord; - u_long SimCyle; - u_long SimLowTime; - - VCPUgetTime(&SimCyle, &SimLowTime); - VCPUprintf(0, "SkGmPhyWrite(Reg=%u, Val=0x%04x), SimCyle=%u, SimLowTime=%u\n", - PhyReg, Val, SimCyle, SimLowTime); -#endif /* VCPU */ - + SK_U32 StartTime; + SK_U32 CurrTime; + SK_U32 Delta; + SK_U32 TimeOut; + + SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, + ("SkGmPhyWrite Port:%d, Reg=%d, Val = 0x%04X\n", + Port, PhyReg, Val)); + pPrt = &pAC->GIni.GP[Port]; - + /* write the PHY register's value */ GM_OUT16(IoC, Port, GM_SMI_DATA, Val); - - /* set PHY-Register offset and 'Write' OpCode (= 0) */ - Val = GM_SMI_CT_PHY_AD(pPrt->PhyAddr) | GM_SMI_CT_REG_AD(PhyReg); - GM_OUT16(IoC, Port, GM_SMI_CTRL, Val); - - GM_IN16(IoC, Port, GM_SMI_CTRL, &Ctrl); - +#ifdef DEBUG /* additional check for MDC/MDIO activity */ - if ((Ctrl & GM_SMI_CT_BUSY) == 0) { - return; + GM_IN16(IoC, Port, GM_SMI_DATA, &Ctrl); + + if (Ctrl != Val) { + + SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_ERR, + ("PHY write impossible on Port %d (Val=0x%04x)\n", Port, Ctrl)); + + return(1); } - - Val |= GM_SMI_CT_BUSY; +#endif /* DEBUG */ - do { -#ifdef VCPU - /* read Timer value */ - SK_IN32(IoC, B2_TI_VAL, &DWord); + /* set PHY-Register offset and 'Write' OpCode (= 0) */ + Ctrl = (SK_U16)(GM_SMI_CT_PHY_AD(pPrt->PhyAddr) | + GM_SMI_CT_REG_AD(PhyReg)); + GM_OUT16(IoC, Port, GM_SMI_CTRL, Ctrl); + + SK_IN32(IoC, GMAC_TI_ST_VAL, &StartTime); + + /* set timeout to 10 ms */ + TimeOut = HW_MS_TO_TICKS(pAC, 10); + + do { /* wait until 'Busy' is cleared */ +#ifdef VCPU VCPUwaitTime(1000); #endif /* VCPU */ + SK_IN32(IoC, GMAC_TI_ST_VAL, &CurrTime); + + if (CurrTime >= StartTime) { + Delta = CurrTime - StartTime; + } + else { + Delta = CurrTime + ~StartTime + 1; + } + + if (Delta > TimeOut) { + + SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_ERR, + ("PHY write timeout on Port %d (Ctrl=0x%04x)\n", Port, Ctrl)); + return(2); + } + GM_IN16(IoC, Port, GM_SMI_CTRL, &Ctrl); - /* wait until 'Busy' is cleared */ - } while (Ctrl == Val); - -#ifdef VCPU - VCPUgetTime(&SimCyle, &SimLowTime); - VCPUprintf(0, "VCPUgetTime(), SimCyle=%u, SimLowTime=%u\n", - SimCyle, SimLowTime); -#endif /* VCPU */ + /* Error on reading SMI Control Register */ + if (Ctrl == 0xffff) { + return(1); + } + } while ((Ctrl & GM_SMI_CT_BUSY) != 0); + + /* dummy read after GM_IN16() */ + SK_IN32(IoC, GMAC_TI_ST_VAL, &CurrTime); + + return(0); } /* SkGmPhyWrite */ #endif /* YUKON */ @@ -310,16 +377,8 @@ int PhyReg, /* Register Address (Offset) */ SK_U16 *pVal) /* Pointer to Value */ { - void (*r_func)(SK_AC *pAC, SK_IOC IoC, int Port, int Reg, SK_U16 *pVal); - if (pAC->GIni.GIGenesis) { - r_func = SkXmPhyRead; - } - else { - r_func = SkGmPhyRead; - } - - r_func(pAC, IoC, Port, PhyReg, pVal); + pAC->GIni.GIFunc.pFnMacPhyRead(pAC, IoC, Port, PhyReg, pVal); } /* SkGePhyRead */ @@ -339,16 +398,8 @@ int PhyReg, /* Register Address (Offset) */ SK_U16 Val) /* Value */ { - void (*w_func)(SK_AC *pAC, SK_IOC IoC, int Port, int Reg, SK_U16 Val); - if (pAC->GIni.GIGenesis) { - w_func = SkXmPhyWrite; - } - else { - w_func = SkGmPhyWrite; - } - - w_func(pAC, IoC, Port, PhyReg, Val); + pAC->GIni.GIFunc.pFnMacPhyWrite(pAC, IoC, Port, PhyReg, Val); } /* SkGePhyWrite */ #endif /* SK_DIAG */ @@ -358,15 +409,15 @@ * SkMacPromiscMode() - Enable / Disable Promiscuous Mode * * Description: - * enables / disables promiscuous mode by setting Mode Register (XMAC) or - * Receive Control Register (GMAC) dep. on board type + * enables / disables promiscuous mode by setting Mode Register (XMAC) or + * Receive Control Register (GMAC) dep. on board type * * Returns: * nothing */ void SkMacPromiscMode( -SK_AC *pAC, /* adapter context */ -SK_IOC IoC, /* IO context */ +SK_AC *pAC, /* Adapter Context */ +SK_IOC IoC, /* I/O Context */ int Port, /* Port Index (MAC_1 + n) */ SK_BOOL Enable) /* Enable / Disable */ { @@ -375,11 +426,11 @@ #endif #ifdef GENESIS SK_U32 MdReg; -#endif +#endif #ifdef GENESIS if (pAC->GIni.GIGenesis) { - + XM_IN32(IoC, Port, XM_MODE, &MdReg); /* enable or disable promiscuous mode */ if (Enable) { @@ -392,12 +443,12 @@ XM_OUT32(IoC, Port, XM_MODE, MdReg); } #endif /* GENESIS */ - + #ifdef YUKON if (pAC->GIni.GIYukon) { - + GM_IN16(IoC, Port, GM_RX_CTRL, &RcReg); - + /* enable or disable unicast and multicast filtering */ if (Enable) { RcReg &= ~(GM_RXCR_UCF_ENA | GM_RXCR_MCF_ENA); @@ -418,28 +469,28 @@ * SkMacHashing() - Enable / Disable Hashing * * Description: - * enables / disables hashing by setting Mode Register (XMAC) or - * Receive Control Register (GMAC) dep. on board type + * enables / disables hashing by setting Mode Register (XMAC) or + * Receive Control Register (GMAC) dep. on board type * * Returns: * nothing */ void SkMacHashing( -SK_AC *pAC, /* adapter context */ -SK_IOC IoC, /* IO context */ +SK_AC *pAC, /* Adapter Context */ +SK_IOC IoC, /* I/O Context */ int Port, /* Port Index (MAC_1 + n) */ SK_BOOL Enable) /* Enable / Disable */ { #ifdef YUKON SK_U16 RcReg; -#endif +#endif #ifdef GENESIS SK_U32 MdReg; #endif #ifdef GENESIS if (pAC->GIni.GIGenesis) { - + XM_IN32(IoC, Port, XM_MODE, &MdReg); /* enable or disable hashing */ if (Enable) { @@ -452,12 +503,12 @@ XM_OUT32(IoC, Port, XM_MODE, MdReg); } #endif /* GENESIS */ - + #ifdef YUKON if (pAC->GIni.GIYukon) { - + GM_IN16(IoC, Port, GM_RX_CTRL, &RcReg); - + /* enable or disable multicast filtering */ if (Enable) { RcReg |= GM_RXCR_MCF_ENA; @@ -485,8 +536,8 @@ * - don't set XMR_FS_ERR in status SK_LENERR_OK_ON/OFF * for inrange length error frames * - don't set XMR_FS_ERR in status SK_BIG_PK_OK_ON/OFF - * for frames > 1514 bytes - * - enable Rx of own packets SK_SELF_RX_ON/OFF + * for frames > 1514 bytes + * - enable Rx of own packets SK_SELF_RX_ON/OFF * * for incoming packets may be enabled/disabled by this function. * Additional modes may be added later. @@ -497,11 +548,11 @@ * nothing */ static void SkXmSetRxCmd( -SK_AC *pAC, /* adapter context */ -SK_IOC IoC, /* IO context */ +SK_AC *pAC, /* Adapter Context */ +SK_IOC IoC, /* I/O Context */ int Port, /* Port Index (MAC_1 + n) */ int Mode) /* Mode is SK_STRIP_FCS_ON/OFF, SK_STRIP_PAD_ON/OFF, - SK_LENERR_OK_ON/OFF, or SK_BIG_PK_OK_ON/OFF */ + SK_LENERR_OK_ON/OFF, or SK_BIG_PK_OK_ON/OFF */ { SK_U16 OldRxCmd; SK_U16 RxCmd; @@ -509,7 +560,7 @@ XM_IN16(IoC, Port, XM_RX_CMD, &OldRxCmd); RxCmd = OldRxCmd; - + switch (Mode & (SK_STRIP_FCS_ON | SK_STRIP_FCS_OFF)) { case SK_STRIP_FCS_ON: RxCmd |= XM_RX_STRIP_FCS; @@ -570,8 +621,8 @@ * The features * - FCS (CRC) stripping, SK_STRIP_FCS_ON/OFF * - don't set GMR_FS_LONG_ERR SK_BIG_PK_OK_ON/OFF - * for frames > 1514 bytes - * - enable Rx of own packets SK_SELF_RX_ON/OFF + * for frames > 1514 bytes + * - enable Rx of own packets SK_SELF_RX_ON/OFF * * for incoming packets may be enabled/disabled by this function. * Additional modes may be added later. @@ -582,20 +633,17 @@ * nothing */ static void SkGmSetRxCmd( -SK_AC *pAC, /* adapter context */ -SK_IOC IoC, /* IO context */ +SK_AC *pAC, /* Adapter Context */ +SK_IOC IoC, /* I/O Context */ int Port, /* Port Index (MAC_1 + n) */ int Mode) /* Mode is SK_STRIP_FCS_ON/OFF, SK_STRIP_PAD_ON/OFF, - SK_LENERR_OK_ON/OFF, or SK_BIG_PK_OK_ON/OFF */ + SK_LENERR_OK_ON/OFF, or SK_BIG_PK_OK_ON/OFF */ { - SK_U16 OldRxCmd; SK_U16 RxCmd; if ((Mode & (SK_STRIP_FCS_ON | SK_STRIP_FCS_OFF)) != 0) { - - GM_IN16(IoC, Port, GM_RX_CTRL, &OldRxCmd); - RxCmd = OldRxCmd; + GM_IN16(IoC, Port, GM_RX_CTRL, &RxCmd); if ((Mode & SK_STRIP_FCS_ON) != 0) { RxCmd |= GM_RXCR_CRC_DIS; @@ -603,17 +651,13 @@ else { RxCmd &= ~GM_RXCR_CRC_DIS; } - /* Write the new mode to the Rx control register if required */ - if (OldRxCmd != RxCmd) { - GM_OUT16(IoC, Port, GM_RX_CTRL, RxCmd); - } + /* Write the new mode to the Rx Control register */ + GM_OUT16(IoC, Port, GM_RX_CTRL, RxCmd); } if ((Mode & (SK_BIG_PK_OK_ON | SK_BIG_PK_OK_OFF)) != 0) { - - GM_IN16(IoC, Port, GM_SERIAL_MODE, &OldRxCmd); - RxCmd = OldRxCmd; + GM_IN16(IoC, Port, GM_SERIAL_MODE, &RxCmd); if ((Mode & SK_BIG_PK_OK_ON) != 0) { RxCmd |= GM_SMOD_JUMBO_ENA; @@ -621,10 +665,8 @@ else { RxCmd &= ~GM_SMOD_JUMBO_ENA; } - /* Write the new mode to the Rx control register if required */ - if (OldRxCmd != RxCmd) { - GM_OUT16(IoC, Port, GM_SERIAL_MODE, RxCmd); - } + /* Write the new mode to the Serial Mode register */ + GM_OUT16(IoC, Port, GM_SERIAL_MODE, RxCmd); } } /* SkGmSetRxCmd */ @@ -639,17 +681,17 @@ * nothing */ void SkMacSetRxCmd( -SK_AC *pAC, /* adapter context */ -SK_IOC IoC, /* IO context */ +SK_AC *pAC, /* Adapter Context */ +SK_IOC IoC, /* I/O Context */ int Port, /* Port Index (MAC_1 + n) */ int Mode) /* Rx Mode */ { if (pAC->GIni.GIGenesis) { - + SkXmSetRxCmd(pAC, IoC, Port, Mode); } else { - + SkGmSetRxCmd(pAC, IoC, Port, Mode); } @@ -666,15 +708,15 @@ * nothing */ void SkMacCrcGener( -SK_AC *pAC, /* adapter context */ -SK_IOC IoC, /* IO context */ +SK_AC *pAC, /* Adapter Context */ +SK_IOC IoC, /* I/O Context */ int Port, /* Port Index (MAC_1 + n) */ SK_BOOL Enable) /* Enable / Disable */ { SK_U16 Word; if (pAC->GIni.GIGenesis) { - + XM_IN16(IoC, Port, XM_TX_CMD, &Word); if (Enable) { @@ -687,9 +729,9 @@ XM_OUT16(IoC, Port, XM_TX_CMD, Word); } else { - + GM_IN16(IoC, Port, GM_TX_CTRL, &Word); - + if (Enable) { Word &= ~GM_TXCR_CRC_DIS; } @@ -719,14 +761,14 @@ * nothing */ void SkXmClrExactAddr( -SK_AC *pAC, /* adapter context */ -SK_IOC IoC, /* IO context */ +SK_AC *pAC, /* Adapter Context */ +SK_IOC IoC, /* I/O Context */ int Port, /* Port Index (MAC_1 + n) */ int StartNum, /* Begin with this Address Register Index (0..15) */ int StopNum) /* Stop after finished with this Register Idx (0..15) */ { int i; - SK_U16 ZeroAddr[3] = {0x0000, 0x0000, 0x0000}; + SK_U16 ZeroAddr[3] = {0, 0, 0}; if ((unsigned)StartNum > 15 || (unsigned)StopNum > 15 || StartNum > StopNum) { @@ -736,7 +778,7 @@ } for (i = StartNum; i <= StopNum; i++) { - XM_OUTADDR(IoC, Port, XM_EXM(i), &ZeroAddr[0]); + XM_OUTADDR(IoC, Port, XM_EXM(i), ZeroAddr); } } /* SkXmClrExactAddr */ #endif /* GENESIS */ @@ -753,21 +795,21 @@ * nothing */ void SkMacFlushTxFifo( -SK_AC *pAC, /* adapter context */ -SK_IOC IoC, /* IO context */ +SK_AC *pAC, /* Adapter Context */ +SK_IOC IoC, /* I/O Context */ int Port) /* Port Index (MAC_1 + n) */ { #ifdef GENESIS SK_U32 MdReg; if (pAC->GIni.GIGenesis) { - + XM_IN32(IoC, Port, XM_MODE, &MdReg); XM_OUT32(IoC, Port, XM_MODE, MdReg | XM_MD_FTF); } #endif /* GENESIS */ - + #ifdef YUKON if (pAC->GIni.GIYukon) { /* no way to flush the FIFO we have to issue a reset */ @@ -789,8 +831,8 @@ * nothing */ void SkMacFlushRxFifo( -SK_AC *pAC, /* adapter context */ -SK_IOC IoC, /* IO context */ +SK_AC *pAC, /* Adapter Context */ +SK_IOC IoC, /* I/O Context */ int Port) /* Port Index (MAC_1 + n) */ { #ifdef GENESIS @@ -803,7 +845,7 @@ XM_OUT32(IoC, Port, XM_MODE, MdReg | XM_MD_FRF); } #endif /* GENESIS */ - + #ifdef YUKON if (pAC->GIni.GIYukon) { /* no way to flush the FIFO we have to issue a reset */ @@ -851,23 +893,23 @@ * nothing */ static void SkXmSoftRst( -SK_AC *pAC, /* adapter context */ -SK_IOC IoC, /* IO context */ +SK_AC *pAC, /* Adapter Context */ +SK_IOC IoC, /* I/O Context */ int Port) /* Port Index (MAC_1 + n) */ { - SK_U16 ZeroAddr[4] = {0x0000, 0x0000, 0x0000, 0x0000}; - + SK_U16 ZeroAddr[4] = {0, 0, 0, 0}; + /* reset the statistics module */ XM_OUT32(IoC, Port, XM_GP_PORT, XM_GP_RES_STAT); /* disable all XMAC IRQs */ XM_OUT16(IoC, Port, XM_IMSK, 0xffff); - + XM_OUT32(IoC, Port, XM_MODE, 0); /* clear Mode Reg */ - + XM_OUT16(IoC, Port, XM_TX_CMD, 0); /* reset TX CMD Reg */ XM_OUT16(IoC, Port, XM_RX_CMD, 0); /* reset RX CMD Reg */ - + /* disable all PHY IRQs */ switch (pAC->GIni.GP[Port].PhyType) { case SK_PHY_BCOM: @@ -885,13 +927,13 @@ } /* clear the Hash Register */ - XM_OUTHASH(IoC, Port, XM_HSM, &ZeroAddr); + XM_OUTHASH(IoC, Port, XM_HSM, ZeroAddr); /* clear the Exact Match Address registers */ SkXmClrExactAddr(pAC, IoC, Port, 0, 15); - + /* clear the Source Check Address registers */ - XM_OUTHASH(IoC, Port, XM_SRC_CHK, &ZeroAddr); + XM_OUTHASH(IoC, Port, XM_SRC_CHK, ZeroAddr); } /* SkXmSoftRst */ @@ -914,8 +956,8 @@ * nothing */ static void SkXmHardRst( -SK_AC *pAC, /* adapter context */ -SK_IOC IoC, /* IO context */ +SK_AC *pAC, /* Adapter Context */ +SK_IOC IoC, /* I/O Context */ int Port) /* Port Index (MAC_1 + n) */ { SK_U32 Reg; @@ -938,19 +980,19 @@ } SK_OUT16(IoC, MR_ADDR(Port, TX_MFF_CTRL1), MFF_SET_MAC_RST); - + SK_IN16(IoC, MR_ADDR(Port, TX_MFF_CTRL1), &Word); - + } while ((Word & MFF_SET_MAC_RST) == 0); } /* For external PHYs there must be special handling */ if (pAC->GIni.GP[Port].PhyType != SK_PHY_XMAC) { - + SK_IN32(IoC, B2_GP_IO, &Reg); - + if (Port == 0) { - Reg |= GP_DIR_0; /* set to output */ + Reg |= GP_DIR_0; /* set to output */ Reg &= ~GP_IO_0; /* set PHY reset (active low) */ } else { @@ -976,12 +1018,12 @@ * nothing */ static void SkXmClearRst( -SK_AC *pAC, /* adapter context */ -SK_IOC IoC, /* IO context */ +SK_AC *pAC, /* Adapter Context */ +SK_IOC IoC, /* I/O Context */ int Port) /* Port Index (MAC_1 + n) */ { SK_U32 DWord; - + /* clear HW reset */ SK_OUT16(IoC, MR_ADDR(Port, TX_MFF_CTRL1), MFF_CLR_MAC_RST); @@ -998,7 +1040,7 @@ /* Clear PHY reset */ SK_OUT32(IoC, B2_GP_IO, DWord); - /* Enable GMII interface */ + /* enable GMII interface */ XM_OUT16(IoC, Port, XM_HW_CFG, XM_HW_GMII_MD); } } /* SkXmClearRst */ @@ -1018,29 +1060,28 @@ * nothing */ static void SkGmSoftRst( -SK_AC *pAC, /* adapter context */ -SK_IOC IoC, /* IO context */ +SK_AC *pAC, /* Adapter Context */ +SK_IOC IoC, /* I/O Context */ int Port) /* Port Index (MAC_1 + n) */ { - SK_U16 EmptyHash[4] = {0x0000, 0x0000, 0x0000, 0x0000}; - SK_U16 RxCtrl; + SK_U16 EmptyHash[4] = { 0x0000, 0x0000, 0x0000, 0x0000 }; + SK_U16 RxCtrl; /* reset the statistics module */ /* disable all GMAC IRQs */ - SK_OUT8(IoC, GMAC_IRQ_MSK, 0); - + SK_OUT8(IoC, MR_ADDR(Port, GMAC_IRQ_MSK), 0); + /* disable all PHY IRQs */ SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_INT_MASK, 0); - + /* clear the Hash Register */ GM_OUTHASH(IoC, Port, GM_MC_ADDR_H1, EmptyHash); - /* Enable Unicast and Multicast filtering */ + /* enable Unicast and Multicast filtering */ GM_IN16(IoC, Port, GM_RX_CTRL, &RxCtrl); - - GM_OUT16(IoC, Port, GM_RX_CTRL, - (SK_U16)(RxCtrl | GM_RXCR_UCF_ENA | GM_RXCR_MCF_ENA)); + + GM_OUT16(IoC, Port, GM_RX_CTRL, RxCtrl | GM_RXCR_UCF_ENA | GM_RXCR_MCF_ENA); } /* SkGmSoftRst */ @@ -1055,16 +1096,16 @@ * nothing */ static void SkGmHardRst( -SK_AC *pAC, /* adapter context */ -SK_IOC IoC, /* IO context */ +SK_AC *pAC, /* Adapter Context */ +SK_IOC IoC, /* I/O Context */ int Port) /* Port Index (MAC_1 + n) */ { SK_U32 DWord; - + /* WA code for COMA mode */ if (pAC->GIni.GIYukonLite && - pAC->GIni.GIChipRev == CHIP_REV_YU_LITE_A3) { - + pAC->GIni.GIChipRev >= CHIP_REV_YU_LITE_A3) { + SK_IN32(IoC, B2_GP_IO, &DWord); DWord |= (GP_DIR_9 | GP_IO_9); @@ -1074,10 +1115,10 @@ } /* set GPHY Control reset */ - SK_OUT32(IoC, MR_ADDR(Port, GPHY_CTRL), GPC_RST_SET); + SK_OUT8(IoC, MR_ADDR(Port, GPHY_CTRL), (SK_U8)GPC_RST_SET); /* set GMAC Control reset */ - SK_OUT32(IoC, MR_ADDR(Port, GMAC_CTRL), GMC_RST_SET); + SK_OUT8(IoC, MR_ADDR(Port, GMAC_CTRL), (SK_U8)GMC_RST_SET); } /* SkGmHardRst */ @@ -1092,24 +1133,29 @@ * nothing */ static void SkGmClearRst( -SK_AC *pAC, /* adapter context */ -SK_IOC IoC, /* IO context */ +SK_AC *pAC, /* Adapter Context */ +SK_IOC IoC, /* I/O Context */ int Port) /* Port Index (MAC_1 + n) */ { SK_U32 DWord; - +#ifndef SK_SLIM + SK_U16 PhyId0; + SK_U16 PhyId1; + SK_U16 Word; +#endif + #ifdef XXX - /* clear GMAC Control reset */ - SK_OUT32(IoC, MR_ADDR(Port, GMAC_CTRL), GMC_RST_CLR); + /* clear GMAC Control reset */ + SK_OUT8(IoC, MR_ADDR(Port, GMAC_CTRL), (SK_U8)GMC_RST_CLR); - /* set GMAC Control reset */ - SK_OUT32(IoC, MR_ADDR(Port, GMAC_CTRL), GMC_RST_SET); + /* set GMAC Control reset */ + SK_OUT8(IoC, MR_ADDR(Port, GMAC_CTRL), (SK_U8)GMC_RST_SET); #endif /* XXX */ /* WA code for COMA mode */ if (pAC->GIni.GIYukonLite && - pAC->GIni.GIChipRev == CHIP_REV_YU_LITE_A3) { - + pAC->GIni.GIChipRev >= CHIP_REV_YU_LITE_A3) { + SK_IN32(IoC, B2_GP_IO, &DWord); DWord |= GP_DIR_9; /* set to output */ @@ -1119,30 +1165,87 @@ SK_OUT32(IoC, B2_GP_IO, DWord); } - /* set HWCFG_MODE */ - DWord = GPC_INT_POL_HI | GPC_DIS_FC | GPC_DIS_SLEEP | - GPC_ENA_XC | GPC_ANEG_ADV_ALL_M | GPC_ENA_PAUSE | - (pAC->GIni.GICopperType ? GPC_HWCFG_GMII_COP : - GPC_HWCFG_GMII_FIB); +#ifdef VCPU + /* set MAC Reset before PHY reset is set */ + SK_OUT8(IoC, MR_ADDR(Port, GMAC_CTRL), (SK_U8)GMC_RST_SET); +#endif /* VCPU */ + + if (CHIP_ID_YUKON_2(pAC)) { + /* set GPHY Control reset */ + SK_OUT8(IoC, MR_ADDR(Port, GPHY_CTRL), (SK_U8)GPC_RST_SET); - /* set GPHY Control reset */ - SK_OUT32(IoC, MR_ADDR(Port, GPHY_CTRL), DWord | GPC_RST_SET); + /* release GPHY Control reset */ + SK_OUT8(IoC, MR_ADDR(Port, GPHY_CTRL), (SK_U8)GPC_RST_CLR); - /* release GPHY Control reset */ - SK_OUT32(IoC, MR_ADDR(Port, GPHY_CTRL), DWord | GPC_RST_CLR); +#ifdef DEBUG + /* additional check for PEX */ + SK_IN16(IoC, GPHY_CTRL, &Word); + + if (pAC->GIni.GIPciBus == SK_PEX_BUS && Word != GPC_RST_CLR) { + + SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_ERR, + ("Error on PEX-bus after GPHY reset\n")); + } +#endif /* DEBUG */ + } + else { + /* set HWCFG_MODE */ + DWord = GPC_INT_POL | GPC_DIS_FC | GPC_DIS_SLEEP | + GPC_ENA_XC | GPC_ANEG_ADV_ALL_M | GPC_ENA_PAUSE | + (pAC->GIni.GICopperType ? GPC_HWCFG_GMII_COP : + GPC_HWCFG_GMII_FIB); + + /* set GPHY Control reset */ + SK_OUT32(IoC, MR_ADDR(Port, GPHY_CTRL), DWord | GPC_RST_SET); + + /* release GPHY Control reset */ + SK_OUT32(IoC, MR_ADDR(Port, GPHY_CTRL), DWord | GPC_RST_CLR); + } #ifdef VCPU + /* wait for internal initialization of GPHY */ + VCPUprintf(0, "Waiting until PHY %d is ready to initialize\n", Port); + VCpuWait(10000); + + /* release GMAC reset */ + SK_OUT8(IoC, MR_ADDR(Port, GMAC_CTRL), (SK_U8)GMC_RST_CLR); + + /* wait for stable GMAC clock */ VCpuWait(9000); #endif /* VCPU */ /* clear GMAC Control reset */ - SK_OUT32(IoC, MR_ADDR(Port, GMAC_CTRL), GMC_PAUSE_ON | GMC_RST_CLR); + SK_OUT8(IoC, MR_ADDR(Port, GMAC_CTRL), (SK_U8)GMC_RST_CLR); + +#ifdef SK_DIAG + if (HW_FEATURE(pAC, HWF_WA_DEV_472) && Port == MAC_2) { + + /* clear GMAC 1 Control reset */ + SK_OUT8(IoC, MR_ADDR(MAC_1, GMAC_CTRL), (SK_U8)GMC_RST_CLR); + + do { + /* set GMAC 2 Control reset */ + SK_OUT8(IoC, MR_ADDR(MAC_2, GMAC_CTRL), (SK_U8)GMC_RST_SET); + + /* clear GMAC 2 Control reset */ + SK_OUT8(IoC, MR_ADDR(MAC_2, GMAC_CTRL), (SK_U8)GMC_RST_CLR); + + SkGmPhyRead(pAC, IoC, MAC_2, PHY_MARV_ID0, &PhyId0); + + SkGmPhyRead(pAC, IoC, MAC_2, PHY_MARV_ID1, &PhyId1); + + SkGmPhyRead(pAC, IoC, MAC_2, PHY_MARV_INT_MASK, &Word); + + } while (Word != 0 || PhyId0 != PHY_MARV_ID0_VAL || + PhyId1 != PHY_MARV_ID1_Y2); + } +#endif /* SK_DIAG */ #ifdef VCPU VCpuWait(2000); - + SK_IN32(IoC, MR_ADDR(Port, GPHY_CTRL), &DWord); - + SK_IN32(IoC, B0_ISRC, &DWord); #endif /* VCPU */ @@ -1160,37 +1263,33 @@ * nothing */ void SkMacSoftRst( -SK_AC *pAC, /* adapter context */ -SK_IOC IoC, /* IO context */ +SK_AC *pAC, /* Adapter Context */ +SK_IOC IoC, /* I/O Context */ int Port) /* Port Index (MAC_1 + n) */ { - SK_GEPORT *pPrt; - - pPrt = &pAC->GIni.GP[Port]; - /* disable receiver and transmitter */ SkMacRxTxDisable(pAC, IoC, Port); #ifdef GENESIS if (pAC->GIni.GIGenesis) { - + SkXmSoftRst(pAC, IoC, Port); } #endif /* GENESIS */ - + #ifdef YUKON if (pAC->GIni.GIYukon) { - + SkGmSoftRst(pAC, IoC, Port); } #endif /* YUKON */ /* flush the MAC's Rx and Tx FIFOs */ SkMacFlushTxFifo(pAC, IoC, Port); - + SkMacFlushRxFifo(pAC, IoC, Port); - pPrt->PState = SK_PRT_STOP; + pAC->GIni.GP[Port].PState = SK_PRT_STOP; } /* SkMacSoftRst */ @@ -1205,30 +1304,32 @@ * nothing */ void SkMacHardRst( -SK_AC *pAC, /* adapter context */ -SK_IOC IoC, /* IO context */ +SK_AC *pAC, /* Adapter Context */ +SK_IOC IoC, /* I/O Context */ int Port) /* Port Index (MAC_1 + n) */ { - + #ifdef GENESIS if (pAC->GIni.GIGenesis) { - + SkXmHardRst(pAC, IoC, Port); } #endif /* GENESIS */ - + #ifdef YUKON if (pAC->GIni.GIYukon) { - + SkGmHardRst(pAC, IoC, Port); } #endif /* YUKON */ + pAC->GIni.GP[Port].PHWLinkUp = SK_FALSE; + pAC->GIni.GP[Port].PState = SK_PRT_RESET; } /* SkMacHardRst */ - +#ifndef SK_SLIM /****************************************************************************** * * SkMacClearRst() - Clear the MAC reset @@ -1239,27 +1340,27 @@ * nothing */ void SkMacClearRst( -SK_AC *pAC, /* adapter context */ -SK_IOC IoC, /* IO context */ +SK_AC *pAC, /* Adapter Context */ +SK_IOC IoC, /* I/O Context */ int Port) /* Port Index (MAC_1 + n) */ { - + #ifdef GENESIS if (pAC->GIni.GIGenesis) { - + SkXmClearRst(pAC, IoC, Port); } #endif /* GENESIS */ - + #ifdef YUKON if (pAC->GIni.GIYukon) { - + SkGmClearRst(pAC, IoC, Port); } #endif /* YUKON */ } /* SkMacClearRst */ - +#endif /* !SK_SLIM */ #ifdef GENESIS /****************************************************************************** @@ -1277,8 +1378,8 @@ * nothing */ void SkXmInitMac( -SK_AC *pAC, /* adapter context */ -SK_IOC IoC, /* IO context */ +SK_AC *pAC, /* Adapter Context */ +SK_IOC IoC, /* I/O Context */ int Port) /* Port Index (MAC_1 + n) */ { SK_GEPORT *pPrt; @@ -1288,13 +1389,13 @@ pPrt = &pAC->GIni.GP[Port]; if (pPrt->PState == SK_PRT_STOP) { - /* Port State: SK_PRT_STOP */ /* Verify that the reset bit is cleared */ SK_IN16(IoC, MR_ADDR(Port, TX_MFF_CTRL1), &SWord); if ((SWord & MFF_SET_MAC_RST) != 0) { /* PState does not match HW state */ - SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E006, SKERR_HWI_E006MSG); + SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_INIT, + ("SkXmInitMac: PState does not match HW state")); /* Correct it */ pPrt->PState = SK_PRT_RESET; } @@ -1313,7 +1414,7 @@ * Must be done AFTER first access to BCOM chip. */ XM_IN16(IoC, Port, XM_MMU_CMD, &SWord); - + XM_OUT16(IoC, Port, XM_MMU_CMD, SWord | XM_MMU_NO_PRE); if (pPrt->PhyId1 == PHY_BCOM_ID1_C0) { @@ -1346,7 +1447,7 @@ * Disable Power Management after reset. */ SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_AUX_CTRL, &SWord); - + SkXmPhyWrite(pAC, IoC, Port, PHY_BCOM_AUX_CTRL, (SK_U16)(SWord | PHY_B_AC_DIS_PM)); @@ -1355,7 +1456,7 @@ /* Dummy read the Interrupt source register */ XM_IN16(IoC, Port, XM_ISRC, &SWord); - + /* * The auto-negotiation process starts immediately after * clearing the reset. The auto-negotiation process should be @@ -1381,7 +1482,7 @@ * independent. Remember this when changing. */ SK_IN16(IoC, (B2_MAC_2 + Port * 8 + i * 2), &SWord); - + XM_OUT16(IoC, Port, (XM_SA + i * 2), SWord); } @@ -1399,7 +1500,7 @@ SWord = SK_XM_THR_SL; /* for single port */ if (pAC->GIni.GIMacsFound > 1) { - switch (pAC->GIni.GIPortUsage) { + switch (pPrt->PPortUsage) { case SK_RED_LINK: SWord = SK_XM_THR_REDL; /* redundant link */ break; @@ -1422,7 +1523,7 @@ /* setup register defaults for the Rx Command Register */ SWord = XM_RX_STRIP_FCS | XM_RX_LENERR_OK; - if (pAC->GIni.GIPortUsage == SK_JUMBO_LINK) { + if (pPrt->PPortUsage == SK_JUMBO_LINK) { SWord |= XM_RX_BIG_PK_OK; } @@ -1434,7 +1535,7 @@ */ SWord |= XM_RX_DIS_CEXT; } - + XM_OUT16(IoC, Port, XM_RX_CMD, SWord); /* @@ -1491,8 +1592,8 @@ * nothing */ void SkGmInitMac( -SK_AC *pAC, /* adapter context */ -SK_IOC IoC, /* IO context */ +SK_AC *pAC, /* Adapter Context */ +SK_IOC IoC, /* I/O Context */ int Port) /* Port Index (MAC_1 + n) */ { SK_GEPORT *pPrt; @@ -1503,24 +1604,29 @@ pPrt = &pAC->GIni.GP[Port]; if (pPrt->PState == SK_PRT_STOP) { - /* Port State: SK_PRT_STOP */ /* Verify that the reset bit is cleared */ SK_IN32(IoC, MR_ADDR(Port, GMAC_CTRL), &DWord); - + if ((DWord & GMC_RST_SET) != 0) { /* PState does not match HW state */ - SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E006, SKERR_HWI_E006MSG); + SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, + ("SkGmInitMac: PState does not match HW state")); /* Correct it */ pPrt->PState = SK_PRT_RESET; } + else { + /* enable PHY interrupts */ + SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_INT_MASK, + (SK_U16)PHY_M_DEF_MSK); + } } if (pPrt->PState == SK_PRT_RESET) { - + SkGmHardRst(pAC, IoC, Port); SkGmClearRst(pAC, IoC, Port); - + /* Auto-negotiation ? */ if (pPrt->PLinkMode == SK_LMODE_HALF || pPrt->PLinkMode == SK_LMODE_FULL) { /* Auto-negotiation disabled */ @@ -1530,10 +1636,10 @@ /* disable auto-update for speed, duplex and flow-control */ SWord |= GM_GPCR_AU_ALL_DIS; - + /* setup General Purpose Control Register */ GM_OUT16(IoC, Port, GM_GP_CTRL, SWord); - + SWord = GM_GPCR_AU_ALL_DIS; } else { @@ -1544,7 +1650,10 @@ switch (pPrt->PLinkSpeed) { case SK_LSPEED_AUTO: case SK_LSPEED_1000MBPS: - SWord |= GM_GPCR_SPEED_1000 | GM_GPCR_SPEED_100; + if ((pPrt->PLinkSpeedCap & SK_LSPEED_CAP_1000MBPS) != 0) { + + SWord |= GM_GPCR_SPEED_1000 | GM_GPCR_SPEED_100; + } break; case SK_LSPEED_100MBPS: SWord |= GM_GPCR_SPEED_100; @@ -1562,8 +1671,6 @@ /* flow-control settings */ switch (pPrt->PFlowCtrlMode) { case SK_FLOW_MODE_NONE: - /* set Pause Off */ - SK_OUT32(IoC, MR_ADDR(Port, GMAC_CTRL), GMC_PAUSE_OFF); /* disable Tx & Rx flow-control */ SWord |= GM_GPCR_FC_TX_DIS | GM_GPCR_FC_RX_DIS | GM_GPCR_AU_FCT_DIS; break; @@ -1581,24 +1688,22 @@ GM_OUT16(IoC, Port, GM_GP_CTRL, SWord); /* dummy read the Interrupt Source Register */ - SK_IN16(IoC, GMAC_IRQ_SRC, &SWord); - + SK_IN16(IoC, MR_ADDR(Port, GMAC_IRQ_SRC), &SWord); + #ifndef VCPU - /* read Id from PHY */ - SkGmPhyRead(pAC, IoC, Port, PHY_MARV_ID1, &pPrt->PhyId1); - SkGmInitPhyMarv(pAC, IoC, Port, SK_FALSE); -#endif /* VCPU */ +#endif /* !VCPU */ } (void)SkGmResetCounter(pAC, IoC, Port); /* setup Transmit Control Register */ - GM_OUT16(IoC, Port, GM_TX_CTRL, TX_COL_THR(pPrt->PMacColThres)); + GM_OUT16(IoC, Port, GM_TX_CTRL, (SK_U16)TX_COL_THR(pPrt->PMacColThres)); /* setup Receive Control Register */ - GM_OUT16(IoC, Port, GM_RX_CTRL, GM_RXCR_UCF_ENA | GM_RXCR_MCF_ENA | - GM_RXCR_CRC_DIS); + SWord = GM_RXCR_UCF_ENA | GM_RXCR_MCF_ENA | GM_RXCR_CRC_DIS; + + GM_OUT16(IoC, Port, GM_RX_CTRL, SWord); /* setup Transmit Flow Control Register */ GM_OUT16(IoC, Port, GM_TX_FLOW_CTRL, 0xffff); @@ -1608,31 +1713,29 @@ GM_IN16(IoC, Port, GM_TX_PARAM, &SWord); #endif /* VCPU */ - SWord = TX_JAM_LEN_VAL(pPrt->PMacJamLen) | - TX_JAM_IPG_VAL(pPrt->PMacJamIpgVal) | - TX_IPG_JAM_DATA(pPrt->PMacJamIpgData); - + SWord = (SK_U16)(TX_JAM_LEN_VAL(pPrt->PMacJamLen) | + TX_JAM_IPG_VAL(pPrt->PMacJamIpgVal) | + TX_IPG_JAM_DATA(pPrt->PMacJamIpgData) | + TX_BACK_OFF_LIM(pPrt->PMacBackOffLim)); + GM_OUT16(IoC, Port, GM_TX_PARAM, SWord); /* configure the Serial Mode Register */ -#ifdef VCPU - GM_IN16(IoC, Port, GM_SERIAL_MODE, &SWord); -#endif /* VCPU */ - - SWord = GM_SMOD_VLAN_ENA | IPG_DATA_VAL(pPrt->PMacIpgData); + SWord = (SK_U16)(DATA_BLIND_VAL(pPrt->PMacDataBlind) | + GM_SMOD_VLAN_ENA | IPG_DATA_VAL(pPrt->PMacIpgData)); if (pPrt->PMacLimit4) { /* reset of collision counter after 4 consecutive collisions */ SWord |= GM_SMOD_LIMIT_4; } - if (pAC->GIni.GIPortUsage == SK_JUMBO_LINK) { + if (pPrt->PPortUsage == SK_JUMBO_LINK) { /* enable jumbo mode (Max. Frame Length = 9018) */ SWord |= GM_SMOD_JUMBO_ENA; } - + GM_OUT16(IoC, Port, GM_SERIAL_MODE, SWord); - + /* * configure the GMACs Station Addresses * in PROM you can find our addresses at: @@ -1661,17 +1764,17 @@ else { GM_OUT16(IoC, Port, (GM_SRC_ADDR_1L + i * 4), SWord); } -#else +#else GM_OUT16(IoC, Port, (GM_SRC_ADDR_1L + i * 4), SWord); #endif /* WA_DEV_16 */ - + /* virtual address: will be used for data */ SK_IN16(IoC, (B2_MAC_1 + Port * 8 + i * 2), &SWord); GM_OUT16(IoC, Port, (GM_SRC_ADDR_2L + i * 4), SWord); - + /* reset Multicast filtering Hash registers 1-3 */ - GM_OUT16(IoC, Port, GM_MC_ADDR_H1 + 4*i, 0); + GM_OUT16(IoC, Port, GM_MC_ADDR_H1 + i * 4, 0); } /* reset Multicast filtering Hash register 4 */ @@ -1682,18 +1785,6 @@ GM_OUT16(IoC, Port, GM_RX_IRQ_MSK, 0); GM_OUT16(IoC, Port, GM_TR_IRQ_MSK, 0); -#if defined(SK_DIAG) || defined(DEBUG) - /* read General Purpose Status */ - GM_IN16(IoC, Port, GM_GP_STAT, &SWord); - - SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, - ("MAC Stat Reg.=0x%04X\n", SWord)); -#endif /* SK_DIAG || DEBUG */ - -#ifdef SK_DIAG - c_print("MAC Stat Reg=0x%04X\n", SWord); -#endif /* SK_DIAG */ - } /* SkGmInitMac */ #endif /* YUKON */ @@ -1712,8 +1803,8 @@ * nothing */ void SkXmInitDupMd( -SK_AC *pAC, /* adapter context */ -SK_IOC IoC, /* IO context */ +SK_AC *pAC, /* Adapter Context */ +SK_IOC IoC, /* I/O Context */ int Port) /* Port Index (MAC_1 + n) */ { switch (pAC->GIni.GP[Port].PLinkModeStatus) { @@ -1760,8 +1851,8 @@ * nothing */ void SkXmInitPauseMd( -SK_AC *pAC, /* adapter context */ -SK_IOC IoC, /* IO context */ +SK_AC *pAC, /* Adapter Context */ +SK_IOC IoC, /* I/O Context */ int Port) /* Port Index (MAC_1 + n) */ { SK_GEPORT *pPrt; @@ -1771,11 +1862,11 @@ pPrt = &pAC->GIni.GP[Port]; XM_IN16(IoC, Port, XM_MMU_CMD, &Word); - + if (pPrt->PFlowCtrlStatus == SK_FLOW_STAT_NONE || pPrt->PFlowCtrlStatus == SK_FLOW_STAT_LOC_SEND) { - /* Disable Pause Frame Reception */ + /* disable Pause Frame Reception */ Word |= XM_MMU_IGN_PF; } else { @@ -1783,10 +1874,10 @@ * enabling pause frame reception is required for 1000BT * because the XMAC is not reset if the link is going down */ - /* Enable Pause Frame Reception */ + /* enable Pause Frame Reception */ Word &= ~XM_MMU_IGN_PF; - } - + } + XM_OUT16(IoC, Port, XM_MMU_CMD, Word); XM_IN32(IoC, Port, XM_MODE, &DWord); @@ -1809,10 +1900,10 @@ /* remember this value is defined in big endian (!) */ XM_OUT16(IoC, Port, XM_MAC_PTIME, 0xffff); - /* Set Pause Mode in Mode Register */ + /* set Pause Mode in Mode Register */ DWord |= XM_PAUSE_MODE; - /* Set Pause Mode in MAC Rx FIFO */ + /* set Pause Mode in MAC Rx FIFO */ SK_OUT16(IoC, MR_ADDR(Port, RX_MFF_CTRL1), MFF_ENA_PAUSE); } else { @@ -1820,13 +1911,13 @@ * disable pause frame generation is required for 1000BT * because the XMAC is not reset if the link is going down */ - /* Disable Pause Mode in Mode Register */ + /* disable Pause Mode in Mode Register */ DWord &= ~XM_PAUSE_MODE; - /* Disable Pause Mode in MAC Rx FIFO */ + /* disable Pause Mode in MAC Rx FIFO */ SK_OUT16(IoC, MR_ADDR(Port, RX_MFF_CTRL1), MFF_DIS_PAUSE); } - + XM_OUT32(IoC, Port, XM_MODE, DWord); } /* SkXmInitPauseMd*/ @@ -1843,8 +1934,8 @@ * nothing */ static void SkXmInitPhyXmac( -SK_AC *pAC, /* adapter context */ -SK_IOC IoC, /* IO context */ +SK_AC *pAC, /* Adapter Context */ +SK_IOC IoC, /* I/O Context */ int Port, /* Port Index (MAC_1 + n) */ SK_BOOL DoLoop) /* Should a Phy LoopBack be set-up? */ { @@ -1853,12 +1944,12 @@ pPrt = &pAC->GIni.GP[Port]; Ctrl = 0; - + /* Auto-negotiation ? */ if (pPrt->PLinkMode == SK_LMODE_HALF || pPrt->PLinkMode == SK_LMODE_FULL) { SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, ("InitPhyXmac: no auto-negotiation Port %d\n", Port)); - /* Set DuplexMode in Config register */ + /* set DuplexMode in Config register */ if (pPrt->PLinkMode == SK_LMODE_FULL) { Ctrl |= PHY_CT_DUP_MD; } @@ -1871,9 +1962,9 @@ else { SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, ("InitPhyXmac: with auto-negotiation Port %d\n", Port)); - /* Set Auto-negotiation advertisement */ + /* set Auto-negotiation advertisement */ - /* Set Full/half duplex capabilities */ + /* set Full/half duplex capabilities */ switch (pPrt->PLinkMode) { case SK_LMODE_AUTOHALF: Ctrl |= PHY_X_AN_HD; @@ -1889,7 +1980,7 @@ SKERR_HWI_E015MSG); } - /* Set Flow-control capabilities */ + /* set Flow-control capabilities */ switch (pPrt->PFlowCtrlMode) { case SK_FLOW_MODE_NONE: Ctrl |= PHY_X_P_NO_PAUSE; @@ -1916,7 +2007,7 @@ } if (DoLoop) { - /* Set the Phy Loopback bit, too */ + /* set the Phy Loopback bit, too */ Ctrl |= PHY_CT_LOOP; } @@ -1937,8 +2028,8 @@ * nothing */ static void SkXmInitPhyBcom( -SK_AC *pAC, /* adapter context */ -SK_IOC IoC, /* IO context */ +SK_AC *pAC, /* Adapter Context */ +SK_IOC IoC, /* I/O Context */ int Port, /* Port Index (MAC_1 + n) */ SK_BOOL DoLoop) /* Should a Phy LoopBack be set-up? */ { @@ -1960,7 +2051,7 @@ /* manually Master/Slave ? */ if (pPrt->PMSMode != SK_MS_MODE_AUTO) { Ctrl2 |= PHY_B_1000C_MSE; - + if (pPrt->PMSMode == SK_MS_MODE_MASTER) { Ctrl2 |= PHY_B_1000C_MSC; } @@ -1969,7 +2060,7 @@ if (pPrt->PLinkMode == SK_LMODE_HALF || pPrt->PLinkMode == SK_LMODE_FULL) { SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, ("InitPhyBcom: no auto-negotiation Port %d\n", Port)); - /* Set DuplexMode in Config register */ + /* set DuplexMode in Config register */ if (pPrt->PLinkMode == SK_LMODE_FULL) { Ctrl1 |= PHY_CT_DUP_MD; } @@ -1987,7 +2078,7 @@ else { SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, ("InitPhyBcom: with auto-negotiation Port %d\n", Port)); - /* Set Auto-negotiation advertisement */ + /* set Auto-negotiation advertisement */ /* * Workaround BCOM Errata #1 for the C5 type. @@ -1995,8 +2086,8 @@ * Set Repeater/DTE bit 10 of the 1000Base-T Control Register */ Ctrl2 |= PHY_B_1000C_RD; - - /* Set Full/half duplex capabilities */ + + /* set Full/half duplex capabilities */ switch (pPrt->PLinkMode) { case SK_LMODE_AUTOHALF: Ctrl2 |= PHY_B_1000C_AHD; @@ -2012,7 +2103,7 @@ SKERR_HWI_E015MSG); } - /* Set Flow-control capabilities */ + /* set Flow-control capabilities */ switch (pPrt->PFlowCtrlMode) { case SK_FLOW_MODE_NONE: Ctrl3 |= PHY_B_P_NO_PAUSE; @@ -2034,27 +2125,27 @@ /* Restart Auto-negotiation */ Ctrl1 |= PHY_CT_ANE | PHY_CT_RE_CFG; } - + /* Initialize LED register here? */ /* No. Please do it in SkDgXmitLed() (if required) and swap - init order of LEDs and XMAC. (MAl) */ - + init order of LEDs and XMAC. (MAl) */ + /* Write 1000Base-T Control Register */ SkXmPhyWrite(pAC, IoC, Port, PHY_BCOM_1000T_CTRL, Ctrl2); SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, - ("Set 1000B-T Ctrl Reg=0x%04X\n", Ctrl2)); - + ("Set 1000B-T Ctrl Reg = 0x%04X\n", Ctrl2)); + /* Write AutoNeg Advertisement Register */ SkXmPhyWrite(pAC, IoC, Port, PHY_BCOM_AUNE_ADV, Ctrl3); SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, - ("Set Auto-Neg.Adv.Reg=0x%04X\n", Ctrl3)); - + ("Set Auto-Neg.Adv.Reg = 0x%04X\n", Ctrl3)); + if (DoLoop) { - /* Set the Phy Loopback bit, too */ + /* set the Phy Loopback bit, too */ Ctrl1 |= PHY_CT_LOOP; } - if (pAC->GIni.GIPortUsage == SK_JUMBO_LINK) { + if (pPrt->PPortUsage == SK_JUMBO_LINK) { /* configure FIFO to high latency for transmission of ext. packets */ Ctrl4 |= PHY_B_PEC_HIGH_LA; @@ -2066,45 +2157,41 @@ /* Configure LED Traffic Mode and Jumbo Frame usage if specified */ SkXmPhyWrite(pAC, IoC, Port, PHY_BCOM_P_EXT_CTRL, Ctrl4); - + /* Write to the Phy control register */ SkXmPhyWrite(pAC, IoC, Port, PHY_BCOM_CTRL, Ctrl1); SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, - ("PHY Control Reg=0x%04X\n", Ctrl1)); + ("PHY Control Reg = 0x%04X\n", Ctrl1)); } /* SkXmInitPhyBcom */ #endif /* GENESIS */ #ifdef YUKON -#ifndef SK_SLIM +#ifdef SK_PHY_LP_MODE /****************************************************************************** * * SkGmEnterLowPowerMode() * - * Description: + * Description: * This function sets the Marvell Alaska PHY to the low power mode * given by parameter mode. * The following low power modes are available: - * - * - Coma Mode (Deep Sleep): - * Power consumption: ~15 - 30 mW + * + * - COMA Mode (Deep Sleep): * The PHY cannot wake up on its own. * * - IEEE 22.2.4.1.5 compatible power down mode - * Power consumption: ~240 mW * The PHY cannot wake up on its own. * * - energy detect mode - * Power consumption: ~160 mW * The PHY can wake up on its own by detecting activity * on the CAT 5 cable. * * - energy detect plus mode - * Power consumption: ~150 mW * The PHY can wake up on its own by detecting activity * on the CAT 5 cable. * Connected devices can be woken up by sending normal link - * pulses every one second. + * pulses every second. * * Note: * @@ -2113,113 +2200,298 @@ * 1: error */ int SkGmEnterLowPowerMode( -SK_AC *pAC, /* adapter context */ -SK_IOC IoC, /* IO context */ +SK_AC *pAC, /* Adapter Context */ +SK_IOC IoC, /* I/O Context */ int Port, /* Port Index (e.g. MAC_1) */ SK_U8 Mode) /* low power mode */ { + SK_U8 LastMode; + SK_U8 Byte; SK_U16 Word; + SK_U16 ClkDiv; SK_U32 DWord; - SK_U8 LastMode; + SK_U32 PowerDownBit; + int ChipId; int Ret = 0; - if (pAC->GIni.GIYukonLite && - pAC->GIni.GIChipRev == CHIP_REV_YU_LITE_A3) { + if (!(CHIP_ID_YUKON_2(pAC) || (pAC->GIni.GIYukonLite && + pAC->GIni.GIChipRev >= CHIP_REV_YU_LITE_A3))) { - /* save current power mode */ - LastMode = pAC->GIni.GP[Port].PPhyPowerState; - pAC->GIni.GP[Port].PPhyPowerState = Mode; - - switch (Mode) { - /* coma mode (deep sleep) */ - case PHY_PM_DEEP_SLEEP: - /* setup General Purpose Control Register */ - GM_OUT16(IoC, 0, GM_GP_CTRL, GM_GPCR_FL_PASS | - GM_GPCR_SPEED_100 | GM_GPCR_AU_ALL_DIS); - - /* apply COMA mode workaround */ - SkGmPhyWrite(pAC, IoC, Port, 29, 0x001f); - SkGmPhyWrite(pAC, IoC, Port, 30, 0xfff3); - - SK_IN32(IoC, PCI_C(PCI_OUR_REG_1), &DWord); - - SK_OUT8(IoC, B2_TST_CTRL1, TST_CFG_WRITE_ON); - - /* Set PHY to Coma Mode */ - SK_OUT32(IoC, PCI_C(PCI_OUR_REG_1), DWord | PCI_PHY_COMA); - - SK_OUT8(IoC, B2_TST_CTRL1, TST_CFG_WRITE_OFF); - - break; - - /* IEEE 22.2.4.1.5 compatible power down mode */ - case PHY_PM_IEEE_POWER_DOWN: - /* - * - disable MAC 125 MHz clock - * - allow MAC power down - */ - SkGmPhyRead(pAC, IoC, Port, PHY_MARV_PHY_CTRL, &Word); - Word |= PHY_M_PC_DIS_125CLK; - Word &= ~PHY_M_PC_MAC_POW_UP; - SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_PHY_CTRL, Word); + return(1); + } - /* - * register changes must be followed by a software - * reset to take effect - */ - SkGmPhyRead(pAC, IoC, Port, PHY_MARV_CTRL, &Word); - Word |= PHY_CT_RESET; - SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_CTRL, Word); - - /* switch IEEE compatible power down mode on */ - SkGmPhyRead(pAC, IoC, Port, PHY_MARV_CTRL, &Word); - Word |= PHY_CT_PDOWN; - SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_CTRL, Word); - break; + /* save current power mode */ + LastMode = pAC->GIni.GP[Port].PPhyPowerState; + pAC->GIni.GP[Port].PPhyPowerState = Mode; - /* energy detect and energy detect plus mode */ - case PHY_PM_ENERGY_DETECT: - case PHY_PM_ENERGY_DETECT_PLUS: - /* - * - disable MAC 125 MHz clock - */ - SkGmPhyRead(pAC, IoC, Port, PHY_MARV_PHY_CTRL, &Word); - Word |= PHY_M_PC_DIS_125CLK; - SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_PHY_CTRL, Word); - - /* activate energy detect mode 1 */ - SkGmPhyRead(pAC, IoC, Port, PHY_MARV_PHY_CTRL, &Word); - - /* energy detect mode */ - if (Mode == PHY_PM_ENERGY_DETECT) { - Word |= PHY_M_PC_EN_DET; + ChipId = pAC->GIni.GIChipId; + + SK_DBG_MSG(pAC, SK_DBGMOD_POWM, SK_DBGCAT_CTRL, + ("SkGmEnterLowPowerMode: %u\n", Mode)); + + /* release GPHY Control reset */ + SK_OUT8(IoC, MR_ADDR(Port, GPHY_CTRL), (SK_U8)GPC_RST_CLR); + + /* release GMAC reset */ + SK_OUT8(IoC, MR_ADDR(Port, GMAC_CTRL), (SK_U8)GMC_RST_CLR); + + if (ChipId == CHIP_ID_YUKON_EC_U) { + /* select page 2 to access MAC control register */ + SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_EXT_ADR, 2); + + SkGmPhyRead(pAC, IoC, Port, PHY_MARV_PHY_CTRL, &Word); + /* allow GMII Power Down */ + Word &= ~PHY_M_MAC_GMIF_PUP; + SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_PHY_CTRL, Word); + + SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_EXT_ADR, 0); + } + + switch (Mode) { + /* COMA mode (deep sleep) */ + case PHY_PM_DEEP_SLEEP: + /* setup General Purpose Control Register */ + GM_OUT16(IoC, Port, GM_GP_CTRL, GM_GPCR_FL_PASS | + GM_GPCR_SPEED_100 | GM_GPCR_AU_ALL_DIS); + + if (CHIP_ID_YUKON_2(pAC)) { + /* set power down bit */ + PowerDownBit = (Port == MAC_1) ? PCI_Y2_PHY1_POWD : + PCI_Y2_PHY2_POWD; + + if (ChipId != CHIP_ID_YUKON_EC) { + + if (ChipId == CHIP_ID_YUKON_EC_U) { + + SkGmPhyRead(pAC, IoC, Port, PHY_MARV_PHY_CTRL, &Word); + /* enable Power Down */ + Word |= PHY_M_PC_POW_D_ENA; + SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_PHY_CTRL, Word); + } + + /* set IEEE compatible Power Down Mode (dev. #4.99) */ + Ret = SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_CTRL, PHY_CT_PDOWN); + } + } + else { + /* apply COMA mode workaround */ + (void)SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_PAGE_ADDR, 0x001f); + + Ret = SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_PAGE_DATA, 0xfff3); + + PowerDownBit = PCI_PHY_COMA; + } + + SK_OUT8(IoC, B2_TST_CTRL1, TST_CFG_WRITE_ON); + + SK_IN32(IoC, PCI_C(pAC, PCI_OUR_REG_1), &DWord); + + /* set PHY to PowerDown/COMA Mode */ + SK_OUT32(IoC, PCI_C(pAC, PCI_OUR_REG_1), DWord | PowerDownBit); + + /* check if this routine was called from a for() loop */ + if (pAC->GIni.GIMacsFound == 1 || Port == MAC_2) { + + /* ASF system clock stopped */ + SK_OUT8(IoC, B28_Y2_ASF_STAT_CMD, (SK_U8)Y2_ASF_CLK_HALT); + + if (ChipId == CHIP_ID_YUKON_EC_U) { + /* set GPHY Control reset */ + SK_OUT8(IoC, MR_ADDR(Port, GPHY_CTRL), (SK_U8)GPC_RST_SET); + + /* additional power saving measurements */ + SK_IN32(IoC, PCI_C(pAC, PCI_OUR_REG_4), &DWord); + + /* set gating core clock for LTSSM in L1 state */ + DWord |= (P_PEX_LTSSM_STAT(P_PEX_LTSSM_L1_STAT) | + /* auto clock gated scheme controlled by CLKREQ */ + P_ASPM_A1_MODE_SELECT | + /* enable Gate Root Core Clock */ + P_CLK_GATE_ROOT_COR_ENA); + + if (HW_FEATURE(pAC, HWF_WA_DEV_4200)) { + /* Enable Clock Power Management (CLKREQ) */ + SK_IN16(IoC, PCI_C(pAC, PEX_LNK_CTRL), &Word); + Word |= PEX_LC_CLK_PM_ENA; + SK_OUT16(IoC, PCI_C(pAC, PEX_LNK_CTRL), Word); } - /* energy detect plus mode */ else { - Word |= PHY_M_PC_EN_DET_PLUS; + /* Force CLKREQ Enable in Our4 (A1b only) */ + DWord |= P_ASPM_FORCE_CLKREQ_ENA; } - SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_PHY_CTRL, Word); + SK_OUT32(IoC, PCI_C(pAC, PCI_OUR_REG_4), DWord); - /* - * reinitialize the PHY to force a software reset - * which is necessary after the register settings - * for the energy detect modes. - * Furthermore reinitialisation prevents that the - * PHY is running out of a stable state. - */ - SkGmInitPhyMarv(pAC, IoC, Port, SK_FALSE); - break; + /* set Mask Register for Release/Gate Clock */ + SK_OUT32(IoC, PCI_C(pAC, PCI_OUR_REG_5), + P_REL_PCIE_EXIT_L1_ST | P_GAT_PCIE_ENTER_L1_ST | + P_REL_PCIE_RX_EX_IDLE | P_GAT_PCIE_RX_EL_IDLE | + P_REL_GPHY_LINK_UP | P_GAT_GPHY_LINK_DOWN); + } - /* don't change current power mode */ - default: - pAC->GIni.GP[Port].PPhyPowerState = LastMode; - Ret = 1; - break; + if (HW_FEATURE(pAC, HWF_RED_CORE_CLK_SUP)) { + /* divide clock by 4 only for Yukon-EC */ + ClkDiv = (ChipId == CHIP_ID_YUKON_EC) ? 1 : 0; + + /* on Yukon-2 clock select value is 31 */ + DWord = (ChipId == CHIP_ID_YUKON_XL) ? + (Y2_CLK_DIV_VAL_2(0) | Y2_CLK_SEL_VAL_2(31)) : + Y2_CLK_DIV_VAL(ClkDiv); + + /* check for Yukon-2 dual port PCI-Express adapter */ + if (!(pAC->GIni.GIMacsFound == 2 && + pAC->GIni.GIPciBus == SK_PEX_BUS)) { + /* enable Core Clock Division */ + DWord |= Y2_CLK_DIV_ENA; + } + + SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, + ("Set Core Clock: 0x%08X\n", DWord)); + + /* reduce Core Clock Frequency */ + SK_OUT32(IoC, B2_Y2_CLK_CTRL, DWord); + } + + if (HW_FEATURE(pAC, HWF_CLK_GATING_ENABLE)) { + /* check for Yukon-2 Rev. A2 */ + if (ChipId == CHIP_ID_YUKON_XL && + pAC->GIni.GIChipRev > CHIP_REV_YU_XL_A1) { + /* enable bits are inverted */ + Byte = 0; + } + else { + Byte = (SK_U8)(Y2_PCI_CLK_LNK1_DIS | Y2_COR_CLK_LNK1_DIS | + Y2_CLK_GAT_LNK1_DIS | Y2_PCI_CLK_LNK2_DIS | + Y2_COR_CLK_LNK2_DIS | Y2_CLK_GAT_LNK2_DIS); + } + + SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, + ("Set Clock Gating: 0x%02X\n", Byte)); + + /* disable MAC/PHY, PCI and Core Clock for both Links */ + SK_OUT8(IoC, B2_Y2_CLK_GATE, Byte); + } + + if (pAC->GIni.GIVauxAvail) { + /* switch power to VAUX */ + SK_OUT8(IoC, B0_POWER_CTRL, (SK_U8)(PC_VAUX_ENA | PC_VCC_ENA | + PC_VAUX_ON | PC_VCC_OFF)); + } +#ifdef DEBUG + SK_IN32(IoC, B0_CTST, &DWord); + + SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, + ("Ctrl/Stat & Switch: 0x%08x\n", DWord)); +#endif /* DEBUG */ + + if (pAC->GIni.GILevel != SK_INIT_IO && + pAC->GIni.GIMacsFound == 1 && + pAC->GIni.GIPciBus == SK_PEX_BUS) { + + if (ChipId == CHIP_ID_YUKON_EC_U) { + +#ifdef PCI_E_L1_STATE + SK_IN16(IoC, PCI_C(pAC, PCI_OUR_REG_1), &Word); + /* force to PCIe L1 */ + Word |= (SK_U16)PCI_FORCE_PEX_L1; + SK_OUT16(IoC, PCI_C(pAC, PCI_OUR_REG_1), Word); +#endif /* PCI_E_L1_STATE */ + } + else { + /* switch to D1 state */ + SK_OUT8(IoC, PCI_C(pAC, PCI_PM_CTL_STS), PCI_PM_STATE_D1); + } + } } - } - /* low power modes are not supported by this chip */ - else { + + break; + + /* IEEE 22.2.4.1.5 compatible power down mode */ + case PHY_PM_IEEE_POWER_DOWN: + + Ret = SkGmPhyRead(pAC, IoC, Port, PHY_MARV_PHY_CTRL, &Word); + + Word |= PHY_M_PC_POL_R_DIS; + + if (!CHIP_ID_YUKON_2(pAC)) { + /* disable MAC 125 MHz clock */ + Word |= PHY_M_PC_DIS_125CLK; + Word &= ~PHY_M_PC_MAC_POW_UP; + } + SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_PHY_CTRL, Word); + + /* these register changes must be followed by a software reset */ + SkGmPhyRead(pAC, IoC, Port, PHY_MARV_CTRL, &Word); + + SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_CTRL, Word | PHY_CT_RESET); + + /* switch IEEE compatible power down mode on */ + SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_CTRL, Word | PHY_CT_PDOWN); + + break; + + /* energy detect and energy detect plus mode */ + case PHY_PM_ENERGY_DETECT: + case PHY_PM_ENERGY_DETECT_PLUS: + + Ret = SkGmPhyRead(pAC, IoC, Port, PHY_MARV_PHY_CTRL, &Word); + + Word |= PHY_M_PC_POL_R_DIS; + + if (!CHIP_ID_YUKON_2(pAC)) { + /* disable MAC 125 MHz clock */ + Word |= PHY_M_PC_DIS_125CLK; + } + + if (ChipId == CHIP_ID_YUKON_FE) { + /* enable Energy Detect (sense & pulse) */ + Word |= PHY_M_PC_ENA_ENE_DT; + } + else { + /* clear energy detect mode bits */ + Word &= ~PHY_M_PC_EN_DET_MSK; + + Word |= (Mode == PHY_PM_ENERGY_DETECT) ? PHY_M_PC_EN_DET : + PHY_M_PC_EN_DET_PLUS; + } + + SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_PHY_CTRL, Word); + + /* these register changes must be followed by a software reset */ + SkGmPhyRead(pAC, IoC, Port, PHY_MARV_CTRL, &Word); + Word |= PHY_CT_RESET; + SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_CTRL, Word); + + if (ChipId == CHIP_ID_YUKON_EC_U) { + /* additional power saving measurements */ + SK_IN32(IoC, PCI_C(pAC, PCI_OUR_REG_4), &DWord); + + /* set gating core clock for LTSSM in L1 state */ + DWord |= (P_PEX_LTSSM_STAT(P_PEX_LTSSM_L1_STAT) | + /* Enable Gate Root Core Clock */ + P_CLK_GATE_ROOT_COR_ENA); + + SK_OUT32(IoC, PCI_C(pAC, PCI_OUR_REG_4), DWord); + + /* set Mask Register for Release/Gate Clock */ + SK_OUT32(IoC, PCI_C(pAC, PCI_OUR_REG_5), + P_REL_PCIE_EXIT_L1_ST | P_GAT_PCIE_ENTER_L1_ST | + P_REL_PCIE_RX_EX_IDLE | P_GAT_PCIE_RX_EL_IDLE | + P_REL_GPHY_LINK_UP | P_GAT_GPHY_LINK_DOWN); + +#ifdef PCI_E_L1_STATE + SK_IN16(IoC, PCI_C(pAC, PCI_OUR_REG_1), &Word); + /* enable PCIe L1 on GPHY link down */ + Word |= (SK_U16)PCI_ENA_GPHY_LNK; + SK_OUT16(IoC, PCI_C(pAC, PCI_OUR_REG_1), Word); +#endif /* PCI_E_L1_STATE */ + } + + break; + + /* don't change current power mode */ + default: + pAC->GIni.GP[Port].PPhyPowerState = LastMode; Ret = 1; } @@ -2231,7 +2503,7 @@ * * SkGmLeaveLowPowerMode() * - * Description: + * Description: * Leave the current low power mode and switch to normal mode * * Note: @@ -2241,115 +2513,169 @@ * 1: error */ int SkGmLeaveLowPowerMode( -SK_AC *pAC, /* adapter context */ -SK_IOC IoC, /* IO context */ +SK_AC *pAC, /* Adapter Context */ +SK_IOC IoC, /* I/O Context */ int Port) /* Port Index (e.g. MAC_1) */ { SK_U32 DWord; + SK_U32 PowerDownBit; SK_U16 Word; SK_U8 LastMode; + int ChipId; int Ret = 0; - if (pAC->GIni.GIYukonLite && - pAC->GIni.GIChipRev == CHIP_REV_YU_LITE_A3) { + if (!(CHIP_ID_YUKON_2(pAC) || (pAC->GIni.GIYukonLite && + pAC->GIni.GIChipRev >= CHIP_REV_YU_LITE_A3))) { - /* save current power mode */ - LastMode = pAC->GIni.GP[Port].PPhyPowerState; - pAC->GIni.GP[Port].PPhyPowerState = PHY_PM_OPERATIONAL_MODE; - - switch (LastMode) { - /* coma mode (deep sleep) */ - case PHY_PM_DEEP_SLEEP: - SK_IN32(IoC, PCI_C(PCI_OUR_REG_1), &DWord); - - SK_OUT8(IoC, B2_TST_CTRL1, TST_CFG_WRITE_ON); - - /* Release PHY from Coma Mode */ - SK_OUT32(IoC, PCI_C(PCI_OUR_REG_1), DWord & ~PCI_PHY_COMA); - - SK_OUT8(IoC, B2_TST_CTRL1, TST_CFG_WRITE_OFF); - - SK_IN32(IoC, B2_GP_IO, &DWord); - - /* set to output */ - DWord |= (GP_DIR_9 | GP_IO_9); - - /* set PHY reset */ - SK_OUT32(IoC, B2_GP_IO, DWord); - - DWord &= ~GP_IO_9; /* clear PHY reset (active high) */ - - /* clear PHY reset */ - SK_OUT32(IoC, B2_GP_IO, DWord); - break; - - /* IEEE 22.2.4.1.5 compatible power down mode */ - case PHY_PM_IEEE_POWER_DOWN: - /* - * - enable MAC 125 MHz clock - * - set MAC power up - */ - SkGmPhyRead(pAC, IoC, Port, PHY_MARV_PHY_CTRL, &Word); - Word &= ~PHY_M_PC_DIS_125CLK; - Word |= PHY_M_PC_MAC_POW_UP; - SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_PHY_CTRL, Word); + return(1); + } - /* - * register changes must be followed by a software - * reset to take effect - */ - SkGmPhyRead(pAC, IoC, Port, PHY_MARV_CTRL, &Word); - Word |= PHY_CT_RESET; - SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_CTRL, Word); - - /* switch IEEE compatible power down mode off */ - SkGmPhyRead(pAC, IoC, Port, PHY_MARV_CTRL, &Word); - Word &= ~PHY_CT_PDOWN; - SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_CTRL, Word); - break; + /* save current power mode */ + LastMode = pAC->GIni.GP[Port].PPhyPowerState; + pAC->GIni.GP[Port].PPhyPowerState = PHY_PM_OPERATIONAL_MODE; - /* energy detect and energy detect plus mode */ - case PHY_PM_ENERGY_DETECT: - case PHY_PM_ENERGY_DETECT_PLUS: - /* - * - enable MAC 125 MHz clock - */ - SkGmPhyRead(pAC, IoC, Port, PHY_MARV_PHY_CTRL, &Word); - Word &= ~PHY_M_PC_DIS_125CLK; - SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_PHY_CTRL, Word); - - /* disable energy detect mode */ - SkGmPhyRead(pAC, IoC, Port, PHY_MARV_PHY_CTRL, &Word); - Word &= ~PHY_M_PC_EN_DET_MSK; - SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_PHY_CTRL, Word); + ChipId = pAC->GIni.GIChipId; - /* - * reinitialize the PHY to force a software reset - * which is necessary after the register settings - * for the energy detect modes. - * Furthermore reinitialisation prevents that the - * PHY is running out of a stable state. - */ - SkGmInitPhyMarv(pAC, IoC, Port, SK_FALSE); - break; + SK_DBG_MSG(pAC, SK_DBGMOD_POWM, SK_DBGCAT_CTRL, + ("SkGmLeaveLowPowerMode: %u\n", LastMode)); - /* don't change current power mode */ - default: - pAC->GIni.GP[Port].PPhyPowerState = LastMode; - Ret = 1; - break; + switch (LastMode) { + /* COMA mode (deep sleep) */ + case PHY_PM_DEEP_SLEEP: + + if (ChipId == CHIP_ID_YUKON_EC_U) { +#ifdef PCI_E_L1_STATE + /* set to default value (leave PCIe L1) */ + SkPciWriteCfgWord(pAC, PCI_OUR_REG_1, 0); +#endif /* PCI_E_L1_STATE */ + + SK_IN32(IoC, PCI_C(pAC, PCI_OUR_REG_4), &DWord); + + DWord &= P_ASPM_CONTROL_MSK; + /* set all bits to 0 except bits 15..12 */ + SK_OUT32(IoC, PCI_C(pAC, PCI_OUR_REG_4), DWord); + + /* set to default value */ + SK_OUT32(IoC, PCI_C(pAC, PCI_OUR_REG_5), 0); } - } - /* low power modes are not supported by this chip */ - else { + else { + SkPciReadCfgWord(pAC, PCI_PM_CTL_STS, &Word); + + /* reset all DState bits */ + Word &= ~(PCI_PM_STATE_MSK); + + /* switch to D0 state */ + SkPciWriteCfgWord(pAC, PCI_PM_CTL_STS, Word); + } + + SK_OUT8(IoC, B2_TST_CTRL1, TST_CFG_WRITE_ON); + + if (CHIP_ID_YUKON_2(pAC)) { + /* disable Core Clock Division */ + SK_OUT32(IoC, B2_Y2_CLK_CTRL, Y2_CLK_DIV_DIS); + + /* set power down bit */ + PowerDownBit = (Port == MAC_1) ? PCI_Y2_PHY1_POWD : + PCI_Y2_PHY2_POWD; + } + else { + PowerDownBit = PCI_PHY_COMA; + } + + SK_IN32(IoC, PCI_C(pAC, PCI_OUR_REG_1), &DWord); + + /* Release PHY from PowerDown/COMA Mode */ + SK_OUT32(IoC, PCI_C(pAC, PCI_OUR_REG_1), DWord & ~PowerDownBit); + + SK_OUT8(IoC, B2_TST_CTRL1, TST_CFG_WRITE_OFF); + + if (CHIP_ID_YUKON_2(pAC)) { + + if (ChipId == CHIP_ID_YUKON_FE) { + /* release IEEE compatible Power Down Mode */ + Ret = SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_CTRL, PHY_CT_ANE); + } + else if (ChipId == CHIP_ID_YUKON_EC_U) { + /* release GPHY Control reset */ + SK_OUT8(IoC, MR_ADDR(Port, GPHY_CTRL), (SK_U8)GPC_RST_CLR); + } + } + else { + SK_IN32(IoC, B2_GP_IO, &DWord); + + /* set to output */ + DWord |= (GP_DIR_9 | GP_IO_9); + + /* set PHY reset */ + SK_OUT32(IoC, B2_GP_IO, DWord); + + DWord &= ~GP_IO_9; /* clear PHY reset (active high) */ + + /* clear PHY reset */ + SK_OUT32(IoC, B2_GP_IO, DWord); + } + + break; + + /* IEEE 22.2.4.1.5 compatible power down mode */ + case PHY_PM_IEEE_POWER_DOWN: + + if (ChipId != CHIP_ID_YUKON_XL) { + + Ret = SkGmPhyRead(pAC, IoC, Port, PHY_MARV_PHY_CTRL, &Word); + Word &= ~PHY_M_PC_DIS_125CLK; /* enable MAC 125 MHz clock */ + Word |= PHY_M_PC_MAC_POW_UP; /* set MAC power up */ + SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_PHY_CTRL, Word); + + /* these register changes must be followed by a software reset */ + SkGmPhyRead(pAC, IoC, Port, PHY_MARV_CTRL, &Word); + Word |= PHY_CT_RESET; + SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_CTRL, Word); + } + + /* switch IEEE compatible power down mode off */ + SkGmPhyRead(pAC, IoC, Port, PHY_MARV_CTRL, &Word); + Word &= ~PHY_CT_PDOWN; + SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_CTRL, Word); + + break; + + /* energy detect and energy detect plus mode */ + case PHY_PM_ENERGY_DETECT: + case PHY_PM_ENERGY_DETECT_PLUS: + + if (ChipId != CHIP_ID_YUKON_XL) { + + Ret = SkGmPhyRead(pAC, IoC, Port, PHY_MARV_PHY_CTRL, &Word); + + if (ChipId == CHIP_ID_YUKON_FE) { + /* disable Energy Detect */ + Word &= ~PHY_M_PC_ENA_ENE_DT; + } + else { + /* disable energy detect mode & enable MAC 125 MHz clock */ + Word &= ~(PHY_M_PC_EN_DET_MSK | PHY_M_PC_DIS_125CLK); + } + + SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_PHY_CTRL, Word); + + /* these register changes must be followed by a software reset */ + SkGmPhyRead(pAC, IoC, Port, PHY_MARV_CTRL, &Word); + Word |= PHY_CT_RESET; + SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_CTRL, Word); + } + break; + + /* don't change current power mode */ + default: + pAC->GIni.GP[Port].PPhyPowerState = LastMode; Ret = 1; } return(Ret); } /* SkGmLeaveLowPowerMode */ -#endif /* !SK_SLIM */ - +#endif /* SK_PHY_LP_MODE */ /****************************************************************************** * @@ -2363,107 +2689,242 @@ * nothing */ static void SkGmInitPhyMarv( -SK_AC *pAC, /* adapter context */ -SK_IOC IoC, /* IO context */ +SK_AC *pAC, /* Adapter Context */ +SK_IOC IoC, /* I/O Context */ int Port, /* Port Index (MAC_1 + n) */ SK_BOOL DoLoop) /* Should a Phy LoopBack be set-up? */ { SK_GEPORT *pPrt; + SK_BOOL AutoNeg; SK_U16 PhyCtrl; SK_U16 C1000BaseT; SK_U16 AutoNegAdv; + SK_U8 PauseMode; + int ChipId; +#ifndef VCPU + SK_U16 SWord; + SK_U16 PageReg; +#ifndef SK_SLIM + SK_U16 LoopSpeed; +#endif /* !SK_SLIM */ SK_U16 ExtPhyCtrl; SK_U16 LedCtrl; - SK_BOOL AutoNeg; + SK_U16 LedOver; +#ifndef SK_DIAG + SK_EVPARA Para; +#endif /* !SK_DIAG */ #if defined(SK_DIAG) || defined(DEBUG) SK_U16 PhyStat; SK_U16 PhyStat1; SK_U16 PhySpecStat; #endif /* SK_DIAG || DEBUG */ +#endif /* !VCPU */ + + /* set Pause On */ + PauseMode = (SK_U8)GMC_PAUSE_ON; pPrt = &pAC->GIni.GP[Port]; + ChipId = pAC->GIni.GIChipId; + /* Auto-negotiation ? */ - if (pPrt->PLinkMode == SK_LMODE_HALF || pPrt->PLinkMode == SK_LMODE_FULL) { - AutoNeg = SK_FALSE; + AutoNeg = pPrt->PLinkMode != SK_LMODE_HALF && + pPrt->PLinkMode != SK_LMODE_FULL; + + SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, + ("InitPhyMarv: Port %d, Auto-neg. %s, LMode %d, LSpeed %d, FlowC %d\n", + Port, AutoNeg ? "ON" : "OFF", + pPrt->PLinkMode, pPrt->PLinkSpeed, pPrt->PFlowCtrlMode)); + +#ifndef VCPU + /* read Id from PHY */ + if (SkGmPhyRead(pAC, IoC, Port, PHY_MARV_ID1, &pPrt->PhyId1) != 0) { + +#ifndef SK_DIAG + Para.Para64 = Port; + SkEventQueue(pAC, SKGE_DRV, SK_DRV_PORT_FAIL, Para); +#endif /* !SK_DIAG */ + + return; } - else { - AutoNeg = SK_TRUE; + + if ((pPrt->PLinkSpeedCap & SK_LSPEED_CAP_1000MBPS) != 0) { + +#ifndef SK_SLIM + if (DoLoop) { + /* special setup for PHY 88E1112 */ + if (ChipId == CHIP_ID_YUKON_XL) { + + LoopSpeed = pPrt->PLinkSpeed; + + if (LoopSpeed == SK_LSPEED_AUTO) { + /* force 1000 Mbps */ + LoopSpeed = SK_LSPEED_1000MBPS; + } + LoopSpeed += 2; + + /* save page register */ + SkGmPhyRead(pAC, IoC, Port, PHY_MARV_EXT_ADR, &PageReg); + + /* select page 2 to access MAC control register */ + SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_EXT_ADR, 2); + + /* set MAC interface speed */ + SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_CTRL, LoopSpeed << 4); + + /* restore page register */ + SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_EXT_ADR, PageReg); + + /* disable link pulses */ + SWord = PHY_M_PC_DIS_LINK_P; + } + else { + /* set 'MAC Power up'-bit, set Manual MDI configuration */ + SWord = PHY_M_PC_MAC_POW_UP; + } + + SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_PHY_CTRL, SWord); + } + else +#endif /* !SK_SLIM */ + if (AutoNeg && pPrt->PLinkSpeed == SK_LSPEED_AUTO && + !(ChipId == CHIP_ID_YUKON_XL || ChipId == CHIP_ID_YUKON_EC_U)) { + /* Read Ext. PHY Specific Control */ + SkGmPhyRead(pAC, IoC, Port, PHY_MARV_EXT_CTRL, &ExtPhyCtrl); + + ExtPhyCtrl &= ~(PHY_M_EC_M_DSC_MSK | PHY_M_EC_S_DSC_MSK | + PHY_M_EC_MAC_S_MSK); + + ExtPhyCtrl |= PHY_M_EC_MAC_S(MAC_TX_CLK_25_MHZ); + + /* on PHY 88E1040 Rev.D0 (and newer) downshift control changed */ + if (pAC->GIni.GIYukonLite || ChipId == CHIP_ID_YUKON_EC) { + /* set downshift counter to 3x and enable downshift */ + ExtPhyCtrl |= PHY_M_EC_DSC_2(2) | PHY_M_EC_DOWN_S_ENA; + } + else { + /* set master & slave downshift counter to 1x */ + ExtPhyCtrl |= PHY_M_EC_M_DSC(0) | PHY_M_EC_S_DSC(1); + } + + SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_EXT_CTRL, ExtPhyCtrl); + SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, + ("Set Ext. PHY Ctrl = 0x%04X\n", ExtPhyCtrl)); + } } - - SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, - ("InitPhyMarv: Port %d, auto-negotiation %s\n", - Port, AutoNeg ? "ON" : "OFF")); -#ifdef VCPU - VCPUprintf(0, "SkGmInitPhyMarv(), Port=%u, DoLoop=%u\n", - Port, DoLoop); -#else /* VCPU */ - if (DoLoop) { - /* Set 'MAC Power up'-bit, set Manual MDI configuration */ - SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_PHY_CTRL, - PHY_M_PC_MAC_POW_UP); + if (CHIP_ID_YUKON_2(pAC)) { + /* Read PHY Specific Control */ + SkGmPhyRead(pAC, IoC, Port, PHY_MARV_PHY_CTRL, &PhyCtrl); + + if (!DoLoop && pAC->GIni.GICopperType) { + + if (ChipId == CHIP_ID_YUKON_FE) { + /* enable Automatic Crossover (!!! Bits 5..4) */ + PhyCtrl |= (SK_U16)(PHY_M_PC_MDI_XMODE(PHY_M_PC_ENA_AUTO) >> 1); + } + else { + /* disable Energy Detect Mode */ + PhyCtrl &= ~PHY_M_PC_EN_DET_MSK; + + /* enable Automatic Crossover */ + PhyCtrl |= (SK_U16)PHY_M_PC_MDI_XMODE(PHY_M_PC_ENA_AUTO); + + /* downshift on PHY 88E1112 and 88E1149 is changed */ + if (AutoNeg && pPrt->PLinkSpeed == SK_LSPEED_AUTO && + (ChipId == CHIP_ID_YUKON_XL || + ChipId == CHIP_ID_YUKON_EC_U)) { + /* set downshift counter to 3x and enable downshift */ + PhyCtrl &= ~PHY_M_PC_DSC_MSK; + PhyCtrl |= PHY_M_PC_DSC(2) | PHY_M_PC_DOWN_S_ENA; + } + } + } + /* workaround for deviation #4.88 (CRC errors) */ + else { + /* disable Automatic Crossover */ + PhyCtrl &= ~PHY_M_PC_MDIX_MSK; + } + + SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_PHY_CTRL, PhyCtrl); } - else if (AutoNeg && pPrt->PLinkSpeed == SK_LSPEED_AUTO) { - /* Read Ext. PHY Specific Control */ - SkGmPhyRead(pAC, IoC, Port, PHY_MARV_EXT_CTRL, &ExtPhyCtrl); - - ExtPhyCtrl &= ~(PHY_M_EC_M_DSC_MSK | PHY_M_EC_S_DSC_MSK | - PHY_M_EC_MAC_S_MSK); - - ExtPhyCtrl |= PHY_M_EC_MAC_S(MAC_TX_CLK_25_MHZ) | - PHY_M_EC_M_DSC(0) | PHY_M_EC_S_DSC(1); - - SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_EXT_CTRL, ExtPhyCtrl); - SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, - ("Set Ext. PHY Ctrl=0x%04X\n", ExtPhyCtrl)); + + /* special setup for PHY 88E1112 Fiber */ + if (ChipId == CHIP_ID_YUKON_XL && !pAC->GIni.GICopperType) { + /* select 1000BASE-X only mode in MAC Specific Ctrl Reg. */ + SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_EXT_ADR, 2); + + SkGmPhyRead(pAC, IoC, Port, PHY_MARV_PHY_CTRL, &SWord); + + SWord &= ~PHY_M_MAC_MD_MSK; + SWord |= PHY_M_MAC_MODE_SEL(PHY_M_MAC_MD_1000BX); + + SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_PHY_CTRL, SWord); + + /* select page 1 to access Fiber registers */ + SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_EXT_ADR, 1); + + if (pAC->GIni.GIPmdTyp == 'P') { + /* for SFP-module set SIGDET polarity to low */ + SkGmPhyRead(pAC, IoC, Port, PHY_MARV_PHY_CTRL, &SWord); + + SWord |= PHY_M_FIB_SIGD_POL; + + SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_PHY_CTRL, SWord); + } } /* Read PHY Control */ SkGmPhyRead(pAC, IoC, Port, PHY_MARV_CTRL, &PhyCtrl); +#ifndef SK_SLIM if (!AutoNeg) { - /* Disable Auto-negotiation */ + /* disable Auto-negotiation */ PhyCtrl &= ~PHY_CT_ANE; } +#endif /* !SK_SLIM */ PhyCtrl |= PHY_CT_RESET; - /* Assert software reset */ + /* assert software reset */ SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_CTRL, PhyCtrl); -#endif /* VCPU */ +#endif /* !VCPU */ PhyCtrl = 0 /* PHY_CT_COL_TST */; C1000BaseT = 0; AutoNegAdv = PHY_SEL_TYPE; +#ifndef SK_SLIM /* manually Master/Slave ? */ if (pPrt->PMSMode != SK_MS_MODE_AUTO) { /* enable Manual Master/Slave */ C1000BaseT |= PHY_M_1000C_MSE; - + if (pPrt->PMSMode == SK_MS_MODE_MASTER) { C1000BaseT |= PHY_M_1000C_MSC; /* set it to Master */ } } - +#endif /* !SK_SLIM */ + /* Auto-negotiation ? */ if (!AutoNeg) { - + +#ifndef SK_SLIM if (pPrt->PLinkMode == SK_LMODE_FULL) { - /* Set Full Duplex Mode */ + /* set Full Duplex Mode */ PhyCtrl |= PHY_CT_DUP_MD; } - /* Set Master/Slave manually if not already done */ + /* set Master/Slave manually if not already done */ if (pPrt->PMSMode == SK_MS_MODE_AUTO) { C1000BaseT |= PHY_M_1000C_MSE; /* set it to Slave */ } - /* Set Speed */ + /* set Speed */ switch (pPrt->PLinkSpeed) { case SK_LSPEED_AUTO: case SK_LSPEED_1000MBPS: - PhyCtrl |= PHY_CT_SP1000; + PhyCtrl |= (((pPrt->PLinkSpeedCap & SK_LSPEED_CAP_1000MBPS) != 0) ? + PHY_CT_SP1000 : PHY_CT_SP100); break; case SK_LSPEED_100MBPS: PhyCtrl |= PHY_CT_SP100; @@ -2475,38 +2936,67 @@ SKERR_HWI_E019MSG); } + if ((pPrt->PFlowCtrlMode == SK_FLOW_STAT_NONE) || + /* disable Pause also for 10/100 Mbps in half duplex mode */ + ((ChipId != CHIP_ID_YUKON_EC_U) && + (pPrt->PLinkMode == SK_LMODE_HALF) && + ((pPrt->PLinkSpeed == SK_LSPEED_STAT_100MBPS) || + (pPrt->PLinkSpeed == SK_LSPEED_STAT_10MBPS)))) { + + /* set Pause Off */ + PauseMode = (SK_U8)GMC_PAUSE_OFF; + } + + SK_OUT8(IoC, MR_ADDR(Port, GMAC_CTRL), PauseMode); + if (!DoLoop) { + /* assert software reset */ PhyCtrl |= PHY_CT_RESET; } +#endif /* !SK_SLIM */ } else { - /* Set Auto-negotiation advertisement */ - + /* set Auto-negotiation advertisement */ + if (pAC->GIni.GICopperType) { - /* Set Speed capabilities */ + /* set Speed capabilities */ switch (pPrt->PLinkSpeed) { case SK_LSPEED_AUTO: - C1000BaseT |= PHY_M_1000C_AHD | PHY_M_1000C_AFD; + if ((pPrt->PLinkSpeedCap & SK_LSPEED_CAP_1000MBPS) != 0) { + C1000BaseT |= PHY_M_1000C_AFD; +#ifdef xSK_DIAG + C1000BaseT |= PHY_M_1000C_AHD; +#endif /* SK_DIAG */ + } AutoNegAdv |= PHY_M_AN_100_FD | PHY_M_AN_100_HD | PHY_M_AN_10_FD | PHY_M_AN_10_HD; break; case SK_LSPEED_1000MBPS: - C1000BaseT |= PHY_M_1000C_AHD | PHY_M_1000C_AFD; + if ((pPrt->PLinkSpeedCap & SK_LSPEED_CAP_1000MBPS) != 0) { + C1000BaseT |= PHY_M_1000C_AFD; +#ifdef xSK_DIAG + C1000BaseT |= PHY_M_1000C_AHD; +#endif /* SK_DIAG */ + } break; case SK_LSPEED_100MBPS: - AutoNegAdv |= PHY_M_AN_100_FD | PHY_M_AN_100_HD | - /* advertise 10Base-T also */ - PHY_M_AN_10_FD | PHY_M_AN_10_HD; + if ((pPrt->PLinkSpeedCap & SK_LSPEED_CAP_100MBPS) != 0) { + AutoNegAdv |= PHY_M_AN_100_FD | PHY_M_AN_100_HD | + /* advertise 10Base-T also */ + PHY_M_AN_10_FD | PHY_M_AN_10_HD; + } break; case SK_LSPEED_10MBPS: - AutoNegAdv |= PHY_M_AN_10_FD | PHY_M_AN_10_HD; + if ((pPrt->PLinkSpeedCap & SK_LSPEED_CAP_10MBPS) != 0) { + AutoNegAdv |= PHY_M_AN_10_FD | PHY_M_AN_10_HD; + } break; default: SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_HWI_E019, SKERR_HWI_E019MSG); } - /* Set Full/half duplex capabilities */ + /* set Full/half duplex capabilities */ switch (pPrt->PLinkMode) { case SK_LMODE_AUTOHALF: C1000BaseT &= ~PHY_M_1000C_AFD; @@ -2522,8 +3012,8 @@ SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_HWI_E015, SKERR_HWI_E015MSG); } - - /* Set Flow-control capabilities */ + + /* set Flow-control capabilities */ switch (pPrt->PFlowCtrlMode) { case SK_FLOW_MODE_NONE: AutoNegAdv |= PHY_B_P_NO_PAUSE; @@ -2542,9 +3032,9 @@ SKERR_HWI_E016MSG); } } - else { /* special defines for FIBER (88E1011S only) */ - - /* Set Full/half duplex capabilities */ + else { /* special defines for FIBER (88E1040S only) */ + + /* set Full/half duplex capabilities */ switch (pPrt->PLinkMode) { case SK_LMODE_AUTOHALF: AutoNegAdv |= PHY_M_AN_1000X_AHD; @@ -2559,8 +3049,8 @@ SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_HWI_E015, SKERR_HWI_E015MSG); } - - /* Set Flow-control capabilities */ + + /* set Flow-control capabilities */ switch (pPrt->PFlowCtrlMode) { case SK_FLOW_MODE_NONE: AutoNegAdv |= PHY_M_P_NO_PAUSE_X; @@ -2585,138 +3075,228 @@ PhyCtrl |= PHY_CT_ANE | PHY_CT_RE_CFG; } } - + #ifdef VCPU /* * E-mail from Gu Lin (08-03-2002): */ - + /* Program PHY register 30 as 16'h0708 for simulation speed up */ SkGmPhyWrite(pAC, IoC, Port, 30, 0x0700 /* 0x0708 */); - + VCpuWait(2000); -#else /* VCPU */ - - /* Write 1000Base-T Control Register */ - SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_1000T_CTRL, C1000BaseT); - SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, - ("Set 1000B-T Ctrl =0x%04X\n", C1000BaseT)); - +#else /* !VCPU */ + + if (ChipId != CHIP_ID_YUKON_FE) { + /* Write 1000Base-T Control Register */ + SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_1000T_CTRL, C1000BaseT); + SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, + ("Set 1000B-T Ctrl = 0x%04X\n", C1000BaseT)); + } + /* Write AutoNeg Advertisement Register */ SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_AUNE_ADV, AutoNegAdv); SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, - ("Set Auto-Neg.Adv.=0x%04X\n", AutoNegAdv)); -#endif /* VCPU */ - + ("Set Auto-Neg.Adv. = 0x%04X\n", AutoNegAdv)); +#endif /* !VCPU */ + +#ifndef SK_SLIM if (DoLoop) { - /* Set the PHY Loopback bit */ + /* set the PHY Loopback bit */ PhyCtrl |= PHY_CT_LOOP; #ifdef XXX /* Program PHY register 16 as 16'h0400 to force link good */ SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_PHY_CTRL, PHY_M_PC_FL_GOOD); -#endif /* XXX */ -#ifndef VCPU if (pPrt->PLinkSpeed != SK_LSPEED_AUTO) { /* Write Ext. PHY Specific Control */ SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_EXT_CTRL, (SK_U16)((pPrt->PLinkSpeed + 2) << 4)); } -#endif /* VCPU */ +#endif /* XXX */ } #ifdef TEST_ONLY else if (pPrt->PLinkSpeed == SK_LSPEED_10MBPS) { - /* Write PHY Specific Control */ - SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_PHY_CTRL, - PHY_M_PC_EN_DET_MSK); + /* Write PHY Specific Control */ + SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_PHY_CTRL, PHY_M_PC_EN_DET_MSK); } #endif +#endif /* !SK_SLIM */ /* Write to the PHY Control register */ SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_CTRL, PhyCtrl); SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, - ("Set PHY Ctrl Reg.=0x%04X\n", PhyCtrl)); + ("Set PHY Ctrl Reg. = 0x%04X\n", PhyCtrl)); #ifdef VCPU VCpuWait(2000); -#else +#else /* !VCPU */ - LedCtrl = PHY_M_LED_PULS_DUR(PULS_170MS) | PHY_M_LED_BLINK_RT(BLINK_84MS); + LedCtrl = PHY_M_LED_PULS_DUR(PULS_170MS); + + LedOver = 0; if ((pAC->GIni.GILedBlinkCtrl & SK_ACT_LED_BLINK) != 0) { - LedCtrl |= PHY_M_LEDC_RX_CTRL | PHY_M_LEDC_TX_CTRL; + + if (ChipId == CHIP_ID_YUKON_FE) { + /* on 88E3082 these bits are at 11..9 (shifted left) */ + LedCtrl |= PHY_M_LED_BLINK_RT(BLINK_84MS) << 1; + + SkGmPhyRead(pAC, IoC, Port, PHY_MARV_FE_LED_PAR, &SWord); + + /* delete ACT LED control bits */ + SWord &= ~PHY_M_FELP_LED1_MSK; + /* change ACT LED control to blink mode */ + SWord |= PHY_M_FELP_LED1_CTRL(LED_PAR_CTRL_ACT_BL); + + SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_FE_LED_PAR, SWord); + } + else if (ChipId == CHIP_ID_YUKON_XL || ChipId == CHIP_ID_YUKON_EC_U) { + /* save page register */ + SkGmPhyRead(pAC, IoC, Port, PHY_MARV_EXT_ADR, &PageReg); + + /* select page 3 to access LED control register */ + SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_EXT_ADR, 3); + + /* set LED Function Control register */ + SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_PHY_CTRL, (SK_U16) + (PHY_M_LEDC_LOS_CTRL(1) | /* LINK/ACT */ + PHY_M_LEDC_INIT_CTRL( + ChipId == CHIP_ID_YUKON_XL ? 7 : 8) | /* 10 Mbps */ + PHY_M_LEDC_STA1_CTRL(7) | /* 100 Mbps */ + PHY_M_LEDC_STA0_CTRL(7))); /* 1000 Mbps */ + + if (ChipId == CHIP_ID_YUKON_XL) { + /* set Polarity Control register */ + SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_PHY_STAT, (SK_U16) + (PHY_M_POLC_LS1_P_MIX(4) | PHY_M_POLC_IS0_P_MIX(4) | + PHY_M_POLC_LOS_CTRL(2) | PHY_M_POLC_INIT_CTRL(2) | + PHY_M_POLC_STA1_CTRL(2) | PHY_M_POLC_STA0_CTRL(2))); + } + else if (ChipId == CHIP_ID_YUKON_EC_U) { + /* set Blink Rate in LED Timer Control Register */ + SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_INT_MASK, + LedCtrl | (SK_U16)PHY_M_LED_BLINK_RT(BLINK_84MS)); + } + /* restore page register */ + SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_EXT_ADR, PageReg); + } + else { + /* set Tx LED (LED_TX) to blink mode on Rx OR Tx activity */ + LedCtrl |= PHY_M_LED_BLINK_RT(BLINK_84MS) | PHY_M_LEDC_TX_CTRL; + + /* on PHY 88E1111 there is a change for LED control */ + if (ChipId == CHIP_ID_YUKON_EC && + (pAC->GIni.GILedBlinkCtrl & SK_DUAL_LED_ACT_LNK) != 0) { + /* Yukon-EC needs setting of 2 bits: 0,6=11) */ + LedCtrl |= PHY_M_LEDC_TX_C_LSB; + } + /* turn off the Rx LED (LED_RX) */ + LedOver |= PHY_M_LED_MO_RX(MO_LED_OFF); + } } if ((pAC->GIni.GILedBlinkCtrl & SK_DUP_LED_NORMAL) != 0) { + /* disable blink mode (LED_DUPLEX) on collisions */ LedCtrl |= PHY_M_LEDC_DP_CTRL; } - - SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_LED_CTRL, LedCtrl); - if ((pAC->GIni.GILedBlinkCtrl & SK_LED_LINK100_ON) != 0) { - /* only in forced 100 Mbps mode */ - if (!AutoNeg && pPrt->PLinkSpeed == SK_LSPEED_100MBPS) { + if (ChipId == CHIP_ID_YUKON_EC_U && + pAC->GIni.GIChipRev == CHIP_REV_YU_EC_U_A1) { - SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_LED_OVER, - PHY_M_LED_MO_100(MO_LED_ON)); + /* apply fixes in PHY AFE */ + SkGmPhyWrite(pAC, IoC, Port, 22, 255); + /* increase differential signal amplitude in 10BASE-T */ + SkGmPhyWrite(pAC, IoC, Port, 24, 0xaa99); + SkGmPhyWrite(pAC, IoC, Port, 23, 0x2011); + + /* fix for IEEE A/B Symmetry failure in 1000BASE-T */ + SkGmPhyWrite(pAC, IoC, Port, 24, 0xa204); + SkGmPhyWrite(pAC, IoC, Port, 23, 0x2002); + + /* set page register to 0 */ + SkGmPhyWrite(pAC, IoC, Port, 22, 0); + } + else { + /* no effect on Yukon-XL and Yukon-EC Ultra */ + SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_LED_CTRL, LedCtrl); + +#ifndef SK_SLIM + if ((pAC->GIni.GILedBlinkCtrl & SK_LED_LINK100_ON) != 0) { + /* only in forced 100 Mbps mode */ + if (!AutoNeg && pPrt->PLinkSpeed == SK_LSPEED_100MBPS) { + /* turn on 100 Mbps LED (LED_LINK100) */ + LedOver |= PHY_M_LED_MO_100(MO_LED_ON); + } + } +#endif /* !SK_SLIM */ + + if (LedOver != 0) { + /* set Manual LED Override */ + SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_LED_OVER, LedOver); } } #ifdef SK_DIAG - c_print("Set PHY Ctrl=0x%04X\n", PhyCtrl); - c_print("Set 1000 B-T=0x%04X\n", C1000BaseT); - c_print("Set Auto-Neg=0x%04X\n", AutoNegAdv); - c_print("Set Ext Ctrl=0x%04X\n", ExtPhyCtrl); + c_print("Set PHY Ctrl = 0x%04X\n", PhyCtrl); + c_print("Set 1000 B-T = 0x%04X\n", C1000BaseT); + c_print("Set Auto-Neg = 0x%04X\n", AutoNegAdv); + c_print("Set Ext Ctrl = 0x%04X\n", ExtPhyCtrl); #endif /* SK_DIAG */ #if defined(SK_DIAG) || defined(DEBUG) /* Read PHY Control */ SkGmPhyRead(pAC, IoC, Port, PHY_MARV_CTRL, &PhyCtrl); SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, - ("PHY Ctrl Reg.=0x%04X\n", PhyCtrl)); - - /* Read 1000Base-T Control Register */ - SkGmPhyRead(pAC, IoC, Port, PHY_MARV_1000T_CTRL, &C1000BaseT); - SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, - ("1000B-T Ctrl =0x%04X\n", C1000BaseT)); - + ("PHY Ctrl Reg. = 0x%04X\n", PhyCtrl)); + /* Read AutoNeg Advertisement Register */ SkGmPhyRead(pAC, IoC, Port, PHY_MARV_AUNE_ADV, &AutoNegAdv); SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, - ("Auto-Neg.Adv.=0x%04X\n", AutoNegAdv)); - - /* Read Ext. PHY Specific Control */ - SkGmPhyRead(pAC, IoC, Port, PHY_MARV_EXT_CTRL, &ExtPhyCtrl); - SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, - ("Ext. PHY Ctrl=0x%04X\n", ExtPhyCtrl)); - + ("Auto-Neg.Adv. = 0x%04X\n", AutoNegAdv)); + + if (ChipId != CHIP_ID_YUKON_FE) { + /* Read 1000Base-T Control Register */ + SkGmPhyRead(pAC, IoC, Port, PHY_MARV_1000T_CTRL, &C1000BaseT); + SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, + ("1000B-T Ctrl = 0x%04X\n", C1000BaseT)); + + /* Read Ext. PHY Specific Control */ + SkGmPhyRead(pAC, IoC, Port, PHY_MARV_EXT_CTRL, &ExtPhyCtrl); + SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, + ("Ext. PHY Ctrl = 0x%04X\n", ExtPhyCtrl)); + } + /* Read PHY Status */ SkGmPhyRead(pAC, IoC, Port, PHY_MARV_STAT, &PhyStat); SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, - ("PHY Stat Reg.=0x%04X\n", PhyStat)); + ("PHY Stat Reg. = 0x%04X\n", PhyStat)); + SkGmPhyRead(pAC, IoC, Port, PHY_MARV_STAT, &PhyStat1); SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, - ("PHY Stat Reg.=0x%04X\n", PhyStat1)); - + ("PHY Stat Reg. = 0x%04X\n", PhyStat1)); + /* Read PHY Specific Status */ SkGmPhyRead(pAC, IoC, Port, PHY_MARV_PHY_STAT, &PhySpecStat); SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, - ("PHY Spec Stat=0x%04X\n", PhySpecStat)); + ("PHY Spec Stat = 0x%04X\n", PhySpecStat)); #endif /* SK_DIAG || DEBUG */ #ifdef SK_DIAG - c_print("PHY Ctrl Reg=0x%04X\n", PhyCtrl); - c_print("PHY 1000 Reg=0x%04X\n", C1000BaseT); - c_print("PHY AnAd Reg=0x%04X\n", AutoNegAdv); - c_print("Ext Ctrl Reg=0x%04X\n", ExtPhyCtrl); - c_print("PHY Stat Reg=0x%04X\n", PhyStat); - c_print("PHY Stat Reg=0x%04X\n", PhyStat1); - c_print("PHY Spec Reg=0x%04X\n", PhySpecStat); + c_print("PHY Ctrl Reg = 0x%04X\n", PhyCtrl); + c_print("PHY 1000 Reg = 0x%04X\n", C1000BaseT); + c_print("PHY AnAd Reg = 0x%04X\n", AutoNegAdv); + c_print("Ext Ctrl Reg = 0x%04X\n", ExtPhyCtrl); + c_print("PHY Stat Reg = 0x%04X\n", PhyStat); + c_print("PHY Stat Reg = 0x%04X\n", PhyStat1); + c_print("PHY Spec Reg = 0x%04X\n", PhySpecStat); #endif /* SK_DIAG */ -#endif /* VCPU */ + /* enable PHY interrupts */ + SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_INT_MASK, (SK_U16)PHY_M_DEF_MSK); +#endif /* !VCPU */ } /* SkGmInitPhyMarv */ #endif /* YUKON */ @@ -2735,8 +3315,8 @@ * nothing */ static void SkXmInitPhyLone( -SK_AC *pAC, /* adapter context */ -SK_IOC IoC, /* IO context */ +SK_AC *pAC, /* Adapter Context */ +SK_IOC IoC, /* I/O Context */ int Port, /* Port Index (MAC_1 + n) */ SK_BOOL DoLoop) /* Should a Phy LoopBack be set-up? */ { @@ -2754,7 +3334,7 @@ /* manually Master/Slave ? */ if (pPrt->PMSMode != SK_MS_MODE_AUTO) { Ctrl2 |= PHY_L_1000C_MSE; - + if (pPrt->PMSMode == SK_MS_MODE_MASTER) { Ctrl2 |= PHY_L_1000C_MSC; } @@ -2767,7 +3347,7 @@ */ SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, ("InitPhyLone: no auto-negotiation Port %d\n", Port)); - /* Set DuplexMode in Config register */ + /* set DuplexMode in Config register */ if (pPrt->PLinkMode == SK_LMODE_FULL) { Ctrl1 |= PHY_CT_DUP_MD; } @@ -2776,7 +3356,6 @@ if (pPrt->PMSMode == SK_MS_MODE_AUTO) { Ctrl2 |= PHY_L_1000C_MSE; /* set it to Slave */ } - /* * Do NOT enable Auto-negotiation here. This would hold * the link down because no IDLES are transmitted @@ -2785,9 +3364,9 @@ else { SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, ("InitPhyLone: with auto-negotiation Port %d\n", Port)); - /* Set Auto-negotiation advertisement */ + /* set Auto-negotiation advertisement */ - /* Set Full/half duplex capabilities */ + /* set Full/half duplex capabilities */ switch (pPrt->PLinkMode) { case SK_LMODE_AUTOHALF: Ctrl2 |= PHY_L_1000C_AHD; @@ -2803,7 +3382,7 @@ SKERR_HWI_E015MSG); } - /* Set Flow-control capabilities */ + /* set Flow-control capabilities */ switch (pPrt->PFlowCtrlMode) { case SK_FLOW_MODE_NONE: Ctrl3 |= PHY_L_P_NO_PAUSE; @@ -2825,26 +3404,26 @@ /* Restart Auto-negotiation */ Ctrl1 = PHY_CT_ANE | PHY_CT_RE_CFG; } - + /* Write 1000Base-T Control Register */ SkXmPhyWrite(pAC, IoC, Port, PHY_LONE_1000T_CTRL, Ctrl2); SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, - ("1000B-T Ctrl Reg=0x%04X\n", Ctrl2)); - + ("1000B-T Ctrl Reg = 0x%04X\n", Ctrl2)); + /* Write AutoNeg Advertisement Register */ SkXmPhyWrite(pAC, IoC, Port, PHY_LONE_AUNE_ADV, Ctrl3); SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, - ("Auto-Neg.Adv.Reg=0x%04X\n", Ctrl3)); + ("Auto-Neg.Adv.Reg = 0x%04X\n", Ctrl3)); if (DoLoop) { - /* Set the Phy Loopback bit, too */ + /* set the Phy Loopback bit, too */ Ctrl1 |= PHY_CT_LOOP; } /* Write to the Phy control register */ SkXmPhyWrite(pAC, IoC, Port, PHY_LONE_CTRL, Ctrl1); SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, - ("PHY Control Reg=0x%04X\n", Ctrl1)); + ("PHY Control Reg = 0x%04X\n", Ctrl1)); } /* SkXmInitPhyLone */ @@ -2860,8 +3439,8 @@ * nothing */ static void SkXmInitPhyNat( -SK_AC *pAC, /* adapter context */ -SK_IOC IoC, /* IO context */ +SK_AC *pAC, /* Adapter Context */ +SK_IOC IoC, /* I/O Context */ int Port, /* Port Index (MAC_1 + n) */ SK_BOOL DoLoop) /* Should a Phy LoopBack be set-up? */ { @@ -2882,8 +3461,8 @@ * nothing */ void SkMacInitPhy( -SK_AC *pAC, /* adapter context */ -SK_IOC IoC, /* IO context */ +SK_AC *pAC, /* Adapter Context */ +SK_IOC IoC, /* I/O Context */ int Port, /* Port Index (MAC_1 + n) */ SK_BOOL DoLoop) /* Should a Phy LoopBack be set-up? */ { @@ -2893,7 +3472,7 @@ #ifdef GENESIS if (pAC->GIni.GIGenesis) { - + switch (pPrt->PhyType) { case SK_PHY_XMAC: SkXmInitPhyXmac(pAC, IoC, Port, DoLoop); @@ -2912,10 +3491,10 @@ } } #endif /* GENESIS */ - + #ifdef YUKON if (pAC->GIni.GIYukon) { - + SkGmInitPhyMarv(pAC, IoC, Port, DoLoop); } #endif /* YUKON */ @@ -2933,17 +3512,17 @@ * * Returns: * SK_AND_OK o.k. - * SK_AND_DUP_CAP Duplex capability error happened - * SK_AND_OTHER Other error happened + * SK_AND_DUP_CAP Duplex capability error happened + * SK_AND_OTHER Other error happened */ static int SkXmAutoNegDoneXmac( -SK_AC *pAC, /* adapter context */ -SK_IOC IoC, /* IO context */ +SK_AC *pAC, /* Adapter Context */ +SK_IOC IoC, /* I/O Context */ int Port) /* Port Index (MAC_1 + n) */ { SK_GEPORT *pPrt; SK_U16 ResAb; /* Resolved Ability */ - SK_U16 LPAb; /* Link Partner Ability */ + SK_U16 LinkPartAb; /* Link Partner Ability */ SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, ("AutoNegDoneXmac, Port %d\n", Port)); @@ -2951,15 +3530,15 @@ pPrt = &pAC->GIni.GP[Port]; /* Get PHY parameters */ - SkXmPhyRead(pAC, IoC, Port, PHY_XMAC_AUNE_LP, &LPAb); + SkXmPhyRead(pAC, IoC, Port, PHY_XMAC_AUNE_LP, &LinkPartAb); SkXmPhyRead(pAC, IoC, Port, PHY_XMAC_RES_ABI, &ResAb); - if ((LPAb & PHY_X_AN_RFB) != 0) { + if ((LinkPartAb & PHY_X_AN_RFB) != 0) { /* At least one of the remote fault bit is set */ - /* Error */ - SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, + SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_ERR, ("AutoNegFail: Remote fault bit set Port %d\n", Port)); pPrt->PAutoNegFail = SK_TRUE; + return(SK_AND_OTHER); } @@ -2972,9 +3551,10 @@ } else { /* Error */ - SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, + SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_ERR, ("AutoNegFail: Duplex mode mismatch Port %d\n", Port)); pPrt->PAutoNegFail = SK_TRUE; + return(SK_AND_DUP_CAP); } @@ -2982,19 +3562,19 @@ /* We are NOT using chapter 4.23 of the Xaqti manual */ /* We are using IEEE 802.3z/D5.0 Table 37-4 */ if ((pPrt->PFlowCtrlMode == SK_FLOW_MODE_SYMMETRIC || - pPrt->PFlowCtrlMode == SK_FLOW_MODE_SYM_OR_REM) && - (LPAb & PHY_X_P_SYM_MD) != 0) { + pPrt->PFlowCtrlMode == SK_FLOW_MODE_SYM_OR_REM) && + (LinkPartAb & PHY_X_P_SYM_MD) != 0) { /* Symmetric PAUSE */ pPrt->PFlowCtrlStatus = SK_FLOW_STAT_SYMMETRIC; } else if (pPrt->PFlowCtrlMode == SK_FLOW_MODE_SYM_OR_REM && - (LPAb & PHY_X_RS_PAUSE) == PHY_X_P_ASYM_MD) { - /* Enable PAUSE receive, disable PAUSE transmit */ + (LinkPartAb & PHY_X_RS_PAUSE) == PHY_X_P_ASYM_MD) { + /* enable PAUSE receive, disable PAUSE transmit */ pPrt->PFlowCtrlStatus = SK_FLOW_STAT_REM_SEND; } else if (pPrt->PFlowCtrlMode == SK_FLOW_MODE_LOC_SEND && - (LPAb & PHY_X_RS_PAUSE) == PHY_X_P_BOTH_MD) { - /* Disable PAUSE receive, enable PAUSE transmit */ + (LinkPartAb & PHY_X_RS_PAUSE) == PHY_X_P_BOTH_MD) { + /* disable PAUSE receive, enable PAUSE transmit */ pPrt->PFlowCtrlStatus = SK_FLOW_STAT_LOC_SEND; } else { @@ -3016,41 +3596,40 @@ * * Returns: * SK_AND_OK o.k. - * SK_AND_DUP_CAP Duplex capability error happened - * SK_AND_OTHER Other error happened + * SK_AND_DUP_CAP Duplex capability error happened + * SK_AND_OTHER Other error happened */ static int SkXmAutoNegDoneBcom( -SK_AC *pAC, /* adapter context */ -SK_IOC IoC, /* IO context */ +SK_AC *pAC, /* Adapter Context */ +SK_IOC IoC, /* I/O Context */ int Port) /* Port Index (MAC_1 + n) */ { SK_GEPORT *pPrt; - SK_U16 LPAb; /* Link Partner Ability */ - SK_U16 AuxStat; /* Auxiliary Status */ - #ifdef TEST_ONLY -01-Sep-2000 RA;:;: SK_U16 ResAb; /* Resolved Ability */ -#endif /* 0 */ +#endif + SK_U16 LinkPartAb; /* Link Partner Ability */ + SK_U16 AuxStat; /* Auxiliary Status */ + SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, ("AutoNegDoneBcom, Port %d\n", Port)); pPrt = &pAC->GIni.GP[Port]; /* Get PHY parameters */ - SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_AUNE_LP, &LPAb); + SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_AUNE_LP, &LinkPartAb); #ifdef TEST_ONLY -01-Sep-2000 RA;:;: SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_1000T_STAT, &ResAb); -#endif /* 0 */ - +#endif + SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_AUX_STAT, &AuxStat); - if ((LPAb & PHY_B_AN_RF) != 0) { + if ((LinkPartAb & PHY_B_AN_RF) != 0) { /* Remote fault bit is set: Error */ - SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, + SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_ERR, ("AutoNegFail: Remote fault bit set Port %d\n", Port)); pPrt->PAutoNegFail = SK_TRUE; + return(SK_AND_OTHER); } @@ -3063,26 +3642,26 @@ } else { /* Error */ - SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, + SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_ERR, ("AutoNegFail: Duplex mode mismatch Port %d\n", Port)); pPrt->PAutoNegFail = SK_TRUE; + return(SK_AND_DUP_CAP); } - + #ifdef TEST_ONLY -01-Sep-2000 RA;:;: /* Check Master/Slave resolution */ if ((ResAb & PHY_B_1000S_MSF) != 0) { - SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, + SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_ERR, ("Master/Slave Fault Port %d\n", Port)); pPrt->PAutoNegFail = SK_TRUE; pPrt->PMSStatus = SK_MS_STAT_FAULT; return(SK_AND_OTHER); } - + pPrt->PMSStatus = ((ResAb & PHY_B_1000S_MSR) != 0) ? SK_MS_STAT_MASTER : SK_MS_STAT_SLAVE; -#endif /* 0 */ +#endif /* Check PAUSE mismatch ??? */ /* We are using IEEE 802.3z/D5.0 Table 37-4 */ @@ -3091,11 +3670,11 @@ pPrt->PFlowCtrlStatus = SK_FLOW_STAT_SYMMETRIC; } else if ((AuxStat & PHY_B_AS_PAUSE_MSK) == PHY_B_AS_PRR) { - /* Enable PAUSE receive, disable PAUSE transmit */ + /* enable PAUSE receive, disable PAUSE transmit */ pPrt->PFlowCtrlStatus = SK_FLOW_STAT_REM_SEND; } else if ((AuxStat & PHY_B_AS_PAUSE_MSK) == PHY_B_AS_PRT) { - /* Disable PAUSE receive, enable PAUSE transmit */ + /* disable PAUSE receive, enable PAUSE transmit */ pPrt->PFlowCtrlStatus = SK_FLOW_STAT_LOC_SEND; } else { @@ -3109,6 +3688,7 @@ #endif /* GENESIS */ +#ifndef SK_SLIM #ifdef YUKON /****************************************************************************** * @@ -3119,102 +3699,148 @@ * * Returns: * SK_AND_OK o.k. - * SK_AND_DUP_CAP Duplex capability error happened - * SK_AND_OTHER Other error happened + * SK_AND_DUP_CAP Duplex capability error happened + * SK_AND_OTHER Other error happened */ static int SkGmAutoNegDoneMarv( -SK_AC *pAC, /* adapter context */ -SK_IOC IoC, /* IO context */ +SK_AC *pAC, /* Adapter Context */ +SK_IOC IoC, /* I/O Context */ int Port) /* Port Index (MAC_1 + n) */ { SK_GEPORT *pPrt; - SK_U16 LPAb; /* Link Partner Ability */ SK_U16 ResAb; /* Resolved Ability */ + SK_U16 LinkPartAb; /* Link Partner Ability */ SK_U16 AuxStat; /* Auxiliary Status */ + SK_U8 PauseMode; /* Pause Mode */ + + /* set Pause On */ + PauseMode = (SK_U8)GMC_PAUSE_ON; SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, ("AutoNegDoneMarv, Port %d\n", Port)); + pPrt = &pAC->GIni.GP[Port]; /* Get PHY parameters */ - SkGmPhyRead(pAC, IoC, Port, PHY_MARV_AUNE_LP, &LPAb); + SkGmPhyRead(pAC, IoC, Port, PHY_MARV_AUNE_LP, &LinkPartAb); SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, - ("Link P.Abil.=0x%04X\n", LPAb)); - - if ((LPAb & PHY_M_AN_RF) != 0) { - SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, + ("Link P.Abil. = 0x%04X\n", LinkPartAb)); + + if ((LinkPartAb & PHY_M_AN_RF) != 0) { + SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_ERR, ("AutoNegFail: Remote fault bit set Port %d\n", Port)); pPrt->PAutoNegFail = SK_TRUE; + return(SK_AND_OTHER); } - SkGmPhyRead(pAC, IoC, Port, PHY_MARV_1000T_STAT, &ResAb); - - /* Check Master/Slave resolution */ - if ((ResAb & PHY_B_1000S_MSF) != 0) { + /* Read PHY Auto-Negotiation Expansion */ + SkGmPhyRead(pAC, IoC, Port, PHY_MARV_AUNE_EXP, &LinkPartAb); + + if ((LinkPartAb & PHY_ANE_LP_CAP) == 0) { + SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, - ("Master/Slave Fault Port %d\n", Port)); - pPrt->PAutoNegFail = SK_TRUE; - pPrt->PMSStatus = SK_MS_STAT_FAULT; - return(SK_AND_OTHER); + ("Link Partner not Auto-Neg. able, AN Exp.: 0x%04X\n", LinkPartAb)); + } + + if ((pPrt->PLinkSpeedCap & SK_LSPEED_CAP_1000MBPS) != 0) { + + SkGmPhyRead(pAC, IoC, Port, PHY_MARV_1000T_STAT, &ResAb); + + /* Check Master/Slave resolution */ + if ((ResAb & PHY_B_1000S_MSF) != 0) { + SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_ERR, + ("Master/Slave Fault Port %d\n", Port)); + pPrt->PAutoNegFail = SK_TRUE; + pPrt->PMSStatus = SK_MS_STAT_FAULT; + return(SK_AND_OTHER); + } + + pPrt->PMSStatus = ((ResAb & PHY_B_1000S_MSR) != 0) ? + (SK_U8)SK_MS_STAT_MASTER : (SK_U8)SK_MS_STAT_SLAVE; } - - pPrt->PMSStatus = ((ResAb & PHY_B_1000S_MSR) != 0) ? - (SK_U8)SK_MS_STAT_MASTER : (SK_U8)SK_MS_STAT_SLAVE; - + /* Read PHY Specific Status */ SkGmPhyRead(pAC, IoC, Port, PHY_MARV_PHY_STAT, &AuxStat); - + /* Check Speed & Duplex resolved */ if ((AuxStat & PHY_M_PS_SPDUP_RES) == 0) { - SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, + SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_ERR, ("AutoNegFail: Speed & Duplex not resolved, Port %d\n", Port)); pPrt->PAutoNegFail = SK_TRUE; pPrt->PLinkModeStatus = (SK_U8)SK_LMODE_STAT_UNKNOWN; + return(SK_AND_DUP_CAP); } - - if ((AuxStat & PHY_M_PS_FULL_DUP) != 0) { - pPrt->PLinkModeStatus = (SK_U8)SK_LMODE_STAT_AUTOFULL; - } - else { - pPrt->PLinkModeStatus = (SK_U8)SK_LMODE_STAT_AUTOHALF; - } - - /* Check PAUSE mismatch ??? */ - /* We are using IEEE 802.3z/D5.0 Table 37-4 */ - if ((AuxStat & PHY_M_PS_PAUSE_MSK) == PHY_M_PS_PAUSE_MSK) { - /* Symmetric PAUSE */ - pPrt->PFlowCtrlStatus = SK_FLOW_STAT_SYMMETRIC; - } - else if ((AuxStat & PHY_M_PS_PAUSE_MSK) == PHY_M_PS_RX_P_EN) { - /* Enable PAUSE receive, disable PAUSE transmit */ - pPrt->PFlowCtrlStatus = SK_FLOW_STAT_REM_SEND; - } - else if ((AuxStat & PHY_M_PS_PAUSE_MSK) == PHY_M_PS_TX_P_EN) { - /* Disable PAUSE receive, enable PAUSE transmit */ - pPrt->PFlowCtrlStatus = SK_FLOW_STAT_LOC_SEND; + + pPrt->PLinkModeStatus = (SK_U8)(((AuxStat & PHY_M_PS_FULL_DUP) != 0) ? + SK_LMODE_STAT_AUTOFULL : SK_LMODE_STAT_AUTOHALF); + + if (pAC->GIni.GIChipId == CHIP_ID_YUKON_FE) { + /* set used link speed */ + pPrt->PLinkSpeedUsed = (SK_U8)(((AuxStat & PHY_M_PS_SPEED_100) != 0) ? + SK_LSPEED_STAT_100MBPS : SK_LSPEED_STAT_10MBPS); } else { - /* PAUSE mismatch -> no PAUSE */ - pPrt->PFlowCtrlStatus = SK_FLOW_STAT_NONE; + /* set used link speed */ + switch ((unsigned)(AuxStat & PHY_M_PS_SPEED_MSK)) { + case (unsigned)PHY_M_PS_SPEED_1000: + pPrt->PLinkSpeedUsed = (SK_U8)SK_LSPEED_STAT_1000MBPS; + break; + case PHY_M_PS_SPEED_100: + pPrt->PLinkSpeedUsed = (SK_U8)SK_LSPEED_STAT_100MBPS; + break; + default: + pPrt->PLinkSpeedUsed = (SK_U8)SK_LSPEED_STAT_10MBPS; + } + + if (pAC->GIni.GIChipId == CHIP_ID_YUKON_XL || + pAC->GIni.GIChipId == CHIP_ID_YUKON_EC_U) { + /* Tx & Rx Pause Enabled bits are at 9..8 */ + AuxStat >>= 6; + + if (!pAC->GIni.GICopperType) { + /* always 1000 Mbps on fiber */ + pPrt->PLinkSpeedUsed = (SK_U8)SK_LSPEED_STAT_1000MBPS; + } + } + + AuxStat &= PHY_M_PS_PAUSE_MSK; + /* We are using IEEE 802.3z/D5.0 Table 37-4 */ + if (AuxStat == PHY_M_PS_PAUSE_MSK) { + /* Symmetric PAUSE */ + pPrt->PFlowCtrlStatus = SK_FLOW_STAT_SYMMETRIC; + } + else if (AuxStat == PHY_M_PS_RX_P_EN) { + /* enable PAUSE receive, disable PAUSE transmit */ + pPrt->PFlowCtrlStatus = SK_FLOW_STAT_REM_SEND; + } + else if (AuxStat == PHY_M_PS_TX_P_EN) { + /* disable PAUSE receive, enable PAUSE transmit */ + pPrt->PFlowCtrlStatus = SK_FLOW_STAT_LOC_SEND; + } + else { + /* PAUSE mismatch -> no PAUSE */ + pPrt->PFlowCtrlStatus = SK_FLOW_STAT_NONE; + } } - - /* set used link speed */ - switch ((unsigned)(AuxStat & PHY_M_PS_SPEED_MSK)) { - case (unsigned)PHY_M_PS_SPEED_1000: - pPrt->PLinkSpeedUsed = (SK_U8)SK_LSPEED_STAT_1000MBPS; - break; - case PHY_M_PS_SPEED_100: - pPrt->PLinkSpeedUsed = (SK_U8)SK_LSPEED_STAT_100MBPS; - break; - default: - pPrt->PLinkSpeedUsed = (SK_U8)SK_LSPEED_STAT_10MBPS; + + if ((pPrt->PFlowCtrlStatus == SK_FLOW_STAT_NONE) || + /* disable Pause also for 10/100 Mbps in half duplex mode */ + ((pAC->GIni.GIChipId != CHIP_ID_YUKON_EC_U) && + (pPrt->PLinkSpeedUsed < (SK_U8)SK_LSPEED_STAT_1000MBPS) && + pPrt->PLinkModeStatus == (SK_U8)SK_LMODE_STAT_AUTOHALF)) { + + /* set Pause Off */ + PauseMode = (SK_U8)GMC_PAUSE_OFF; } + SK_OUT8(IoC, MR_ADDR(Port, GMAC_CTRL), PauseMode); + return(SK_AND_OK); } /* SkGmAutoNegDoneMarv */ #endif /* YUKON */ +#endif /* !SK_SLIM */ #ifdef OTHER_PHY @@ -3227,17 +3853,17 @@ * * Returns: * SK_AND_OK o.k. - * SK_AND_DUP_CAP Duplex capability error happened - * SK_AND_OTHER Other error happened + * SK_AND_DUP_CAP Duplex capability error happened + * SK_AND_OTHER Other error happened */ static int SkXmAutoNegDoneLone( -SK_AC *pAC, /* adapter context */ -SK_IOC IoC, /* IO context */ +SK_AC *pAC, /* Adapter Context */ +SK_IOC IoC, /* I/O Context */ int Port) /* Port Index (MAC_1 + n) */ { SK_GEPORT *pPrt; SK_U16 ResAb; /* Resolved Ability */ - SK_U16 LPAb; /* Link Partner Ability */ + SK_U16 LinkPartAb; /* Link Partner Ability */ SK_U16 QuickStat; /* Auxiliary Status */ SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, @@ -3245,16 +3871,16 @@ pPrt = &pAC->GIni.GP[Port]; /* Get PHY parameters */ - SkXmPhyRead(pAC, IoC, Port, PHY_LONE_AUNE_LP, &LPAb); + SkXmPhyRead(pAC, IoC, Port, PHY_LONE_AUNE_LP, &LinkPartAb); SkXmPhyRead(pAC, IoC, Port, PHY_LONE_1000T_STAT, &ResAb); SkXmPhyRead(pAC, IoC, Port, PHY_LONE_Q_STAT, &QuickStat); - if ((LPAb & PHY_L_AN_RF) != 0) { + if ((LinkPartAb & PHY_L_AN_RF) != 0) { /* Remote fault bit is set */ - /* Error */ - SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, + SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_ERR, ("AutoNegFail: Remote fault bit set Port %d\n", Port)); pPrt->PAutoNegFail = SK_TRUE; + return(SK_AND_OTHER); } @@ -3265,28 +3891,25 @@ else { pPrt->PLinkModeStatus = (SK_U8)SK_LMODE_STAT_AUTOHALF; } - + /* Check Master/Slave resolution */ if ((ResAb & PHY_L_1000S_MSF) != 0) { /* Error */ - SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, + SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_ERR, ("Master/Slave Fault Port %d\n", Port)); pPrt->PAutoNegFail = SK_TRUE; pPrt->PMSStatus = SK_MS_STAT_FAULT; return(SK_AND_OTHER); } - else if (ResAb & PHY_L_1000S_MSR) { - pPrt->PMSStatus = SK_MS_STAT_MASTER; - } - else { - pPrt->PMSStatus = SK_MS_STAT_SLAVE; - } + + pPrt->PMSStatus = ((ResAb & PHY_L_1000S_MSR) != 0) ? + (SK_U8)SK_MS_STAT_MASTER : (SK_U8)SK_MS_STAT_SLAVE; /* Check PAUSE mismatch */ /* We are using IEEE 802.3z/D5.0 Table 37-4 */ /* we must manually resolve the abilities here */ pPrt->PFlowCtrlStatus = SK_FLOW_STAT_NONE; - + switch (pPrt->PFlowCtrlMode) { case SK_FLOW_MODE_NONE: /* default */ @@ -3294,7 +3917,7 @@ case SK_FLOW_MODE_LOC_SEND: if ((QuickStat & (PHY_L_QS_PAUSE | PHY_L_QS_AS_PAUSE)) == (PHY_L_QS_PAUSE | PHY_L_QS_AS_PAUSE)) { - /* Disable PAUSE receive, enable PAUSE transmit */ + /* disable PAUSE receive, enable PAUSE transmit */ pPrt->PFlowCtrlStatus = SK_FLOW_STAT_LOC_SEND; } break; @@ -3307,7 +3930,7 @@ case SK_FLOW_MODE_SYM_OR_REM: if ((QuickStat & (PHY_L_QS_PAUSE | PHY_L_QS_AS_PAUSE)) == PHY_L_QS_AS_PAUSE) { - /* Enable PAUSE receive, disable PAUSE transmit */ + /* enable PAUSE receive, disable PAUSE transmit */ pPrt->PFlowCtrlStatus = SK_FLOW_STAT_REM_SEND; } else if ((QuickStat & PHY_L_QS_PAUSE) != 0) { @@ -3319,7 +3942,7 @@ SK_ERR_LOG(pAC, SK_ERRCL_SW | SK_ERRCL_INIT, SKERR_HWI_E016, SKERR_HWI_E016MSG); } - + return(SK_AND_OK); } /* SkXmAutoNegDoneLone */ @@ -3333,12 +3956,12 @@ * * Returns: * SK_AND_OK o.k. - * SK_AND_DUP_CAP Duplex capability error happened - * SK_AND_OTHER Other error happened + * SK_AND_DUP_CAP Duplex capability error happened + * SK_AND_OTHER Other error happened */ static int SkXmAutoNegDoneNat( -SK_AC *pAC, /* adapter context */ -SK_IOC IoC, /* IO context */ +SK_AC *pAC, /* Adapter Context */ +SK_IOC IoC, /* I/O Context */ int Port) /* Port Index (MAC_1 + n) */ { /* todo: National */ @@ -3355,12 +3978,12 @@ * * Returns: * SK_AND_OK o.k. - * SK_AND_DUP_CAP Duplex capability error happened - * SK_AND_OTHER Other error happened + * SK_AND_DUP_CAP Duplex capability error happened + * SK_AND_OTHER Other error happened */ -int SkMacAutoNegDone( -SK_AC *pAC, /* adapter context */ -SK_IOC IoC, /* IO context */ +int SkMacAutoNegDone( +SK_AC *pAC, /* Adapter Context */ +SK_IOC IoC, /* I/O Context */ int Port) /* Port Index (MAC_1 + n) */ { SK_GEPORT *pPrt; @@ -3372,9 +3995,9 @@ #ifdef GENESIS if (pAC->GIni.GIGenesis) { - + switch (pPrt->PhyType) { - + case SK_PHY_XMAC: Rtv = SkXmAutoNegDoneXmac(pAC, IoC, Port); break; @@ -3394,30 +4017,33 @@ } } #endif /* GENESIS */ - + +#ifndef SK_SLIM #ifdef YUKON if (pAC->GIni.GIYukon) { - + Rtv = SkGmAutoNegDoneMarv(pAC, IoC, Port); } #endif /* YUKON */ - + if (Rtv != SK_AND_OK) { return(Rtv); } SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, ("AutoNeg done Port %d\n", Port)); - + /* We checked everything and may now enable the link */ pPrt->PAutoNegFail = SK_FALSE; +#endif /* !SK_SLIM */ SkMacRxTxEnable(pAC, IoC, Port); - + return(SK_AND_OK); } /* SkMacAutoNegDone */ +#ifndef SK_SLIM #ifdef GENESIS /****************************************************************************** * @@ -3431,7 +4057,7 @@ */ static void SkXmSetRxTxEn( SK_AC *pAC, /* Adapter Context */ -SK_IOC IoC, /* IO context */ +SK_IOC IoC, /* I/O Context */ int Port, /* Port Index (MAC_1 + n) */ int Para) /* Parameter to set: MAC or PHY LoopBack, Duplex Mode */ { @@ -3456,7 +4082,7 @@ Word &= ~XM_MMU_GMII_LOOP; break; } - + switch (Para & (SK_PHY_FULLD_ON | SK_PHY_FULLD_OFF)) { case SK_PHY_FULLD_ON: Word |= XM_MMU_GMII_FD; @@ -3465,7 +4091,7 @@ Word &= ~XM_MMU_GMII_FD; break; } - + XM_OUT16(IoC, Port, XM_MMU_CMD, Word | XM_MMU_ENA_RX | XM_MMU_ENA_TX); /* dummy read to ensure writing */ @@ -3488,12 +4114,12 @@ */ static void SkGmSetRxTxEn( SK_AC *pAC, /* Adapter Context */ -SK_IOC IoC, /* IO context */ +SK_IOC IoC, /* I/O Context */ int Port, /* Port Index (MAC_1 + n) */ int Para) /* Parameter to set: MAC LoopBack, Duplex Mode */ { SK_U16 Ctrl; - + GM_IN16(IoC, Port, GM_GP_CTRL, &Ctrl); switch (Para & (SK_MAC_LOOPB_ON | SK_MAC_LOOPB_OFF)) { @@ -3513,18 +4139,18 @@ Ctrl &= ~GM_GPCR_DUP_FULL; break; } - - GM_OUT16(IoC, Port, GM_GP_CTRL, (SK_U16)(Ctrl | GM_GPCR_RX_ENA | - GM_GPCR_TX_ENA)); + GM_OUT16(IoC, Port, GM_GP_CTRL, Ctrl | GM_GPCR_RX_ENA | GM_GPCR_TX_ENA); + +#ifdef XXX /* dummy read to ensure writing */ GM_IN16(IoC, Port, GM_GP_CTRL, &Ctrl); +#endif /* XXX */ } /* SkGmSetRxTxEn */ #endif /* YUKON */ -#ifndef SK_SLIM /****************************************************************************** * * SkMacSetRxTxEn() - Special Set Rx/Tx Enable and parameters @@ -3535,20 +4161,20 @@ */ void SkMacSetRxTxEn( SK_AC *pAC, /* Adapter Context */ -SK_IOC IoC, /* IO context */ +SK_IOC IoC, /* I/O Context */ int Port, /* Port Index (MAC_1 + n) */ int Para) { #ifdef GENESIS if (pAC->GIni.GIGenesis) { - + SkXmSetRxTxEn(pAC, IoC, Port, Para); } #endif /* GENESIS */ - + #ifdef YUKON if (pAC->GIni.GIYukon) { - + SkGmSetRxTxEn(pAC, IoC, Port, Para); } #endif /* YUKON */ @@ -3568,8 +4194,8 @@ * != 0 Error happened */ int SkMacRxTxEnable( -SK_AC *pAC, /* adapter context */ -SK_IOC IoC, /* IO context */ +SK_AC *pAC, /* Adapter Context */ +SK_IOC IoC, /* I/O Context */ int Port) /* Port Index (MAC_1 + n) */ { SK_GEPORT *pPrt; @@ -3587,9 +4213,9 @@ } if ((pPrt->PLinkMode == SK_LMODE_AUTOHALF || - pPrt->PLinkMode == SK_LMODE_AUTOFULL || - pPrt->PLinkMode == SK_LMODE_AUTOBOTH) && - pPrt->PAutoNegFail) { + pPrt->PLinkMode == SK_LMODE_AUTOFULL || + pPrt->PLinkMode == SK_LMODE_AUTOBOTH) && + pPrt->PAutoNegFail) { /* Auto-negotiation is not done or failed */ return(0); } @@ -3598,9 +4224,9 @@ if (pAC->GIni.GIGenesis) { /* set Duplex Mode and Pause Mode */ SkXmInitDupMd(pAC, IoC, Port); - + SkXmInitPauseMd(pAC, IoC, Port); - + /* * Initialize the Interrupt Mask Register. Default IRQs are... * - Link Asynchronous Event @@ -3616,23 +4242,23 @@ /* add IRQ for Receive FIFO Overflow */ IntMask &= ~XM_IS_RXF_OV; #endif /* DEBUG */ - + if (pPrt->PhyType != SK_PHY_XMAC) { /* disable GP0 interrupt bit */ IntMask |= XM_IS_INP_ASS; } XM_OUT16(IoC, Port, XM_IMSK, IntMask); - + /* get MMU Command Reg. */ XM_IN16(IoC, Port, XM_MMU_CMD, &Reg); - + if (pPrt->PhyType != SK_PHY_XMAC && (pPrt->PLinkModeStatus == SK_LMODE_STAT_FULL || pPrt->PLinkModeStatus == SK_LMODE_STAT_AUTOFULL)) { /* set to Full Duplex */ Reg |= XM_MMU_GMII_FD; } - + switch (pPrt->PhyType) { case SK_PHY_BCOM: /* @@ -3642,7 +4268,7 @@ SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_AUX_CTRL, &SWord); SkXmPhyWrite(pAC, IoC, Port, PHY_BCOM_AUX_CTRL, (SK_U16)(SWord & ~PHY_B_AC_DIS_PM)); - SkXmPhyWrite(pAC, IoC, Port, PHY_BCOM_INT_MASK, + SkXmPhyWrite(pAC, IoC, Port, PHY_BCOM_INT_MASK, (SK_U16)PHY_B_DEF_MSK); break; #ifdef OTHER_PHY @@ -3656,12 +4282,12 @@ break; #endif /* OTHER_PHY */ } - + /* enable Rx/Tx */ XM_OUT16(IoC, Port, XM_MMU_CMD, Reg | XM_MMU_ENA_RX | XM_MMU_ENA_TX); } #endif /* GENESIS */ - + #ifdef YUKON if (pAC->GIni.GIYukon) { /* @@ -3672,34 +4298,34 @@ */ IntMask = GMAC_DEF_MSK; -#ifdef DEBUG +#if (defined(DEBUG) || defined(YUK2)) && (!defined(SK_SLIM)) /* add IRQ for Receive FIFO Overrun */ IntMask |= GM_IS_RX_FF_OR; -#endif /* DEBUG */ - - SK_OUT8(IoC, GMAC_IRQ_MSK, (SK_U8)IntMask); - +#endif + + SK_OUT8(IoC, MR_ADDR(Port, GMAC_IRQ_MSK), (SK_U8)IntMask); + /* get General Purpose Control */ GM_IN16(IoC, Port, GM_GP_CTRL, &Reg); - + if (pPrt->PLinkModeStatus == SK_LMODE_STAT_FULL || pPrt->PLinkModeStatus == SK_LMODE_STAT_AUTOFULL) { /* set to Full Duplex */ Reg |= GM_GPCR_DUP_FULL; } - + /* enable Rx/Tx */ - GM_OUT16(IoC, Port, GM_GP_CTRL, (SK_U16)(Reg | GM_GPCR_RX_ENA | - GM_GPCR_TX_ENA)); + GM_OUT16(IoC, Port, GM_GP_CTRL, Reg | GM_GPCR_RX_ENA | GM_GPCR_TX_ENA); -#ifndef VCPU - /* Enable all PHY interrupts */ - SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_INT_MASK, - (SK_U16)PHY_M_DEF_MSK); -#endif /* VCPU */ +#ifdef XXX + /* dummy read to ensure writing */ + GM_IN16(IoC, Port, GM_GP_CTRL, &Reg); +#endif /* XXX */ } #endif /* YUKON */ - + + pAC->GIni.GP[Port].PState = SK_PRT_RUN; + return(0); } /* SkMacRxTxEnable */ @@ -3715,33 +4341,38 @@ */ void SkMacRxTxDisable( SK_AC *pAC, /* Adapter Context */ -SK_IOC IoC, /* IO context */ +SK_IOC IoC, /* I/O Context */ int Port) /* Port Index (MAC_1 + n) */ { SK_U16 Word; #ifdef GENESIS if (pAC->GIni.GIGenesis) { - + XM_IN16(IoC, Port, XM_MMU_CMD, &Word); - - XM_OUT16(IoC, Port, XM_MMU_CMD, Word & ~(XM_MMU_ENA_RX | XM_MMU_ENA_TX)); - + + Word &= ~(XM_MMU_ENA_RX | XM_MMU_ENA_TX); + + XM_OUT16(IoC, Port, XM_MMU_CMD, Word); + /* dummy read to ensure writing */ XM_IN16(IoC, Port, XM_MMU_CMD, &Word); } #endif /* GENESIS */ - + #ifdef YUKON if (pAC->GIni.GIYukon) { - + GM_IN16(IoC, Port, GM_GP_CTRL, &Word); - GM_OUT16(IoC, Port, GM_GP_CTRL, (SK_U16)(Word & ~(GM_GPCR_RX_ENA | - GM_GPCR_TX_ENA))); + Word &= ~(GM_GPCR_RX_ENA | GM_GPCR_TX_ENA); + GM_OUT16(IoC, Port, GM_GP_CTRL, Word); + +#ifdef XXX /* dummy read to ensure writing */ GM_IN16(IoC, Port, GM_GP_CTRL, &Word); +#endif /* XXX */ } #endif /* YUKON */ @@ -3758,7 +4389,7 @@ */ void SkMacIrqDisable( SK_AC *pAC, /* Adapter Context */ -SK_IOC IoC, /* IO context */ +SK_IOC IoC, /* I/O Context */ int Port) /* Port Index (MAC_1 + n) */ { SK_GEPORT *pPrt; @@ -3770,18 +4401,18 @@ #ifdef GENESIS if (pAC->GIni.GIGenesis) { - + /* disable all XMAC IRQs */ - XM_OUT16(IoC, Port, XM_IMSK, 0xffff); - - /* Disable all PHY interrupts */ + XM_OUT16(IoC, Port, XM_IMSK, 0xffff); + + /* disable all PHY interrupts */ switch (pPrt->PhyType) { case SK_PHY_BCOM: /* Make sure that PHY is initialized */ if (pPrt->PState != SK_PRT_RESET) { /* NOT allowed if BCOM is in RESET state */ /* Workaround BCOM Errata (#10523) all BCom */ - /* Disable Power Management if link is down */ + /* disable Power Management if link is down */ SkXmPhyRead(pAC, IoC, Port, PHY_BCOM_AUX_CTRL, &Word); SkXmPhyWrite(pAC, IoC, Port, PHY_BCOM_AUX_CTRL, (SK_U16)(Word | PHY_B_AC_DIS_PM)); @@ -3800,16 +4431,16 @@ } } #endif /* GENESIS */ - + #ifdef YUKON if (pAC->GIni.GIYukon) { /* disable all GMAC IRQs */ - SK_OUT8(IoC, GMAC_IRQ_MSK, 0); - + SK_OUT8(IoC, MR_ADDR(Port, GMAC_IRQ_MSK), 0); + #ifndef VCPU - /* Disable all PHY interrupts */ + /* disable all PHY interrupts */ SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_INT_MASK, 0); -#endif /* VCPU */ +#endif /* !VCPU */ } #endif /* YUKON */ @@ -3821,29 +4452,72 @@ * * SkXmSendCont() - Enable / Disable Send Continuous Mode * - * Description: enable / disable Send Continuous Mode on XMAC + * Description: enable / disable Send Continuous Mode on XMAC resp. + * Packet Generation on GPHY * * Returns: * nothing */ void SkXmSendCont( -SK_AC *pAC, /* adapter context */ -SK_IOC IoC, /* IO context */ +SK_AC *pAC, /* Adapter Context */ +SK_IOC IoC, /* I/O Context */ int Port, /* Port Index (MAC_1 + n) */ SK_BOOL Enable) /* Enable / Disable */ { + SK_U16 Reg; + SK_U16 Save; SK_U32 MdReg; - XM_IN32(IoC, Port, XM_MODE, &MdReg); + if (pAC->GIni.GIGenesis) { + XM_IN32(IoC, Port, XM_MODE, &MdReg); - if (Enable) { - MdReg |= XM_MD_TX_CONT; + if (Enable) { + MdReg |= XM_MD_TX_CONT; + } + else { + MdReg &= ~XM_MD_TX_CONT; + } + /* setup Mode Register */ + XM_OUT32(IoC, Port, XM_MODE, MdReg); } else { - MdReg &= ~XM_MD_TX_CONT; + if (pAC->GIni.GIChipId == CHIP_ID_YUKON_EC) { + /* select page 18 */ + SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_PAGE_ADDR, 18); + + SkGmPhyRead(pAC, IoC, Port, PHY_MARV_PAGE_DATA, &Reg); + + Reg &= ~0x003c; /* clear bits 5..2 */ + + if (Enable) { + /* enable packet generation, 1518 byte length */ + Reg |= (BIT_5S | BIT_3S); + } + + SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_PAGE_DATA, Reg); + } + else if (pAC->GIni.GIChipId == CHIP_ID_YUKON_XL) { + /* save page register */ + SkGmPhyRead(pAC, IoC, Port, PHY_MARV_EXT_ADR, &Save); + + /* select page 6 to access Packet Generation register */ + SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_EXT_ADR, 6); + + SkGmPhyRead(pAC, IoC, Port, PHY_MARV_PHY_CTRL, &Reg); + + Reg &= ~0x003f; /* clear bits 5..0 */ + + if (Enable) { + /* enable packet generation, 1518 byte length */ + Reg |= (BIT_3S | BIT_1S); + } + + SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_PHY_CTRL, Reg); + + /* restore page register */ + SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_EXT_ADR, Save); + } } - /* setup Mode Register */ - XM_OUT32(IoC, Port, XM_MODE, MdReg); } /* SkXmSendCont */ @@ -3858,8 +4532,8 @@ * nothing */ void SkMacTimeStamp( -SK_AC *pAC, /* adapter context */ -SK_IOC IoC, /* IO context */ +SK_AC *pAC, /* Adapter Context */ +SK_IOC IoC, /* I/O Context */ int Port, /* Port Index (MAC_1 + n) */ SK_BOOL Enable) /* Enable / Disable */ { @@ -3904,8 +4578,8 @@ * is set true. */ void SkXmAutoNegLipaXmac( -SK_AC *pAC, /* adapter context */ -SK_IOC IoC, /* IO context */ +SK_AC *pAC, /* Adapter Context */ +SK_IOC IoC, /* I/O Context */ int Port, /* Port Index (MAC_1 + n) */ SK_U16 IStatus) /* Interrupt Status word to analyse */ { @@ -3917,8 +4591,9 @@ (IStatus & (XM_IS_LIPA_RC | XM_IS_RX_PAGE | XM_IS_AND)) != 0) { SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, - ("AutoNegLipa: AutoNeg detected on Port %d, IStatus=0x%04X\n", + ("AutoNegLipa: AutoNeg detected on Port %d, IStatus = 0x%04X\n", Port, IStatus)); + pPrt->PLipaAutoNeg = SK_LIPA_AUTO; } } /* SkXmAutoNegLipaXmac */ @@ -3934,8 +4609,8 @@ * is set true. */ void SkMacAutoNegLipaPhy( -SK_AC *pAC, /* adapter context */ -SK_IOC IoC, /* IO context */ +SK_AC *pAC, /* Adapter Context */ +SK_IOC IoC, /* I/O Context */ int Port, /* Port Index (MAC_1 + n) */ SK_U16 PhyStat) /* PHY Status word to analyse */ { @@ -3947,8 +4622,9 @@ (PhyStat & PHY_ST_AN_OVER) != 0) { SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, - ("AutoNegLipa: AutoNeg detected on Port %d, PhyStat=0x%04X\n", + ("AutoNegLipa: AutoNeg detected on Port %d, PhyStat = 0x%04X\n", Port, PhyStat)); + pPrt->PLipaAutoNeg = SK_LIPA_AUTO; } } /* SkMacAutoNegLipaPhy */ @@ -3963,7 +4639,7 @@ * * Note: * With an external PHY, some interrupt bits are not meaningfull any more: - * - LinkAsyncEvent (bit #14) XM_IS_LNK_AE + * - LinkAsyncEvent (bit #14) XM_IS_LNK_AE * - LinkPartnerReqConfig (bit #10) XM_IS_LIPA_RC * - Page Received (bit #9) XM_IS_RX_PAGE * - NextPageLoadedForXmt (bit #8) XM_IS_TX_PAGE @@ -3975,22 +4651,23 @@ * nothing */ void SkXmIrq( -SK_AC *pAC, /* adapter context */ -SK_IOC IoC, /* IO context */ +SK_AC *pAC, /* Adapter Context */ +SK_IOC IoC, /* I/O Context */ int Port) /* Port Index (MAC_1 + n) */ { SK_GEPORT *pPrt; - SK_EVPARA Para; SK_U16 IStatus; /* Interrupt status read from the XMAC */ SK_U16 IStatus2; #ifdef SK_SLIM - SK_U64 OverflowStatus; -#endif + SK_U64 OverflowStatus; +#else + SK_EVPARA Para; +#endif /* SK_SLIM */ pPrt = &pAC->GIni.GP[Port]; - + XM_IN16(IoC, Port, XM_ISRC, &IStatus); - + /* LinkPartner Auto-negable? */ if (pPrt->PhyType == SK_PHY_XMAC) { SkXmAutoNegLipaXmac(pAC, IoC, Port, IStatus); @@ -4001,7 +4678,7 @@ XM_IS_RX_PAGE | XM_IS_TX_PAGE | XM_IS_AND | XM_IS_INP_ASS); } - + SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ, ("XmacIrq Port %d Isr 0x%04X\n", Port, IStatus)); @@ -4111,49 +4788,55 @@ * nothing */ void SkGmIrq( -SK_AC *pAC, /* adapter context */ -SK_IOC IoC, /* IO context */ +SK_AC *pAC, /* Adapter Context */ +SK_IOC IoC, /* I/O Context */ int Port) /* Port Index (MAC_1 + n) */ { SK_GEPORT *pPrt; SK_U8 IStatus; /* Interrupt status */ #ifdef SK_SLIM - SK_U64 OverflowStatus; + SK_U64 OverflowStatus; #else SK_EVPARA Para; -#endif +#endif /* SK_SLIM */ pPrt = &pAC->GIni.GP[Port]; - - SK_IN8(IoC, GMAC_IRQ_SRC, &IStatus); - + + SK_IN8(IoC, MR_ADDR(Port, GMAC_IRQ_SRC), &IStatus); + #ifdef XXX /* LinkPartner Auto-negable? */ SkMacAutoNegLipaPhy(pAC, IoC, Port, IStatus); #endif /* XXX */ - + SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_IRQ, - ("GmacIrq Port %d Isr 0x%04X\n", Port, IStatus)); + ("GmacIrq Port %d Isr 0x%02X\n", Port, IStatus)); /* Combined Tx & Rx Counter Overflow SIRQ Event */ if (IStatus & (GM_IS_RX_CO_OV | GM_IS_TX_CO_OV)) { /* these IRQs will be cleared by reading GMACs register */ #ifdef SK_SLIM - SkGmOverflowStatus(pAC, IoC, Port, IStatus, &OverflowStatus); + SkGmOverflowStatus(pAC, IoC, Port, (SK_U16)IStatus, &OverflowStatus); #else Para.Para32[0] = (SK_U32)Port; Para.Para32[1] = (SK_U32)IStatus; SkPnmiEvent(pAC, IoC, SK_PNMI_EVT_SIRQ_OVERFLOW, Para); -#endif +#endif /* SK_SLIM */ } +#ifndef SK_SLIM if (IStatus & GM_IS_RX_FF_OR) { /* clear GMAC Rx FIFO Overrun IRQ */ SK_OUT8(IoC, MR_ADDR(Port, RX_GMF_CTRL_T), (SK_U8)GMF_CLI_RX_FO); + + Para.Para64 = Port; + SkEventQueue(pAC, SKGE_DRV, SK_DRV_RX_OVERFLOW, Para); + #ifdef DEBUG pPrt->PRxOverCnt++; #endif /* DEBUG */ } +#endif /* !SK_SLIM */ if (IStatus & GM_IS_TX_FF_UR) { /* clear GMAC Tx FIFO Underrun IRQ */ @@ -4183,8 +4866,8 @@ * nothing */ void SkMacIrq( -SK_AC *pAC, /* adapter context */ -SK_IOC IoC, /* IO context */ +SK_AC *pAC, /* Adapter Context */ +SK_IOC IoC, /* I/O Context */ int Port) /* Port Index (MAC_1 + n) */ { #ifdef GENESIS @@ -4193,7 +4876,7 @@ SkXmIrq(pAC, IoC, Port); } #endif /* GENESIS */ - + #ifdef YUKON if (pAC->GIni.GIYukon) { /* IRQ from GMAC */ @@ -4220,8 +4903,8 @@ * 1: something went wrong */ int SkXmUpdateStats( -SK_AC *pAC, /* adapter context */ -SK_IOC IoC, /* IO context */ +SK_AC *pAC, /* Adapter Context */ +SK_IOC IoC, /* I/O Context */ unsigned int Port) /* Port Index (MAC_1 + n) */ { SK_GEPORT *pPrt; @@ -4243,7 +4926,7 @@ do { XM_IN16(IoC, Port, XM_STAT_CMD, &StatReg); - + if (++WaitIndex > 10) { SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_HWI_E021, SKERR_HWI_E021MSG); @@ -4251,7 +4934,7 @@ return(1); } } while ((StatReg & (XM_SC_SNP_TXC | XM_SC_SNP_RXC)) != 0); - + return(0); } /* SkXmUpdateStats */ @@ -4270,19 +4953,19 @@ * 1: something went wrong */ int SkXmMacStatistic( -SK_AC *pAC, /* adapter context */ -SK_IOC IoC, /* IO context */ +SK_AC *pAC, /* Adapter Context */ +SK_IOC IoC, /* I/O Context */ unsigned int Port, /* Port Index (MAC_1 + n) */ SK_U16 StatAddr, /* MIB counter base address */ -SK_U32 SK_FAR *pVal) /* ptr to return statistic value */ +SK_U32 SK_FAR *pVal) /* Pointer to return statistic value */ { if ((StatAddr < XM_TXF_OK) || (StatAddr > XM_RXF_MAX_SZ)) { - + SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E022, SKERR_HWI_E022MSG); - + return(1); } - + XM_IN32(IoC, Port, StatAddr, pVal); return(0); @@ -4301,12 +4984,12 @@ * 1: something went wrong */ int SkXmResetCounter( -SK_AC *pAC, /* adapter context */ -SK_IOC IoC, /* IO context */ +SK_AC *pAC, /* Adapter Context */ +SK_IOC IoC, /* I/O Context */ unsigned int Port) /* Port Index (MAC_1 + n) */ { XM_OUT16(IoC, Port, XM_STAT_CMD, XM_SC_CLR_RXC | XM_SC_CLR_TXC); - /* Clear two times according to Errata #3 */ + /* Clear two times according to XMAC Errata #3 */ XM_OUT16(IoC, Port, XM_STAT_CMD, XM_SC_CLR_RXC | XM_SC_CLR_TXC); return(0); @@ -4333,11 +5016,11 @@ * 1: something went wrong */ int SkXmOverflowStatus( -SK_AC *pAC, /* adapter context */ -SK_IOC IoC, /* IO context */ +SK_AC *pAC, /* Adapter Context */ +SK_IOC IoC, /* I/O Context */ unsigned int Port, /* Port Index (MAC_1 + n) */ -SK_U16 IStatus, /* Interupt Status from MAC */ -SK_U64 SK_FAR *pStatus) /* ptr for return overflow status value */ +SK_U16 IStatus, /* Interrupt Status from MAC */ +SK_U64 SK_FAR *pStatus) /* Pointer for return overflow status value */ { SK_U64 Status; /* Overflow status */ SK_U32 RegVal; @@ -4349,7 +5032,7 @@ XM_IN32(IoC, Port, XM_RX_CNT_EV, &RegVal); Status |= (SK_U64)RegVal << 32; } - + if ((IStatus & XM_IS_TXC_OV) != 0) { XM_IN32(IoC, Port, XM_TX_CNT_EV, &RegVal); @@ -4376,8 +5059,8 @@ * 1: something went wrong */ int SkGmUpdateStats( -SK_AC *pAC, /* adapter context */ -SK_IOC IoC, /* IO context */ +SK_AC *pAC, /* Adapter Context */ +SK_IOC IoC, /* I/O Context */ unsigned int Port) /* Port Index (MAC_1 + n) */ { return(0); @@ -4398,24 +5081,27 @@ * 1: something went wrong */ int SkGmMacStatistic( -SK_AC *pAC, /* adapter context */ -SK_IOC IoC, /* IO context */ +SK_AC *pAC, /* Adapter Context */ +SK_IOC IoC, /* I/O Context */ unsigned int Port, /* Port Index (MAC_1 + n) */ SK_U16 StatAddr, /* MIB counter base address */ -SK_U32 SK_FAR *pVal) /* ptr to return statistic value */ +SK_U32 SK_FAR *pVal) /* Pointer to return statistic value */ { if ((StatAddr < GM_RXF_UC_OK) || (StatAddr > GM_TXE_FIFO_UR)) { - + SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_HWI_E022, SKERR_HWI_E022MSG); - - SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, + + SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_ERR, ("SkGmMacStat: wrong MIB counter 0x%04X\n", StatAddr)); return(1); } - + GM_IN32(IoC, Port, StatAddr, pVal); + /* dummy read after GM_IN32() */ + SK_IN16(IoC, B0_RAP, &StatAddr); + return(0); } /* SkGmMacStatistic */ @@ -4432,8 +5118,8 @@ * 1: something went wrong */ int SkGmResetCounter( -SK_AC *pAC, /* adapter context */ -SK_IOC IoC, /* IO context */ +SK_AC *pAC, /* Adapter Context */ +SK_IOC IoC, /* I/O Context */ unsigned int Port) /* Port Index (MAC_1 + n) */ { SK_U16 Reg; /* Phy Address Register */ @@ -4444,16 +5130,16 @@ /* set MIB Clear Counter Mode */ GM_OUT16(IoC, Port, GM_PHY_ADDR, Reg | GM_PAR_MIB_CLR); - + /* read all MIB Counters with Clear Mode set */ for (i = 0; i < GM_MIB_CNT_SIZE; i++) { /* the reset is performed only when the lower 16 bits are read */ GM_IN16(IoC, Port, GM_MIB_CNT_BASE + 8*i, &Word); } - + /* clear MIB Clear Counter Mode */ GM_OUT16(IoC, Port, GM_PHY_ADDR, Reg); - + return(0); } /* SkGmResetCounter */ @@ -4467,48 +5153,62 @@ * resulting counter overflow status is written to , whereas the * the following bit coding is used: * 63:56 - unused - * 55:48 - TxRx interrupt register bit7:0 - * 32:47 - Rx interrupt register + * 55:48 - TxRx interrupt register bit 7:0 + * 47:32 - Rx interrupt register * 31:24 - unused - * 23:16 - TxRx interrupt register bit15:8 - * 15:0 - Tx interrupt register + * 23:16 - TxRx interrupt register bit 15:8 + * 15: 0 - Tx interrupt register * * Returns: * 0: success * 1: something went wrong */ int SkGmOverflowStatus( -SK_AC *pAC, /* adapter context */ -SK_IOC IoC, /* IO context */ +SK_AC *pAC, /* Adapter Context */ +SK_IOC IoC, /* I/O Context */ unsigned int Port, /* Port Index (MAC_1 + n) */ -SK_U16 IStatus, /* Interupt Status from MAC */ -SK_U64 SK_FAR *pStatus) /* ptr for return overflow status value */ +SK_U16 IStatus, /* Interrupt Status from MAC */ +SK_U64 SK_FAR *pStatus) /* Pointer for return overflow status value */ { - SK_U64 Status; /* Overflow status */ SK_U16 RegVal; +#ifndef SK_SLIM + SK_U64 Status; /* Overflow status */ Status = 0; +#endif /* !SK_SLIM */ if ((IStatus & GM_IS_RX_CO_OV) != 0) { /* this register is self-clearing after read */ GM_IN16(IoC, Port, GM_RX_IRQ_SRC, &RegVal); + +#ifndef SK_SLIM Status |= (SK_U64)RegVal << 32; +#endif /* !SK_SLIM */ } - + if ((IStatus & GM_IS_TX_CO_OV) != 0) { /* this register is self-clearing after read */ GM_IN16(IoC, Port, GM_TX_IRQ_SRC, &RegVal); + +#ifndef SK_SLIM Status |= (SK_U64)RegVal; +#endif /* !SK_SLIM */ } - + /* this register is self-clearing after read */ GM_IN16(IoC, Port, GM_TR_IRQ_SRC, &RegVal); + +#ifndef SK_SLIM /* Rx overflow interrupt register bits (LoByte)*/ Status |= (SK_U64)((SK_U8)RegVal) << 48; /* Tx overflow interrupt register bits (HiByte)*/ Status |= (SK_U64)(RegVal >> 8) << 16; *pStatus = Status; +#endif /* !SK_SLIM */ + + /* dummy read after GM_IN16() */ + SK_IN16(IoC, B0_RAP, &RegVal); return(0); } /* SkGmOverflowStatus */ @@ -4524,60 +5224,118 @@ * gets the results if 'StartTest' is true * * NOTE: this test is meaningful only when link is down - * + * * Returns: * 0: success * 1: no YUKON copper * 2: test in progress */ int SkGmCableDiagStatus( -SK_AC *pAC, /* adapter context */ -SK_IOC IoC, /* IO context */ +SK_AC *pAC, /* Adapter Context */ +SK_IOC IoC, /* I/O Context */ int Port, /* Port Index (MAC_1 + n) */ SK_BOOL StartTest) /* flag for start / get result */ { int i; + int CableDiagOffs; + int MdiPairs; + SK_BOOL FastEthernet; + SK_BOOL Yukon2; SK_U16 RegVal; SK_GEPORT *pPrt; pPrt = &pAC->GIni.GP[Port]; if (pPrt->PhyType != SK_PHY_MARV_COPPER) { - + return(1); } + Yukon2 = pAC->GIni.GIChipId == CHIP_ID_YUKON_XL || + pAC->GIni.GIChipId == CHIP_ID_YUKON_EC_U; + + if (pAC->GIni.GIChipId == CHIP_ID_YUKON_FE) { + + CableDiagOffs = PHY_MARV_FE_VCT_TX; + FastEthernet = SK_TRUE; + MdiPairs = 2; + } + else { + CableDiagOffs = Yukon2 ? PHY_MARV_PHY_CTRL : PHY_MARV_CABLE_DIAG; + FastEthernet = SK_FALSE; + MdiPairs = 4; + } + if (StartTest) { + + /* set to RESET to avoid PortCheckUp */ + pPrt->PState = SK_PRT_RESET; + /* only start the cable test */ - if ((pPrt->PhyId1 & PHY_I1_REV_MSK) < 4) { - /* apply TDR workaround from Marvell */ - SkGmPhyWrite(pAC, IoC, Port, 29, 0x001e); - - SkGmPhyWrite(pAC, IoC, Port, 30, 0xcc00); - SkGmPhyWrite(pAC, IoC, Port, 30, 0xc800); - SkGmPhyWrite(pAC, IoC, Port, 30, 0xc400); - SkGmPhyWrite(pAC, IoC, Port, 30, 0xc000); - SkGmPhyWrite(pAC, IoC, Port, 30, 0xc100); + if (!FastEthernet) { + + if ((((pPrt->PhyId1 & PHY_I1_MOD_NUM) >> 4) == 2) && + ((pPrt->PhyId1 & PHY_I1_REV_MSK) < 4)) { + /* apply TDR workaround for model 2, rev. < 4 */ + SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_PAGE_ADDR, 0x001e); + + SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_PAGE_DATA, 0xcc00); + SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_PAGE_DATA, 0xc800); + SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_PAGE_DATA, 0xc400); + SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_PAGE_DATA, 0xc000); + SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_PAGE_DATA, 0xc100); + } + +#ifdef YUKON_DBG + if (pAC->GIni.GIChipId == CHIP_ID_YUKON_EC) { + /* set address to 1 for page 1 */ + SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_EXT_ADR, 1); + + /* disable waiting period */ + SkGmPhyWrite(pAC, IoC, Port, CableDiagOffs, + PHY_M_CABD_DIS_WAIT); + } +#endif + if (Yukon2) { + /* set address to 5 for page 5 */ + SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_EXT_ADR, 5); + +#ifdef YUKON_DBG + /* disable waiting period */ + SkGmPhyWrite(pAC, IoC, Port, CableDiagOffs + 1, + PHY_M_CABD_DIS_WAIT); +#endif + } + else { + /* set address to 0 for MDI[0] (Page 0) */ + SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_EXT_ADR, 0); + } } + else { + RegVal = PHY_CT_RESET | PHY_CT_SP100; - /* set address to 0 for MDI[0] */ - SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_EXT_ADR, 0); + SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_CTRL, RegVal); - /* Read Cable Diagnostic Reg */ - SkGmPhyRead(pAC, IoC, Port, PHY_MARV_CABLE_DIAG, &RegVal); +#ifdef xYUKON_DBG + SkGmPhyRead(pAC, IoC, Port, PHY_MARV_FE_SPEC_2, &RegVal); + /* disable waiting period */ + RegVal |= PHY_M_FESC_DIS_WAIT; + + SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_FE_SPEC_2, RegVal); +#endif + } /* start Cable Diagnostic Test */ - SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_CABLE_DIAG, - (SK_U16)(RegVal | PHY_M_CABD_ENA_TEST)); - + SkGmPhyWrite(pAC, IoC, Port, CableDiagOffs, PHY_M_CABD_ENA_TEST); + return(0); } - + /* Read Cable Diagnostic Reg */ - SkGmPhyRead(pAC, IoC, Port, PHY_MARV_CABLE_DIAG, &RegVal); + SkGmPhyRead(pAC, IoC, Port, CableDiagOffs, &RegVal); SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_CTRL, - ("PHY Cable Diag.=0x%04X\n", RegVal)); + ("PHY Cable Diag. = 0x%04X\n", RegVal)); if ((RegVal & PHY_M_CABD_ENA_TEST) != 0) { /* test is running */ @@ -4585,16 +5343,24 @@ } /* get the test results */ - for (i = 0; i < 4; i++) { - /* set address to i for MDI[i] */ - SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_EXT_ADR, (SK_U16)i); + for (i = 0; i < MdiPairs; i++) { + + if (!FastEthernet && !Yukon2) { + /* set address to i for MDI[i] */ + SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_EXT_ADR, (SK_U16)i); + } /* get Cable Diagnostic values */ - SkGmPhyRead(pAC, IoC, Port, PHY_MARV_CABLE_DIAG, &RegVal); + SkGmPhyRead(pAC, IoC, Port, CableDiagOffs, &RegVal); pPrt->PMdiPairLen[i] = (SK_U8)(RegVal & PHY_M_CABD_DIST_MSK); pPrt->PMdiPairSts[i] = (SK_U8)((RegVal & PHY_M_CABD_STAT_MSK) >> 13); + + if (FastEthernet || Yukon2) { + /* get next register */ + CableDiagOffs++; + } } return(0); @@ -4603,3 +5369,4 @@ #endif /* YUKON */ /* End of file */ + diff -urN linux-2.4.32-600/drivers/net/sk98lin/sky2.c linux-2.4.32-600-sk98_831/drivers/net/sk98lin/sky2.c --- linux-2.4.32-600/drivers/net/sk98lin/sky2.c Thu Jan 1 01:00:00 1970 +++ linux-2.4.32-600-sk98_831/drivers/net/sk98lin/sky2.c Sun Feb 26 11:12:56 2006 @@ -0,0 +1,2717 @@ +/****************************************************************************** + * + * Name: sky2.c + * Project: Yukon2 specific functions and implementations + * Version: $Revision: 1.35.2.39 $ + * Date: $Date: 2005/09/05 08:59:54 $ + * Purpose: The main driver source module + * + *****************************************************************************/ + +/****************************************************************************** + * + * (C)Copyright 1998-2002 SysKonnect GmbH. + * (C)Copyright 2002-2005 Marvell. + * + * Driver for Marvell Yukon/2 chipset and SysKonnect Gigabit Ethernet + * Server Adapters. + * + * Author: Ralph Roesler (rroesler@syskonnect.de) + * Mirko Lindner (mlindner@syskonnect.de) + * + * Address all question to: linux@syskonnect.de + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * The information in this file is provided "AS IS" without warranty. + * + *****************************************************************************/ + +#include "h/skdrv1st.h" +#include "h/skdrv2nd.h" +#include + +/****************************************************************************** + * + * Local Function Prototypes + * + *****************************************************************************/ + +static void InitPacketQueues(SK_AC *pAC,int Port); +static void GiveTxBufferToHw(SK_AC *pAC,SK_IOC IoC,int Port); +static void GiveRxBufferToHw(SK_AC *pAC,SK_IOC IoC,int Port,SK_PACKET *pPacket); +static SK_BOOL HandleReceives(SK_AC *pAC,int Port,SK_U16 Len,SK_U32 FrameStatus,SK_U16 Tcp1,SK_U16 Tcp2,SK_U32 Tist,SK_U16 Vlan); +static void CheckForSendComplete(SK_AC *pAC,SK_IOC IoC,int Port,SK_PKT_QUEUE *pPQ,SK_LE_TABLE *pLETab,unsigned int Done); +static void UnmapAndFreeTxPktBuffer(SK_AC *pAC,SK_PACKET *pSkPacket,int TxPort); +static SK_BOOL AllocateAndInitLETables(SK_AC *pAC); +static SK_BOOL AllocatePacketBuffersYukon2(SK_AC *pAC); +static void FreeLETables(SK_AC *pAC); +static void FreePacketBuffers(SK_AC *pAC); +static SK_BOOL AllocAndMapRxBuffer(SK_AC *pAC,SK_PACKET *pSkPacket,int Port); +#ifdef CONFIG_SK98LIN_NAPI +static SK_BOOL HandleStatusLEs(SK_AC *pAC,int *WorkDone,int WorkToDo); +#else +static SK_BOOL HandleStatusLEs(SK_AC *pAC); +#endif + +extern void SkGeCheckTimer (DEV_NET *pNet); +extern void SkLocalEventQueue( SK_AC *pAC, + SK_U32 Class, + SK_U32 Event, + SK_U32 Param1, + SK_U32 Param2, + SK_BOOL Flag); +extern void SkLocalEventQueue64( SK_AC *pAC, + SK_U32 Class, + SK_U32 Event, + SK_U64 Param, + SK_BOOL Flag); + +/****************************************************************************** + * + * Local Variables + * + *****************************************************************************/ + +#define MAX_NBR_RX_BUFFERS_IN_HW 0x15 +static SK_U8 NbrRxBuffersInHW; +#define FLUSH_OPC(le) + +/****************************************************************************** + * + * Global Functions + * + *****************************************************************************/ + +int SkY2Xmit( struct sk_buff *skb, struct SK_NET_DEVICE *dev); +void FillReceiveTableYukon2(SK_AC *pAC,SK_IOC IoC,int Port); + +/***************************************************************************** + * + * SkY2RestartStatusUnit - restarts teh status unit + * + * Description: + * Reenables the status unit after any De-Init (e.g. when altering + * the sie of the MTU via 'ifconfig a.b.c.d mtu xxx') + * + * Returns: N/A + */ +void SkY2RestartStatusUnit( +SK_AC *pAC) /* pointer to adapter control context */ +{ + SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_MSG, + ("==> SkY2RestartStatusUnit\n")); + + /* + ** It might be that the TX timer is not started. Therefore + ** it is initialized here -> to be more investigated! + */ + SK_OUT32(pAC->IoBase, STAT_TX_TIMER_INI, HW_MS_TO_TICKS(pAC,10)); + + pAC->StatusLETable.Done = 0; + pAC->StatusLETable.Put = 0; + pAC->StatusLETable.HwPut = 0; + SkGeY2InitStatBmu(pAC, pAC->IoBase, &pAC->StatusLETable); + + SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_MSG, + ("<== SkY2RestartStatusUnit\n")); +} + +/***************************************************************************** + * + * SkY2RlmtSend - sends out a single RLMT notification + * + * Description: + * This function sends out an RLMT frame + * + * Returns: + * > 0 - on succes: the number of bytes in the message + * = 0 - on resource shortage: this frame sent or dropped, now + * the ring is full ( -> set tbusy) + * < 0 - on failure: other problems ( -> return failure to upper layers) + */ +int SkY2RlmtSend ( +SK_AC *pAC, /* pointer to adapter control context */ +int PortNr, /* index of port the packet(s) shall be send to */ +struct sk_buff *pMessage) /* pointer to send-message */ +{ + SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_MSG, + ("=== SkY2RlmtSend\n")); +#if 0 + return -1; // temporarily do not send out RLMT frames +#endif + skb_shinfo(pMessage)->nr_frags = (2*MAX_SKB_FRAGS) + PortNr; + return(SkY2Xmit(pMessage, pAC->dev[PortNr])); // SkY2Xmit needs device +} + +/***************************************************************************** + * + * SkY2AllocateResources - Allocates all required resources for Yukon2 + * + * Description: + * This function allocates all memory needed for the Yukon2. + * It maps also RX buffers to the LETables and initializes the + * status list element table. + * + * Returns: + * SK_TRUE, if all resources could be allocated and setup succeeded + * SK_FALSE, if an error + */ +SK_BOOL SkY2AllocateResources ( +SK_AC *pAC) /* pointer to adapter control context */ +{ + int CurrMac; + + SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_INIT, + ("==> SkY2AllocateResources\n")); + + /* + ** Initialize the packet queue variables first + */ + for (CurrMac = 0; CurrMac < pAC->GIni.GIMacsFound; CurrMac++) { + InitPacketQueues(pAC, CurrMac); + } + + /* + ** Get sufficient memory for the LETables + */ + if (!AllocateAndInitLETables(pAC)) { + SK_DBG_MSG(pAC, SK_DBGMOD_DRV, + SK_DBGCAT_INIT | SK_DBGCAT_DRV_ERROR, + ("No memory for LETable.\n")); + return(SK_FALSE); + } + + /* + ** Allocate and intialize memory for both RX and TX + ** packet and fragment buffers. On an error, free + ** previously allocated LETable memory and quit. + */ + if (!AllocatePacketBuffersYukon2(pAC)) { + FreeLETables(pAC); + SK_DBG_MSG(pAC, SK_DBGMOD_DRV, + SK_DBGCAT_INIT | SK_DBGCAT_DRV_ERROR, + ("No memory for Packetbuffers.\n")); + return(SK_FALSE); + } + + /* + ** Rx and Tx LE tables will be initialized in SkGeOpen() + ** + ** It might be that the TX timer is not started. Therefore + ** it is initialized here -> to be more investigated! + */ + SK_OUT32(pAC->IoBase, STAT_TX_TIMER_INI, HW_MS_TO_TICKS(pAC,10)); + SkGeY2InitStatBmu(pAC, pAC->IoBase, &pAC->StatusLETable); + + pAC->MaxUnusedRxLeWorking = MAX_UNUSED_RX_LE_WORKING; + + SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_INIT, + ("<== SkY2AllocateResources\n")); + + return (SK_TRUE); +} + +/***************************************************************************** + * + * SkY2FreeResources - Frees previously allocated resources of Yukon2 + * + * Description: + * This function frees all previously allocated memory of the Yukon2. + * + * Returns: N/A + */ +void SkY2FreeResources ( +SK_AC *pAC) /* pointer to adapter control context */ +{ + SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_MSG, + ("==> SkY2FreeResources\n")); + + FreeLETables(pAC); + FreePacketBuffers(pAC); + + SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_MSG, + ("<== SkY2FreeResources\n")); +} + +/***************************************************************************** + * + * SkY2AllocateRxBuffers - Allocates the receive buffers for a port + * + * Description: + * This function allocated all the RX buffers of the Yukon2. + * + * Returns: N/A + */ +void SkY2AllocateRxBuffers ( +SK_AC *pAC, /* pointer to adapter control context */ +SK_IOC IoC, /* I/O control context */ +int Port) /* port index of RX */ +{ + SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_INIT, + ("==> SkY2AllocateRxBuffers (Port %c)\n", Port)); + + FillReceiveTableYukon2(pAC, IoC, Port); + + SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_INIT, + ("<== SkY2AllocateRxBuffers\n")); +} + +/***************************************************************************** + * + * SkY2FreeRxBuffers - Free's all allocates RX buffers of + * + * Description: + * This function frees all RX buffers of the Yukon2 for a single port + * + * Returns: N/A + */ +void SkY2FreeRxBuffers ( +SK_AC *pAC, /* pointer to adapter control context */ +SK_IOC IoC, /* I/O control context */ +int Port) /* port index of RX */ +{ + SK_PACKET *pSkPacket; + unsigned long Flags; /* for POP/PUSH macros */ + + SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_MSG, + ("==> SkY2FreeRxBuffers (Port %c)\n", Port)); + + if (pAC->RxPort[Port].ReceivePacketTable != NULL) { + POP_FIRST_PKT_FROM_QUEUE(&pAC->RxPort[Port].RxQ_working, pSkPacket); + while (pSkPacket != NULL) { + if ((pSkPacket->pFrag) != NULL) { + pci_unmap_page(pAC->PciDev, + (dma_addr_t) pSkPacket->pFrag->pPhys, + pSkPacket->pFrag->FragLen - 2, + PCI_DMA_FROMDEVICE); + + /* wipe out any rubbish data that may interfere */ + skb_shinfo(pSkPacket->pMBuf)->nr_frags = 0; + skb_shinfo(pSkPacket->pMBuf)->frag_list = NULL; + DEV_KFREE_SKB_ANY(pSkPacket->pMBuf); + pSkPacket->pMBuf = NULL; + pSkPacket->pFrag->pPhys = (SK_U64) 0; + pSkPacket->pFrag->pVirt = NULL; + } + PUSH_PKT_AS_LAST_IN_QUEUE(&pAC->RxPort[Port].RxQ_waiting, pSkPacket); + POP_FIRST_PKT_FROM_QUEUE(&pAC->RxPort[Port].RxQ_working, pSkPacket); + } + } + + SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_MSG, + ("<== SkY2FreeRxBuffers\n")); +} + +/***************************************************************************** + * + * SkY2FreeTxBuffers - Free's any currently maintained Tx buffer + * + * Description: + * This function frees the TX buffers of the Yukon2 for a single port + * which might be in use by a transmit action + * + * Returns: N/A + */ +void SkY2FreeTxBuffers ( +SK_AC *pAC, /* pointer to adapter control context */ +SK_IOC IoC, /* I/O control context */ +int Port) /* port index of TX */ +{ + SK_PACKET *pSkPacket; + SK_FRAG *pSkFrag; + unsigned long Flags; + + SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_MSG, + ("==> SkY2FreeTxBuffers (Port %c)\n", Port)); + + if (pAC->TxPort[Port][0].TransmitPacketTable != NULL) { + POP_FIRST_PKT_FROM_QUEUE(&pAC->TxPort[Port][0].TxAQ_working, pSkPacket); + while (pSkPacket != NULL) { + if ((pSkFrag = pSkPacket->pFrag) != NULL) { + UnmapAndFreeTxPktBuffer(pAC, pSkPacket, Port); + } + PUSH_PKT_AS_LAST_IN_QUEUE(&pAC->TxPort[Port][0].TxQ_free, pSkPacket); + POP_FIRST_PKT_FROM_QUEUE(&pAC->TxPort[Port][0].TxAQ_working, pSkPacket); + } +#if USE_SYNC_TX_QUEUE + POP_FIRST_PKT_FROM_QUEUE(&pAC->TxPort[Port][0].TxSQ_working, pSkPacket); + while (pSkPacket != NULL) { + if ((pSkFrag = pSkPacket->pFrag) != NULL) { + UnmapAndFreeTxPktBuffer(pAC, pSkPacket, Port); + } + PUSH_PKT_AS_LAST_IN_QUEUE(&pAC->TxPort[Port][0].TxQ_free, pSkPacket); + POP_FIRST_PKT_FROM_QUEUE(&pAC->TxPort[Port][0].TxSQ_working, pSkPacket); + } +#endif + } + + SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_MSG, + ("<== SkY2FreeTxBuffers\n")); +} + +/***************************************************************************** + * + * SkY2Isr - handle a receive IRQ for all yukon2 cards + * + * Description: + * This function is called when a receive IRQ is set. (only for yukon2) + * HandleReceives does the deferred processing of all outstanding + * interrupt operations. + * + * Returns: N/A + */ +SkIsrRetVar SkY2Isr ( +int irq, /* the irq we have received (might be shared!) */ +void *dev_id, /* current device id */ +struct pt_regs *ptregs) /* not used by our driver */ +{ + struct SK_NET_DEVICE *dev = (struct SK_NET_DEVICE *)dev_id; + DEV_NET *pNet = (DEV_NET*) dev->priv; + SK_AC *pAC = pNet->pAC; + SK_U32 IntSrc; + unsigned long Flags; +#ifndef CONFIG_SK98LIN_NAPI + SK_BOOL handledStatLE = SK_FALSE; +#else + SK_BOOL SetIntMask = SK_FALSE; +#endif + + SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_INT_SRC, + ("==> SkY2Isr\n")); + + SK_IN32(pAC->IoBase, B0_Y2_SP_ISRC2, &IntSrc); + + if ((IntSrc == 0) && (!pNet->NetConsoleMode)){ + SK_OUT32(pAC->IoBase, B0_Y2_SP_ICR, 2); + SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_INT_SRC, + ("No Interrupt\n ==> SkY2Isr\n")); + return; + + } + +#ifdef Y2_RECOVERY + if (pNet->InRecover) { + SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_INT_SRC, + ("Already in recover\n ==> SkY2Isr\n")); + SK_OUT32(pAC->IoBase, B0_Y2_SP_ICR, 2); + return; + } +#endif + +#ifdef CONFIG_SK98LIN_NAPI + if (netif_rx_schedule_prep(pAC->dev[0])) { + pAC->GIni.GIValIrqMask &= ~(Y2_IS_STAT_BMU); + SK_OUT32(pAC->IoBase, B0_IMSK, pAC->GIni.GIValIrqMask); + SetIntMask = SK_TRUE; + __netif_rx_schedule(pAC->dev[0]); + } + + if (netif_rx_schedule_prep(pAC->dev[1])) { + if (!SetIntMask) { + pAC->GIni.GIValIrqMask &= ~(Y2_IS_STAT_BMU); + SK_OUT32(pAC->IoBase, B0_IMSK, pAC->GIni.GIValIrqMask); + } + __netif_rx_schedule(pAC->dev[1]); + } +#else + handledStatLE = HandleStatusLEs(pAC); +#endif + + /* + ** Check for Special Interrupts + */ + if ((IntSrc & ~Y2_IS_STAT_BMU) || pAC->CheckQueue || pNet->TimerExpired) { + pAC->CheckQueue = SK_FALSE; + spin_lock_irqsave(&pAC->SlowPathLock, Flags); + SkGeSirqIsr(pAC, pAC->IoBase, IntSrc); + SkEventDispatcher(pAC, pAC->IoBase); + spin_unlock_irqrestore(&pAC->SlowPathLock, Flags); + } + + /* Speed enhancement for a2 chipsets */ + if (HW_FEATURE(pAC, HWF_WA_DEV_42)) { + spin_lock_irqsave(&pAC->SetPutIndexLock, Flags); + SkGeY2SetPutIndex(pAC, pAC->IoBase, Y2_PREF_Q_ADDR(Q_XA1,0), &pAC->TxPort[0][0].TxALET); + SkGeY2SetPutIndex(pAC, pAC->IoBase, Y2_PREF_Q_ADDR(Q_R1,0), &pAC->RxPort[0].RxLET); + spin_unlock_irqrestore(&pAC->SetPutIndexLock, Flags); + } + + /* + ** Reenable interrupts and signal end of ISR + */ + SK_OUT32(pAC->IoBase, B0_Y2_SP_ICR, 2); + + /* + ** Stop and restart TX timer in case a Status LE was handled + */ +#ifndef CONFIG_SK98LIN_NAPI + if ((HW_FEATURE(pAC, HWF_WA_DEV_43_418)) && (handledStatLE)) { + SK_OUT8(pAC->IoBase, STAT_TX_TIMER_CTRL, TIM_STOP); + SK_OUT8(pAC->IoBase, STAT_TX_TIMER_CTRL, TIM_START); + } +#endif + + if (!(IS_Q_EMPTY(&(pAC->TxPort[0][TX_PRIO_LOW].TxAQ_waiting)))) { + GiveTxBufferToHw(pAC, pAC->IoBase, 0); + } + if (!(IS_Q_EMPTY(&(pAC->TxPort[1][TX_PRIO_LOW].TxAQ_waiting)))) { + GiveTxBufferToHw(pAC, pAC->IoBase, 1); + } + + SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_INT_SRC, + ("<== SkY2Isr\n")); + + return; +} /* SkY2Isr */ + +/***************************************************************************** + * + * SkY2Xmit - Linux frame transmit function for Yukon2 + * + * Description: + * The system calls this function to send frames onto the wire. + * It puts the frame in the tx descriptor ring. If the ring is + * full then, the 'tbusy' flag is set. + * + * Returns: + * 0, if everything is ok + * !=0, on error + * + * WARNING: + * returning 1 in 'tbusy' case caused system crashes (double + * allocated skb's) !!! + */ +int SkY2Xmit( +struct sk_buff *skb, /* socket buffer to be sent */ +struct SK_NET_DEVICE *dev) /* via which device? */ +{ + DEV_NET *pNet = (DEV_NET*) dev->priv; + SK_AC *pAC = pNet->pAC; + SK_U8 FragIdx = 0; + SK_PACKET *pSkPacket; + SK_FRAG *PrevFrag; + SK_FRAG *CurrFrag; + SK_PKT_QUEUE *pWorkQueue; /* corresponding TX queue */ + SK_PKT_QUEUE *pWaitQueue; + SK_PKT_QUEUE *pFreeQueue; + SK_LE_TABLE *pLETab; /* corresponding LETable */ + skb_frag_t *sk_frag; + SK_U64 PhysAddr; + unsigned long Flags; + unsigned int Port; + int CurrFragCtr; + + SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_TX_PROGRESS, + ("==> SkY2Xmit\n")); + + /* + ** Get port and return if no free packet is available + */ + if (skb_shinfo(skb)->nr_frags > MAX_SKB_FRAGS) { + Port = skb_shinfo(skb)->nr_frags - (2*MAX_SKB_FRAGS); + skb_shinfo(skb)->nr_frags = 0; + } else { + Port = (pAC->RlmtNets == 2) ? pNet->PortNr : pAC->ActivePort; + } + + if (IS_Q_EMPTY(&(pAC->TxPort[Port][TX_PRIO_LOW].TxQ_free))) { + SK_DBG_MSG(pAC, SK_DBGMOD_DRV, + SK_DBGCAT_DRV_TX_PROGRESS | SK_DBGCAT_DRV_ERROR, + ("Not free packets available for send\n")); + return 1; /* zero bytes sent! */ + } + + /* + ** Put any new packet to be sent in the waiting queue and + ** handle also any possible fragment of that packet. + */ + pWorkQueue = &(pAC->TxPort[Port][TX_PRIO_LOW].TxAQ_working); + pWaitQueue = &(pAC->TxPort[Port][TX_PRIO_LOW].TxAQ_waiting); + pFreeQueue = &(pAC->TxPort[Port][TX_PRIO_LOW].TxQ_free); + pLETab = &(pAC->TxPort[Port][TX_PRIO_LOW].TxALET); + + /* + ** Normal send operations require only one fragment, because + ** only one sk_buff data area is passed. + ** In contradiction to this, scatter-gather (zerocopy) send + ** operations might pass one or more additional fragments + ** where each fragment needs a separate fragment info packet. + */ + if (((skb_shinfo(skb)->nr_frags + 1) * MAX_FRAG_OVERHEAD) > + NUM_FREE_LE_IN_TABLE(pLETab)) { + SK_DBG_MSG(pAC, SK_DBGMOD_DRV, + SK_DBGCAT_DRV_TX_PROGRESS | SK_DBGCAT_DRV_ERROR, + ("Not enough LE available for send\n")); + return 1; /* zero bytes sent! */ + } + + if ((skb_shinfo(skb)->nr_frags + 1) > MAX_NUM_FRAGS) { + SK_DBG_MSG(pAC, SK_DBGMOD_DRV, + SK_DBGCAT_DRV_TX_PROGRESS | SK_DBGCAT_DRV_ERROR, + ("Not even one fragment available for send\n")); + return 1; /* zero bytes sent! */ + } + + /* + ** Get first packet from free packet queue + */ + POP_FIRST_PKT_FROM_QUEUE(pFreeQueue, pSkPacket); + if(pSkPacket == NULL) { + SK_DBG_MSG(pAC, SK_DBGMOD_DRV, + SK_DBGCAT_DRV_TX_PROGRESS | SK_DBGCAT_DRV_ERROR, + ("Could not obtain free packet used for xmit\n")); + return 1; /* zero bytes sent! */ + } + + pSkPacket->pFrag = &(pSkPacket->FragArray[FragIdx]); + + /* + ** map the sk_buff to be available for the adapter + */ + PhysAddr = (SK_U64) pci_map_page(pAC->PciDev, + virt_to_page(skb->data), + ((unsigned long) skb->data & ~PAGE_MASK), + skb_headlen(skb), + PCI_DMA_TODEVICE); + pSkPacket->pMBuf = skb; + pSkPacket->pFrag->pPhys = PhysAddr; + pSkPacket->pFrag->FragLen = skb_headlen(skb); + pSkPacket->pFrag->pNext = NULL; /* initial has no next default */ + pSkPacket->NumFrags = skb_shinfo(skb)->nr_frags + 1; + + PrevFrag = pSkPacket->pFrag; + + /* + ** Each scatter-gather fragment need to be mapped... + */ + for ( CurrFragCtr = 0; + CurrFragCtr < skb_shinfo(skb)->nr_frags; + CurrFragCtr++) { + FragIdx++; + sk_frag = &skb_shinfo(skb)->frags[CurrFragCtr]; + CurrFrag = &(pSkPacket->FragArray[FragIdx]); + + /* + ** map the sk_buff to be available for the adapter + */ + PhysAddr = (SK_U64) pci_map_page(pAC->PciDev, + sk_frag->page, + sk_frag->page_offset, + sk_frag->size, + PCI_DMA_TODEVICE); + + CurrFrag->pPhys = PhysAddr; + CurrFrag->FragLen = sk_frag->size; + CurrFrag->pNext = NULL; + + /* + ** Add the new fragment to the list of fragments + */ + PrevFrag->pNext = CurrFrag; + PrevFrag = CurrFrag; + } + + /* + ** Add packet to waiting packets queue + */ + PUSH_PKT_AS_LAST_IN_QUEUE(pWaitQueue, pSkPacket); + GiveTxBufferToHw(pAC, pAC->IoBase, Port); + dev->trans_start = jiffies; + SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_TX_PROGRESS, + ("<== SkY2Xmit(return 0)\n")); + return (0); +} /* SkY2Xmit */ + +#ifdef CONFIG_SK98LIN_NAPI +/***************************************************************************** + * + * SkY2Poll - NAPI Rx polling callback for Yukon2 chipsets + * + * Description: + * Called by the Linux system in case NAPI polling is activated + * + * Returns + * The number of work data still to be handled + * + * Notes + * The slowpath lock needs to be set because HW accesses may + * interfere with slowpath events (e.g. TWSI) + */ +int SkY2Poll( +struct net_device *dev, /* device that needs to be polled */ +int *budget) /* how many budget do we have? */ +{ + SK_AC *pAC = ((DEV_NET*)(dev->priv))->pAC; + int WorkToDo = min(*budget, dev->quota); + int WorkDone = 0; + SK_BOOL handledStatLE = SK_FALSE; + unsigned long Flags; + + spin_lock_irqsave(&pAC->SlowPathLock, Flags); + handledStatLE = HandleStatusLEs(pAC, &WorkDone, WorkToDo); + + *budget -= WorkDone; + dev->quota -= WorkDone; + + if(WorkDone < WorkToDo) { + netif_rx_complete(dev); + pAC->GIni.GIValIrqMask |= (Y2_IS_STAT_BMU); + SK_OUT32(pAC->IoBase, B0_IMSK, pAC->GIni.GIValIrqMask); + if ((HW_FEATURE(pAC, HWF_WA_DEV_43_418)) && (handledStatLE)) { + SK_OUT8(pAC->IoBase, STAT_TX_TIMER_CTRL, TIM_STOP); + SK_OUT8(pAC->IoBase, STAT_TX_TIMER_CTRL, TIM_START); + } + } + spin_unlock_irqrestore(&pAC->SlowPathLock, Flags); + return (WorkDone >= WorkToDo); +} /* SkY2Poll */ +#endif + +/****************************************************************************** + * + * SkY2PortStop - stop a port on Yukon2 + * + * Description: + * This function stops a port of the Yukon2 chip. This stop + * stop needs to be performed in a specific order: + * + * a) Stop the Prefetch unit + * b) Stop the Port (MAC, PHY etc.) + * + * Returns: N/A + */ +void SkY2PortStop( +SK_AC *pAC, /* adapter control context */ +SK_IOC IoC, /* I/O control context (address of adapter registers) */ +int Port, /* port to stop (MAC_1 + n) */ +int Dir, /* StopDirection (SK_STOP_RX, SK_STOP_TX, SK_STOP_ALL) */ +int RstMode) /* Reset Mode (SK_SOFT_RST, SK_HARD_RST) */ +{ + SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_MSG, + ("==> SkY2PortStop (Port %c)\n", 'A' + Port)); + + /* + ** Stop the HW + */ + SkGeStopPort(pAC, IoC, Port, Dir, RstMode); + + /* + ** Move any TX packet from work queues into the free queue again + ** and initialize the TX LETable variables + */ + SkY2FreeTxBuffers(pAC, pAC->IoBase, Port); + pAC->TxPort[Port][TX_PRIO_LOW].TxALET.Bmu.RxTx.TcpWp = 0; + pAC->TxPort[Port][TX_PRIO_LOW].TxALET.Bmu.RxTx.MssValue = 0; + pAC->TxPort[Port][TX_PRIO_LOW].TxALET.BufHighAddr = 0; + pAC->TxPort[Port][TX_PRIO_LOW].TxALET.Done = 0; + pAC->TxPort[Port][TX_PRIO_LOW].TxALET.Put = 0; + // pAC->GIni.GP[Port].PState = SK_PRT_STOP; + + /* + ** Move any RX packet from work queue into the waiting queue + ** and initialize the RX LETable variables + */ + SkY2FreeRxBuffers(pAC, pAC->IoBase, Port); + pAC->RxPort[Port].RxLET.BufHighAddr = 0; + + SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_MSG, + ("<== SkY2PortStop()\n")); +} + +/****************************************************************************** + * + * SkY2PortStart - start a port on Yukon2 + * + * Description: + * This function starts a port of the Yukon2 chip. This start + * action needs to be performed in a specific order: + * + * a) Initialize the LET indices (PUT/GET to 0) + * b) Initialize the LET in HW (enables also prefetch unit) + * c) Move all RX buffers from waiting queue to working queue + * which involves also setting up of RX list elements + * d) Initialize the FIFO settings of Yukon2 (Watermark etc.) + * e) Initialize the Port (MAC, PHY etc.) + * f) Initialize the MC addresses + * + * Returns: N/A + */ +void SkY2PortStart( +SK_AC *pAC, /* adapter control context */ +SK_IOC IoC, /* I/O control context (address of adapter registers) */ +int Port) /* port to start */ +{ + // SK_GEPORT *pPrt = &pAC->GIni.GP[Port]; + SK_HWLE *pLE; + SK_U32 DWord; + SK_U32 PrefetchReg; /* register for Put index */ + + SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_MSG, + ("==> SkY2PortStart (Port %c)\n", 'A' + Port)); + + /* + ** Initialize the LET indices + */ + pAC->RxPort[Port].RxLET.Done = 0; + pAC->RxPort[Port].RxLET.Put = 0; + pAC->RxPort[Port].RxLET.HwPut = 0; + pAC->TxPort[Port][TX_PRIO_LOW].TxALET.Done = 0; + pAC->TxPort[Port][TX_PRIO_LOW].TxALET.Put = 0; + pAC->TxPort[Port][TX_PRIO_LOW].TxALET.HwPut = 0; + if (HW_SYNC_TX_SUPPORTED(pAC)) { + pAC->TxPort[Port][TX_PRIO_LOW].TxSLET.Done = 0; + pAC->TxPort[Port][TX_PRIO_LOW].TxSLET.Put = 0; + pAC->TxPort[Port][TX_PRIO_LOW].TxSLET.HwPut = 0; + } + + if (HW_FEATURE(pAC, HWF_WA_DEV_420)) { + /* + ** It might be that we have to limit the RX buffers + ** effectively passed to HW. Initialize the start + ** value in that case... + */ + NbrRxBuffersInHW = 0; + } + + /* + ** TODO on dual net adapters we need to check if + ** StatusLETable need to be set... + ** + ** pAC->StatusLETable.Done = 0; + ** pAC->StatusLETable.Put = 0; + ** pAC->StatusLETable.HwPut = 0; + ** SkGeY2InitPrefetchUnit(pAC, pAC->IoBase, Q_ST, &pAC->StatusLETable); + */ + + /* + ** Initialize the LET in HW (enables also prefetch unit) + */ + SkGeY2InitPrefetchUnit(pAC, IoC,(Port == 0) ? Q_R1 : Q_R2, + &pAC->RxPort[Port].RxLET); + SkGeY2InitPrefetchUnit( pAC, IoC,(Port == 0) ? Q_XA1 : Q_XA2, + &pAC->TxPort[Port][TX_PRIO_LOW].TxALET); + if (HW_SYNC_TX_SUPPORTED(pAC)) { + SkGeY2InitPrefetchUnit( pAC, IoC, (Port == 0) ? Q_XS1 : Q_XS2, + &pAC->TxPort[Port][TX_PRIO_HIGH].TxSLET); + } + + + /* + ** Using new values for the watermarks and the timer for + ** low latency optimization + */ + if (pAC->LowLatency) { + SK_OUT8(IoC, STAT_FIFO_WM, 1); + SK_OUT8(IoC, STAT_FIFO_ISR_WM, 1); + SK_OUT32(IoC, STAT_LEV_TIMER_INI, 50); + SK_OUT32(IoC, STAT_ISR_TIMER_INI, 10); + } + + + /* + ** Initialize the Port (MAC, PHY etc.) + */ + if (SkGeInitPort(pAC, IoC, Port)) { + if (Port == 0) { + printk("%s: SkGeInitPort A failed.\n",pAC->dev[0]->name); + } else { + printk("%s: SkGeInitPort B failed.\n",pAC->dev[1]->name); + } + } + + if (IS_GMAC(pAC)) { + /* disable Rx GMAC FIFO Flush Mode */ + SK_OUT8(IoC, MR_ADDR(Port, RX_GMF_CTRL_T), (SK_U8) GMF_RX_F_FL_OFF); + } + + /* + ** Initialize the MC addresses + */ + SkAddrMcUpdate(pAC,IoC, Port); + + SkMacRxTxEnable(pAC, IoC,Port); + + if (pAC->RxPort[Port].UseRxCsum) { + SkGeRxCsum(pAC, IoC, Port, SK_TRUE); + + GET_RX_LE(pLE, &pAC->RxPort[Port].RxLET); + RXLE_SET_STACS1(pLE, pAC->CsOfs1); + RXLE_SET_STACS2(pLE, pAC->CsOfs2); + RXLE_SET_CTRL(pLE, 0); + + RXLE_SET_OPC(pLE, OP_TCPSTART | HW_OWNER); + FLUSH_OPC(pLE); + if (Port == 0) { + PrefetchReg=Y2_PREF_Q_ADDR(Q_R1,PREF_UNIT_PUT_IDX_REG); + } else { + PrefetchReg=Y2_PREF_Q_ADDR(Q_R2,PREF_UNIT_PUT_IDX_REG); + } + DWord = GET_PUT_IDX(&pAC->RxPort[Port].RxLET); + SK_OUT32(IoC, PrefetchReg, DWord); + UPDATE_HWPUT_IDX(&pAC->RxPort[Port].RxLET); + } + + pAC->GIni.GP[Port].PState = SK_PRT_RUN; + SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_MSG, + ("<== SkY2PortStart()\n")); +} + +/****************************************************************************** + * + * Local Functions + * + *****************************************************************************/ + +/***************************************************************************** + * + * InitPacketQueues - initialize SW settings of packet queues + * + * Description: + * This function will initialize the packet queues for a port. + * + * Returns: N/A + */ +static void InitPacketQueues( +SK_AC *pAC, /* pointer to adapter control context */ +int Port) /* index of port to be initialized */ +{ + SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_INIT, + ("==> InitPacketQueues(Port %c)\n", 'A' + Port)); + + pAC->RxPort[Port].RxQ_working.pHead = NULL; + pAC->RxPort[Port].RxQ_working.pTail = NULL; + spin_lock_init(&pAC->RxPort[Port].RxQ_working.QueueLock); + + pAC->RxPort[Port].RxQ_waiting.pHead = NULL; + pAC->RxPort[Port].RxQ_waiting.pTail = NULL; + spin_lock_init(&pAC->RxPort[Port].RxQ_waiting.QueueLock); + + pAC->TxPort[Port][TX_PRIO_LOW].TxQ_free.pHead = NULL; + pAC->TxPort[Port][TX_PRIO_LOW].TxQ_free.pTail = NULL; + spin_lock_init(&pAC->TxPort[Port][TX_PRIO_LOW].TxQ_free.QueueLock); + + pAC->TxPort[Port][TX_PRIO_LOW].TxAQ_working.pHead = NULL; + pAC->TxPort[Port][TX_PRIO_LOW].TxAQ_working.pTail = NULL; + spin_lock_init(&pAC->TxPort[Port][TX_PRIO_LOW].TxAQ_working.QueueLock); + + pAC->TxPort[Port][TX_PRIO_LOW].TxAQ_waiting.pHead = NULL; + pAC->TxPort[Port][TX_PRIO_LOW].TxAQ_waiting.pTail = NULL; + spin_lock_init(&pAC->TxPort[Port][TX_PRIO_LOW].TxAQ_waiting.QueueLock); + +#if USE_SYNC_TX_QUEUE + pAC->TxPort[Port][TX_PRIO_LOW].TxSQ_working.pHead = NULL; + pAC->TxPort[Port][TX_PRIO_LOW].TxSQ_working.pTail = NULL; + spin_lock_init(&pAC->TxPort[Port][TX_PRIO_LOW].TxSQ_working.QueueLock); + + pAC->TxPort[Port][TX_PRIO_LOW].TxSQ_waiting.pHead = NULL; + pAC->TxPort[Port][TX_PRIO_LOW].TxSQ_waiting.pTail = NULL; + spin_lock_init(&pAC->TxPort[Port][TX_PRIO_LOW].TxSQ_waiting.QueueLock); +#endif + + SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_INIT, + ("<== InitPacketQueues(Port %c)\n", 'A' + Port)); +} /* InitPacketQueues */ + +/***************************************************************************** + * + * GiveTxBufferToHw - commits a previously allocated DMA area to HW + * + * Description: + * This functions gives transmit buffers to HW. If no list elements + * are available the buffers will be queued. + * + * Notes: + * This function can run only once in a system at one time. + * + * Returns: N/A + */ +static void GiveTxBufferToHw( +SK_AC *pAC, /* pointer to adapter control context */ +SK_IOC IoC, /* I/O control context (address of registers) */ +int Port) /* port index for which the buffer is used */ +{ + SK_HWLE *pLE; + SK_PACKET *pSkPacket; + SK_FRAG *pFrag; + SK_PKT_QUEUE *pWorkQueue; /* corresponding TX queue */ + SK_PKT_QUEUE *pWaitQueue; + SK_LE_TABLE *pLETab; /* corresponding LETable */ + SK_BOOL SetOpcodePacketFlag; + SK_U32 HighAddress; + SK_U32 LowAddress; + SK_U16 TcpSumStart; + SK_U16 TcpSumWrite; + SK_U8 OpCode; + SK_U8 Ctrl; + unsigned long Flags; + unsigned long LockFlag; + int Protocol; +#ifdef NETIF_F_TSO + SK_U16 Mss; + int TcpOptLen; + int IpTcpLen; +#endif + + SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_TX_PROGRESS, + ("==> GiveTxBufferToHw\n")); + + if (IS_Q_EMPTY(&(pAC->TxPort[Port][TX_PRIO_LOW].TxAQ_waiting))) { + return; + } + + spin_lock_irqsave(&pAC->TxQueueLock, LockFlag); + + /* + ** Initialize queue settings + */ + pWorkQueue = &(pAC->TxPort[Port][TX_PRIO_LOW].TxAQ_working); + pWaitQueue = &(pAC->TxPort[Port][TX_PRIO_LOW].TxAQ_waiting); + pLETab = &(pAC->TxPort[Port][TX_PRIO_LOW].TxALET); + + POP_FIRST_PKT_FROM_QUEUE(pWaitQueue, pSkPacket); + while (pSkPacket != NULL) { + SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_TX_PROGRESS, + ("\tWe have a packet to send %p\n", pSkPacket)); + + /* + ** the first frag of a packet gets opcode OP_PACKET + */ + SetOpcodePacketFlag = SK_TRUE; + pFrag = pSkPacket->pFrag; + + /* + ** fill list elements with data from fragments + */ + while (pFrag != NULL) { + SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_TX_PROGRESS, + ("\tGet LE\n")); +#ifdef NETIF_F_TSO + Mss = skb_shinfo(pSkPacket->pMBuf)->tso_size; + if (Mss) { + TcpOptLen = ((pSkPacket->pMBuf->h.th->doff - 5) * 4); + IpTcpLen = ((pSkPacket->pMBuf->nh.iph->ihl * 4) + + sizeof(struct tcphdr)); + Mss += (TcpOptLen + IpTcpLen + C_LEN_ETHERMAC_HEADER); + } + if (pLETab->Bmu.RxTx.MssValue != Mss) { + pLETab->Bmu.RxTx.MssValue = Mss; + /* Take a new LE for TSO from the table */ + GET_TX_LE(pLE, pLETab); + +#if 0 + if(pSkPacket->VlanId) { + TXLE_SET_OPC(pLE, OP_LRGLENVLAN | HW_OWNER); + TXLE_SET_VLAN(pLE, pSkPacket->VlanId); + pSkPacket->VlanId = 0; + Ctrl |= INS_VLAN; + } else { +#endif + TXLE_SET_OPC(pLE, OP_LRGLEN | HW_OWNER); +#if 0 + } +#endif + /* set maximum segment size for new packet */ + TXLE_SET_LSLEN(pLE, pLETab->Bmu.RxTx.MssValue); + FLUSH_OPC(pLE) ; + } +#endif + GET_TX_LE(pLE, pLETab); + Ctrl = 0; + + SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_TX_PROGRESS, + ("\tGot empty LE %p idx %d\n", pLE, GET_PUT_IDX(pLETab))); + + SK_DBG_DUMP_TX_LE(pLE); + + LowAddress = (SK_U32) (pFrag->pPhys & 0xffffffff); + HighAddress = (SK_U32) (pFrag->pPhys >> 32); + + if (HighAddress != pLETab->BufHighAddr) { + /* set opcode high part of the address in one LE */ + OpCode = OP_ADDR64 | HW_OWNER; + + /* Set now the 32 high bits of the address */ + TXLE_SET_ADDR( pLE, HighAddress); + + /* Set the opcode into the LE */ + TXLE_SET_OPC(pLE, OpCode); + + /* Flush the LE to memory */ + FLUSH_OPC(pLE); + + /* remember the HighAddress we gave to the Hardware */ + pLETab->BufHighAddr = HighAddress; + + /* get a new LE because we filled one with high address */ + GET_TX_LE(pLE, pLETab); + } + + /* + ** TCP checksum offload + */ + if ((pSkPacket->pMBuf->ip_summed == CHECKSUM_HW) && + (SetOpcodePacketFlag == SK_TRUE)) { + Protocol = ((SK_U8)pSkPacket->pMBuf->data[C_OFFSET_IPPROTO] & 0xff); + /* if (Protocol & C_PROTO_ID_IP) { Ctrl = 0; } */ + if (Protocol & C_PROTO_ID_TCP) { + Ctrl = CALSUM | WR_SUM | INIT_SUM | LOCK_SUM; + /* TCP Checksum Calculation Start Position */ + TcpSumStart = C_LEN_ETHERMAC_HEADER + IP_HDR_LEN; + /* TCP Checksum Write Position */ + TcpSumWrite = TcpSumStart + TCP_CSUM_OFFS; + } else { + Ctrl = UDPTCP | CALSUM | WR_SUM | INIT_SUM | LOCK_SUM; + /* TCP Checksum Calculation Start Position */ + TcpSumStart = ETHER_MAC_HDR_LEN + IP_HDR_LEN; + /* UDP Checksum Write Position */ + TcpSumWrite = TcpSumStart + UDP_CSUM_OFFS; + } + + if ((Ctrl) && (pLETab->Bmu.RxTx.TcpWp != TcpSumWrite)) { + /* Update the last value of the write position */ + pLETab->Bmu.RxTx.TcpWp = TcpSumWrite; + + /* Set the Lock field for this LE: */ + /* Checksum calculation for one packet only */ + TXLE_SET_LCKCS(pLE, 1); + + /* Set the start position for checksum. */ + TXLE_SET_STACS(pLE, TcpSumStart); + + /* Set the position where the checksum will be writen */ + TXLE_SET_WRICS(pLE, TcpSumWrite); + + /* Set the initial value for checksum */ + /* PseudoHeader CS passed from Linux -> 0! */ + TXLE_SET_INICS(pLE, 0); + + /* Set the opcode for tcp checksum */ + TXLE_SET_OPC(pLE, OP_TCPLISW | HW_OWNER); + + /* Flush the LE to memory */ + FLUSH_OPC(pLE); + + /* get a new LE because we filled one with data for checksum */ + GET_TX_LE(pLE, pLETab); + } + } /* end TCP offload handling */ + + TXLE_SET_ADDR(pLE, LowAddress); + TXLE_SET_LEN(pLE, pFrag->FragLen); + + if (SetOpcodePacketFlag){ +#ifdef NETIF_F_TSO + if (Mss) { + OpCode = OP_LARGESEND | HW_OWNER; + } else { +#endif + OpCode = OP_PACKET| HW_OWNER; +#ifdef NETIF_F_TSO + } +#endif + SetOpcodePacketFlag = SK_FALSE; + } else { + /* Follow packet in a sequence has always OP_BUFFER */ + OpCode = OP_BUFFER | HW_OWNER; + } + + /* Check if the low address is near the upper limit. */ + CHECK_LOW_ADDRESS(pLETab->BufHighAddr, LowAddress, pFrag->FragLen); + + pFrag = pFrag->pNext; + if (pFrag == NULL) { + /* mark last fragment */ + Ctrl |= EOP; + } + TXLE_SET_CTRL(pLE, Ctrl); + TXLE_SET_OPC(pLE, OpCode); + FLUSH_OPC(pLE); + + SK_DBG_DUMP_TX_LE(pLE); + } + + /* + ** Remember next LE for tx complete + */ + pSkPacket->NextLE = GET_PUT_IDX(pLETab); + SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_TX_PROGRESS, + ("\tNext LE for pkt %p is %d\n", pSkPacket, pSkPacket->NextLE)); + + /* + ** Add packet to working packets queue + */ + PUSH_PKT_AS_LAST_IN_QUEUE(pWorkQueue, pSkPacket); + + /* + ** give transmit start command + */ + if (HW_FEATURE(pAC, HWF_WA_DEV_42)) { + spin_lock(&pAC->SetPutIndexLock); + SkGeY2SetPutIndex(pAC, pAC->IoBase, Y2_PREF_Q_ADDR(Q_XA1,0), &pAC->TxPort[0][0].TxALET); + spin_unlock(&pAC->SetPutIndexLock); + } else { + /* write put index */ + if (Port == 0) { + SK_OUT32(pAC->IoBase, + Y2_PREF_Q_ADDR(Q_XA1,PREF_UNIT_PUT_IDX_REG), + GET_PUT_IDX(&pAC->TxPort[0][0].TxALET)); + UPDATE_HWPUT_IDX(&pAC->TxPort[0][0].TxALET); + } else { + SK_OUT32(pAC->IoBase, + Y2_PREF_Q_ADDR(Q_XA2, PREF_UNIT_PUT_IDX_REG), + GET_PUT_IDX(&pAC->TxPort[1][0].TxALET)); + UPDATE_HWPUT_IDX(&pAC->TxPort[1][0].TxALET); + } + } + + if (IS_Q_EMPTY(&(pAC->TxPort[Port][TX_PRIO_LOW].TxAQ_waiting))) { + break; /* get out of while */ + } + POP_FIRST_PKT_FROM_QUEUE(pWaitQueue, pSkPacket); + } /* while (pSkPacket != NULL) */ + + spin_unlock_irqrestore(&pAC->TxQueueLock, LockFlag); + + SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_TX_PROGRESS, + ("<== GiveTxBufferToHw\n")); + return; +} /* GiveTxBufferToHw */ + +/*********************************************************************** + * + * GiveRxBufferToHw - commits a previously allocated DMA area to HW + * + * Description: + * This functions gives receive buffers to HW. If no list elements + * are available the buffers will be queued. + * + * Notes: + * This function can run only once in a system at one time. + * + * Returns: N/A + */ +static void GiveRxBufferToHw( +SK_AC *pAC, /* pointer to adapter control context */ +SK_IOC IoC, /* I/O control context (address of registers) */ +int Port, /* port index for which the buffer is used */ +SK_PACKET *pPacket) /* receive buffer(s) */ +{ + SK_HWLE *pLE; + SK_LE_TABLE *pLETab; + SK_BOOL Done = SK_FALSE; /* at least on LE changed? */ + SK_U32 LowAddress; + SK_U32 HighAddress; + SK_U32 PrefetchReg; /* register for Put index */ + unsigned NumFree; + unsigned Required; + unsigned long Flags; + + SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_RX_PROGRESS, + ("==> GiveRxBufferToHw(Port %c, Packet %p)\n", 'A' + Port, pPacket)); + + pLETab = &pAC->RxPort[Port].RxLET; + + if (Port == 0) { + PrefetchReg = Y2_PREF_Q_ADDR(Q_R1, PREF_UNIT_PUT_IDX_REG); + } else { + PrefetchReg = Y2_PREF_Q_ADDR(Q_R2, PREF_UNIT_PUT_IDX_REG); + } + + if (pPacket != NULL) { + /* + ** For the time being, we have only one packet passed + ** to this function which might be changed in future! + */ + PUSH_PKT_AS_LAST_IN_QUEUE(&pAC->RxPort[Port].RxQ_waiting, pPacket); + } + + /* + ** now pPacket contains the very first waiting packet + */ + POP_FIRST_PKT_FROM_QUEUE(&pAC->RxPort[Port].RxQ_waiting, pPacket); + while (pPacket != NULL) { + if (HW_FEATURE(pAC, HWF_WA_DEV_420)) { + if (NbrRxBuffersInHW >= MAX_NBR_RX_BUFFERS_IN_HW) { + PUSH_PKT_AS_FIRST_IN_QUEUE(&pAC->RxPort[Port].RxQ_waiting, pPacket); + SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_RX_PROGRESS, + ("<== GiveRxBufferToHw()\n")); + return; + } + NbrRxBuffersInHW++; + } + + SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_RX_PROGRESS, + ("Try to add packet %p\n", pPacket)); + + /* + ** Check whether we have enough listelements: + ** + ** we have to take into account that each fragment + ** may need an additional list element for the high + ** part of the address here I simplified it by + ** using MAX_FRAG_OVERHEAD maybe it's worth to split + ** this constant for Rx and Tx or to calculate the + ** real number of needed LE's + */ + SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_RX_PROGRESS, + ("\tNum %d Put %d Done %d Free %d %d\n", + pLETab->Num, pLETab->Put, pLETab->Done, + NUM_FREE_LE_IN_TABLE(pLETab), + (NUM_FREE_LE_IN_TABLE(pLETab)))); + + Required = pPacket->NumFrags + MAX_FRAG_OVERHEAD; + NumFree = NUM_FREE_LE_IN_TABLE(pLETab); + if (NumFree) { + NumFree--; + } + + if (Required > NumFree ) { + SK_DBG_MSG(pAC, SK_DBGMOD_DRV, + SK_DBGCAT_DRV_RX_PROGRESS | SK_DBGCAT_DRV_ERROR, + ("\tOut of LEs have %d need %d\n", + NumFree, Required)); + + SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_RX_PROGRESS, + ("\tWaitQueue starts with packet %p\n", pPacket)); + PUSH_PKT_AS_FIRST_IN_QUEUE(&pAC->RxPort[Port].RxQ_waiting, pPacket); + if (Done) { + /* + ** write Put index to BMU or Polling Unit and make the LE's + ** available for the hardware + */ + SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_RX_PROGRESS, + ("\tWrite new Put Idx\n")); + + SK_OUT32(IoC, PrefetchReg, GET_PUT_IDX(pLETab)); + UPDATE_HWPUT_IDX(pLETab); + } + SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_RX_PROGRESS, + ("<== GiveRxBufferToHw()\n")); + return; + } else { + if (!AllocAndMapRxBuffer(pAC, pPacket, Port)) { + /* + ** Failure while allocating sk_buff might + ** be due to temporary short of resources + ** Maybe next time buffers are available. + ** Until this, the packet remains in the + ** RX waiting queue... + */ + SK_DBG_MSG(pAC, SK_DBGMOD_DRV, + SK_DBGCAT_DRV_RX_PROGRESS | SK_DBGCAT_DRV_ERROR, + ("Failed to allocate Rx buffer\n")); + + SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_RX_PROGRESS, + ("WaitQueue starts with packet %p\n", pPacket)); + PUSH_PKT_AS_FIRST_IN_QUEUE(&pAC->RxPort[Port].RxQ_waiting, pPacket); + if (Done) { + /* + ** write Put index to BMU or Polling + ** Unit and make the LE's + ** available for the hardware + */ + SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_RX_PROGRESS, + ("\tWrite new Put Idx\n")); + + SK_OUT32(IoC, PrefetchReg, GET_PUT_IDX(pLETab)); + UPDATE_HWPUT_IDX(pLETab); + } + SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_RX_PROGRESS, + ("<== GiveRxBufferToHw()\n")); + return; + } + } + Done = SK_TRUE; + + LowAddress = (SK_U32) (pPacket->pFrag->pPhys & 0xffffffff); + HighAddress = (SK_U32) (pPacket->pFrag->pPhys >> 32); + if (HighAddress != pLETab->BufHighAddr) { + /* get a new LE for high address */ + GET_RX_LE(pLE, pLETab); + + /* Set now the 32 high bits of the address */ + RXLE_SET_ADDR(pLE, HighAddress); + + /* Set the control bits of the address */ + RXLE_SET_CTRL(pLE, 0); + + /* Set the opcode into the LE */ + RXLE_SET_OPC(pLE, (OP_ADDR64 | HW_OWNER)); + + /* Flush the LE to memory */ + FLUSH_OPC(pLE); + + /* remember the HighAddress we gave to the Hardware */ + pLETab->BufHighAddr = HighAddress; + } + + /* + ** Fill data into listelement + */ + GET_RX_LE(pLE, pLETab); + RXLE_SET_ADDR(pLE, LowAddress); + RXLE_SET_LEN(pLE, pPacket->pFrag->FragLen); + RXLE_SET_CTRL(pLE, 0); + RXLE_SET_OPC(pLE, (OP_PACKET | HW_OWNER)); + FLUSH_OPC(pLE); + + SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_RX_PROGRESS, + ("=== LE filled\n")); + + SK_DBG_DUMP_RX_LE(pLE); + + /* + ** Remember next LE for rx complete + */ + pPacket->NextLE = GET_PUT_IDX(pLETab); + + SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_RX_PROGRESS, + ("\tPackets Next LE is %d\n", pPacket->NextLE)); + + /* + ** Add packet to working receive buffer queue and get + ** any next packet out of the waiting queue + */ + PUSH_PKT_AS_LAST_IN_QUEUE(&pAC->RxPort[Port].RxQ_working, pPacket); + if (IS_Q_EMPTY(&(pAC->RxPort[Port].RxQ_waiting))) { + break; /* get out of while processing */ + } + POP_FIRST_PKT_FROM_QUEUE(&pAC->RxPort[Port].RxQ_waiting, pPacket); + } + + SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_RX_PROGRESS, + ("\tWaitQueue is empty\n")); + + if (Done) { + /* + ** write Put index to BMU or Polling Unit and make the LE's + ** available for the hardware + */ + SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_RX_PROGRESS, + ("\tWrite new Put Idx\n")); + + /* Speed enhancement for a2 chipsets */ + if (HW_FEATURE(pAC, HWF_WA_DEV_42)) { + spin_lock_irqsave(&pAC->SetPutIndexLock, Flags); + SkGeY2SetPutIndex(pAC, pAC->IoBase, Y2_PREF_Q_ADDR(Q_R1,0), pLETab); + spin_unlock_irqrestore(&pAC->SetPutIndexLock, Flags); + } else { + /* write put index */ + if (Port == 0) { + SK_OUT32(IoC, + Y2_PREF_Q_ADDR(Q_R1, PREF_UNIT_PUT_IDX_REG), + GET_PUT_IDX(pLETab)); + } else { + SK_OUT32(IoC, + Y2_PREF_Q_ADDR(Q_R2, PREF_UNIT_PUT_IDX_REG), + GET_PUT_IDX(pLETab)); + } + + /* Update put index */ + UPDATE_HWPUT_IDX(pLETab); + } + } + + SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_RX_PROGRESS, + ("<== GiveRxBufferToHw()\n")); +} /* GiveRxBufferToHw */ + +/*********************************************************************** + * + * FillReceiveTableYukon2 - map any waiting RX buffers to HW + * + * Description: + * If the list element table contains more empty elements than + * specified this function tries to refill them. + * + * Notes: + * This function can run only once per port in a system at one time. + * + * Returns: N/A + */ +void FillReceiveTableYukon2( +SK_AC *pAC, /* pointer to adapter control context */ +SK_IOC IoC, /* I/O control context */ +int Port) /* port index of RX */ +{ + SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_RX_PROGRESS, + ("==> FillReceiveTableYukon2 (Port %c)\n", 'A' + Port)); + + if (NUM_FREE_LE_IN_TABLE(&pAC->RxPort[Port].RxLET) > + pAC->MaxUnusedRxLeWorking) { + + /* + ** Give alle waiting receive buffers down + ** The queue holds all RX packets that + ** need a fresh allocation of the sk_buff. + */ + if (pAC->RxPort[Port].RxQ_waiting.pHead != NULL) { + SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_RX_PROGRESS, + ("Waiting queue is not empty -> give it to HW")); + GiveRxBufferToHw(pAC, IoC, Port, NULL); + } + } + + SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_RX_PROGRESS, + ("<== FillReceiveTableYukon2 ()\n")); +} /* FillReceiveTableYukon2 */ + +/****************************************************************************** + * + * + * HandleReceives - will pass any ready RX packet to kernel + * + * Description: + * This functions handles a received packet. It checks wether it is + * valid, updates the receive list element table and gives the receive + * buffer to Linux + * + * Notes: + * This function can run only once per port at one time in the system. + * + * Returns: N/A + */ +static SK_BOOL HandleReceives( +SK_AC *pAC, /* adapter control context */ +int Port, /* port on which a packet has been received */ +SK_U16 Len, /* number of bytes which was actually received */ +SK_U32 FrameStatus, /* MAC frame status word */ +SK_U16 Tcp1, /* first hw checksum */ +SK_U16 Tcp2, /* second hw checksum */ +SK_U32 Tist, /* timestamp */ +SK_U16 Vlan) /* Vlan Id */ +{ + + SK_PACKET *pSkPacket; + SK_LE_TABLE *pLETab; + SK_MBUF *pRlmtMbuf; /* buffer for giving RLMT frame */ + struct sk_buff *pMsg; /* ptr to message holding frame */ +#ifdef __ia64__ + struct sk_buff *pNewMsg; /* used when IP aligning */ +#endif + +#ifdef CONFIG_SK98LIN_NAPI + SK_BOOL SlowPathLock = SK_FALSE; +#else + SK_BOOL SlowPathLock = SK_TRUE; +#endif + SK_BOOL IsGoodPkt; + SK_BOOL IsBc; + SK_BOOL IsMc; + SK_EVPARA EvPara; /* an event parameter union */ + SK_I16 LenToFree; /* must be signed integer */ + + unsigned long Flags; /* for spin lock */ + unsigned int RlmtNotifier; + unsigned short Type; + int IpFrameLength; + int FrameLength; /* total length of recvd frame */ + int HeaderLength; + int NumBytes; + int Result; + int Offset = 0; + +#ifdef Y2_SYNC_CHECK + SK_U16 MyTcp; +#endif + + SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_RX_PROGRESS, + ("==> HandleReceives (Port %c)\n", 'A' + Port)); + + /* + ** initialize vars for selected port + */ + pLETab = &pAC->RxPort[Port].RxLET; + + /* + ** check whether we want to receive this packet + */ + SK_Y2_RXSTAT_CHECK_PKT(Len, FrameStatus, IsGoodPkt); + + /* + ** Remember length to free (in case of RxBuffer overruns; + ** unlikely, but might happen once in a while) + */ + LenToFree = (SK_I16) Len; + + /* + ** maybe we put these two checks into the SK_RXDESC_CHECK_PKT macro too + */ + if (Len > pAC->RxPort[Port].RxBufSize) { + IsGoodPkt = SK_FALSE; + } + + /* + ** take first receive buffer out of working queue + */ + POP_FIRST_PKT_FROM_QUEUE(&pAC->RxPort[Port].RxQ_working, pSkPacket); + if (pSkPacket == NULL) { + SK_DBG_MSG(pAC, SK_DBGMOD_DRV, + SK_DBGCAT_DRV_ERROR, + ("Packet not available. NULL pointer.\n")); + return(SK_TRUE); + } + + if (HW_FEATURE(pAC, HWF_WA_DEV_420)) { + NbrRxBuffersInHW--; + } + + /* + ** Verify the received length of the frame! Note that having + ** multiple RxBuffers being aware of one single receive packet + ** (one packet spread over multiple RxBuffers) is not supported + ** by this driver! + */ + if ((Len > pAC->RxPort[Port].RxBufSize) || + (Len > (SK_U16) pSkPacket->PacketLen)) { + IsGoodPkt = SK_FALSE; + } + + /* + ** Reset own bit in LE's between old and new Done index + ** This is not really necessary but makes debugging easier + */ + CLEAR_LE_OWN_FROM_DONE_TO(pLETab, pSkPacket->NextLE); + + /* + ** Free the list elements for new Rx buffers + */ + SET_DONE_INDEX(pLETab, pSkPacket->NextLE); + pMsg = pSkPacket->pMBuf; + FrameLength = Len; + + SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_RX_PROGRESS, + ("Received frame of length %d on port %d\n",FrameLength, Port)); + + if (!IsGoodPkt) { + /* + ** release the DMA mapping + */ +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,5) + pci_dma_sync_single(pAC->PciDev, + (dma_addr_t) pSkPacket->pFrag->pPhys, + pSkPacket->pFrag->FragLen, + PCI_DMA_FROMDEVICE); + +#else + pci_dma_sync_single_for_cpu(pAC->PciDev, + (dma_addr_t) pSkPacket->pFrag->pPhys, + pSkPacket->pFrag->FragLen, + PCI_DMA_FROMDEVICE); +#endif + + DEV_KFREE_SKB_ANY(pSkPacket->pMBuf); + PUSH_PKT_AS_LAST_IN_QUEUE(&pAC->RxPort[Port].RxQ_waiting, pSkPacket); + SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_RX_PROGRESS, + ("<== HandleReceives (Port %c)\n", 'A' + Port)); + + /* + ** Sanity check for RxBuffer overruns... + */ + LenToFree = LenToFree - (pSkPacket->pFrag->FragLen); + while (LenToFree > 0) { + POP_FIRST_PKT_FROM_QUEUE(&pAC->RxPort[Port].RxQ_working, pSkPacket); + if (HW_FEATURE(pAC, HWF_WA_DEV_420)) { + NbrRxBuffersInHW--; + } + CLEAR_LE_OWN_FROM_DONE_TO(pLETab, pSkPacket->NextLE); + SET_DONE_INDEX(pLETab, pSkPacket->NextLE); +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,5) + pci_dma_sync_single(pAC->PciDev, + (dma_addr_t) pSkPacket->pFrag->pPhys, + pSkPacket->pFrag->FragLen, + PCI_DMA_FROMDEVICE); +#else + pci_dma_sync_single_for_device(pAC->PciDev, + (dma_addr_t) pSkPacket->pFrag->pPhys, + pSkPacket->pFrag->FragLen, + PCI_DMA_FROMDEVICE); +#endif + + DEV_KFREE_SKB_ANY(pSkPacket->pMBuf); + PUSH_PKT_AS_LAST_IN_QUEUE(&pAC->RxPort[Port].RxQ_waiting, pSkPacket); + LenToFree = LenToFree - ((SK_I16)(pSkPacket->pFrag->FragLen)); + + SK_DBG_MSG(pAC, SK_DBGMOD_DRV, + SK_DBGCAT_DRV_RX_PROGRESS | SK_DBGCAT_DRV_ERROR, + ("<==HandleReceives (Port %c) drop faulty len pkt(2)\n",'A'+Port)); + } + return(SK_TRUE); + } else { + /* + ** Release the DMA mapping + */ + pci_unmap_single(pAC->PciDev, + pSkPacket->pFrag->pPhys, + pAC->RxPort[Port].RxBufSize, + PCI_DMA_FROMDEVICE); + + skb_put(pMsg, FrameLength); /* set message len */ + pMsg->ip_summed = CHECKSUM_NONE; /* initial default */ + +#ifdef Y2_SYNC_CHECK + pAC->FramesWithoutSyncCheck++; + if (pAC->FramesWithoutSyncCheck > Y2_RESYNC_WATERMARK) { + if ((Tcp1 != 1) || (Tcp2 != 0)) { + pAC->FramesWithoutSyncCheck = 0; + MyTcp = (SK_U16) SkCsCalculateChecksum( + &pMsg->data[14], + FrameLength - 14); + if (MyTcp != Tcp1) { + /* Queue port reset event */ + SkLocalEventQueue(pAC, SKGE_DRV, + SK_DRV_RECOVER,Port,-1,SK_FALSE); + } + } + } +#endif + + if (pAC->RxPort[Port].UseRxCsum) { + Type = ntohs(*((short*)&pMsg->data[12])); + if (Type == 0x800) { + *((char *)&(IpFrameLength)) = pMsg->data[16]; + *(((char *)&(IpFrameLength))+1) = pMsg->data[17]; + IpFrameLength = ntohs(IpFrameLength); + HeaderLength = FrameLength - IpFrameLength; + if (HeaderLength == 0xe) { + Result = + SkCsGetReceiveInfo(pAC,&pMsg->data[14],Tcp1,Tcp2, Port); + if ((Result == SKCS_STATUS_IP_FRAGMENT) || + (Result == SKCS_STATUS_IP_CSUM_OK) || + (Result == SKCS_STATUS_TCP_CSUM_OK) || + (Result == SKCS_STATUS_UDP_CSUM_OK)) { + pMsg->ip_summed = CHECKSUM_UNNECESSARY; + } else if ((Result == SKCS_STATUS_TCP_CSUM_ERROR) || + (Result == SKCS_STATUS_UDP_CSUM_ERROR) || + (Result == SKCS_STATUS_IP_CSUM_ERROR_UDP) || + (Result == SKCS_STATUS_IP_CSUM_ERROR_TCP) || + (Result == SKCS_STATUS_IP_CSUM_ERROR)) { + SK_DBG_MSG(NULL, SK_DBGMOD_DRV, + SK_DBGCAT_DRV_RX_PROGRESS | SK_DBGCAT_DRV_ERROR, + ("skge: CRC error. Frame dropped!\n")); + DEV_KFREE_SKB_ANY(pMsg); + PUSH_PKT_AS_LAST_IN_QUEUE(&pAC->RxPort[Port].RxQ_waiting, pSkPacket); + SK_DBG_MSG(pAC,SK_DBGMOD_DRV,SK_DBGCAT_DRV_RX_PROGRESS, + ("<==HandleReceives(Port %c)\n",'A'+Port)); + return(SK_TRUE); + } else { + pMsg->ip_summed = CHECKSUM_NONE; + } + } /* end if (HeaderLength == valid) */ + } /* end if (Type == 0x800) -> IP frame */ + } /* end if (pRxPort->UseRxCsum) */ + + SK_DBG_MSG(NULL, SK_DBGMOD_DRV, + SK_DBGCAT_DRV_RX_PROGRESS,("V")); + RlmtNotifier = SK_RLMT_RX_PROTOCOL; + + IsBc = (FrameStatus & GMR_FS_BC) ? SK_TRUE : SK_FALSE; + SK_RLMT_PRE_LOOKAHEAD(pAC,Port,FrameLength, + IsBc,&Offset,&NumBytes); + if (NumBytes != 0) { + IsMc = (FrameStatus & GMR_FS_MC) ? SK_TRUE : SK_FALSE; + SK_RLMT_LOOKAHEAD(pAC,Port,&pMsg->data[Offset], + IsBc,IsMc,&RlmtNotifier); + } + + if (RlmtNotifier == SK_RLMT_RX_PROTOCOL) { + SK_DBG_MSG(NULL,SK_DBGMOD_DRV, + SK_DBGCAT_DRV_RX_PROGRESS,("W")); + if ((Port == pAC->ActivePort)||(pAC->RlmtNets == 2)) { + /* send up only frames from active port */ + SK_DBG_MSG(NULL, SK_DBGMOD_DRV, + SK_DBGCAT_DRV_RX_PROGRESS,("U")); +#ifdef xDEBUG + DumpMsg(pMsg, "Rx"); +#endif + SK_PNMI_CNT_RX_OCTETS_DELIVERED(pAC, + FrameLength, Port); +#ifdef __ia64__ + pNewMsg = alloc_skb(pMsg->len, GFP_ATOMIC); + skb_reserve(pNewMsg, 2); /* to align IP */ + SK_MEMCPY(pNewMsg->data,pMsg->data,pMsg->len); + pNewMsg->ip_summed = pMsg->ip_summed; + skb_put(pNewMsg, pMsg->len); + DEV_KFREE_SKB_ANY(pMsg); + pMsg = pNewMsg; +#endif + pMsg->dev = pAC->dev[Port]; + pMsg->protocol = eth_type_trans(pMsg, + pAC->dev[Port]); + netif_rx(pMsg); + pAC->dev[Port]->last_rx = jiffies; + } else { /* drop frame */ + SK_DBG_MSG(NULL,SK_DBGMOD_DRV, + SK_DBGCAT_DRV_RX_PROGRESS,("D")); + DEV_KFREE_SKB_ANY(pMsg); + } + } else { /* This is an RLMT-packet! */ + SK_DBG_MSG(NULL, SK_DBGMOD_DRV, + SK_DBGCAT_DRV_RX_PROGRESS,("R")); + pRlmtMbuf = SkDrvAllocRlmtMbuf(pAC, + pAC->IoBase, FrameLength); + if (pRlmtMbuf != NULL) { + pRlmtMbuf->pNext = NULL; + pRlmtMbuf->Length = FrameLength; + pRlmtMbuf->PortIdx = Port; + EvPara.pParaPtr = pRlmtMbuf; + SK_MEMCPY((char*)(pRlmtMbuf->pData), + (char*)(pMsg->data),FrameLength); + + if (SlowPathLock == SK_TRUE) { + spin_lock_irqsave(&pAC->SlowPathLock, Flags); + SkEventQueue(pAC, SKGE_RLMT, + SK_RLMT_PACKET_RECEIVED, + EvPara); + pAC->CheckQueue = SK_TRUE; + spin_unlock_irqrestore(&pAC->SlowPathLock, Flags); + } else { + SkEventQueue(pAC, SKGE_RLMT, + SK_RLMT_PACKET_RECEIVED, + EvPara); + pAC->CheckQueue = SK_TRUE; + } + + SK_DBG_MSG(NULL, SK_DBGMOD_DRV, + SK_DBGCAT_DRV_RX_PROGRESS,("Q")); + } + if (pAC->dev[Port]->flags & (IFF_PROMISC | IFF_ALLMULTI)) { +#ifdef __ia64__ + pNewMsg = alloc_skb(pMsg->len, GFP_ATOMIC); + skb_reserve(pNewMsg, 2); /* to align IP */ + SK_MEMCPY(pNewMsg->data,pMsg->data,pMsg->len); + pNewMsg->ip_summed = pMsg->ip_summed; + pNewMsg->len = pMsg->len; + DEV_KFREE_SKB_ANY(pMsg); + pMsg = pNewMsg; +#endif + pMsg->dev = pAC->dev[Port]; + pMsg->protocol = eth_type_trans(pMsg,pAC->dev[Port]); + netif_rx(pMsg); + pAC->dev[Port]->last_rx = jiffies; + } else { + DEV_KFREE_SKB_ANY(pMsg); + } + } /* if packet for rlmt */ + PUSH_PKT_AS_LAST_IN_QUEUE(&pAC->RxPort[Port].RxQ_waiting, pSkPacket); + } /* end if-else (IsGoodPkt) */ + + SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_RX_PROGRESS, + ("<== HandleReceives (Port %c)\n", 'A' + Port)); + return(SK_TRUE); + +} /* HandleReceives */ + +/*********************************************************************** + * + * CheckForSendComplete - Frees any freeable Tx bufffer + * + * Description: + * This function checks the queues of a port for completed send + * packets and returns these packets back to the OS. + * + * Notes: + * This function can run simultaneously for both ports if + * the OS function OSReturnPacket() can handle this, + * + * Such a send complete does not mean, that the packet is really + * out on the wire. We just know that the adapter has copied it + * into its internal memory and the buffer in the systems memory + * is no longer needed. + * + * Returns: N/A + */ +static void CheckForSendComplete( +SK_AC *pAC, /* pointer to adapter control context */ +SK_IOC IoC, /* I/O control context */ +int Port, /* port index */ +SK_PKT_QUEUE *pPQ, /* tx working packet queue to check */ +SK_LE_TABLE *pLETab, /* corresponding list element table */ +unsigned int Done) /* done index reported for this LET */ +{ + SK_PACKET *pSkPacket; + SK_PKT_QUEUE SendCmplPktQ = { NULL, NULL, SPIN_LOCK_UNLOCKED }; + SK_BOOL DoWakeQueue = SK_FALSE; + unsigned long Flags; + unsigned Put; + + SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_TX_PROGRESS, + ("==> CheckForSendComplete(Port %c)\n", 'A' + Port)); + + /* + ** Reset own bit in LE's between old and new Done index + ** This is not really necessairy but makes debugging easier + */ + SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_TX_PROGRESS, + ("Clear Own Bits in TxTable from %d to %d\n", + pLETab->Done, (Done == 0) ? + NUM_LE_IN_TABLE(pLETab) : + (Done - 1))); + + spin_lock_irqsave(&(pPQ->QueueLock), Flags); + + CLEAR_LE_OWN_FROM_DONE_TO(pLETab, Done); + + Put = GET_PUT_IDX(pLETab); + + /* + ** Check whether some packets have been completed + */ + PLAIN_POP_FIRST_PKT_FROM_QUEUE(pPQ, pSkPacket); + while (pSkPacket != NULL) { + + SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_TX_PROGRESS, + ("Check Completion of Tx packet %p\n", pSkPacket)); + SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_TX_PROGRESS, + ("Put %d NewDone %d NextLe of Packet %d\n", Put, Done, + pSkPacket->NextLE)); + + if ((Put > Done) && + ((pSkPacket->NextLE > Put) || (pSkPacket->NextLE <= Done))) { + PLAIN_PUSH_PKT_AS_LAST_IN_QUEUE(&SendCmplPktQ, pSkPacket); + SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_TX_PROGRESS, + ("Packet finished (a)\n")); + } else if ((Done > Put) && + (pSkPacket->NextLE > Put) && (pSkPacket->NextLE <= Done)) { + PLAIN_PUSH_PKT_AS_LAST_IN_QUEUE(&SendCmplPktQ, pSkPacket); + SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_TX_PROGRESS, + ("Packet finished (b)\n")); + } else if ((Done == TXA_MAX_LE-1) && (Put == 0) && (pSkPacket->NextLE == 0)) { + PLAIN_PUSH_PKT_AS_LAST_IN_QUEUE(&SendCmplPktQ, pSkPacket); + SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_TX_PROGRESS, + ("Packet finished (b)\n")); + DoWakeQueue = SK_TRUE; + } else if (Done == Put) { + /* all packets have been sent */ + PLAIN_PUSH_PKT_AS_LAST_IN_QUEUE(&SendCmplPktQ, pSkPacket); + SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_TX_PROGRESS, + ("Packet finished (c)\n")); + } else { + SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_TX_PROGRESS, + ("Packet not yet finished\n")); + PLAIN_PUSH_PKT_AS_FIRST_IN_QUEUE(pPQ, pSkPacket); + break; + } + PLAIN_POP_FIRST_PKT_FROM_QUEUE(pPQ, pSkPacket); + } + spin_unlock_irqrestore(&(pPQ->QueueLock), Flags); + + /* + ** Set new done index in list element table + */ + SET_DONE_INDEX(pLETab, Done); + + /* + ** All TX packets that are send complete should be added to + ** the free queue again for new sents to come + */ + pSkPacket = SendCmplPktQ.pHead; + while (pSkPacket != NULL) { + while (pSkPacket->pFrag != NULL) { + pci_unmap_page(pAC->PciDev, + (dma_addr_t) pSkPacket->pFrag->pPhys, + pSkPacket->pFrag->FragLen, + PCI_DMA_FROMDEVICE); + pSkPacket->pFrag = pSkPacket->pFrag->pNext; + } + + DEV_KFREE_SKB_ANY(pSkPacket->pMBuf); + pSkPacket->pMBuf = NULL; + pSkPacket = pSkPacket->pNext; /* get next packet */ + } + + /* + ** Append the available TX packets back to free queue + */ + if (SendCmplPktQ.pHead != NULL) { + spin_lock_irqsave(&(pAC->TxPort[Port][0].TxQ_free.QueueLock), Flags); + if (pAC->TxPort[Port][0].TxQ_free.pTail != NULL) { + pAC->TxPort[Port][0].TxQ_free.pTail->pNext = SendCmplPktQ.pHead; + pAC->TxPort[Port][0].TxQ_free.pTail = SendCmplPktQ.pTail; + if (pAC->TxPort[Port][0].TxQ_free.pHead->pNext == NULL) { + netif_wake_queue(pAC->dev[Port]); + } + } else { + pAC->TxPort[Port][0].TxQ_free.pHead = SendCmplPktQ.pHead; + pAC->TxPort[Port][0].TxQ_free.pTail = SendCmplPktQ.pTail; + netif_wake_queue(pAC->dev[Port]); + } + if (Done == Put) { + netif_wake_queue(pAC->dev[Port]); + } + if (DoWakeQueue) { + netif_wake_queue(pAC->dev[Port]); + DoWakeQueue = SK_FALSE; + } + spin_unlock_irqrestore(&pAC->TxPort[Port][0].TxQ_free.QueueLock, Flags); + } + + SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_TX_PROGRESS, + ("<== CheckForSendComplete()\n")); + + return; +} /* CheckForSendComplete */ + +/***************************************************************************** + * + * UnmapAndFreeTxPktBuffer + * + * Description: + * This function free any allocated space of receive buffers + * + * Arguments: + * pAC - A pointer to the adapter context struct. + * + */ +static void UnmapAndFreeTxPktBuffer( +SK_AC *pAC, /* pointer to adapter context */ +SK_PACKET *pSkPacket, /* pointer to port struct of ring to fill */ +int TxPort) /* TX port index */ +{ + SK_FRAG *pFrag = pSkPacket->pFrag; + + SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_TX_PROGRESS, + ("--> UnmapAndFreeTxPktBuffer\n")); + + while (pFrag != NULL) { + pci_unmap_page(pAC->PciDev, + (dma_addr_t) pFrag->pPhys, + pFrag->FragLen, + PCI_DMA_FROMDEVICE); + pFrag = pFrag->pNext; + } + + DEV_KFREE_SKB_ANY(pSkPacket->pMBuf); + pSkPacket->pMBuf = NULL; + + SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_TX_PROGRESS, + ("<-- UnmapAndFreeTxPktBuffer\n")); +} + +/***************************************************************************** + * + * HandleStatusLEs + * + * Description: + * This function checks for any new status LEs that may have been + * received. Those status LEs may either be Rx or Tx ones. + * + * Returns: N/A + */ +static SK_BOOL HandleStatusLEs( +#ifdef CONFIG_SK98LIN_NAPI +SK_AC *pAC, /* pointer to adapter context */ +int *WorkDone, /* Done counter needed for NAPI */ +int WorkToDo) /* ToDo counter for NAPI */ +#else +SK_AC *pAC) /* pointer to adapter context */ +#endif +{ + int DoneTxA[SK_MAX_MACS]; + int DoneTxS[SK_MAX_MACS]; + int Port; + SK_BOOL handledStatLE = SK_FALSE; + SK_BOOL NewDone = SK_FALSE; + SK_HWLE *pLE; + SK_U16 HighVal; + SK_U32 LowVal; + SK_U8 OpCode; + int i; + + SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_INT_SRC, + ("==> HandleStatusLEs\n")); + + do { + SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_INT_SRC, + ("Check next Own Bit of ST-LE[%d]: 0x%li \n", + (pAC->StatusLETable.Done + 1) % NUM_LE_IN_TABLE(&pAC->StatusLETable), + OWN_OF_FIRST_LE(&pAC->StatusLETable))); + + while (OWN_OF_FIRST_LE(&pAC->StatusLETable) == HW_OWNER) { + GET_ST_LE(pLE, &pAC->StatusLETable); + SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_INT_SRC, + ("Working on finished status LE[%d]:\n", + GET_DONE_INDEX(&pAC->StatusLETable))); + SK_DBG_DUMP_ST_LE(pLE); + handledStatLE = SK_TRUE; + OpCode = STLE_GET_OPC(pLE) & ~HW_OWNER; + Port = STLE_GET_LINK(pLE); + +#ifdef USE_TIST_FOR_RESET + if (SK_ADAPTER_WAITING_FOR_TIST(pAC)) { + /* do we just have a tist LE ? */ + if ((OpCode & OP_RXTIMESTAMP) == OP_RXTIMESTAMP) { + for (i = 0; i < pAC->GIni.GIMacsFound; i++) { + if (SK_PORT_WAITING_FOR_ANY_TIST(pAC, i)) { + /* if a port is waiting for any tist it is done */ + SK_CLR_STATE_FOR_PORT(pAC, i); + SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DUMP, + ("Got any Tist on port %c (now 0x%X!!!)\n", + 'A' + i, pAC->AdapterResetState)); + } + if (SK_PORT_WAITING_FOR_SPECIFIC_TIST(pAC, i)) { + Y2_GET_TIST_LOW_VAL(pAC->IoBase, &LowVal); + if ((pAC->MinTistHi != pAC->GIni.GITimeStampCnt) || + (pAC->MinTistLo < LowVal)) { + /* time is up now */ + SK_CLR_STATE_FOR_PORT(pAC, i); + SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DUMP, + ("Got expected Tist on Port %c (now 0x%X)!!!\n", + 'A' + i, pAC->AdapterResetState)); +#ifdef Y2_SYNC_CHECK + pAC->FramesWithoutSyncCheck = + Y2_RESYNC_WATERMARK; +#endif + } else { + SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DUMP, + ("Got Tist %l:%l on Port %c but still waiting\n", + pAC->GIni.GITimeStampCnt, pAC->MinTistLo, + 'A' + i)); + } + } + } +#ifndef Y2_RECOVERY + if (!SK_ADAPTER_WAITING_FOR_TIST(pAC)) { + /* nobody needs tist anymore - turn it off */ + Y2_DISABLE_TIST(pAC->IoBase); + SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DUMP, + ("Turn off Tist !!!\n")); + } +#endif + } else if (OpCode == OP_TXINDEXLE) { + /* + * change OpCode to notify the folowing code + * to ignore the done index from this LE + * unfortunately tist LEs will be generated only + * for RxStat LEs + * so in order to get a safe Done index for a + * port currently waiting for a tist we have to + * get the done index directly from the BMU + */ + OpCode = OP_MOD_TXINDEX; + SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DUMP, + ("Mark unusable TX_INDEX LE!!!\n")); + } else { + if (SK_PORT_WAITING_FOR_TIST(pAC, Port)) { + SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DUMP, + ("Ignore LE 0x%X on Port %c!!!\n", + OpCode, 'A' + Port)); + OpCode = OP_MOD_LE; +#ifdef Y2_LE_CHECK + /* mark entries invalid */ + pAC->LastOpc = 0xFF; + pAC->LastPort = 3; +#endif + } + } + } /* if (SK_ADAPTER_WAITING_FOR_TIST(pAC)) */ +#endif + + + + + +#ifdef Y2_LE_CHECK + if (pAC->LastOpc != 0xFF) { + /* last opc is valid + * check if current opcode follows last opcode + */ + if ((((OpCode & OP_RXTIMESTAMP) == OP_RXTIMESTAMP) && (pAC->LastOpc != OP_RXSTAT)) || + (((OpCode & OP_RXCHKS) == OP_RXCHKS) && (pAC->LastOpc != OP_RXTIMESTAMP)) || + ((OpCode == OP_RXSTAT) && (pAC->LastOpc != OP_RXCHKS))) { + + /* opcode sequence broken + * current LE is invalid + */ + + if (pAC->LastOpc == OP_RXTIMESTAMP) { + /* force invalid checksum */ + pLE->St.StUn.StRxTCPCSum.RxTCPSum1 = 1; + pLE->St.StUn.StRxTCPCSum.RxTCPSum2 = 0; + OpCode = pAC->LastOpc = OP_RXCHKS; + Port = pAC->LastPort; + } else if (pAC->LastOpc == OP_RXCHKS) { + /* force invalid frame */ + Port = pAC->LastPort; + pLE->St.Stat.BufLen = 64; + pLE->St.StUn.StRxStatWord = GMR_FS_CRC_ERR; + OpCode = pAC->LastOpc = OP_RXSTAT; +#ifdef Y2_SYNC_CHECK + /* force rx sync check */ + pAC->FramesWithoutSyncCheck = Y2_RESYNC_WATERMARK; +#endif + } else if (pAC->LastOpc == OP_RXSTAT) { + /* create dont care tist */ + pLE->St.StUn.StRxTimeStamp = 0; + OpCode = pAC->LastOpc = OP_RXTIMESTAMP; + /* dont know the port yet */ + } else { +#ifdef DEBUG + SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_INT_SRC, + ("Unknown LastOpc %X for Timestamp on port %c.\n", + pAC->LastOpc, Port)); +#endif + } + } + } +#endif + + switch (OpCode) { + case OP_RXSTAT: +#ifdef Y2_RECOVERY + pAC->LastOpc = OP_RXSTAT; +#endif + /* + ** This is always the last Status LE belonging + ** to a received packet -> handle it... + */ + if ((Port != 0) && (Port != 1)) { + /* Unknown port */ + panic("sk98lin: Unknown port %d\n", + Port); + } + + HandleReceives( + pAC, + Port, + STLE_GET_LEN(pLE), + STLE_GET_FRSTATUS(pLE), + pAC->StatusLETable.Bmu.Stat.TcpSum1, + pAC->StatusLETable.Bmu.Stat.TcpSum2, + pAC->StatusLETable.Bmu.Stat.RxTimeStamp, + pAC->StatusLETable.Bmu.Stat.VlanId); +#ifdef CONFIG_SK98LIN_NAPI + if (*WorkDone >= WorkToDo) { + break; + } + (*WorkDone)++; +#endif + break; + case OP_RXVLAN: + /* this value will be used for next RXSTAT */ + pAC->StatusLETable.Bmu.Stat.VlanId = STLE_GET_VLAN(pLE); + break; + case OP_RXTIMEVLAN: + /* this value will be used for next RXSTAT */ + pAC->StatusLETable.Bmu.Stat.VlanId = STLE_GET_VLAN(pLE); + /* fall through */ + case OP_RXTIMESTAMP: + /* this value will be used for next RXSTAT */ + pAC->StatusLETable.Bmu.Stat.RxTimeStamp = STLE_GET_TIST(pLE); +#ifdef Y2_RECOVERY + pAC->LastOpc = OP_RXTIMESTAMP; + pAC->LastPort = Port; +#endif + break; + case OP_RXCHKSVLAN: + /* this value will be used for next RXSTAT */ + pAC->StatusLETable.Bmu.Stat.VlanId = STLE_GET_VLAN(pLE); + /* fall through */ + case OP_RXCHKS: + /* this value will be used for next RXSTAT */ + pAC->StatusLETable.Bmu.Stat.TcpSum1 = STLE_GET_TCP1(pLE); + pAC->StatusLETable.Bmu.Stat.TcpSum2 = STLE_GET_TCP2(pLE); +#ifdef Y2_RECOVERY + pAC->LastPort = Port; + pAC->LastOpc = OP_RXCHKS; +#endif + break; + case OP_RSS_HASH: + /* this value will be used for next RXSTAT */ +#if 0 + pAC->StatusLETable.Bmu.Stat.RssHashValue = STLE_GET_RSS(pLE); +#endif + break; + case OP_TXINDEXLE: + /* + ** :;:; TODO + ** it would be possible to check for which queues + ** the index has been changed and call + ** CheckForSendComplete() only for such queues + */ + STLE_GET_DONE_IDX(pLE,LowVal,HighVal); + SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_INT_SRC, + ("LowVal: 0x%x HighVal: 0x%x\n", LowVal, HighVal)); + + /* + ** It would be possible to check whether we really + ** need the values for second port or sync queue, + ** but I think checking whether we need them is + ** more expensive than the calculation + */ + DoneTxA[0] = STLE_GET_DONE_IDX_TXA1(LowVal,HighVal); + DoneTxS[0] = STLE_GET_DONE_IDX_TXS1(LowVal,HighVal); + DoneTxA[1] = STLE_GET_DONE_IDX_TXA2(LowVal,HighVal); + DoneTxS[1] = STLE_GET_DONE_IDX_TXS2(LowVal,HighVal); + + SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_INT_SRC, + ("DoneTxa1 0x%x DoneTxS1: 0x%x DoneTxa2 0x%x DoneTxS2: 0x%x\n", + DoneTxA[0], DoneTxS[0], DoneTxA[1], DoneTxS[1])); + + NewDone = SK_TRUE; + break; +#ifdef USE_TIST_FOR_RESET + case OP_MOD_TXINDEX: + SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DUMP, + ("OP_MOD_TXINDEX\n")); + SK_IN16(pAC->IoBase, Q_ADDR(Q_XA1, Q_DONE), &DoneTxA[0]); + if (pAC->GIni.GIMacsFound > 1) { + SK_IN16(pAC->IoBase, Q_ADDR(Q_XA2, Q_DONE), &DoneTxA[1]); + } + NewDone = SK_TRUE; + break; + case OP_MOD_LE: + SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DUMP, + ("Ignore marked LE on port in Reset\n")); + break; +#endif + + default: + /* + ** Have to handle the illegal Opcode in Status LE + */ + SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_INT_SRC, + ("Unexpected OpCode\n")); + break; + } + +#ifdef Y2_RECOVERY + OpCode = STLE_GET_OPC(pLE) & ~HW_OWNER; + STLE_SET_OPC(pLE, OpCode); +#else + /* + ** Reset own bit we have to do this in order to detect a overflow + */ + STLE_SET_OPC(pLE, SW_OWNER); +#endif + } /* while (OWN_OF_FIRST_LE(&pAC->StatusLETable) == HW_OWNER) */ + + /* + ** Now handle any new transmit complete + */ + if (NewDone) { + SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_INT_SRC, + ("Done Index for Tx BMU has been changed\n")); + for (Port = 0; Port < pAC->GIni.GIMacsFound; Port++) { + /* + ** Do we have a new Done idx ? + */ + if (DoneTxA[Port] != GET_DONE_INDEX(&pAC->TxPort[Port][0].TxALET)) { + SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_INT_SRC, + ("Check TxA%d\n", Port + 1)); + CheckForSendComplete(pAC, pAC->IoBase, Port, + &(pAC->TxPort[Port][0].TxAQ_working), + &pAC->TxPort[Port][0].TxALET, + DoneTxA[Port]); + } else { + SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_INT_SRC, + ("No changes for TxA%d\n", Port + 1)); + } +#if USE_SYNC_TX_QUEUE + if (HW_SYNC_TX_SUPPORTED(pAC)) { + /* + ** Do we have a new Done idx ? + */ + if (DoneTxS[Port] != + GET_DONE_INDEX(&pAC->TxPort[Port][0].TxSLET)) { + SK_DBG_MSG(pAC, SK_DBGMOD_DRV, + SK_DBGCAT_DRV_INT_SRC, + ("Check TxS%d\n", Port)); + CheckForSendComplete(pAC, pAC->IoBase, Port, + &(pAC->TxPort[Port][0].TxSQ_working), + &pAC->TxPort[Port][0].TxSLET, + DoneTxS[Port]); + } else { + SK_DBG_MSG(pAC, SK_DBGMOD_DRV, + SK_DBGCAT_DRV_INT_SRC, + ("No changes for TxS%d\n", Port)); + } + } +#endif + } + } + NewDone = SK_FALSE; + + /* + ** Check whether we have to refill our RX table + */ + if (HW_FEATURE(pAC, HWF_WA_DEV_420)) { + if (NbrRxBuffersInHW < MAX_NBR_RX_BUFFERS_IN_HW) { + for (Port = 0; Port < pAC->GIni.GIMacsFound; Port++) { + SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_INT_SRC, + ("Check for refill of RxBuffers on Port %c\n", 'A' + Port)); + FillReceiveTableYukon2(pAC, pAC->IoBase, Port); + } + } + } else { + for (Port = 0; Port < pAC->GIni.GIMacsFound; Port++) { + SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_INT_SRC, + ("Check for refill of RxBuffers on Port %c\n", 'A' + Port)); + if (NUM_FREE_LE_IN_TABLE(&pAC->RxPort[Port].RxLET) >= 64) { + FillReceiveTableYukon2(pAC, pAC->IoBase, Port); + } + } + } +#ifdef CONFIG_SK98LIN_NAPI + if (*WorkDone >= WorkToDo) { + break; + } +#endif + } while (OWN_OF_FIRST_LE(&pAC->StatusLETable) == HW_OWNER); + + /* + ** Clear status BMU + */ + SK_OUT32(pAC->IoBase, STAT_CTRL, SC_STAT_CLR_IRQ); + + return(handledStatLE); +} /* HandleStatusLEs */ + +/***************************************************************************** + * + * AllocateAndInitLETables - allocate memory for the LETable and init + * + * Description: + * This function will allocate space for the LETable and will also + * initialize them. The size of the tables must have been specified + * before. + * + * Arguments: + * pAC - A pointer to the adapter context struct. + * + * Returns: + * SK_TRUE - all LETables initialized + * SK_FALSE - failed + */ +static SK_BOOL AllocateAndInitLETables( +SK_AC *pAC) /* pointer to adapter context */ +{ + char *pVirtMemAddr; + dma_addr_t pPhysMemAddr = 0; + SK_U32 CurrMac; + unsigned Size; + unsigned Aligned; + unsigned Alignment; + + SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_INIT, + ("==> AllocateAndInitLETables()\n")); + + /* + ** Determine how much memory we need with respect to alignment + */ + Alignment = MAX_LEN_OF_LE_TAB; + Size = 0; + for (CurrMac = 0; CurrMac < pAC->GIni.GIMacsFound; CurrMac++) { + SK_ALIGN_SIZE(LE_TAB_SIZE(RX_MAX_LE), Alignment, Aligned); + Size += Aligned; + SK_ALIGN_SIZE(LE_TAB_SIZE(TXA_MAX_LE), Alignment, Aligned); + Size += Aligned; + SK_ALIGN_SIZE(LE_TAB_SIZE(TXS_MAX_LE), Alignment, Aligned); + Size += Aligned; + } + SK_ALIGN_SIZE(LE_TAB_SIZE(ST_MAX_LE), Alignment, Aligned); + Size += Aligned; + Size += Alignment; + pAC->SizeOfAlignedLETables = Size; + + SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_INIT, + ("Need %08x bytes in total\n", Size)); + + /* + ** Allocate the memory + */ + pVirtMemAddr = pci_alloc_consistent(pAC->PciDev, Size, &pPhysMemAddr); + if (pVirtMemAddr == NULL) { + SK_DBG_MSG(pAC, SK_DBGMOD_DRV, + SK_DBGCAT_INIT | SK_DBGCAT_DRV_ERROR, + ("AllocateAndInitLETables: kernel malloc failed!\n")); + return (SK_FALSE); + } + + /* + ** Initialize the memory + */ + SK_MEMSET(pVirtMemAddr, 0, Size); + ALIGN_ADDR(pVirtMemAddr, Alignment); /* Macro defined in skgew.h */ + + SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_INIT, + ("Virtual address of LETab is %8p!\n", pVirtMemAddr)); + SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_INIT, + ("Phys address of LETab is %8p!\n", (void *) pPhysMemAddr)); + + for (CurrMac = 0; CurrMac < pAC->GIni.GIMacsFound; CurrMac++) { + SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_INIT, + ("RxLeTable for Port %c", 'A' + CurrMac)); + SkGeY2InitSingleLETable( + pAC, + &pAC->RxPort[CurrMac].RxLET, + RX_MAX_LE, + pVirtMemAddr, + (SK_U32) (pPhysMemAddr & 0xffffffff), + (SK_U32) (((SK_U64) pPhysMemAddr) >> 32)); + + SK_ALIGN_SIZE(LE_TAB_SIZE(RX_MAX_LE), Alignment, Aligned); + pVirtMemAddr += Aligned; + pPhysMemAddr += Aligned; + + SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_INIT, + ("TxALeTable for Port %c", 'A' + CurrMac)); + SkGeY2InitSingleLETable( + pAC, + &pAC->TxPort[CurrMac][0].TxALET, + TXA_MAX_LE, + pVirtMemAddr, + (SK_U32) (pPhysMemAddr & 0xffffffff), + (SK_U32) (((SK_U64) pPhysMemAddr) >> 32)); + + SK_ALIGN_SIZE(LE_TAB_SIZE(TXA_MAX_LE), Alignment, Aligned); + pVirtMemAddr += Aligned; + pPhysMemAddr += Aligned; + + SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_INIT, + ("TxSLeTable for Port %c", 'A' + CurrMac)); + SkGeY2InitSingleLETable( + pAC, + &pAC->TxPort[CurrMac][0].TxSLET, + TXS_MAX_LE, + pVirtMemAddr, + (SK_U32) (pPhysMemAddr & 0xffffffff), + (SK_U32) (((SK_U64) pPhysMemAddr) >> 32)); + + SK_ALIGN_SIZE(LE_TAB_SIZE(TXS_MAX_LE), Alignment, Aligned); + pVirtMemAddr += Aligned; + pPhysMemAddr += Aligned; + } + + SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_MSG,("StLeTable")); + + SkGeY2InitSingleLETable( + pAC, + &pAC->StatusLETable, + ST_MAX_LE, + pVirtMemAddr, + (SK_U32) (pPhysMemAddr & 0xffffffff), + (SK_U32) (((SK_U64) pPhysMemAddr) >> 32)); + + SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_INIT, + ("<== AllocateAndInitLETables(OK)\n")); + return(SK_TRUE); +} /* AllocateAndInitLETables */ + +/***************************************************************************** + * + * AllocatePacketBuffersYukon2 - allocate packet and fragment buffers + * + * Description: + * This function will allocate space for the packets and fragments + * + * Arguments: + * pAC - A pointer to the adapter context struct. + * + * Returns: + * SK_TRUE - Memory was allocated correctly + * SK_FALSE - An error occured + */ +static SK_BOOL AllocatePacketBuffersYukon2( +SK_AC *pAC) /* pointer to adapter context */ +{ + SK_PACKET *pRxPacket; + SK_PACKET *pTxPacket; + SK_U32 CurrBuff; + SK_U32 CurrMac; + unsigned long Flags; /* needed for POP/PUSH functions */ + + SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_INIT, + ("==> AllocatePacketBuffersYukon2()")); + + for (CurrMac = 0; CurrMac < pAC->GIni.GIMacsFound; CurrMac++) { + /* + ** Allocate RX packet space, initialize the packets and + ** add them to the RX waiting queue. Waiting queue means + ** that packet and fragment are initialized, but no sk_buff + ** has been assigned to it yet. + */ + pAC->RxPort[CurrMac].ReceivePacketTable = + kmalloc((RX_MAX_NBR_BUFFERS * sizeof(SK_PACKET)), GFP_KERNEL); + + if (pAC->RxPort[CurrMac].ReceivePacketTable == NULL) { + SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_INIT | SK_DBGCAT_DRV_ERROR, + ("AllocatePacketBuffersYukon2: no mem RxPkts (port %i)",CurrMac)); + break; + } else { + SK_MEMSET(pAC->RxPort[CurrMac].ReceivePacketTable, 0, + (RX_MAX_NBR_BUFFERS * sizeof(SK_PACKET))); + + pRxPacket = pAC->RxPort[CurrMac].ReceivePacketTable; + + for (CurrBuff=0;CurrBuffpFrag = &(pRxPacket->FragArray[0]); + pRxPacket->NumFrags = 1; + PUSH_PKT_AS_LAST_IN_QUEUE(&pAC->RxPort[CurrMac].RxQ_waiting, pRxPacket); + pRxPacket++; + } + } + + /* + ** Allocate TX packet space, initialize the packets and + ** add them to the TX free queue. Free queue means that + ** packet is available and initialized, but no fragment + ** has been assigned to it. (Must be done at TX side) + */ + pAC->TxPort[CurrMac][0].TransmitPacketTable = + kmalloc((TX_MAX_NBR_BUFFERS * sizeof(SK_PACKET)), GFP_KERNEL); + + if (pAC->TxPort[CurrMac][0].TransmitPacketTable == NULL) { + SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_INIT | SK_DBGCAT_DRV_ERROR, + ("AllocatePacketBuffersYukon2: no mem TxPkts (port %i)",CurrMac)); + kfree(pAC->RxPort[CurrMac].ReceivePacketTable); + return(SK_FALSE); + } else { + SK_MEMSET(pAC->TxPort[CurrMac][0].TransmitPacketTable, 0, + (TX_MAX_NBR_BUFFERS * sizeof(SK_PACKET))); + + pTxPacket = pAC->TxPort[CurrMac][0].TransmitPacketTable; + + for (CurrBuff=0;CurrBuffTxPort[CurrMac][0].TxQ_free, pTxPacket); + pTxPacket++; + } + } + } /* end for (CurrMac = 0; CurrMac < pAC->GIni.GIMacsFound; CurrMac++) */ + + SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_INIT, + ("<== AllocatePacketBuffersYukon2 (OK)\n")); + return(SK_TRUE); + +} /* AllocatePacketBuffersYukon2 */ + +/***************************************************************************** + * + * FreeLETables - release allocated memory of LETables + * + * Description: + * This function will free all resources of the LETables + * + * Arguments: + * pAC - A pointer to the adapter context struct. + * + * Returns: N/A + */ +static void FreeLETables( +SK_AC *pAC) /* pointer to adapter control context */ +{ + dma_addr_t pPhysMemAddr; + char *pVirtMemAddr; + + SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_MSG, + ("==> FreeLETables()\n")); + + /* + ** The RxLETable is the first of all LET. + ** Therefore we can use its address for the input + ** of the free function. + */ + pVirtMemAddr = (char *) pAC->RxPort[0].RxLET.pLETab; + pPhysMemAddr = (((SK_U64) pAC->RxPort[0].RxLET.pPhyLETABHigh << (SK_U64) 32) | + ((SK_U64) pAC->RxPort[0].RxLET.pPhyLETABLow)); + + /* free continuous memory */ + pci_free_consistent(pAC->PciDev, pAC->SizeOfAlignedLETables, + pVirtMemAddr, pPhysMemAddr); + + SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_MSG, + ("<== FreeLETables()\n")); +} /* FreeLETables */ + +/***************************************************************************** + * + * FreePacketBuffers - free's all packet buffers of an adapter + * + * Description: + * This function will free all previously allocated memory of the + * packet buffers. + * + * Arguments: + * pAC - A pointer to the adapter context struct. + * + * Returns: N/A + */ +static void FreePacketBuffers( +SK_AC *pAC) /* pointer to adapter control context */ +{ + int Port; + + SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_MSG, + ("==> FreePacketBuffers()\n")); + + for (Port = 0; Port < pAC->GIni.GIMacsFound; Port++) { + kfree(pAC->RxPort[Port].ReceivePacketTable); + kfree(pAC->TxPort[Port][0].TransmitPacketTable); + } + + SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_MSG, + ("<== FreePacketBuffers()\n")); +} /* FreePacketBuffers */ + +/***************************************************************************** + * + * AllocAndMapRxBuffer - fill one buffer into the receive packet/fragment + * + * Description: + * The function allocates a new receive buffer and assigns it to the + * the passsed receive packet/fragment + * + * Returns: + * SK_TRUE - a buffer was allocated and assigned + * SK_FALSE - a buffer could not be added + */ +static SK_BOOL AllocAndMapRxBuffer( +SK_AC *pAC, /* pointer to the adapter control context */ +SK_PACKET *pSkPacket, /* pointer to packet that is to fill */ +int Port) /* port the packet belongs to */ +{ + struct sk_buff *pMsgBlock; /* pointer to a new message block */ + SK_U64 PhysAddr; /* physical address of a rx buffer */ + + SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_RX_PROGRESS, + ("--> AllocAndMapRxBuffer (Port: %i)\n", Port)); + + pMsgBlock = alloc_skb(pAC->RxPort[Port].RxBufSize, GFP_ATOMIC); + if (pMsgBlock == NULL) { + SK_DBG_MSG(NULL, SK_DBGMOD_DRV, + SK_DBGCAT_DRV_RX_PROGRESS | SK_DBGCAT_DRV_ERROR, + ("%s: Allocation of rx buffer failed !\n", + pAC->dev[Port]->name)); + SK_PNMI_CNT_NO_RX_BUF(pAC, pAC->RxPort[Port].PortIndex); + return(SK_FALSE); + } + skb_reserve(pMsgBlock, 8); + + PhysAddr = (SK_U64) pci_map_page(pAC->PciDev, + virt_to_page(pMsgBlock->data), + ((unsigned long) pMsgBlock->data & + ~PAGE_MASK), + pAC->RxPort[Port].RxBufSize, + PCI_DMA_FROMDEVICE); + + pSkPacket->pFrag->pVirt = pMsgBlock->data; + pSkPacket->pFrag->pPhys = PhysAddr; + pSkPacket->pFrag->FragLen = pAC->RxPort[Port].RxBufSize; /* for correct unmap */ + pSkPacket->pMBuf = pMsgBlock; + pSkPacket->PacketLen = pAC->RxPort[Port].RxBufSize; + + SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_RX_PROGRESS, + ("<-- AllocAndMapRxBuffer\n")); + + return (SK_TRUE); +} /* AllocAndMapRxBuffer */ + +/******************************************************************************* + * + * End of file + * + ******************************************************************************/ diff -urN linux-2.4.32-600/drivers/net/sk98lin/sky2le.c linux-2.4.32-600-sk98_831/drivers/net/sk98lin/sky2le.c --- linux-2.4.32-600/drivers/net/sk98lin/sky2le.c Thu Jan 1 01:00:00 1970 +++ linux-2.4.32-600-sk98_831/drivers/net/sk98lin/sky2le.c Sun Feb 26 11:13:02 2006 @@ -0,0 +1,512 @@ +/***************************************************************************** + * + * Name: sky2le.c + * Project: Gigabit Ethernet Adapters, Common Modules + * Version: $Revision: 1.12 $ + * Date: $Date: 2005/12/14 16:11:35 $ + * Purpose: Functions for handling List Element Tables + * + *****************************************************************************/ + +/****************************************************************************** + * + * LICENSE: + * (C)Copyright 2002-2004 Marvell. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * The information in this file is provided "AS IS" without warranty. + * /LICENSE + * + ******************************************************************************/ + +/***************************************************************************** + * + * Description: + * + * This module contains the code necessary for handling List Elements. + * + * Supported Gigabit Ethernet Chipsets: + * Yukon-2 (PCI, PCI-X, PCI-Express) + * + * Include File Hierarchy: + * + * + *****************************************************************************/ +#include "h/skdrv1st.h" +#include "h/skdrv2nd.h" + +/* defines *******************************************************************/ +/* typedefs ******************************************************************/ +/* global variables **********************************************************/ +/* local variables ***********************************************************/ + +#if (defined(DEBUG) || ((!defined(LINT)) && (!defined(SK_SLIM)))) +static const char SysKonnectFileId[] = + "@(#) $Id: sky2le.c,v 1.12 2005/12/14 16:11:35 ibrueder Exp $ (C) Marvell."; +#endif /* DEBUG || (!LINT && !SK_SLIM) */ + +/* function prototypes *******************************************************/ + +/***************************************************************************** + * + * SkGeY2InitSingleLETable() - initializes a list element table + * + * Description: + * This function will initialize the selected list element table. + * Should be called once during DriverInit. No InitLevel required. + * + * Arguments: + * pAC - pointer to the adapter context struct. + * pLETab - pointer to list element table structure + * NumLE - number of list elements in this table + * pVMem - virtual address of memory allocated for this LE table + * PMemLowAddr - physical address of memory to be used for the LE table + * PMemHighAddr + * + * Returns: + * nothing + */ +void SkGeY2InitSingleLETable( +SK_AC *pAC, /* pointer to adapter context */ +SK_LE_TABLE *pLETab, /* pointer to list element table to be initialized */ +unsigned int NumLE, /* number of list elements to be filled in tab */ +void *pVMem, /* virtual address of memory used for list elements */ +SK_U32 PMemLowAddr, /* physical addr of mem used for LE */ +SK_U32 PMemHighAddr) +{ + unsigned int i; + + SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_INIT, + ("==> SkGeY2InitSingleLETable()\n")); + +#ifdef DEBUG + if (NumLE != 2) { /* not table for polling unit */ + if ((NumLE % MIN_LEN_OF_LE_TAB) != 0 || NumLE > MAX_LEN_OF_LE_TAB) { + SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_ERR, + ("ERROR: Illegal number of list elements %d\n", NumLE)); + } + } +#endif /* DEBUG */ + + /* special case: unused list element table */ + if (NumLE == 0) { + PMemLowAddr = 0; + PMemHighAddr = 0; + pVMem = 0; + } + + /* + * in order to get the best possible performance the macros to access + * list elements use & instead of % + * this requires the length of LE tables to be a power of 2 + */ + + /* + * this code guarantees that we use the next power of 2 below the + * value specified for NumLe - this way some LEs in the table may + * not be used but the macros work correctly + * this code does not check for bad values below 128 because in such a + * case we cannot do anything here + */ + + if ((NumLE != 2) && (NumLE != 0)) { + /* no check for polling unit and unused sync Tx */ + i = MIN_LEN_OF_LE_TAB; + while (NumLE > i) { + i *= 2; + if (i > MAX_LEN_OF_LE_TAB) { + break; + } + } + if (NumLE != i) { + SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_ERR, + ("ERROR: Illegal number of list elements %d adjusted to %d\n", + NumLE, (i / 2))); + NumLE = i / 2; + } + } + + /* set addresses */ + pLETab->pPhyLETABLow = PMemLowAddr; + pLETab->pPhyLETABHigh = PMemHighAddr; + pLETab->pLETab = pVMem; + + SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_INIT, + ("contains %d LEs", NumLE)); + SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_INIT, + (" and starts at virt %08lx and phys %08lx:%08lx\n", + pVMem, PMemHighAddr, PMemLowAddr)); + + /* initialize indexes */ + pLETab->Done = 0; + pLETab->Put = 0; + pLETab->HwPut = 0; + /* initialize size */ + pLETab->Num = NumLE; + + SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_INIT, + ("<== SkGeY2InitSingleLETable()\n")); +} /* SkGeY2InitSingleLETable */ + +/***************************************************************************** + * + * SkGeY2InitPrefetchUnit() - Initialize a Prefetch Unit + * + * Description: + * Calling this function requires an already configured list element + * table. The prefetch unit to be configured is specified in the parameter + * 'Queue'. The function is able to initialze the prefetch units of + * the following queues: Q_R1, Q_R2, Q_XS1, Q_XS2, Q_XA1, Q_XA2. + * The funcution should be called before SkGeInitPort(). + * + * Arguments: + * pAC - pointer to the adapter context struct. + * IoC - I/O context. + * Queue - I/O offset of queue e.g. Q_XA1. + * pLETab - pointer to list element table to be initialized + * + * Returns: N/A + */ +void SkGeY2InitPrefetchUnit( +SK_AC *pAC, /* pointer to adapter context */ +SK_IOC IoC, /* I/O context */ +unsigned int Queue, /* Queue offset for finding the right registers */ +SK_LE_TABLE *pLETab) /* pointer to list element table to be initialized */ +{ + SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_INIT, + ("==> SkGeY2InitPrefetchUnit()\n")); + +#ifdef DEBUG + if (Queue != Q_R1 && Queue != Q_R2 && Queue != Q_XS1 && + Queue != Q_XS2 && Queue != Q_XA1 && Queue != Q_XA2) { + SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_ERR, + ("ERROR: Illegal queue identifier %x\n", Queue)); + } +#endif /* DEBUG */ + + /* disable the prefetch unit */ + SK_OUT32(IoC, Y2_PREF_Q_ADDR(Queue, PREF_UNIT_CTRL_REG), PREF_UNIT_RST_SET); + SK_OUT32(IoC, Y2_PREF_Q_ADDR(Queue, PREF_UNIT_CTRL_REG), PREF_UNIT_RST_CLR); + + SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_INIT, + ("Base address: %08lx:%08lx\n", pLETab->pPhyLETABHigh, + pLETab->pPhyLETABLow)); + + /* Set the list base address high part*/ + SK_OUT32(IoC, Y2_PREF_Q_ADDR(Queue, PREF_UNIT_ADDR_HI_REG), + pLETab->pPhyLETABHigh); + + /* Set the list base address low part */ + SK_OUT32(IoC, Y2_PREF_Q_ADDR(Queue, PREF_UNIT_ADDR_LOW_REG), + pLETab->pPhyLETABLow); + + SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_INIT, + ("Last index: %d\n", pLETab->Num-1)); + + /* Set the list last index */ + SK_OUT16(IoC, Y2_PREF_Q_ADDR(Queue, PREF_UNIT_LAST_IDX_REG), + (SK_U16)(pLETab->Num - 1)); + + /* turn on prefetch unit */ + SK_OUT32(IoC, Y2_PREF_Q_ADDR(Queue, PREF_UNIT_CTRL_REG), PREF_UNIT_OP_ON); + + SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_INIT, + ("<== SkGeY2InitPrefetchUnit()\n")); +} /* SkGeY2InitPrefetchUnit */ + + +/***************************************************************************** + * + * SkGeY2InitStatBmu() - Initialize the Status BMU + * + * Description: + * Calling this function requires an already configured list element + * table. Ensure the status BMU is only initialized once during + * DriverInit - InitLevel2 required. + * + * Arguments: + * pAC - pointer to the adapter context struct. + * IoC - I/O context. + * pLETab - pointer to status LE table to be initialized + * + * Returns: N/A + */ +void SkGeY2InitStatBmu( +SK_AC *pAC, /* pointer to adapter context */ +SK_IOC IoC, /* I/O context */ +SK_LE_TABLE *pLETab) /* pointer to status LE table */ +{ + SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_INIT, + ("==> SkGeY2InitStatBmu()\n")); + + /* disable the prefetch unit */ + SK_OUT32(IoC, STAT_CTRL, SC_STAT_RST_SET); + SK_OUT32(IoC, STAT_CTRL, SC_STAT_RST_CLR); + + SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_INIT, + ("Base address Low: %08lX\n", pLETab->pPhyLETABLow)); + + /* Set the list base address */ + SK_OUT32(IoC, STAT_LIST_ADDR_LO, pLETab->pPhyLETABLow); + + SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_INIT, + ("Base address High: %08lX\n", pLETab->pPhyLETABHigh)); + + SK_OUT32(IoC, STAT_LIST_ADDR_HI, pLETab->pPhyLETABHigh); + + SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_INIT, + ("Last index: %d\n", pLETab->Num - 1)); + + /* Set the list last index */ + SK_OUT16(IoC, STAT_LAST_IDX, (SK_U16)(pLETab->Num - 1)); + + if (HW_FEATURE(pAC, HWF_WA_DEV_43_418)) { + + SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_INIT, + ("Set Tx index threshold\n")); + /* WA for dev. #4.3 */ + SK_OUT16(IoC, STAT_TX_IDX_TH, ST_TXTH_IDX_MASK); + + /* set Status-FIFO watermark */ + SK_OUT8(IoC, STAT_FIFO_WM, 0x21); /* WA for dev. #4.18 */ + + /* set Status-FIFO ISR watermark */ + SK_OUT8(IoC, STAT_FIFO_ISR_WM, 0x07); /* WA for dev. #4.18 */ + + /* WA for dev. #4.3 and #4.18 */ + /* set Status-FIFO Tx timer init value */ + SK_OUT32(IoC, STAT_TX_TIMER_INI, HW_MS_TO_TICKS(pAC, 10)); + } + else { + /* + * Further settings may be added if required... + * 1) Status-FIFO watermark (STAT_FIFO_WM, STAT_FIFO_ISR_WM) + * 2) Status-FIFO timer values (STAT_TX_TIMER_INI, + * STAT_LEV_TIMER_INI and STAT_ISR_TIMER_INI) + * but tests shows that the default values give the best results, + * therefore the defaults are used. + */ + + /* + * Theses settings should avoid the + * temporary hanging of the status BMU. + * May be not all required... still under investigation... + */ + SK_OUT16(IoC, STAT_TX_IDX_TH, 0x000a); + + /* set Status-FIFO watermark */ + SK_OUT8(IoC, STAT_FIFO_WM, 0x10); + + + /* set Status-FIFO ISR watermark */ + if (HW_FEATURE(pAC, HWF_WA_DEV_4109)) { + SK_OUT8(IoC, STAT_FIFO_ISR_WM, 0x10); + } + else { + SK_OUT8(IoC, STAT_FIFO_ISR_WM, 0x04); + } + + SK_OUT32(IoC, STAT_ISR_TIMER_INI, 0x0190); + } + + /* start Status-FIFO timer */ + SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_INIT, + ("Start Status FiFo timer\n")); + + /* enable the prefetch unit */ + /* operational bit not functional for Yukon-EC, but fixed in Yukon-2 */ + SK_OUT32(IoC, STAT_CTRL, SC_STAT_OP_ON); + + /* start Status-FIFO timer */ + SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_INIT, + ("Start Status FiFo timer\n")); + + SK_OUT8(IoC, STAT_TX_TIMER_CTRL, TIM_START); + SK_OUT8(IoC, STAT_LEV_TIMER_CTRL, TIM_START); + SK_OUT8(IoC, STAT_ISR_TIMER_CTRL, TIM_START); + + SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_INIT, + ("<== SkGeY2InitStatBmu()\n")); +} /* SkGeY2InitStatBmu */ + +#ifdef USE_POLLING_UNIT +/***************************************************************************** + * + * SkGeY2InitPollUnit() - Initialize the Polling Unit + * + * Description: + * This function will write the data of one polling LE table into the + * adapter. + * + * Arguments: + * pAC - pointer to the adapter context struct. + * IoC - I/O context. + * pLETab - pointer to polling LE table to be initialized + * + * Returns: N/A + */ +void SkGeY2InitPollUnit( +SK_AC *pAC, /* pointer to adapter context */ +SK_IOC IoC, /* I/O context */ +SK_LE_TABLE *pLETab) /* pointer to polling LE table */ +{ + SK_HWLE *pLE; + int i; +#ifdef VCPU + VCPU_VARS(); +#endif /* VCPU */ + + SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_INIT, + ("==> SkGeY2InitPollUnit()\n")); + +#ifdef VCPU + for (i = 0; i < SK_MAX_MACS; i++) { + GET_PO_LE(pLE, pLETab, i); + VCPU_START_AND_COPY_LE(); + /* initialize polling LE but leave indexes invalid */ + POLE_SET_OPC(pLE, OP_PUTIDX | HW_OWNER); + POLE_SET_LINK(pLE, i); + POLE_SET_RXIDX(pLE, 0); + POLE_SET_TXAIDX(pLE, 0); + POLE_SET_TXSIDX(pLE, 0); + VCPU_WRITE_LE(); + SK_DBG_DUMP_PO_LE(pLE); + } +#endif /* VCPU */ + + /* disable the polling unit */ + SK_OUT32(IoC, POLL_CTRL, PC_POLL_RST_SET); + SK_OUT32(IoC, POLL_CTRL, PC_POLL_RST_CLR); + + SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_INIT, + ("Base address Low: %08lX\n", pLETab->pPhyLETABLow)); + + /* Set the list base address */ + SK_OUT32(IoC, POLL_LIST_ADDR_LO, pLETab->pPhyLETABLow); + + SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_INIT, + ("Base address High: %08lX\n", pLETab->pPhyLETABHigh)); + + SK_OUT32(IoC, POLL_LIST_ADDR_HI, pLETab->pPhyLETABHigh); + + /* we don't need to write the last index - it is hardwired to 1 */ + + /* enable the prefetch unit */ + SK_OUT32(IoC, POLL_CTRL, PC_POLL_OP_ON); + + /* + * now we have to start the descriptor poll timer because it triggers + * the polling unit + */ + + /* + * still playing with the value (timer runs at 125 MHz) + * descriptor poll timer is enabled by GeInit + */ + SK_OUT32(IoC, B28_DPT_INI, + (SK_DPOLL_DEF_Y2 * (SK_U32)pAC->GIni.GIHstClkFact / 100)); + + SK_OUT8(IoC, B28_DPT_CTRL, TIM_START); + + SK_DBG_MSG(pAC, SK_DBGMOD_HWM, SK_DBGCAT_INIT, + ("<== SkGeY2InitPollUnit()\n")); +} /* SkGeY2InitPollUnit */ +#endif /* USE_POLLING_UNIT */ + + +/****************************************************************************** + * + * SkGeY2SetPutIndex + * + * Description: + * This function is writing the Done index of a transmit + * list element table. + * + * Notes: + * Dev. Issue 4.2 + * + * Returns: N/A + */ +void SkGeY2SetPutIndex( +SK_AC *pAC, /* pointer to adapter context */ +SK_IOC IoC, /* pointer to the IO context */ +SK_U32 StartAddrPrefetchUnit, /* start address of the prefetch unit */ +SK_LE_TABLE *pLETab) /* list element table to work with */ +{ + unsigned int Put; + SK_U16 EndOfListIndex; + SK_U16 HwGetIndex; + SK_U16 HwPutIndex; + + /* set put index we would like to write */ + Put = GET_PUT_IDX(pLETab); + + /* + * in this case we wrap around + * new put is lower than last put given to hw + */ + if (Put < pLETab->HwPut) { + + /* set put index = last index of list */ + EndOfListIndex = (NUM_LE_IN_TABLE(pLETab)-1); + + /* read get index of hw prefetch unit */ + SK_IN16(IoC, (StartAddrPrefetchUnit + PREF_UNIT_GET_IDX_REG), + &HwGetIndex); + + /* read put index of hw prefetch unit */ + SK_IN16(IoC, (StartAddrPrefetchUnit + PREF_UNIT_PUT_IDX_REG), + &HwPutIndex); + + /* prefetch unit reached end of list */ + /* prefetch unit reached first list element */ + if (HwGetIndex == 0) { + /* restore watermark */ + SK_OUT8(IoC, StartAddrPrefetchUnit + PREF_UNIT_FIFO_WM_REG, 0xe0U); + /* write put index */ + SK_OUT16(IoC, StartAddrPrefetchUnit + PREF_UNIT_PUT_IDX_REG, + (SK_U16)Put); + + /* remember put index we wrote to hw */ + pLETab->HwPut = Put; + } + else if (HwGetIndex == EndOfListIndex) { + /* set watermark to one list element */ + SK_OUT8(IoC, StartAddrPrefetchUnit + PREF_UNIT_FIFO_WM_REG, 8); + /* set put index to first list element */ + SK_OUT16(IoC, StartAddrPrefetchUnit + PREF_UNIT_PUT_IDX_REG, 0); + } + /* prefetch unit did not reach end of list yet */ + /* and we did not write put index to end of list yet */ + else if ((HwPutIndex != EndOfListIndex) && + (HwGetIndex != EndOfListIndex)) { + /* write put index */ + SK_OUT16(IoC, StartAddrPrefetchUnit + PREF_UNIT_PUT_IDX_REG, + EndOfListIndex); + } + else { + /* do nothing */ + } + } + else { +#ifdef XXX /* leads in to problems in the Windows Driver */ + if (Put != pLETab->HwPut) { + /* write put index */ + SK_OUT16(IoC, StartAddrPrefetchUnit + PREF_UNIT_PUT_IDX_REG, + (SK_U16)Put); + /* update put index */ + UPDATE_HWPUT_IDX(pLETab); + } +#else + /* write put index */ + SK_OUT16(IoC, StartAddrPrefetchUnit + PREF_UNIT_PUT_IDX_REG, + (SK_U16)Put); + /* update put index */ + UPDATE_HWPUT_IDX(pLETab); +#endif + } +} /* SkGeY2SetPutIndex */ +