[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Message-ID: <20260123033233.16906-1-enelsonmoore@gmail.com>
Date: Thu, 22 Jan 2026 19:30:41 -0800
From: Ethan Nelson-Moore <enelsonmoore@...il.com>
To: netdev@...r.kernel.org,
linux-doc@...r.kernel.org,
linux-pci@...r.kernel.org,
linux-mips@...r.kernel.org,
linux-s390@...r.kernel.org,
rust-for-linux@...r.kernel.org
Cc: Jon Mason <jdmason@...zu.us>,
Ethan Nelson-Moore <enelsonmoore@...il.com>,
Jonathan Corbet <corbet@....net>,
Linas Vepstas <linasvepstas@...il.com>,
Mahesh J Salgaonkar <mahesh@...ux.ibm.com>,
"Oliver O'Halloran" <oohall@...il.com>,
Bjorn Helgaas <bhelgaas@...gle.com>,
"David S. Miller" <davem@...emloft.net>,
Eric Dumazet <edumazet@...gle.com>,
Jakub Kicinski <kuba@...nel.org>,
Paolo Abeni <pabeni@...hat.com>,
Simon Horman <horms@...nel.org>,
Thomas Bogendoerfer <tsbogend@...ha.franken.de>,
Madhavan Srinivasan <maddy@...ux.ibm.com>,
Michael Ellerman <mpe@...erman.id.au>,
Nicholas Piggin <npiggin@...il.com>,
"Christophe Leroy (CS GROUP)" <chleroy@...nel.org>,
Heiko Carstens <hca@...ux.ibm.com>,
Vasily Gorbik <gor@...ux.ibm.com>,
Alexander Gordeev <agordeev@...ux.ibm.com>,
Christian Borntraeger <borntraeger@...ux.ibm.com>,
Sven Schnelle <svens@...ux.ibm.com>,
Andrew Lunn <andrew+netdev@...n.ch>,
Danilo Krummrich <dakr@...nel.org>,
Krzysztof Wilczyński <kwilczynski@...nel.org>,
Miguel Ojeda <ojeda@...nel.org>,
Boqun Feng <boqun.feng@...il.com>,
Gary Guo <gary@...yguo.net>,
Björn Roy Baron <bjorn3_gh@...tonmail.com>,
Benno Lossin <lossin@...nel.org>,
Andreas Hindborg <a.hindborg@...nel.org>,
Alice Ryhl <aliceryhl@...gle.com>,
Trevor Gross <tmgross@...ch.edu>,
Andrew Morton <akpm@...ux-foundation.org>,
Martin Kepplinger-Novaković <martink@...teo.de>,
Pavel Machek <pavel@....cz>,
MD Danish Anwar <danishanwar@...com>,
Mengyuan Lou <mengyuanlou@...-swift.com>,
Pablo Neira Ayuso <pablo@...filter.org>,
Huacai Chen <chenhuacai@...nel.org>,
"Theodore Ts'o" <tytso@....edu>,
Takashi Iwai <tiwai@...e.de>,
Eric Biggers <ebiggers@...gle.com>,
Madadi Vineeth Reddy <vineethr@...ux.ibm.com>,
Ard Biesheuvel <ardb@...nel.org>,
"Martin K. Petersen" <martin.petersen@...cle.com>,
Frederic Barrat <fbarrat@...ux.ibm.com>,
Andrew Donnellan <ajd@...ux.ibm.com>,
Herbert Xu <herbert@...dor.apana.org.au>,
Vadim Fedorenko <vadim.fedorenko@...ux.dev>,
Lorenzo Bianconi <lorenzo@...nel.org>,
Dong Yibo <dong100@...se.com>,
Lukas Bulwahn <lukas.bulwahn@...hat.com>,
Vivian Wang <wangruikang@...as.ac.cn>,
Thomas Gleixner <tglx@...nel.org>,
Ingo Molnar <mingo@...nel.org>
Subject: [PATCH net-next] net: ethernet: neterion: s2io: remove unused driver
The s2io driver supports Exar (formerly Neterion) PCI-X 10 Gigabit
Ethernet cards. Hardware supporting PCI-X has not been manufactured
in years. On x86, it was quickly replaced by PCIe. While it stuck around
longer on POWER hardware, the last POWER hardware to support it was
POWER7, which is not supported by ppc64le Linux distributions. The last
supported mainstream ppc64 Linux distribution was RHEL 7; while it is
still supported under ELS, ELS is only available for x86 and IBM Z. It
is possible to use many PCI-X cards in standard PCI slots (which are
still available on new motherboards), but it does not make sense to do
so for 10 Gigabit Ethernet because the maximum bandwidth of standard
PCI is only 1067 Mbps. It is therefore highly unlikely that this driver
is still being used. Remove the driver, and move the former maintainer
to the CREDITS file (restoring credit for the vxge driver, which was
removed in commit f05643a0f60b ("eth: remove neterion/vxge").
Signed-off-by: Ethan Nelson-Moore <enelsonmoore@...il.com>
---
CREDITS | 4 +
Documentation/.renames.txt | 1 -
Documentation/PCI/pci-error-recovery.rst | 1 -
.../device_drivers/ethernet/index.rst | 1 -
.../device_drivers/ethernet/neterion/s2io.rst | 196 -
MAINTAINERS | 7 -
arch/mips/configs/loongson2k_defconfig | 1 -
arch/mips/configs/mtx1_defconfig | 1 -
arch/powerpc/configs/powernv_defconfig | 1 -
arch/powerpc/configs/ppc64_defconfig | 1 -
arch/powerpc/configs/ppc6xx_defconfig | 1 -
arch/powerpc/configs/skiroot_defconfig | 1 -
arch/s390/configs/debug_defconfig | 1 -
arch/s390/configs/defconfig | 1 -
drivers/net/ethernet/Kconfig | 1 -
drivers/net/ethernet/Makefile | 1 -
drivers/net/ethernet/neterion/Kconfig | 35 -
drivers/net/ethernet/neterion/Makefile | 6 -
drivers/net/ethernet/neterion/s2io-regs.h | 958 --
drivers/net/ethernet/neterion/s2io.c | 8572 -----------------
drivers/net/ethernet/neterion/s2io.h | 1124 ---
include/linux/pci_ids.h | 6 -
rust/kernel/pci/id.rs | 1 -
23 files changed, 4 insertions(+), 10918 deletions(-)
delete mode 100644 Documentation/networking/device_drivers/ethernet/neterion/s2io.rst
delete mode 100644 drivers/net/ethernet/neterion/Kconfig
delete mode 100644 drivers/net/ethernet/neterion/Makefile
delete mode 100644 drivers/net/ethernet/neterion/s2io-regs.h
delete mode 100644 drivers/net/ethernet/neterion/s2io.c
delete mode 100644 drivers/net/ethernet/neterion/s2io.h
diff --git a/CREDITS b/CREDITS
index 680bc55024a9..04ffe036828c 100644
--- a/CREDITS
+++ b/CREDITS
@@ -2659,6 +2659,10 @@ S: 3404 E. Harmony Road
S: Fort Collins, CO 80528
S: USA
+N: Jon Mason
+E: jdmason@...zu.us
+D: Neterion 10GbE drivers (s2io/vxge)
+
N: Torben Mathiasen
E: torben.mathiasen@...paq.com
E: torben@...nel.dk
diff --git a/Documentation/.renames.txt b/Documentation/.renames.txt
index c0bd5d3dc8b9..a37d68471d50 100644
--- a/Documentation/.renames.txt
+++ b/Documentation/.renames.txt
@@ -819,7 +819,6 @@ networking/device_drivers/intel/ixgbe networking/device_drivers/ethernet/intel/i
networking/device_drivers/intel/ixgbevf networking/device_drivers/ethernet/intel/ixgbevf
networking/device_drivers/marvell/octeontx2 networking/device_drivers/ethernet/marvell/octeontx2
networking/device_drivers/microsoft/netvsc networking/device_drivers/ethernet/microsoft/netvsc
-networking/device_drivers/neterion/s2io networking/device_drivers/ethernet/neterion/s2io
networking/device_drivers/netronome/nfp networking/device_drivers/ethernet/netronome/nfp
networking/device_drivers/pensando/ionic networking/device_drivers/ethernet/pensando/ionic
networking/device_drivers/qualcomm/rmnet networking/device_drivers/cellular/qualcomm/rmnet
diff --git a/Documentation/PCI/pci-error-recovery.rst b/Documentation/PCI/pci-error-recovery.rst
index 43bc4e3665b4..43838723fde9 100644
--- a/Documentation/PCI/pci-error-recovery.rst
+++ b/Documentation/PCI/pci-error-recovery.rst
@@ -460,7 +460,6 @@ That is, the recovery API only requires that:
- drivers/net/e1000e
- drivers/net/ixgbe
- drivers/net/cxgb3
- - drivers/net/s2io.c
The cor_error_detected() callback is invoked in handle_error_source() when
the error severity is "correctable". The callback is optional and allows
diff --git a/Documentation/networking/device_drivers/ethernet/index.rst b/Documentation/networking/device_drivers/ethernet/index.rst
index bcc02355f828..5e8fc3d6d741 100644
--- a/Documentation/networking/device_drivers/ethernet/index.rst
+++ b/Documentation/networking/device_drivers/ethernet/index.rst
@@ -48,7 +48,6 @@ Contents:
meta/fbnic
microsoft/netvsc
mucse/rnpgbe
- neterion/s2io
netronome/nfp
pensando/ionic
pensando/ionic_rdma
diff --git a/Documentation/networking/device_drivers/ethernet/neterion/s2io.rst b/Documentation/networking/device_drivers/ethernet/neterion/s2io.rst
deleted file mode 100644
index d731b5a98561..000000000000
--- a/Documentation/networking/device_drivers/ethernet/neterion/s2io.rst
+++ /dev/null
@@ -1,196 +0,0 @@
-.. SPDX-License-Identifier: GPL-2.0
-
-=========================================================
-Neterion's (Formerly S2io) Xframe I/II PCI-X 10GbE driver
-=========================================================
-
-Release notes for Neterion's (Formerly S2io) Xframe I/II PCI-X 10GbE driver.
-
-.. Contents
- - 1. Introduction
- - 2. Identifying the adapter/interface
- - 3. Features supported
- - 4. Command line parameters
- - 5. Performance suggestions
- - 6. Available Downloads
-
-
-1. Introduction
-===============
-This Linux driver supports Neterion's Xframe I PCI-X 1.0 and
-Xframe II PCI-X 2.0 adapters. It supports several features
-such as jumbo frames, MSI/MSI-X, checksum offloads, TSO, UFO and so on.
-See below for complete list of features.
-
-All features are supported for both IPv4 and IPv6.
-
-2. Identifying the adapter/interface
-====================================
-
-a. Insert the adapter(s) in your system.
-b. Build and load driver::
-
- # insmod s2io.ko
-
-c. View log messages::
-
- # dmesg | tail -40
-
-You will see messages similar to::
-
- eth3: Neterion Xframe I 10GbE adapter (rev 3), Version 2.0.9.1, Intr type INTA
- eth4: Neterion Xframe II 10GbE adapter (rev 2), Version 2.0.9.1, Intr type INTA
- eth4: Device is on 64 bit 133MHz PCIX(M1) bus
-
-The above messages identify the adapter type(Xframe I/II), adapter revision,
-driver version, interface name(eth3, eth4), Interrupt type(INTA, MSI, MSI-X).
-In case of Xframe II, the PCI/PCI-X bus width and frequency are displayed
-as well.
-
-To associate an interface with a physical adapter use "ethtool -p <ethX>".
-The corresponding adapter's LED will blink multiple times.
-
-3. Features supported
-=====================
-a. Jumbo frames. Xframe I/II supports MTU up to 9600 bytes,
- modifiable using ip command.
-
-b. Offloads. Supports checksum offload(TCP/UDP/IP) on transmit
- and receive, TSO.
-
-c. Multi-buffer receive mode. Scattering of packet across multiple
- buffers. Currently driver supports 2-buffer mode which yields
- significant performance improvement on certain platforms(SGI Altix,
- IBM xSeries).
-
-d. MSI/MSI-X. Can be enabled on platforms which support this feature
- resulting in noticeable performance improvement (up to 7% on certain
- platforms).
-
-e. Statistics. Comprehensive MAC-level and software statistics displayed
- using "ethtool -S" option.
-
-f. Multi-FIFO/Ring. Supports up to 8 transmit queues and receive rings,
- with multiple steering options.
-
-4. Command line parameters
-==========================
-
-a. tx_fifo_num
- Number of transmit queues
-
-Valid range: 1-8
-
-Default: 1
-
-b. rx_ring_num
- Number of receive rings
-
-Valid range: 1-8
-
-Default: 1
-
-c. tx_fifo_len
- Size of each transmit queue
-
-Valid range: Total length of all queues should not exceed 8192
-
-Default: 4096
-
-d. rx_ring_sz
- Size of each receive ring(in 4K blocks)
-
-Valid range: Limited by memory on system
-
-Default: 30
-
-e. intr_type
- Specifies interrupt type. Possible values 0(INTA), 2(MSI-X)
-
-Valid values: 0, 2
-
-Default: 2
-
-5. Performance suggestions
-==========================
-
-General:
-
-a. Set MTU to maximum(9000 for switch setup, 9600 in back-to-back configuration)
-b. Set TCP windows size to optimal value.
-
-For instance, for MTU=1500 a value of 210K has been observed to result in
-good performance::
-
- # sysctl -w net.ipv4.tcp_rmem="210000 210000 210000"
- # sysctl -w net.ipv4.tcp_wmem="210000 210000 210000"
-
-For MTU=9000, TCP window size of 10 MB is recommended::
-
- # sysctl -w net.ipv4.tcp_rmem="10000000 10000000 10000000"
- # sysctl -w net.ipv4.tcp_wmem="10000000 10000000 10000000"
-
-Transmit performance:
-
-a. By default, the driver respects BIOS settings for PCI bus parameters.
- However, you may want to experiment with PCI bus parameters
- max-split-transactions(MOST) and MMRBC (use setpci command).
-
- A MOST value of 2 has been found optimal for Opterons and 3 for Itanium.
-
- It could be different for your hardware.
-
- Set MMRBC to 4K**.
-
- For example you can set
-
- For opteron::
-
- #setpci -d 17d5:* 62=1d
-
- For Itanium::
-
- #setpci -d 17d5:* 62=3d
-
- For detailed description of the PCI registers, please see Xframe User Guide.
-
-b. Ensure Transmit Checksum offload is enabled. Use ethtool to set/verify this
- parameter.
-
-c. Turn on TSO(using "ethtool -K")::
-
- # ethtool -K <ethX> tso on
-
-Receive performance:
-
-a. By default, the driver respects BIOS settings for PCI bus parameters.
- However, you may want to set PCI latency timer to 248::
-
- #setpci -d 17d5:* LATENCY_TIMER=f8
-
- For detailed description of the PCI registers, please see Xframe User Guide.
-
-b. Use 2-buffer mode. This results in large performance boost on
- certain platforms(eg. SGI Altix, IBM xSeries).
-
-c. Ensure Receive Checksum offload is enabled. Use "ethtool -K ethX" command to
- set/verify this option.
-
-d. Enable NAPI feature(in kernel configuration Device Drivers ---> Network
- device support ---> Ethernet (10000 Mbit) ---> S2IO 10Gbe Xframe NIC) to
- bring down CPU utilization.
-
-.. note::
-
- For AMD opteron platforms with 8131 chipset, MMRBC=1 and MOST=1 are
- recommended as safe parameters.
-
-For more information, please review the AMD8131 errata at
-http://vip.amd.com/us-en/assets/content_type/white_papers_and_tech_docs/
-26310_AMD-8131_HyperTransport_PCI-X_Tunnel_Revision_Guide_rev_3_18.pdf
-
-6. Support
-==========
-
-For further support please contact either your 10GbE Xframe NIC vendor (IBM,
-HP, SGI etc.)
diff --git a/MAINTAINERS b/MAINTAINERS
index 92768bceb929..0a0b0edbf071 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -18030,13 +18030,6 @@ L: netdev@...r.kernel.org
S: Maintained
F: net/sched/sch_netem.c
-NETERION 10GbE DRIVERS (s2io)
-M: Jon Mason <jdmason@...zu.us>
-L: netdev@...r.kernel.org
-S: Maintained
-F: Documentation/networking/device_drivers/ethernet/neterion/s2io.rst
-F: drivers/net/ethernet/neterion/
-
NETFILTER
M: Pablo Neira Ayuso <pablo@...filter.org>
M: Florian Westphal <fw@...len.de>
diff --git a/arch/mips/configs/loongson2k_defconfig b/arch/mips/configs/loongson2k_defconfig
index aec1fd1902eb..a5c50b63d478 100644
--- a/arch/mips/configs/loongson2k_defconfig
+++ b/arch/mips/configs/loongson2k_defconfig
@@ -161,7 +161,6 @@ CONFIG_IXGBE=y
# CONFIG_NET_VENDOR_MICROSEMI is not set
# CONFIG_NET_VENDOR_MYRI is not set
# CONFIG_NET_VENDOR_NATSEMI is not set
-# CONFIG_NET_VENDOR_NETERION is not set
# CONFIG_NET_VENDOR_NETRONOME is not set
# CONFIG_NET_VENDOR_NI is not set
# CONFIG_NET_VENDOR_NVIDIA is not set
diff --git a/arch/mips/configs/mtx1_defconfig b/arch/mips/configs/mtx1_defconfig
index 49dee536009f..77050ae3945f 100644
--- a/arch/mips/configs/mtx1_defconfig
+++ b/arch/mips/configs/mtx1_defconfig
@@ -283,7 +283,6 @@ CONFIG_MYRI10GE=m
CONFIG_FEALNX=m
CONFIG_NATSEMI=m
CONFIG_NS83820=m
-CONFIG_S2IO=m
CONFIG_PCMCIA_AXNET=m
CONFIG_NE2K_PCI=m
CONFIG_PCMCIA_PCNET=m
diff --git a/arch/powerpc/configs/powernv_defconfig b/arch/powerpc/configs/powernv_defconfig
index bd4685612de6..9ac746cfb4be 100644
--- a/arch/powerpc/configs/powernv_defconfig
+++ b/arch/powerpc/configs/powernv_defconfig
@@ -166,7 +166,6 @@ CONFIG_BNX2X=m
# CONFIG_CAVIUM_PTP is not set
CONFIG_CHELSIO_T1=m
CONFIG_BE2NET=m
-CONFIG_S2IO=m
CONFIG_E100=y
CONFIG_E1000=y
CONFIG_E1000E=y
diff --git a/arch/powerpc/configs/ppc64_defconfig b/arch/powerpc/configs/ppc64_defconfig
index 2d92c11eea7e..f0d9b55cb26b 100644
--- a/arch/powerpc/configs/ppc64_defconfig
+++ b/arch/powerpc/configs/ppc64_defconfig
@@ -221,7 +221,6 @@ CONFIG_IXGBE=m
CONFIG_I40E=m
CONFIG_MLX4_EN=m
CONFIG_MYRI10GE=m
-CONFIG_S2IO=m
CONFIG_PASEMI_MAC=y
CONFIG_NETXEN_NIC=m
CONFIG_SUNGEM=y
diff --git a/arch/powerpc/configs/ppc6xx_defconfig b/arch/powerpc/configs/ppc6xx_defconfig
index 787d707f64a4..3c08f46f3d41 100644
--- a/arch/powerpc/configs/ppc6xx_defconfig
+++ b/arch/powerpc/configs/ppc6xx_defconfig
@@ -434,7 +434,6 @@ CONFIG_ULI526X=m
CONFIG_PCMCIA_XIRCOM=m
CONFIG_DL2K=m
CONFIG_SUNDANCE=m
-CONFIG_S2IO=m
CONFIG_FEC_MPC52xx=m
CONFIG_GIANFAR=m
CONFIG_PCMCIA_FMVJ18X=m
diff --git a/arch/powerpc/configs/skiroot_defconfig b/arch/powerpc/configs/skiroot_defconfig
index 2b71a6dc399e..f3d17a02659f 100644
--- a/arch/powerpc/configs/skiroot_defconfig
+++ b/arch/powerpc/configs/skiroot_defconfig
@@ -160,7 +160,6 @@ CONFIG_MLX5_CORE_EN=y
# CONFIG_NET_VENDOR_MICROSEMI is not set
CONFIG_MYRI10GE=m
# CONFIG_NET_VENDOR_NATSEMI is not set
-CONFIG_S2IO=m
# CONFIG_NET_VENDOR_NETRONOME is not set
# CONFIG_NET_VENDOR_NI is not set
# CONFIG_NET_VENDOR_NVIDIA is not set
diff --git a/arch/s390/configs/debug_defconfig b/arch/s390/configs/debug_defconfig
index 0713914b25b4..0973b830c868 100644
--- a/arch/s390/configs/debug_defconfig
+++ b/arch/s390/configs/debug_defconfig
@@ -560,7 +560,6 @@ CONFIG_MLX5_SF=y
# CONFIG_NET_VENDOR_MYRI is not set
# CONFIG_NET_VENDOR_NI is not set
# CONFIG_NET_VENDOR_NATSEMI is not set
-# CONFIG_NET_VENDOR_NETERION is not set
# CONFIG_NET_VENDOR_NETRONOME is not set
# CONFIG_NET_VENDOR_NVIDIA is not set
# CONFIG_NET_VENDOR_OKI is not set
diff --git a/arch/s390/configs/defconfig b/arch/s390/configs/defconfig
index c064e0cacc98..54ff5faf3541 100644
--- a/arch/s390/configs/defconfig
+++ b/arch/s390/configs/defconfig
@@ -550,7 +550,6 @@ CONFIG_MLX5_SF=y
# CONFIG_NET_VENDOR_MYRI is not set
# CONFIG_NET_VENDOR_NI is not set
# CONFIG_NET_VENDOR_NATSEMI is not set
-# CONFIG_NET_VENDOR_NETERION is not set
# CONFIG_NET_VENDOR_NETRONOME is not set
# CONFIG_NET_VENDOR_NVIDIA is not set
# CONFIG_NET_VENDOR_OKI is not set
diff --git a/drivers/net/ethernet/Kconfig b/drivers/net/ethernet/Kconfig
index 678beefe314a..aa7103e7f47f 100644
--- a/drivers/net/ethernet/Kconfig
+++ b/drivers/net/ethernet/Kconfig
@@ -131,7 +131,6 @@ config FEALNX
source "drivers/net/ethernet/ni/Kconfig"
source "drivers/net/ethernet/natsemi/Kconfig"
-source "drivers/net/ethernet/neterion/Kconfig"
source "drivers/net/ethernet/netronome/Kconfig"
source "drivers/net/ethernet/8390/Kconfig"
source "drivers/net/ethernet/nvidia/Kconfig"
diff --git a/drivers/net/ethernet/Makefile b/drivers/net/ethernet/Makefile
index c9922628d8d6..6615a67a63d5 100644
--- a/drivers/net/ethernet/Makefile
+++ b/drivers/net/ethernet/Makefile
@@ -68,7 +68,6 @@ obj-$(CONFIG_NET_VENDOR_MUCSE) += mucse/
obj-$(CONFIG_NET_VENDOR_MYRI) += myricom/
obj-$(CONFIG_FEALNX) += fealnx.o
obj-$(CONFIG_NET_VENDOR_NATSEMI) += natsemi/
-obj-$(CONFIG_NET_VENDOR_NETERION) += neterion/
obj-$(CONFIG_NET_VENDOR_NETRONOME) += netronome/
obj-$(CONFIG_NET_VENDOR_NI) += ni/
obj-$(CONFIG_NET_VENDOR_NVIDIA) += nvidia/
diff --git a/drivers/net/ethernet/neterion/Kconfig b/drivers/net/ethernet/neterion/Kconfig
deleted file mode 100644
index 09a89e72f904..000000000000
--- a/drivers/net/ethernet/neterion/Kconfig
+++ /dev/null
@@ -1,35 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0-only
-#
-# Exar device configuration
-#
-
-config NET_VENDOR_NETERION
- bool "Neterion (Exar) devices"
- default y
- depends on PCI
- help
- If you have a network (Ethernet) card belonging to this class, say Y.
-
- Note that the answer to this question doesn't directly affect the
- kernel: saying N will just cause the configurator to skip all
- the questions about Neterion/Exar cards. If you say Y, you will be
- asked for your specific card in the following questions.
-
-if NET_VENDOR_NETERION
-
-config S2IO
- tristate "Neterion (Exar) Xframe 10Gb Ethernet Adapter"
- depends on PCI
- help
- This driver supports Exar Corp's Xframe Series 10Gb Ethernet Adapters.
- These were originally released from S2IO, which renamed itself
- Neterion. So, the adapters might be labeled as either one, depending
- on its age.
-
- More specific information on configuring the driver is in
- <file:Documentation/networking/device_drivers/ethernet/neterion/s2io.rst>.
-
- To compile this driver as a module, choose M here. The module
- will be called s2io.
-
-endif # NET_VENDOR_NETERION
diff --git a/drivers/net/ethernet/neterion/Makefile b/drivers/net/ethernet/neterion/Makefile
deleted file mode 100644
index de98b4e6eff9..000000000000
--- a/drivers/net/ethernet/neterion/Makefile
+++ /dev/null
@@ -1,6 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0-only
-#
-# Makefile for the Exar network device drivers.
-#
-
-obj-$(CONFIG_S2IO) += s2io.o
diff --git a/drivers/net/ethernet/neterion/s2io-regs.h b/drivers/net/ethernet/neterion/s2io-regs.h
deleted file mode 100644
index 3688325c11f5..000000000000
--- a/drivers/net/ethernet/neterion/s2io-regs.h
+++ /dev/null
@@ -1,958 +0,0 @@
-/************************************************************************
- * regs.h: A Linux PCI-X Ethernet driver for Neterion 10GbE Server NIC
- * Copyright(c) 2002-2010 Exar Corp.
-
- * This software may be used and distributed according to the terms of
- * the GNU General Public License (GPL), incorporated herein by reference.
- * Drivers based on or derived from this code fall under the GPL and must
- * retain the authorship, copyright and license notice. This file is not
- * a complete program and may only be used when the entire operating
- * system is licensed under the GPL.
- * See the file COPYING in this distribution for more information.
- ************************************************************************/
-#ifndef _REGS_H
-#define _REGS_H
-
-#define TBD 0
-
-struct XENA_dev_config {
-/* Convention: mHAL_XXX is mask, vHAL_XXX is value */
-
-/* General Control-Status Registers */
- u64 general_int_status;
-#define GEN_INTR_TXPIC s2BIT(0)
-#define GEN_INTR_TXDMA s2BIT(1)
-#define GEN_INTR_TXMAC s2BIT(2)
-#define GEN_INTR_TXXGXS s2BIT(3)
-#define GEN_INTR_TXTRAFFIC s2BIT(8)
-#define GEN_INTR_RXPIC s2BIT(32)
-#define GEN_INTR_RXDMA s2BIT(33)
-#define GEN_INTR_RXMAC s2BIT(34)
-#define GEN_INTR_MC s2BIT(35)
-#define GEN_INTR_RXXGXS s2BIT(36)
-#define GEN_INTR_RXTRAFFIC s2BIT(40)
-#define GEN_ERROR_INTR GEN_INTR_TXPIC | GEN_INTR_RXPIC | \
- GEN_INTR_TXDMA | GEN_INTR_RXDMA | \
- GEN_INTR_TXMAC | GEN_INTR_RXMAC | \
- GEN_INTR_TXXGXS| GEN_INTR_RXXGXS| \
- GEN_INTR_MC
-
- u64 general_int_mask;
-
- u8 unused0[0x100 - 0x10];
-
- u64 sw_reset;
-/* XGXS must be removed from reset only once. */
-#define SW_RESET_XENA vBIT(0xA5,0,8)
-#define SW_RESET_FLASH vBIT(0xA5,8,8)
-#define SW_RESET_EOI vBIT(0xA5,16,8)
-#define SW_RESET_ALL (SW_RESET_XENA | \
- SW_RESET_FLASH | \
- SW_RESET_EOI)
-/* The SW_RESET register must read this value after a successful reset. */
-#define SW_RESET_RAW_VAL 0xA5000000
-
-
- u64 adapter_status;
-#define ADAPTER_STATUS_TDMA_READY s2BIT(0)
-#define ADAPTER_STATUS_RDMA_READY s2BIT(1)
-#define ADAPTER_STATUS_PFC_READY s2BIT(2)
-#define ADAPTER_STATUS_TMAC_BUF_EMPTY s2BIT(3)
-#define ADAPTER_STATUS_PIC_QUIESCENT s2BIT(5)
-#define ADAPTER_STATUS_RMAC_REMOTE_FAULT s2BIT(6)
-#define ADAPTER_STATUS_RMAC_LOCAL_FAULT s2BIT(7)
-#define ADAPTER_STATUS_RMAC_PCC_IDLE vBIT(0xFF,8,8)
-#define ADAPTER_STATUS_RMAC_PCC_FOUR_IDLE vBIT(0x0F,8,8)
-#define ADAPTER_STATUS_RC_PRC_QUIESCENT vBIT(0xFF,16,8)
-#define ADAPTER_STATUS_MC_DRAM_READY s2BIT(24)
-#define ADAPTER_STATUS_MC_QUEUES_READY s2BIT(25)
-#define ADAPTER_STATUS_RIC_RUNNING s2BIT(26)
-#define ADAPTER_STATUS_M_PLL_LOCK s2BIT(30)
-#define ADAPTER_STATUS_P_PLL_LOCK s2BIT(31)
-
- u64 adapter_control;
-#define ADAPTER_CNTL_EN s2BIT(7)
-#define ADAPTER_EOI_TX_ON s2BIT(15)
-#define ADAPTER_LED_ON s2BIT(23)
-#define ADAPTER_UDPI(val) vBIT(val,36,4)
-#define ADAPTER_WAIT_INT s2BIT(48)
-#define ADAPTER_ECC_EN s2BIT(55)
-
- u64 serr_source;
-#define SERR_SOURCE_PIC s2BIT(0)
-#define SERR_SOURCE_TXDMA s2BIT(1)
-#define SERR_SOURCE_RXDMA s2BIT(2)
-#define SERR_SOURCE_MAC s2BIT(3)
-#define SERR_SOURCE_MC s2BIT(4)
-#define SERR_SOURCE_XGXS s2BIT(5)
-#define SERR_SOURCE_ANY (SERR_SOURCE_PIC | \
- SERR_SOURCE_TXDMA | \
- SERR_SOURCE_RXDMA | \
- SERR_SOURCE_MAC | \
- SERR_SOURCE_MC | \
- SERR_SOURCE_XGXS)
-
- u64 pci_mode;
-#define GET_PCI_MODE(val) ((val & vBIT(0xF, 0, 4)) >> 60)
-#define PCI_MODE_PCI_33 0
-#define PCI_MODE_PCI_66 0x1
-#define PCI_MODE_PCIX_M1_66 0x2
-#define PCI_MODE_PCIX_M1_100 0x3
-#define PCI_MODE_PCIX_M1_133 0x4
-#define PCI_MODE_PCIX_M2_66 0x5
-#define PCI_MODE_PCIX_M2_100 0x6
-#define PCI_MODE_PCIX_M2_133 0x7
-#define PCI_MODE_UNSUPPORTED s2BIT(0)
-#define PCI_MODE_32_BITS s2BIT(8)
-#define PCI_MODE_UNKNOWN_MODE s2BIT(9)
-
- u8 unused_0[0x800 - 0x128];
-
-/* PCI-X Controller registers */
- u64 pic_int_status;
- u64 pic_int_mask;
-#define PIC_INT_TX s2BIT(0)
-#define PIC_INT_FLSH s2BIT(1)
-#define PIC_INT_MDIO s2BIT(2)
-#define PIC_INT_IIC s2BIT(3)
-#define PIC_INT_GPIO s2BIT(4)
-#define PIC_INT_RX s2BIT(32)
-
- u64 txpic_int_reg;
- u64 txpic_int_mask;
-#define PCIX_INT_REG_ECC_SG_ERR s2BIT(0)
-#define PCIX_INT_REG_ECC_DB_ERR s2BIT(1)
-#define PCIX_INT_REG_FLASHR_R_FSM_ERR s2BIT(8)
-#define PCIX_INT_REG_FLASHR_W_FSM_ERR s2BIT(9)
-#define PCIX_INT_REG_INI_TX_FSM_SERR s2BIT(10)
-#define PCIX_INT_REG_INI_TXO_FSM_ERR s2BIT(11)
-#define PCIX_INT_REG_TRT_FSM_SERR s2BIT(13)
-#define PCIX_INT_REG_SRT_FSM_SERR s2BIT(14)
-#define PCIX_INT_REG_PIFR_FSM_SERR s2BIT(15)
-#define PCIX_INT_REG_WRC_TX_SEND_FSM_SERR s2BIT(21)
-#define PCIX_INT_REG_RRC_TX_REQ_FSM_SERR s2BIT(23)
-#define PCIX_INT_REG_INI_RX_FSM_SERR s2BIT(48)
-#define PCIX_INT_REG_RA_RX_FSM_SERR s2BIT(50)
-/*
-#define PCIX_INT_REG_WRC_RX_SEND_FSM_SERR s2BIT(52)
-#define PCIX_INT_REG_RRC_RX_REQ_FSM_SERR s2BIT(54)
-#define PCIX_INT_REG_RRC_RX_SPLIT_FSM_SERR s2BIT(58)
-*/
- u64 txpic_alarms;
- u64 rxpic_int_reg;
- u64 rxpic_int_mask;
- u64 rxpic_alarms;
-
- u64 flsh_int_reg;
- u64 flsh_int_mask;
-#define PIC_FLSH_INT_REG_CYCLE_FSM_ERR s2BIT(63)
-#define PIC_FLSH_INT_REG_ERR s2BIT(62)
- u64 flash_alarms;
-
- u64 mdio_int_reg;
- u64 mdio_int_mask;
-#define MDIO_INT_REG_MDIO_BUS_ERR s2BIT(0)
-#define MDIO_INT_REG_DTX_BUS_ERR s2BIT(8)
-#define MDIO_INT_REG_LASI s2BIT(39)
- u64 mdio_alarms;
-
- u64 iic_int_reg;
- u64 iic_int_mask;
-#define IIC_INT_REG_BUS_FSM_ERR s2BIT(4)
-#define IIC_INT_REG_BIT_FSM_ERR s2BIT(5)
-#define IIC_INT_REG_CYCLE_FSM_ERR s2BIT(6)
-#define IIC_INT_REG_REQ_FSM_ERR s2BIT(7)
-#define IIC_INT_REG_ACK_ERR s2BIT(8)
- u64 iic_alarms;
-
- u8 unused4[0x08];
-
- u64 gpio_int_reg;
-#define GPIO_INT_REG_DP_ERR_INT s2BIT(0)
-#define GPIO_INT_REG_LINK_DOWN s2BIT(1)
-#define GPIO_INT_REG_LINK_UP s2BIT(2)
- u64 gpio_int_mask;
-#define GPIO_INT_MASK_LINK_DOWN s2BIT(1)
-#define GPIO_INT_MASK_LINK_UP s2BIT(2)
- u64 gpio_alarms;
-
- u8 unused5[0x38];
-
- u64 tx_traffic_int;
-#define TX_TRAFFIC_INT_n(n) s2BIT(n)
- u64 tx_traffic_mask;
-
- u64 rx_traffic_int;
-#define RX_TRAFFIC_INT_n(n) s2BIT(n)
- u64 rx_traffic_mask;
-
-/* PIC Control registers */
- u64 pic_control;
-#define PIC_CNTL_RX_ALARM_MAP_1 s2BIT(0)
-#define PIC_CNTL_SHARED_SPLITS(n) vBIT(n,11,5)
-
- u64 swapper_ctrl;
-#define SWAPPER_CTRL_PIF_R_FE s2BIT(0)
-#define SWAPPER_CTRL_PIF_R_SE s2BIT(1)
-#define SWAPPER_CTRL_PIF_W_FE s2BIT(8)
-#define SWAPPER_CTRL_PIF_W_SE s2BIT(9)
-#define SWAPPER_CTRL_TXP_FE s2BIT(16)
-#define SWAPPER_CTRL_TXP_SE s2BIT(17)
-#define SWAPPER_CTRL_TXD_R_FE s2BIT(18)
-#define SWAPPER_CTRL_TXD_R_SE s2BIT(19)
-#define SWAPPER_CTRL_TXD_W_FE s2BIT(20)
-#define SWAPPER_CTRL_TXD_W_SE s2BIT(21)
-#define SWAPPER_CTRL_TXF_R_FE s2BIT(22)
-#define SWAPPER_CTRL_TXF_R_SE s2BIT(23)
-#define SWAPPER_CTRL_RXD_R_FE s2BIT(32)
-#define SWAPPER_CTRL_RXD_R_SE s2BIT(33)
-#define SWAPPER_CTRL_RXD_W_FE s2BIT(34)
-#define SWAPPER_CTRL_RXD_W_SE s2BIT(35)
-#define SWAPPER_CTRL_RXF_W_FE s2BIT(36)
-#define SWAPPER_CTRL_RXF_W_SE s2BIT(37)
-#define SWAPPER_CTRL_XMSI_FE s2BIT(40)
-#define SWAPPER_CTRL_XMSI_SE s2BIT(41)
-#define SWAPPER_CTRL_STATS_FE s2BIT(48)
-#define SWAPPER_CTRL_STATS_SE s2BIT(49)
-
- u64 pif_rd_swapper_fb;
-#define IF_RD_SWAPPER_FB 0x0123456789ABCDEF
-
- u64 scheduled_int_ctrl;
-#define SCHED_INT_CTRL_TIMER_EN s2BIT(0)
-#define SCHED_INT_CTRL_ONE_SHOT s2BIT(1)
-#define SCHED_INT_CTRL_INT2MSI(val) vBIT(val,10,6)
-#define SCHED_INT_PERIOD TBD
-
- u64 txreqtimeout;
-#define TXREQTO_VAL(val) vBIT(val,0,32)
-#define TXREQTO_EN s2BIT(63)
-
- u64 statsreqtimeout;
-#define STATREQTO_VAL(n) TBD
-#define STATREQTO_EN s2BIT(63)
-
- u64 read_retry_delay;
- u64 read_retry_acceleration;
- u64 write_retry_delay;
- u64 write_retry_acceleration;
-
- u64 xmsi_control;
- u64 xmsi_access;
- u64 xmsi_address;
- u64 xmsi_data;
-
- u64 rx_mat;
-#define RX_MAT_SET(ring, msi) vBIT(msi, (8 * ring), 8)
-
- u8 unused6[0x8];
-
- u64 tx_mat0_n[0x8];
-#define TX_MAT_SET(fifo, msi) vBIT(msi, (8 * fifo), 8)
-
- u64 xmsi_mask_reg;
- u64 stat_byte_cnt;
-#define STAT_BC(n) vBIT(n,4,12)
-
- /* Automated statistics collection */
- u64 stat_cfg;
-#define STAT_CFG_STAT_EN s2BIT(0)
-#define STAT_CFG_ONE_SHOT_EN s2BIT(1)
-#define STAT_CFG_STAT_NS_EN s2BIT(8)
-#define STAT_CFG_STAT_RO s2BIT(9)
-#define STAT_TRSF_PER(n) TBD
-#define PER_SEC 0x208d5
-#define SET_UPDT_PERIOD(n) vBIT((PER_SEC*n),32,32)
-#define SET_UPDT_CLICKS(val) vBIT(val, 32, 32)
-
- u64 stat_addr;
-
- /* General Configuration */
- u64 mdio_control;
-#define MDIO_MMD_INDX_ADDR(val) vBIT(val, 0, 16)
-#define MDIO_MMD_DEV_ADDR(val) vBIT(val, 19, 5)
-#define MDIO_MMS_PRT_ADDR(val) vBIT(val, 27, 5)
-#define MDIO_CTRL_START_TRANS(val) vBIT(val, 56, 4)
-#define MDIO_OP(val) vBIT(val, 60, 2)
-#define MDIO_OP_ADDR_TRANS 0x0
-#define MDIO_OP_WRITE_TRANS 0x1
-#define MDIO_OP_READ_POST_INC_TRANS 0x2
-#define MDIO_OP_READ_TRANS 0x3
-#define MDIO_MDIO_DATA(val) vBIT(val, 32, 16)
-
- u64 dtx_control;
-
- u64 i2c_control;
-#define I2C_CONTROL_DEV_ID(id) vBIT(id,1,3)
-#define I2C_CONTROL_ADDR(addr) vBIT(addr,5,11)
-#define I2C_CONTROL_BYTE_CNT(cnt) vBIT(cnt,22,2)
-#define I2C_CONTROL_READ s2BIT(24)
-#define I2C_CONTROL_NACK s2BIT(25)
-#define I2C_CONTROL_CNTL_START vBIT(0xE,28,4)
-#define I2C_CONTROL_CNTL_END(val) (val & vBIT(0x1,28,4))
-#define I2C_CONTROL_GET_DATA(val) (u32)(val & 0xFFFFFFFF)
-#define I2C_CONTROL_SET_DATA(val) vBIT(val,32,32)
-
- u64 gpio_control;
-#define GPIO_CTRL_GPIO_0 s2BIT(8)
- u64 misc_control;
-#define FAULT_BEHAVIOUR s2BIT(0)
-#define EXT_REQ_EN s2BIT(1)
-#define MISC_LINK_STABILITY_PRD(val) vBIT(val,29,3)
-
- u8 unused7_1[0x230 - 0x208];
-
- u64 pic_control2;
- u64 ini_dperr_ctrl;
-
- u64 wreq_split_mask;
-#define WREQ_SPLIT_MASK_SET_MASK(val) vBIT(val, 52, 12)
-
- u8 unused7_2[0x800 - 0x248];
-
-/* TxDMA registers */
- u64 txdma_int_status;
- u64 txdma_int_mask;
-#define TXDMA_PFC_INT s2BIT(0)
-#define TXDMA_TDA_INT s2BIT(1)
-#define TXDMA_PCC_INT s2BIT(2)
-#define TXDMA_TTI_INT s2BIT(3)
-#define TXDMA_LSO_INT s2BIT(4)
-#define TXDMA_TPA_INT s2BIT(5)
-#define TXDMA_SM_INT s2BIT(6)
- u64 pfc_err_reg;
-#define PFC_ECC_SG_ERR s2BIT(7)
-#define PFC_ECC_DB_ERR s2BIT(15)
-#define PFC_SM_ERR_ALARM s2BIT(23)
-#define PFC_MISC_0_ERR s2BIT(31)
-#define PFC_MISC_1_ERR s2BIT(32)
-#define PFC_PCIX_ERR s2BIT(39)
- u64 pfc_err_mask;
- u64 pfc_err_alarm;
-
- u64 tda_err_reg;
-#define TDA_Fn_ECC_SG_ERR vBIT(0xff,0,8)
-#define TDA_Fn_ECC_DB_ERR vBIT(0xff,8,8)
-#define TDA_SM0_ERR_ALARM s2BIT(22)
-#define TDA_SM1_ERR_ALARM s2BIT(23)
-#define TDA_PCIX_ERR s2BIT(39)
- u64 tda_err_mask;
- u64 tda_err_alarm;
-
- u64 pcc_err_reg;
-#define PCC_FB_ECC_SG_ERR vBIT(0xFF,0,8)
-#define PCC_TXB_ECC_SG_ERR vBIT(0xFF,8,8)
-#define PCC_FB_ECC_DB_ERR vBIT(0xFF,16, 8)
-#define PCC_TXB_ECC_DB_ERR vBIT(0xff,24,8)
-#define PCC_SM_ERR_ALARM vBIT(0xff,32,8)
-#define PCC_WR_ERR_ALARM vBIT(0xff,40,8)
-#define PCC_N_SERR vBIT(0xff,48,8)
-#define PCC_6_COF_OV_ERR s2BIT(56)
-#define PCC_7_COF_OV_ERR s2BIT(57)
-#define PCC_6_LSO_OV_ERR s2BIT(58)
-#define PCC_7_LSO_OV_ERR s2BIT(59)
-#define PCC_ENABLE_FOUR vBIT(0x0F,0,8)
- u64 pcc_err_mask;
- u64 pcc_err_alarm;
-
- u64 tti_err_reg;
-#define TTI_ECC_SG_ERR s2BIT(7)
-#define TTI_ECC_DB_ERR s2BIT(15)
-#define TTI_SM_ERR_ALARM s2BIT(23)
- u64 tti_err_mask;
- u64 tti_err_alarm;
-
- u64 lso_err_reg;
-#define LSO6_SEND_OFLOW s2BIT(12)
-#define LSO7_SEND_OFLOW s2BIT(13)
-#define LSO6_ABORT s2BIT(14)
-#define LSO7_ABORT s2BIT(15)
-#define LSO6_SM_ERR_ALARM s2BIT(22)
-#define LSO7_SM_ERR_ALARM s2BIT(23)
- u64 lso_err_mask;
- u64 lso_err_alarm;
-
- u64 tpa_err_reg;
-#define TPA_TX_FRM_DROP s2BIT(7)
-#define TPA_SM_ERR_ALARM s2BIT(23)
-
- u64 tpa_err_mask;
- u64 tpa_err_alarm;
-
- u64 sm_err_reg;
-#define SM_SM_ERR_ALARM s2BIT(15)
- u64 sm_err_mask;
- u64 sm_err_alarm;
-
- u8 unused8[0x100 - 0xB8];
-
-/* TxDMA arbiter */
- u64 tx_dma_wrap_stat;
-
-/* Tx FIFO controller */
-#define X_MAX_FIFOS 8
-#define X_FIFO_MAX_LEN 0x1FFF /*8191 */
- u64 tx_fifo_partition_0;
-#define TX_FIFO_PARTITION_EN s2BIT(0)
-#define TX_FIFO_PARTITION_0_PRI(val) vBIT(val,5,3)
-#define TX_FIFO_PARTITION_0_LEN(val) vBIT(val,19,13)
-#define TX_FIFO_PARTITION_1_PRI(val) vBIT(val,37,3)
-#define TX_FIFO_PARTITION_1_LEN(val) vBIT(val,51,13 )
-
- u64 tx_fifo_partition_1;
-#define TX_FIFO_PARTITION_2_PRI(val) vBIT(val,5,3)
-#define TX_FIFO_PARTITION_2_LEN(val) vBIT(val,19,13)
-#define TX_FIFO_PARTITION_3_PRI(val) vBIT(val,37,3)
-#define TX_FIFO_PARTITION_3_LEN(val) vBIT(val,51,13)
-
- u64 tx_fifo_partition_2;
-#define TX_FIFO_PARTITION_4_PRI(val) vBIT(val,5,3)
-#define TX_FIFO_PARTITION_4_LEN(val) vBIT(val,19,13)
-#define TX_FIFO_PARTITION_5_PRI(val) vBIT(val,37,3)
-#define TX_FIFO_PARTITION_5_LEN(val) vBIT(val,51,13)
-
- u64 tx_fifo_partition_3;
-#define TX_FIFO_PARTITION_6_PRI(val) vBIT(val,5,3)
-#define TX_FIFO_PARTITION_6_LEN(val) vBIT(val,19,13)
-#define TX_FIFO_PARTITION_7_PRI(val) vBIT(val,37,3)
-#define TX_FIFO_PARTITION_7_LEN(val) vBIT(val,51,13)
-
-#define TX_FIFO_PARTITION_PRI_0 0 /* highest */
-#define TX_FIFO_PARTITION_PRI_1 1
-#define TX_FIFO_PARTITION_PRI_2 2
-#define TX_FIFO_PARTITION_PRI_3 3
-#define TX_FIFO_PARTITION_PRI_4 4
-#define TX_FIFO_PARTITION_PRI_5 5
-#define TX_FIFO_PARTITION_PRI_6 6
-#define TX_FIFO_PARTITION_PRI_7 7 /* lowest */
-
- u64 tx_w_round_robin_0;
- u64 tx_w_round_robin_1;
- u64 tx_w_round_robin_2;
- u64 tx_w_round_robin_3;
- u64 tx_w_round_robin_4;
-
- u64 tti_command_mem;
-#define TTI_CMD_MEM_WE s2BIT(7)
-#define TTI_CMD_MEM_STROBE_NEW_CMD s2BIT(15)
-#define TTI_CMD_MEM_STROBE_BEING_EXECUTED s2BIT(15)
-#define TTI_CMD_MEM_OFFSET(n) vBIT(n,26,6)
-
- u64 tti_data1_mem;
-#define TTI_DATA1_MEM_TX_TIMER_VAL(n) vBIT(n,6,26)
-#define TTI_DATA1_MEM_TX_TIMER_AC_CI(n) vBIT(n,38,2)
-#define TTI_DATA1_MEM_TX_TIMER_AC_EN s2BIT(38)
-#define TTI_DATA1_MEM_TX_TIMER_CI_EN s2BIT(39)
-#define TTI_DATA1_MEM_TX_URNG_A(n) vBIT(n,41,7)
-#define TTI_DATA1_MEM_TX_URNG_B(n) vBIT(n,49,7)
-#define TTI_DATA1_MEM_TX_URNG_C(n) vBIT(n,57,7)
-
- u64 tti_data2_mem;
-#define TTI_DATA2_MEM_TX_UFC_A(n) vBIT(n,0,16)
-#define TTI_DATA2_MEM_TX_UFC_B(n) vBIT(n,16,16)
-#define TTI_DATA2_MEM_TX_UFC_C(n) vBIT(n,32,16)
-#define TTI_DATA2_MEM_TX_UFC_D(n) vBIT(n,48,16)
-
-/* Tx Protocol assist */
- u64 tx_pa_cfg;
-#define TX_PA_CFG_IGNORE_FRM_ERR s2BIT(1)
-#define TX_PA_CFG_IGNORE_SNAP_OUI s2BIT(2)
-#define TX_PA_CFG_IGNORE_LLC_CTRL s2BIT(3)
-#define TX_PA_CFG_IGNORE_L2_ERR s2BIT(6)
-#define RX_PA_CFG_STRIP_VLAN_TAG s2BIT(15)
-
-/* Recent add, used only debug purposes. */
- u64 pcc_enable;
-
- u8 unused9[0x700 - 0x178];
-
- u64 txdma_debug_ctrl;
-
- u8 unused10[0x1800 - 0x1708];
-
-/* RxDMA Registers */
- u64 rxdma_int_status;
- u64 rxdma_int_mask;
-#define RXDMA_INT_RC_INT_M s2BIT(0)
-#define RXDMA_INT_RPA_INT_M s2BIT(1)
-#define RXDMA_INT_RDA_INT_M s2BIT(2)
-#define RXDMA_INT_RTI_INT_M s2BIT(3)
-
- u64 rda_err_reg;
-#define RDA_RXDn_ECC_SG_ERR vBIT(0xFF,0,8)
-#define RDA_RXDn_ECC_DB_ERR vBIT(0xFF,8,8)
-#define RDA_FRM_ECC_SG_ERR s2BIT(23)
-#define RDA_FRM_ECC_DB_N_AERR s2BIT(31)
-#define RDA_SM1_ERR_ALARM s2BIT(38)
-#define RDA_SM0_ERR_ALARM s2BIT(39)
-#define RDA_MISC_ERR s2BIT(47)
-#define RDA_PCIX_ERR s2BIT(55)
-#define RDA_RXD_ECC_DB_SERR s2BIT(63)
- u64 rda_err_mask;
- u64 rda_err_alarm;
-
- u64 rc_err_reg;
-#define RC_PRCn_ECC_SG_ERR vBIT(0xFF,0,8)
-#define RC_PRCn_ECC_DB_ERR vBIT(0xFF,8,8)
-#define RC_FTC_ECC_SG_ERR s2BIT(23)
-#define RC_FTC_ECC_DB_ERR s2BIT(31)
-#define RC_PRCn_SM_ERR_ALARM vBIT(0xFF,32,8)
-#define RC_FTC_SM_ERR_ALARM s2BIT(47)
-#define RC_RDA_FAIL_WR_Rn vBIT(0xFF,48,8)
- u64 rc_err_mask;
- u64 rc_err_alarm;
-
- u64 prc_pcix_err_reg;
-#define PRC_PCI_AB_RD_Rn vBIT(0xFF,0,8)
-#define PRC_PCI_DP_RD_Rn vBIT(0xFF,8,8)
-#define PRC_PCI_AB_WR_Rn vBIT(0xFF,16,8)
-#define PRC_PCI_DP_WR_Rn vBIT(0xFF,24,8)
-#define PRC_PCI_AB_F_WR_Rn vBIT(0xFF,32,8)
-#define PRC_PCI_DP_F_WR_Rn vBIT(0xFF,40,8)
- u64 prc_pcix_err_mask;
- u64 prc_pcix_err_alarm;
-
- u64 rpa_err_reg;
-#define RPA_ECC_SG_ERR s2BIT(7)
-#define RPA_ECC_DB_ERR s2BIT(15)
-#define RPA_FLUSH_REQUEST s2BIT(22)
-#define RPA_SM_ERR_ALARM s2BIT(23)
-#define RPA_CREDIT_ERR s2BIT(31)
- u64 rpa_err_mask;
- u64 rpa_err_alarm;
-
- u64 rti_err_reg;
-#define RTI_ECC_SG_ERR s2BIT(7)
-#define RTI_ECC_DB_ERR s2BIT(15)
-#define RTI_SM_ERR_ALARM s2BIT(23)
- u64 rti_err_mask;
- u64 rti_err_alarm;
-
- u8 unused11[0x100 - 0x88];
-
-/* DMA arbiter */
- u64 rx_queue_priority;
-#define RX_QUEUE_0_PRIORITY(val) vBIT(val,5,3)
-#define RX_QUEUE_1_PRIORITY(val) vBIT(val,13,3)
-#define RX_QUEUE_2_PRIORITY(val) vBIT(val,21,3)
-#define RX_QUEUE_3_PRIORITY(val) vBIT(val,29,3)
-#define RX_QUEUE_4_PRIORITY(val) vBIT(val,37,3)
-#define RX_QUEUE_5_PRIORITY(val) vBIT(val,45,3)
-#define RX_QUEUE_6_PRIORITY(val) vBIT(val,53,3)
-#define RX_QUEUE_7_PRIORITY(val) vBIT(val,61,3)
-
-#define RX_QUEUE_PRI_0 0 /* highest */
-#define RX_QUEUE_PRI_1 1
-#define RX_QUEUE_PRI_2 2
-#define RX_QUEUE_PRI_3 3
-#define RX_QUEUE_PRI_4 4
-#define RX_QUEUE_PRI_5 5
-#define RX_QUEUE_PRI_6 6
-#define RX_QUEUE_PRI_7 7 /* lowest */
-
- u64 rx_w_round_robin_0;
- u64 rx_w_round_robin_1;
- u64 rx_w_round_robin_2;
- u64 rx_w_round_robin_3;
- u64 rx_w_round_robin_4;
-
- /* Per-ring controller regs */
-#define RX_MAX_RINGS 8
-#if 0
-#define RX_MAX_RINGS_SZ 0xFFFF /* 65536 */
-#define RX_MIN_RINGS_SZ 0x3F /* 63 */
-#endif
- u64 prc_rxd0_n[RX_MAX_RINGS];
- u64 prc_ctrl_n[RX_MAX_RINGS];
-#define PRC_CTRL_RC_ENABLED s2BIT(7)
-#define PRC_CTRL_RING_MODE (s2BIT(14)|s2BIT(15))
-#define PRC_CTRL_RING_MODE_1 vBIT(0,14,2)
-#define PRC_CTRL_RING_MODE_3 vBIT(1,14,2)
-#define PRC_CTRL_RING_MODE_5 vBIT(2,14,2)
-#define PRC_CTRL_RING_MODE_x vBIT(3,14,2)
-#define PRC_CTRL_NO_SNOOP (s2BIT(22)|s2BIT(23))
-#define PRC_CTRL_NO_SNOOP_DESC s2BIT(22)
-#define PRC_CTRL_NO_SNOOP_BUFF s2BIT(23)
-#define PRC_CTRL_BIMODAL_INTERRUPT s2BIT(37)
-#define PRC_CTRL_GROUP_READS s2BIT(38)
-#define PRC_CTRL_RXD_BACKOFF_INTERVAL(val) vBIT(val,40,24)
-
- u64 prc_alarm_action;
-#define PRC_ALARM_ACTION_RR_R0_STOP s2BIT(3)
-#define PRC_ALARM_ACTION_RW_R0_STOP s2BIT(7)
-#define PRC_ALARM_ACTION_RR_R1_STOP s2BIT(11)
-#define PRC_ALARM_ACTION_RW_R1_STOP s2BIT(15)
-#define PRC_ALARM_ACTION_RR_R2_STOP s2BIT(19)
-#define PRC_ALARM_ACTION_RW_R2_STOP s2BIT(23)
-#define PRC_ALARM_ACTION_RR_R3_STOP s2BIT(27)
-#define PRC_ALARM_ACTION_RW_R3_STOP s2BIT(31)
-#define PRC_ALARM_ACTION_RR_R4_STOP s2BIT(35)
-#define PRC_ALARM_ACTION_RW_R4_STOP s2BIT(39)
-#define PRC_ALARM_ACTION_RR_R5_STOP s2BIT(43)
-#define PRC_ALARM_ACTION_RW_R5_STOP s2BIT(47)
-#define PRC_ALARM_ACTION_RR_R6_STOP s2BIT(51)
-#define PRC_ALARM_ACTION_RW_R6_STOP s2BIT(55)
-#define PRC_ALARM_ACTION_RR_R7_STOP s2BIT(59)
-#define PRC_ALARM_ACTION_RW_R7_STOP s2BIT(63)
-
-/* Receive traffic interrupts */
- u64 rti_command_mem;
-#define RTI_CMD_MEM_WE s2BIT(7)
-#define RTI_CMD_MEM_STROBE s2BIT(15)
-#define RTI_CMD_MEM_STROBE_NEW_CMD s2BIT(15)
-#define RTI_CMD_MEM_STROBE_CMD_BEING_EXECUTED s2BIT(15)
-#define RTI_CMD_MEM_OFFSET(n) vBIT(n,29,3)
-
- u64 rti_data1_mem;
-#define RTI_DATA1_MEM_RX_TIMER_VAL(n) vBIT(n,3,29)
-#define RTI_DATA1_MEM_RX_TIMER_AC_EN s2BIT(38)
-#define RTI_DATA1_MEM_RX_TIMER_CI_EN s2BIT(39)
-#define RTI_DATA1_MEM_RX_URNG_A(n) vBIT(n,41,7)
-#define RTI_DATA1_MEM_RX_URNG_B(n) vBIT(n,49,7)
-#define RTI_DATA1_MEM_RX_URNG_C(n) vBIT(n,57,7)
-
- u64 rti_data2_mem;
-#define RTI_DATA2_MEM_RX_UFC_A(n) vBIT(n,0,16)
-#define RTI_DATA2_MEM_RX_UFC_B(n) vBIT(n,16,16)
-#define RTI_DATA2_MEM_RX_UFC_C(n) vBIT(n,32,16)
-#define RTI_DATA2_MEM_RX_UFC_D(n) vBIT(n,48,16)
-
- u64 rx_pa_cfg;
-#define RX_PA_CFG_IGNORE_FRM_ERR s2BIT(1)
-#define RX_PA_CFG_IGNORE_SNAP_OUI s2BIT(2)
-#define RX_PA_CFG_IGNORE_LLC_CTRL s2BIT(3)
-#define RX_PA_CFG_IGNORE_L2_ERR s2BIT(6)
-
- u64 unused_11_1;
-
- u64 ring_bump_counter1;
- u64 ring_bump_counter2;
-
- u8 unused12[0x700 - 0x1F0];
-
- u64 rxdma_debug_ctrl;
-
- u8 unused13[0x2000 - 0x1f08];
-
-/* Media Access Controller Register */
- u64 mac_int_status;
- u64 mac_int_mask;
-#define MAC_INT_STATUS_TMAC_INT s2BIT(0)
-#define MAC_INT_STATUS_RMAC_INT s2BIT(1)
-
- u64 mac_tmac_err_reg;
-#define TMAC_ECC_SG_ERR s2BIT(7)
-#define TMAC_ECC_DB_ERR s2BIT(15)
-#define TMAC_TX_BUF_OVRN s2BIT(23)
-#define TMAC_TX_CRI_ERR s2BIT(31)
-#define TMAC_TX_SM_ERR s2BIT(39)
-#define TMAC_DESC_ECC_SG_ERR s2BIT(47)
-#define TMAC_DESC_ECC_DB_ERR s2BIT(55)
-
- u64 mac_tmac_err_mask;
- u64 mac_tmac_err_alarm;
-
- u64 mac_rmac_err_reg;
-#define RMAC_RX_BUFF_OVRN s2BIT(0)
-#define RMAC_FRM_RCVD_INT s2BIT(1)
-#define RMAC_UNUSED_INT s2BIT(2)
-#define RMAC_RTS_PNUM_ECC_SG_ERR s2BIT(5)
-#define RMAC_RTS_DS_ECC_SG_ERR s2BIT(6)
-#define RMAC_RD_BUF_ECC_SG_ERR s2BIT(7)
-#define RMAC_RTH_MAP_ECC_SG_ERR s2BIT(8)
-#define RMAC_RTH_SPDM_ECC_SG_ERR s2BIT(9)
-#define RMAC_RTS_VID_ECC_SG_ERR s2BIT(10)
-#define RMAC_DA_SHADOW_ECC_SG_ERR s2BIT(11)
-#define RMAC_RTS_PNUM_ECC_DB_ERR s2BIT(13)
-#define RMAC_RTS_DS_ECC_DB_ERR s2BIT(14)
-#define RMAC_RD_BUF_ECC_DB_ERR s2BIT(15)
-#define RMAC_RTH_MAP_ECC_DB_ERR s2BIT(16)
-#define RMAC_RTH_SPDM_ECC_DB_ERR s2BIT(17)
-#define RMAC_RTS_VID_ECC_DB_ERR s2BIT(18)
-#define RMAC_DA_SHADOW_ECC_DB_ERR s2BIT(19)
-#define RMAC_LINK_STATE_CHANGE_INT s2BIT(31)
-#define RMAC_RX_SM_ERR s2BIT(39)
-#define RMAC_SINGLE_ECC_ERR (s2BIT(5) | s2BIT(6) | s2BIT(7) |\
- s2BIT(8) | s2BIT(9) | s2BIT(10)|\
- s2BIT(11))
-#define RMAC_DOUBLE_ECC_ERR (s2BIT(13) | s2BIT(14) | s2BIT(15) |\
- s2BIT(16) | s2BIT(17) | s2BIT(18)|\
- s2BIT(19))
- u64 mac_rmac_err_mask;
- u64 mac_rmac_err_alarm;
-
- u8 unused14[0x100 - 0x40];
-
- u64 mac_cfg;
-#define MAC_CFG_TMAC_ENABLE s2BIT(0)
-#define MAC_CFG_RMAC_ENABLE s2BIT(1)
-#define MAC_CFG_LAN_NOT_WAN s2BIT(2)
-#define MAC_CFG_TMAC_LOOPBACK s2BIT(3)
-#define MAC_CFG_TMAC_APPEND_PAD s2BIT(4)
-#define MAC_CFG_RMAC_STRIP_FCS s2BIT(5)
-#define MAC_CFG_RMAC_STRIP_PAD s2BIT(6)
-#define MAC_CFG_RMAC_PROM_ENABLE s2BIT(7)
-#define MAC_RMAC_DISCARD_PFRM s2BIT(8)
-#define MAC_RMAC_BCAST_ENABLE s2BIT(9)
-#define MAC_RMAC_ALL_ADDR_ENABLE s2BIT(10)
-#define MAC_RMAC_INVLD_IPG_THR(val) vBIT(val,16,8)
-
- u64 tmac_avg_ipg;
-#define TMAC_AVG_IPG(val) vBIT(val,0,8)
-
- u64 rmac_max_pyld_len;
-#define RMAC_MAX_PYLD_LEN(val) vBIT(val,2,14)
-#define RMAC_MAX_PYLD_LEN_DEF vBIT(1500,2,14)
-#define RMAC_MAX_PYLD_LEN_JUMBO_DEF vBIT(9600,2,14)
-
- u64 rmac_err_cfg;
-#define RMAC_ERR_FCS s2BIT(0)
-#define RMAC_ERR_FCS_ACCEPT s2BIT(1)
-#define RMAC_ERR_TOO_LONG s2BIT(1)
-#define RMAC_ERR_TOO_LONG_ACCEPT s2BIT(1)
-#define RMAC_ERR_RUNT s2BIT(2)
-#define RMAC_ERR_RUNT_ACCEPT s2BIT(2)
-#define RMAC_ERR_LEN_MISMATCH s2BIT(3)
-#define RMAC_ERR_LEN_MISMATCH_ACCEPT s2BIT(3)
-
- u64 rmac_cfg_key;
-#define RMAC_CFG_KEY(val) vBIT(val,0,16)
-
-#define S2IO_MAC_ADDR_START_OFFSET 0
-
-#define S2IO_XENA_MAX_MC_ADDRESSES 64 /* multicast addresses */
-#define S2IO_HERC_MAX_MC_ADDRESSES 256
-
-#define S2IO_XENA_MAX_MAC_ADDRESSES 16
-#define S2IO_HERC_MAX_MAC_ADDRESSES 64
-
-#define S2IO_XENA_MC_ADDR_START_OFFSET 16
-#define S2IO_HERC_MC_ADDR_START_OFFSET 64
-
- u64 rmac_addr_cmd_mem;
-#define RMAC_ADDR_CMD_MEM_WE s2BIT(7)
-#define RMAC_ADDR_CMD_MEM_RD 0
-#define RMAC_ADDR_CMD_MEM_STROBE_NEW_CMD s2BIT(15)
-#define RMAC_ADDR_CMD_MEM_STROBE_CMD_EXECUTING s2BIT(15)
-#define RMAC_ADDR_CMD_MEM_OFFSET(n) vBIT(n,26,6)
-
- u64 rmac_addr_data0_mem;
-#define RMAC_ADDR_DATA0_MEM_ADDR(n) vBIT(n,0,48)
-#define RMAC_ADDR_DATA0_MEM_USER s2BIT(48)
-
- u64 rmac_addr_data1_mem;
-#define RMAC_ADDR_DATA1_MEM_MASK(n) vBIT(n,0,48)
-
- u8 unused15[0x8];
-
-/*
- u64 rmac_addr_cfg;
-#define RMAC_ADDR_UCASTn_EN(n) mBIT(0)_n(n)
-#define RMAC_ADDR_MCASTn_EN(n) mBIT(0)_n(n)
-#define RMAC_ADDR_BCAST_EN vBIT(0)_48
-#define RMAC_ADDR_ALL_ADDR_EN vBIT(0)_49
-*/
- u64 tmac_ipg_cfg;
-
- u64 rmac_pause_cfg;
-#define RMAC_PAUSE_GEN s2BIT(0)
-#define RMAC_PAUSE_GEN_ENABLE s2BIT(0)
-#define RMAC_PAUSE_RX s2BIT(1)
-#define RMAC_PAUSE_RX_ENABLE s2BIT(1)
-#define RMAC_PAUSE_HG_PTIME_DEF vBIT(0xFFFF,16,16)
-#define RMAC_PAUSE_HG_PTIME(val) vBIT(val,16,16)
-
- u64 rmac_red_cfg;
-
- u64 rmac_red_rate_q0q3;
- u64 rmac_red_rate_q4q7;
-
- u64 mac_link_util;
-#define MAC_TX_LINK_UTIL vBIT(0xFE,1,7)
-#define MAC_TX_LINK_UTIL_DISABLE vBIT(0xF, 8,4)
-#define MAC_TX_LINK_UTIL_VAL( n ) vBIT(n,8,4)
-#define MAC_RX_LINK_UTIL vBIT(0xFE,33,7)
-#define MAC_RX_LINK_UTIL_DISABLE vBIT(0xF,40,4)
-#define MAC_RX_LINK_UTIL_VAL( n ) vBIT(n,40,4)
-
-#define MAC_LINK_UTIL_DISABLE MAC_TX_LINK_UTIL_DISABLE | \
- MAC_RX_LINK_UTIL_DISABLE
-
- u64 rmac_invalid_ipg;
-
-/* rx traffic steering */
-#define MAC_RTS_FRM_LEN_SET(len) vBIT(len,2,14)
- u64 rts_frm_len_n[8];
-
- u64 rts_qos_steering;
-
-#define MAX_DIX_MAP 4
- u64 rts_dix_map_n[MAX_DIX_MAP];
-#define RTS_DIX_MAP_ETYPE(val) vBIT(val,0,16)
-#define RTS_DIX_MAP_SCW(val) s2BIT(val,21)
-
- u64 rts_q_alternates;
- u64 rts_default_q;
-
- u64 rts_ctrl;
-#define RTS_CTRL_IGNORE_SNAP_OUI s2BIT(2)
-#define RTS_CTRL_IGNORE_LLC_CTRL s2BIT(3)
-
- u64 rts_pn_cam_ctrl;
-#define RTS_PN_CAM_CTRL_WE s2BIT(7)
-#define RTS_PN_CAM_CTRL_STROBE_NEW_CMD s2BIT(15)
-#define RTS_PN_CAM_CTRL_STROBE_BEING_EXECUTED s2BIT(15)
-#define RTS_PN_CAM_CTRL_OFFSET(n) vBIT(n,24,8)
- u64 rts_pn_cam_data;
-#define RTS_PN_CAM_DATA_TCP_SELECT s2BIT(7)
-#define RTS_PN_CAM_DATA_PORT(val) vBIT(val,8,16)
-#define RTS_PN_CAM_DATA_SCW(val) vBIT(val,24,8)
-
- u64 rts_ds_mem_ctrl;
-#define RTS_DS_MEM_CTRL_WE s2BIT(7)
-#define RTS_DS_MEM_CTRL_STROBE_NEW_CMD s2BIT(15)
-#define RTS_DS_MEM_CTRL_STROBE_CMD_BEING_EXECUTED s2BIT(15)
-#define RTS_DS_MEM_CTRL_OFFSET(n) vBIT(n,26,6)
- u64 rts_ds_mem_data;
-#define RTS_DS_MEM_DATA(n) vBIT(n,0,8)
-
- u8 unused16[0x700 - 0x220];
-
- u64 mac_debug_ctrl;
-#define MAC_DBG_ACTIVITY_VALUE 0x411040400000000ULL
-
- u8 unused17[0x2800 - 0x2708];
-
-/* memory controller registers */
- u64 mc_int_status;
-#define MC_INT_STATUS_MC_INT s2BIT(0)
- u64 mc_int_mask;
-#define MC_INT_MASK_MC_INT s2BIT(0)
-
- u64 mc_err_reg;
-#define MC_ERR_REG_ECC_DB_ERR_L s2BIT(14)
-#define MC_ERR_REG_ECC_DB_ERR_U s2BIT(15)
-#define MC_ERR_REG_MIRI_ECC_DB_ERR_0 s2BIT(18)
-#define MC_ERR_REG_MIRI_ECC_DB_ERR_1 s2BIT(20)
-#define MC_ERR_REG_MIRI_CRI_ERR_0 s2BIT(22)
-#define MC_ERR_REG_MIRI_CRI_ERR_1 s2BIT(23)
-#define MC_ERR_REG_SM_ERR s2BIT(31)
-#define MC_ERR_REG_ECC_ALL_SNG (s2BIT(2) | s2BIT(3) | s2BIT(4) | s2BIT(5) |\
- s2BIT(17) | s2BIT(19))
-#define MC_ERR_REG_ECC_ALL_DBL (s2BIT(10) | s2BIT(11) | s2BIT(12) |\
- s2BIT(13) | s2BIT(18) | s2BIT(20))
-#define PLL_LOCK_N s2BIT(39)
- u64 mc_err_mask;
- u64 mc_err_alarm;
-
- u8 unused18[0x100 - 0x28];
-
-/* MC configuration */
- u64 rx_queue_cfg;
-#define RX_QUEUE_CFG_Q0_SZ(n) vBIT(n,0,8)
-#define RX_QUEUE_CFG_Q1_SZ(n) vBIT(n,8,8)
-#define RX_QUEUE_CFG_Q2_SZ(n) vBIT(n,16,8)
-#define RX_QUEUE_CFG_Q3_SZ(n) vBIT(n,24,8)
-#define RX_QUEUE_CFG_Q4_SZ(n) vBIT(n,32,8)
-#define RX_QUEUE_CFG_Q5_SZ(n) vBIT(n,40,8)
-#define RX_QUEUE_CFG_Q6_SZ(n) vBIT(n,48,8)
-#define RX_QUEUE_CFG_Q7_SZ(n) vBIT(n,56,8)
-
- u64 mc_rldram_mrs;
-#define MC_RLDRAM_QUEUE_SIZE_ENABLE s2BIT(39)
-#define MC_RLDRAM_MRS_ENABLE s2BIT(47)
-
- u64 mc_rldram_interleave;
-
- u64 mc_pause_thresh_q0q3;
- u64 mc_pause_thresh_q4q7;
-
- u64 mc_red_thresh_q[8];
-
- u8 unused19[0x200 - 0x168];
- u64 mc_rldram_ref_per;
- u8 unused20[0x220 - 0x208];
- u64 mc_rldram_test_ctrl;
-#define MC_RLDRAM_TEST_MODE s2BIT(47)
-#define MC_RLDRAM_TEST_WRITE s2BIT(7)
-#define MC_RLDRAM_TEST_GO s2BIT(15)
-#define MC_RLDRAM_TEST_DONE s2BIT(23)
-#define MC_RLDRAM_TEST_PASS s2BIT(31)
-
- u8 unused21[0x240 - 0x228];
- u64 mc_rldram_test_add;
- u8 unused22[0x260 - 0x248];
- u64 mc_rldram_test_d0;
- u8 unused23[0x280 - 0x268];
- u64 mc_rldram_test_d1;
- u8 unused24[0x300 - 0x288];
- u64 mc_rldram_test_d2;
-
- u8 unused24_1[0x360 - 0x308];
- u64 mc_rldram_ctrl;
-#define MC_RLDRAM_ENABLE_ODT s2BIT(7)
-
- u8 unused24_2[0x640 - 0x368];
- u64 mc_rldram_ref_per_herc;
-#define MC_RLDRAM_SET_REF_PERIOD(val) vBIT(val, 0, 16)
-
- u8 unused24_3[0x660 - 0x648];
- u64 mc_rldram_mrs_herc;
-
- u8 unused25[0x700 - 0x668];
- u64 mc_debug_ctrl;
-
- u8 unused26[0x3000 - 0x2f08];
-
-/* XGXG */
- /* XGXS control registers */
-
- u64 xgxs_int_status;
-#define XGXS_INT_STATUS_TXGXS s2BIT(0)
-#define XGXS_INT_STATUS_RXGXS s2BIT(1)
- u64 xgxs_int_mask;
-#define XGXS_INT_MASK_TXGXS s2BIT(0)
-#define XGXS_INT_MASK_RXGXS s2BIT(1)
-
- u64 xgxs_txgxs_err_reg;
-#define TXGXS_ECC_SG_ERR s2BIT(7)
-#define TXGXS_ECC_DB_ERR s2BIT(15)
-#define TXGXS_ESTORE_UFLOW s2BIT(31)
-#define TXGXS_TX_SM_ERR s2BIT(39)
-
- u64 xgxs_txgxs_err_mask;
- u64 xgxs_txgxs_err_alarm;
-
- u64 xgxs_rxgxs_err_reg;
-#define RXGXS_ESTORE_OFLOW s2BIT(7)
-#define RXGXS_RX_SM_ERR s2BIT(39)
- u64 xgxs_rxgxs_err_mask;
- u64 xgxs_rxgxs_err_alarm;
-
- u8 unused27[0x100 - 0x40];
-
- u64 xgxs_cfg;
- u64 xgxs_status;
-
- u64 xgxs_cfg_key;
- u64 xgxs_efifo_cfg; /* CHANGED */
- u64 rxgxs_ber_0; /* CHANGED */
- u64 rxgxs_ber_1; /* CHANGED */
-
- u64 spi_control;
-#define SPI_CONTROL_KEY(key) vBIT(key,0,4)
-#define SPI_CONTROL_BYTECNT(cnt) vBIT(cnt,29,3)
-#define SPI_CONTROL_CMD(cmd) vBIT(cmd,32,8)
-#define SPI_CONTROL_ADDR(addr) vBIT(addr,40,24)
-#define SPI_CONTROL_SEL1 s2BIT(4)
-#define SPI_CONTROL_REQ s2BIT(7)
-#define SPI_CONTROL_NACK s2BIT(5)
-#define SPI_CONTROL_DONE s2BIT(6)
- u64 spi_data;
-#define SPI_DATA_WRITE(data,len) vBIT(data,0,len)
-};
-
-#define XENA_REG_SPACE sizeof(struct XENA_dev_config)
-#define XENA_EEPROM_SPACE (0x01 << 11)
-
-#endif /* _REGS_H */
diff --git a/drivers/net/ethernet/neterion/s2io.c b/drivers/net/ethernet/neterion/s2io.c
deleted file mode 100644
index 1e55ccb4822b..000000000000
--- a/drivers/net/ethernet/neterion/s2io.c
+++ /dev/null
@@ -1,8572 +0,0 @@
-/************************************************************************
- * s2io.c: A Linux PCI-X Ethernet driver for Neterion 10GbE Server NIC
- * Copyright(c) 2002-2010 Exar Corp.
- *
- * This software may be used and distributed according to the terms of
- * the GNU General Public License (GPL), incorporated herein by reference.
- * Drivers based on or derived from this code fall under the GPL and must
- * retain the authorship, copyright and license notice. This file is not
- * a complete program and may only be used when the entire operating
- * system is licensed under the GPL.
- * See the file COPYING in this distribution for more information.
- *
- * Credits:
- * Jeff Garzik : For pointing out the improper error condition
- * check in the s2io_xmit routine and also some
- * issues in the Tx watch dog function. Also for
- * patiently answering all those innumerable
- * questions regaring the 2.6 porting issues.
- * Stephen Hemminger : Providing proper 2.6 porting mechanism for some
- * macros available only in 2.6 Kernel.
- * Francois Romieu : For pointing out all code part that were
- * deprecated and also styling related comments.
- * Grant Grundler : For helping me get rid of some Architecture
- * dependent code.
- * Christopher Hellwig : Some more 2.6 specific issues in the driver.
- *
- * The module loadable parameters that are supported by the driver and a brief
- * explanation of all the variables.
- *
- * rx_ring_num : This can be used to program the number of receive rings used
- * in the driver.
- * rx_ring_sz: This defines the number of receive blocks each ring can have.
- * This is also an array of size 8.
- * rx_ring_mode: This defines the operation mode of all 8 rings. The valid
- * values are 1, 2.
- * tx_fifo_num: This defines the number of Tx FIFOs thats used int the driver.
- * tx_fifo_len: This too is an array of 8. Each element defines the number of
- * Tx descriptors that can be associated with each corresponding FIFO.
- * intr_type: This defines the type of interrupt. The values can be 0(INTA),
- * 2(MSI_X). Default value is '2(MSI_X)'
- * lro_max_pkts: This parameter defines maximum number of packets can be
- * aggregated as a single large packet
- * napi: This parameter used to enable/disable NAPI (polling Rx)
- * Possible values '1' for enable and '0' for disable. Default is '1'
- * vlan_tag_strip: This can be used to enable or disable vlan stripping.
- * Possible values '1' for enable , '0' for disable.
- * Default is '2' - which means disable in promisc mode
- * and enable in non-promiscuous mode.
- * multiq: This parameter used to enable/disable MULTIQUEUE support.
- * Possible values '1' for enable and '0' for disable. Default is '0'
- ************************************************************************/
-
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-
-#include <linux/module.h>
-#include <linux/types.h>
-#include <linux/errno.h>
-#include <linux/ioport.h>
-#include <linux/pci.h>
-#include <linux/dma-mapping.h>
-#include <linux/kernel.h>
-#include <linux/netdevice.h>
-#include <linux/etherdevice.h>
-#include <linux/mdio.h>
-#include <linux/skbuff.h>
-#include <linux/init.h>
-#include <linux/delay.h>
-#include <linux/stddef.h>
-#include <linux/ioctl.h>
-#include <linux/timex.h>
-#include <linux/ethtool.h>
-#include <linux/workqueue.h>
-#include <linux/if_vlan.h>
-#include <linux/ip.h>
-#include <linux/tcp.h>
-#include <linux/uaccess.h>
-#include <linux/io.h>
-#include <linux/io-64-nonatomic-lo-hi.h>
-#include <linux/slab.h>
-#include <linux/prefetch.h>
-#include <net/tcp.h>
-#include <net/checksum.h>
-
-#include <asm/div64.h>
-#include <asm/irq.h>
-
-/* local include */
-#include "s2io.h"
-#include "s2io-regs.h"
-
-#define DRV_VERSION "2.0.26.28"
-
-/* S2io Driver name & version. */
-static const char s2io_driver_name[] = "Neterion";
-static const char s2io_driver_version[] = DRV_VERSION;
-
-static const int rxd_size[2] = {32, 48};
-static const int rxd_count[2] = {127, 85};
-
-static inline int RXD_IS_UP2DT(struct RxD_t *rxdp)
-{
- int ret;
-
- ret = ((!(rxdp->Control_1 & RXD_OWN_XENA)) &&
- (GET_RXD_MARKER(rxdp->Control_2) != THE_RXD_MARK));
-
- return ret;
-}
-
-/*
- * Cards with following subsystem_id have a link state indication
- * problem, 600B, 600C, 600D, 640B, 640C and 640D.
- * macro below identifies these cards given the subsystem_id.
- */
-#define CARDS_WITH_FAULTY_LINK_INDICATORS(dev_type, subid) \
- (dev_type == XFRAME_I_DEVICE) ? \
- ((((subid >= 0x600B) && (subid <= 0x600D)) || \
- ((subid >= 0x640B) && (subid <= 0x640D))) ? 1 : 0) : 0
-
-#define LINK_IS_UP(val64) (!(val64 & (ADAPTER_STATUS_RMAC_REMOTE_FAULT | \
- ADAPTER_STATUS_RMAC_LOCAL_FAULT)))
-
-static inline int is_s2io_card_up(const struct s2io_nic *sp)
-{
- return test_bit(__S2IO_STATE_CARD_UP, &sp->state);
-}
-
-/* Ethtool related variables and Macros. */
-static const char s2io_gstrings[][ETH_GSTRING_LEN] = {
- "Register test\t(offline)",
- "Eeprom test\t(offline)",
- "Link test\t(online)",
- "RLDRAM test\t(offline)",
- "BIST Test\t(offline)"
-};
-
-static const char ethtool_xena_stats_keys[][ETH_GSTRING_LEN] = {
- {"tmac_frms"},
- {"tmac_data_octets"},
- {"tmac_drop_frms"},
- {"tmac_mcst_frms"},
- {"tmac_bcst_frms"},
- {"tmac_pause_ctrl_frms"},
- {"tmac_ttl_octets"},
- {"tmac_ucst_frms"},
- {"tmac_nucst_frms"},
- {"tmac_any_err_frms"},
- {"tmac_ttl_less_fb_octets"},
- {"tmac_vld_ip_octets"},
- {"tmac_vld_ip"},
- {"tmac_drop_ip"},
- {"tmac_icmp"},
- {"tmac_rst_tcp"},
- {"tmac_tcp"},
- {"tmac_udp"},
- {"rmac_vld_frms"},
- {"rmac_data_octets"},
- {"rmac_fcs_err_frms"},
- {"rmac_drop_frms"},
- {"rmac_vld_mcst_frms"},
- {"rmac_vld_bcst_frms"},
- {"rmac_in_rng_len_err_frms"},
- {"rmac_out_rng_len_err_frms"},
- {"rmac_long_frms"},
- {"rmac_pause_ctrl_frms"},
- {"rmac_unsup_ctrl_frms"},
- {"rmac_ttl_octets"},
- {"rmac_accepted_ucst_frms"},
- {"rmac_accepted_nucst_frms"},
- {"rmac_discarded_frms"},
- {"rmac_drop_events"},
- {"rmac_ttl_less_fb_octets"},
- {"rmac_ttl_frms"},
- {"rmac_usized_frms"},
- {"rmac_osized_frms"},
- {"rmac_frag_frms"},
- {"rmac_jabber_frms"},
- {"rmac_ttl_64_frms"},
- {"rmac_ttl_65_127_frms"},
- {"rmac_ttl_128_255_frms"},
- {"rmac_ttl_256_511_frms"},
- {"rmac_ttl_512_1023_frms"},
- {"rmac_ttl_1024_1518_frms"},
- {"rmac_ip"},
- {"rmac_ip_octets"},
- {"rmac_hdr_err_ip"},
- {"rmac_drop_ip"},
- {"rmac_icmp"},
- {"rmac_tcp"},
- {"rmac_udp"},
- {"rmac_err_drp_udp"},
- {"rmac_xgmii_err_sym"},
- {"rmac_frms_q0"},
- {"rmac_frms_q1"},
- {"rmac_frms_q2"},
- {"rmac_frms_q3"},
- {"rmac_frms_q4"},
- {"rmac_frms_q5"},
- {"rmac_frms_q6"},
- {"rmac_frms_q7"},
- {"rmac_full_q0"},
- {"rmac_full_q1"},
- {"rmac_full_q2"},
- {"rmac_full_q3"},
- {"rmac_full_q4"},
- {"rmac_full_q5"},
- {"rmac_full_q6"},
- {"rmac_full_q7"},
- {"rmac_pause_cnt"},
- {"rmac_xgmii_data_err_cnt"},
- {"rmac_xgmii_ctrl_err_cnt"},
- {"rmac_accepted_ip"},
- {"rmac_err_tcp"},
- {"rd_req_cnt"},
- {"new_rd_req_cnt"},
- {"new_rd_req_rtry_cnt"},
- {"rd_rtry_cnt"},
- {"wr_rtry_rd_ack_cnt"},
- {"wr_req_cnt"},
- {"new_wr_req_cnt"},
- {"new_wr_req_rtry_cnt"},
- {"wr_rtry_cnt"},
- {"wr_disc_cnt"},
- {"rd_rtry_wr_ack_cnt"},
- {"txp_wr_cnt"},
- {"txd_rd_cnt"},
- {"txd_wr_cnt"},
- {"rxd_rd_cnt"},
- {"rxd_wr_cnt"},
- {"txf_rd_cnt"},
- {"rxf_wr_cnt"}
-};
-
-static const char ethtool_enhanced_stats_keys[][ETH_GSTRING_LEN] = {
- {"rmac_ttl_1519_4095_frms"},
- {"rmac_ttl_4096_8191_frms"},
- {"rmac_ttl_8192_max_frms"},
- {"rmac_ttl_gt_max_frms"},
- {"rmac_osized_alt_frms"},
- {"rmac_jabber_alt_frms"},
- {"rmac_gt_max_alt_frms"},
- {"rmac_vlan_frms"},
- {"rmac_len_discard"},
- {"rmac_fcs_discard"},
- {"rmac_pf_discard"},
- {"rmac_da_discard"},
- {"rmac_red_discard"},
- {"rmac_rts_discard"},
- {"rmac_ingm_full_discard"},
- {"link_fault_cnt"}
-};
-
-static const char ethtool_driver_stats_keys[][ETH_GSTRING_LEN] = {
- {"\n DRIVER STATISTICS"},
- {"single_bit_ecc_errs"},
- {"double_bit_ecc_errs"},
- {"parity_err_cnt"},
- {"serious_err_cnt"},
- {"soft_reset_cnt"},
- {"fifo_full_cnt"},
- {"ring_0_full_cnt"},
- {"ring_1_full_cnt"},
- {"ring_2_full_cnt"},
- {"ring_3_full_cnt"},
- {"ring_4_full_cnt"},
- {"ring_5_full_cnt"},
- {"ring_6_full_cnt"},
- {"ring_7_full_cnt"},
- {"alarm_transceiver_temp_high"},
- {"alarm_transceiver_temp_low"},
- {"alarm_laser_bias_current_high"},
- {"alarm_laser_bias_current_low"},
- {"alarm_laser_output_power_high"},
- {"alarm_laser_output_power_low"},
- {"warn_transceiver_temp_high"},
- {"warn_transceiver_temp_low"},
- {"warn_laser_bias_current_high"},
- {"warn_laser_bias_current_low"},
- {"warn_laser_output_power_high"},
- {"warn_laser_output_power_low"},
- {"lro_aggregated_pkts"},
- {"lro_flush_both_count"},
- {"lro_out_of_sequence_pkts"},
- {"lro_flush_due_to_max_pkts"},
- {"lro_avg_aggr_pkts"},
- {"mem_alloc_fail_cnt"},
- {"pci_map_fail_cnt"},
- {"watchdog_timer_cnt"},
- {"mem_allocated"},
- {"mem_freed"},
- {"link_up_cnt"},
- {"link_down_cnt"},
- {"link_up_time"},
- {"link_down_time"},
- {"tx_tcode_buf_abort_cnt"},
- {"tx_tcode_desc_abort_cnt"},
- {"tx_tcode_parity_err_cnt"},
- {"tx_tcode_link_loss_cnt"},
- {"tx_tcode_list_proc_err_cnt"},
- {"rx_tcode_parity_err_cnt"},
- {"rx_tcode_abort_cnt"},
- {"rx_tcode_parity_abort_cnt"},
- {"rx_tcode_rda_fail_cnt"},
- {"rx_tcode_unkn_prot_cnt"},
- {"rx_tcode_fcs_err_cnt"},
- {"rx_tcode_buf_size_err_cnt"},
- {"rx_tcode_rxd_corrupt_cnt"},
- {"rx_tcode_unkn_err_cnt"},
- {"tda_err_cnt"},
- {"pfc_err_cnt"},
- {"pcc_err_cnt"},
- {"tti_err_cnt"},
- {"tpa_err_cnt"},
- {"sm_err_cnt"},
- {"lso_err_cnt"},
- {"mac_tmac_err_cnt"},
- {"mac_rmac_err_cnt"},
- {"xgxs_txgxs_err_cnt"},
- {"xgxs_rxgxs_err_cnt"},
- {"rc_err_cnt"},
- {"prc_pcix_err_cnt"},
- {"rpa_err_cnt"},
- {"rda_err_cnt"},
- {"rti_err_cnt"},
- {"mc_err_cnt"}
-};
-
-#define S2IO_XENA_STAT_LEN ARRAY_SIZE(ethtool_xena_stats_keys)
-#define S2IO_ENHANCED_STAT_LEN ARRAY_SIZE(ethtool_enhanced_stats_keys)
-#define S2IO_DRIVER_STAT_LEN ARRAY_SIZE(ethtool_driver_stats_keys)
-
-#define XFRAME_I_STAT_LEN (S2IO_XENA_STAT_LEN + S2IO_DRIVER_STAT_LEN)
-#define XFRAME_II_STAT_LEN (XFRAME_I_STAT_LEN + S2IO_ENHANCED_STAT_LEN)
-
-#define XFRAME_I_STAT_STRINGS_LEN (XFRAME_I_STAT_LEN * ETH_GSTRING_LEN)
-#define XFRAME_II_STAT_STRINGS_LEN (XFRAME_II_STAT_LEN * ETH_GSTRING_LEN)
-
-#define S2IO_TEST_LEN ARRAY_SIZE(s2io_gstrings)
-#define S2IO_STRINGS_LEN (S2IO_TEST_LEN * ETH_GSTRING_LEN)
-
-/* copy mac addr to def_mac_addr array */
-static void do_s2io_copy_mac_addr(struct s2io_nic *sp, int offset, u64 mac_addr)
-{
- sp->def_mac_addr[offset].mac_addr[5] = (u8) (mac_addr);
- sp->def_mac_addr[offset].mac_addr[4] = (u8) (mac_addr >> 8);
- sp->def_mac_addr[offset].mac_addr[3] = (u8) (mac_addr >> 16);
- sp->def_mac_addr[offset].mac_addr[2] = (u8) (mac_addr >> 24);
- sp->def_mac_addr[offset].mac_addr[1] = (u8) (mac_addr >> 32);
- sp->def_mac_addr[offset].mac_addr[0] = (u8) (mac_addr >> 40);
-}
-
-/*
- * Constants to be programmed into the Xena's registers, to configure
- * the XAUI.
- */
-
-#define END_SIGN 0x0
-static const u64 herc_act_dtx_cfg[] = {
- /* Set address */
- 0x8000051536750000ULL, 0x80000515367500E0ULL,
- /* Write data */
- 0x8000051536750004ULL, 0x80000515367500E4ULL,
- /* Set address */
- 0x80010515003F0000ULL, 0x80010515003F00E0ULL,
- /* Write data */
- 0x80010515003F0004ULL, 0x80010515003F00E4ULL,
- /* Set address */
- 0x801205150D440000ULL, 0x801205150D4400E0ULL,
- /* Write data */
- 0x801205150D440004ULL, 0x801205150D4400E4ULL,
- /* Set address */
- 0x80020515F2100000ULL, 0x80020515F21000E0ULL,
- /* Write data */
- 0x80020515F2100004ULL, 0x80020515F21000E4ULL,
- /* Done */
- END_SIGN
-};
-
-static const u64 xena_dtx_cfg[] = {
- /* Set address */
- 0x8000051500000000ULL, 0x80000515000000E0ULL,
- /* Write data */
- 0x80000515D9350004ULL, 0x80000515D93500E4ULL,
- /* Set address */
- 0x8001051500000000ULL, 0x80010515000000E0ULL,
- /* Write data */
- 0x80010515001E0004ULL, 0x80010515001E00E4ULL,
- /* Set address */
- 0x8002051500000000ULL, 0x80020515000000E0ULL,
- /* Write data */
- 0x80020515F2100004ULL, 0x80020515F21000E4ULL,
- END_SIGN
-};
-
-/*
- * Constants for Fixing the MacAddress problem seen mostly on
- * Alpha machines.
- */
-static const u64 fix_mac[] = {
- 0x0060000000000000ULL, 0x0060600000000000ULL,
- 0x0040600000000000ULL, 0x0000600000000000ULL,
- 0x0020600000000000ULL, 0x0060600000000000ULL,
- 0x0020600000000000ULL, 0x0060600000000000ULL,
- 0x0020600000000000ULL, 0x0060600000000000ULL,
- 0x0020600000000000ULL, 0x0060600000000000ULL,
- 0x0020600000000000ULL, 0x0060600000000000ULL,
- 0x0020600000000000ULL, 0x0060600000000000ULL,
- 0x0020600000000000ULL, 0x0060600000000000ULL,
- 0x0020600000000000ULL, 0x0060600000000000ULL,
- 0x0020600000000000ULL, 0x0060600000000000ULL,
- 0x0020600000000000ULL, 0x0060600000000000ULL,
- 0x0020600000000000ULL, 0x0000600000000000ULL,
- 0x0040600000000000ULL, 0x0060600000000000ULL,
- END_SIGN
-};
-
-MODULE_DESCRIPTION("Neterion 10GbE driver");
-MODULE_LICENSE("GPL");
-MODULE_VERSION(DRV_VERSION);
-
-
-/* Module Loadable parameters. */
-S2IO_PARM_INT(tx_fifo_num, FIFO_DEFAULT_NUM);
-S2IO_PARM_INT(rx_ring_num, 1);
-S2IO_PARM_INT(multiq, 0);
-S2IO_PARM_INT(rx_ring_mode, 1);
-S2IO_PARM_INT(use_continuous_tx_intrs, 1);
-S2IO_PARM_INT(rmac_pause_time, 0x100);
-S2IO_PARM_INT(mc_pause_threshold_q0q3, 187);
-S2IO_PARM_INT(mc_pause_threshold_q4q7, 187);
-S2IO_PARM_INT(shared_splits, 0);
-S2IO_PARM_INT(tmac_util_period, 5);
-S2IO_PARM_INT(rmac_util_period, 5);
-S2IO_PARM_INT(l3l4hdr_size, 128);
-/* 0 is no steering, 1 is Priority steering, 2 is Default steering */
-S2IO_PARM_INT(tx_steering_type, TX_DEFAULT_STEERING);
-/* Frequency of Rx desc syncs expressed as power of 2 */
-S2IO_PARM_INT(rxsync_frequency, 3);
-/* Interrupt type. Values can be 0(INTA), 2(MSI_X) */
-S2IO_PARM_INT(intr_type, 2);
-/* Large receive offload feature */
-
-/* Max pkts to be aggregated by LRO at one time. If not specified,
- * aggregation happens until we hit max IP pkt size(64K)
- */
-S2IO_PARM_INT(lro_max_pkts, 0xFFFF);
-S2IO_PARM_INT(indicate_max_pkts, 0);
-
-S2IO_PARM_INT(napi, 1);
-S2IO_PARM_INT(vlan_tag_strip, NO_STRIP_IN_PROMISC);
-
-static unsigned int tx_fifo_len[MAX_TX_FIFOS] =
-{DEFAULT_FIFO_0_LEN, [1 ...(MAX_TX_FIFOS - 1)] = DEFAULT_FIFO_1_7_LEN};
-static unsigned int rx_ring_sz[MAX_RX_RINGS] =
-{[0 ...(MAX_RX_RINGS - 1)] = SMALL_BLK_CNT};
-static unsigned int rts_frm_len[MAX_RX_RINGS] =
-{[0 ...(MAX_RX_RINGS - 1)] = 0 };
-
-module_param_array(tx_fifo_len, uint, NULL, 0);
-module_param_array(rx_ring_sz, uint, NULL, 0);
-module_param_array(rts_frm_len, uint, NULL, 0);
-
-/*
- * S2IO device table.
- * This table lists all the devices that this driver supports.
- */
-static const struct pci_device_id s2io_tbl[] = {
- {PCI_VENDOR_ID_S2IO, PCI_DEVICE_ID_S2IO_WIN,
- PCI_ANY_ID, PCI_ANY_ID},
- {PCI_VENDOR_ID_S2IO, PCI_DEVICE_ID_S2IO_UNI,
- PCI_ANY_ID, PCI_ANY_ID},
- {PCI_VENDOR_ID_S2IO, PCI_DEVICE_ID_HERC_WIN,
- PCI_ANY_ID, PCI_ANY_ID},
- {PCI_VENDOR_ID_S2IO, PCI_DEVICE_ID_HERC_UNI,
- PCI_ANY_ID, PCI_ANY_ID},
- {0,}
-};
-
-MODULE_DEVICE_TABLE(pci, s2io_tbl);
-
-static const struct pci_error_handlers s2io_err_handler = {
- .error_detected = s2io_io_error_detected,
- .slot_reset = s2io_io_slot_reset,
- .resume = s2io_io_resume,
-};
-
-static struct pci_driver s2io_driver = {
- .name = "S2IO",
- .id_table = s2io_tbl,
- .probe = s2io_init_nic,
- .remove = s2io_rem_nic,
- .err_handler = &s2io_err_handler,
-};
-
-/* A simplifier macro used both by init and free shared_mem Fns(). */
-#define TXD_MEM_PAGE_CNT(len, per_each) DIV_ROUND_UP(len, per_each)
-
-/* netqueue manipulation helper functions */
-static inline void s2io_stop_all_tx_queue(struct s2io_nic *sp)
-{
- if (!sp->config.multiq) {
- int i;
-
- for (i = 0; i < sp->config.tx_fifo_num; i++)
- sp->mac_control.fifos[i].queue_state = FIFO_QUEUE_STOP;
- }
- netif_tx_stop_all_queues(sp->dev);
-}
-
-static inline void s2io_stop_tx_queue(struct s2io_nic *sp, int fifo_no)
-{
- if (!sp->config.multiq)
- sp->mac_control.fifos[fifo_no].queue_state =
- FIFO_QUEUE_STOP;
-
- netif_tx_stop_all_queues(sp->dev);
-}
-
-static inline void s2io_start_all_tx_queue(struct s2io_nic *sp)
-{
- if (!sp->config.multiq) {
- int i;
-
- for (i = 0; i < sp->config.tx_fifo_num; i++)
- sp->mac_control.fifos[i].queue_state = FIFO_QUEUE_START;
- }
- netif_tx_start_all_queues(sp->dev);
-}
-
-static inline void s2io_wake_all_tx_queue(struct s2io_nic *sp)
-{
- if (!sp->config.multiq) {
- int i;
-
- for (i = 0; i < sp->config.tx_fifo_num; i++)
- sp->mac_control.fifos[i].queue_state = FIFO_QUEUE_START;
- }
- netif_tx_wake_all_queues(sp->dev);
-}
-
-static inline void s2io_wake_tx_queue(
- struct fifo_info *fifo, int cnt, u8 multiq)
-{
-
- if (multiq) {
- if (cnt && __netif_subqueue_stopped(fifo->dev, fifo->fifo_no))
- netif_wake_subqueue(fifo->dev, fifo->fifo_no);
- } else if (cnt && (fifo->queue_state == FIFO_QUEUE_STOP)) {
- if (netif_queue_stopped(fifo->dev)) {
- fifo->queue_state = FIFO_QUEUE_START;
- netif_wake_queue(fifo->dev);
- }
- }
-}
-
-/**
- * init_shared_mem - Allocation and Initialization of Memory
- * @nic: Device private variable.
- * Description: The function allocates all the memory areas shared
- * between the NIC and the driver. This includes Tx descriptors,
- * Rx descriptors and the statistics block.
- */
-
-static int init_shared_mem(struct s2io_nic *nic)
-{
- u32 size;
- void *tmp_v_addr, *tmp_v_addr_next;
- dma_addr_t tmp_p_addr, tmp_p_addr_next;
- struct RxD_block *pre_rxd_blk = NULL;
- int i, j, blk_cnt;
- int lst_size, lst_per_page;
- struct net_device *dev = nic->dev;
- unsigned long tmp;
- struct buffAdd *ba;
- struct config_param *config = &nic->config;
- struct mac_info *mac_control = &nic->mac_control;
- unsigned long long mem_allocated = 0;
-
- /* Allocation and initialization of TXDLs in FIFOs */
- size = 0;
- for (i = 0; i < config->tx_fifo_num; i++) {
- struct tx_fifo_config *tx_cfg = &config->tx_cfg[i];
-
- size += tx_cfg->fifo_len;
- }
- if (size > MAX_AVAILABLE_TXDS) {
- DBG_PRINT(ERR_DBG,
- "Too many TxDs requested: %d, max supported: %d\n",
- size, MAX_AVAILABLE_TXDS);
- return -EINVAL;
- }
-
- size = 0;
- for (i = 0; i < config->tx_fifo_num; i++) {
- struct tx_fifo_config *tx_cfg = &config->tx_cfg[i];
-
- size = tx_cfg->fifo_len;
- /*
- * Legal values are from 2 to 8192
- */
- if (size < 2) {
- DBG_PRINT(ERR_DBG, "Fifo %d: Invalid length (%d) - "
- "Valid lengths are 2 through 8192\n",
- i, size);
- return -EINVAL;
- }
- }
-
- lst_size = (sizeof(struct TxD) * config->max_txds);
- lst_per_page = PAGE_SIZE / lst_size;
-
- for (i = 0; i < config->tx_fifo_num; i++) {
- struct fifo_info *fifo = &mac_control->fifos[i];
- struct tx_fifo_config *tx_cfg = &config->tx_cfg[i];
- int fifo_len = tx_cfg->fifo_len;
- int list_holder_size = fifo_len * sizeof(struct list_info_hold);
-
- fifo->list_info = kzalloc(list_holder_size, GFP_KERNEL);
- if (!fifo->list_info) {
- DBG_PRINT(INFO_DBG, "Malloc failed for list_info\n");
- return -ENOMEM;
- }
- mem_allocated += list_holder_size;
- }
- for (i = 0; i < config->tx_fifo_num; i++) {
- int page_num = TXD_MEM_PAGE_CNT(config->tx_cfg[i].fifo_len,
- lst_per_page);
- struct fifo_info *fifo = &mac_control->fifos[i];
- struct tx_fifo_config *tx_cfg = &config->tx_cfg[i];
-
- fifo->tx_curr_put_info.offset = 0;
- fifo->tx_curr_put_info.fifo_len = tx_cfg->fifo_len - 1;
- fifo->tx_curr_get_info.offset = 0;
- fifo->tx_curr_get_info.fifo_len = tx_cfg->fifo_len - 1;
- fifo->fifo_no = i;
- fifo->nic = nic;
- fifo->max_txds = MAX_SKB_FRAGS + 2;
- fifo->dev = dev;
-
- for (j = 0; j < page_num; j++) {
- int k = 0;
- dma_addr_t tmp_p;
- void *tmp_v;
- tmp_v = dma_alloc_coherent(&nic->pdev->dev, PAGE_SIZE,
- &tmp_p, GFP_KERNEL);
- if (!tmp_v) {
- DBG_PRINT(INFO_DBG,
- "dma_alloc_coherent failed for TxDL\n");
- return -ENOMEM;
- }
- /* If we got a zero DMA address(can happen on
- * certain platforms like PPC), reallocate.
- * Store virtual address of page we don't want,
- * to be freed later.
- */
- if (!tmp_p) {
- mac_control->zerodma_virt_addr = tmp_v;
- DBG_PRINT(INIT_DBG,
- "%s: Zero DMA address for TxDL. "
- "Virtual address %p\n",
- dev->name, tmp_v);
- tmp_v = dma_alloc_coherent(&nic->pdev->dev,
- PAGE_SIZE, &tmp_p,
- GFP_KERNEL);
- if (!tmp_v) {
- DBG_PRINT(INFO_DBG,
- "dma_alloc_coherent failed for TxDL\n");
- return -ENOMEM;
- }
- mem_allocated += PAGE_SIZE;
- }
- while (k < lst_per_page) {
- int l = (j * lst_per_page) + k;
- if (l == tx_cfg->fifo_len)
- break;
- fifo->list_info[l].list_virt_addr =
- tmp_v + (k * lst_size);
- fifo->list_info[l].list_phy_addr =
- tmp_p + (k * lst_size);
- k++;
- }
- }
- }
-
- for (i = 0; i < config->tx_fifo_num; i++) {
- struct fifo_info *fifo = &mac_control->fifos[i];
- struct tx_fifo_config *tx_cfg = &config->tx_cfg[i];
-
- size = tx_cfg->fifo_len;
- fifo->ufo_in_band_v = kcalloc(size, sizeof(u64), GFP_KERNEL);
- if (!fifo->ufo_in_band_v)
- return -ENOMEM;
- mem_allocated += (size * sizeof(u64));
- }
-
- /* Allocation and initialization of RXDs in Rings */
- size = 0;
- for (i = 0; i < config->rx_ring_num; i++) {
- struct rx_ring_config *rx_cfg = &config->rx_cfg[i];
- struct ring_info *ring = &mac_control->rings[i];
-
- if (rx_cfg->num_rxd % (rxd_count[nic->rxd_mode] + 1)) {
- DBG_PRINT(ERR_DBG, "%s: Ring%d RxD count is not a "
- "multiple of RxDs per Block\n",
- dev->name, i);
- return FAILURE;
- }
- size += rx_cfg->num_rxd;
- ring->block_count = rx_cfg->num_rxd /
- (rxd_count[nic->rxd_mode] + 1);
- ring->pkt_cnt = rx_cfg->num_rxd - ring->block_count;
- }
- if (nic->rxd_mode == RXD_MODE_1)
- size = (size * (sizeof(struct RxD1)));
- else
- size = (size * (sizeof(struct RxD3)));
-
- for (i = 0; i < config->rx_ring_num; i++) {
- struct rx_ring_config *rx_cfg = &config->rx_cfg[i];
- struct ring_info *ring = &mac_control->rings[i];
-
- ring->rx_curr_get_info.block_index = 0;
- ring->rx_curr_get_info.offset = 0;
- ring->rx_curr_get_info.ring_len = rx_cfg->num_rxd - 1;
- ring->rx_curr_put_info.block_index = 0;
- ring->rx_curr_put_info.offset = 0;
- ring->rx_curr_put_info.ring_len = rx_cfg->num_rxd - 1;
- ring->nic = nic;
- ring->ring_no = i;
-
- blk_cnt = rx_cfg->num_rxd / (rxd_count[nic->rxd_mode] + 1);
- /* Allocating all the Rx blocks */
- for (j = 0; j < blk_cnt; j++) {
- struct rx_block_info *rx_blocks;
- int l;
-
- rx_blocks = &ring->rx_blocks[j];
- size = SIZE_OF_BLOCK; /* size is always page size */
- tmp_v_addr = dma_alloc_coherent(&nic->pdev->dev, size,
- &tmp_p_addr, GFP_KERNEL);
- if (tmp_v_addr == NULL) {
- /*
- * In case of failure, free_shared_mem()
- * is called, which should free any
- * memory that was alloced till the
- * failure happened.
- */
- rx_blocks->block_virt_addr = tmp_v_addr;
- return -ENOMEM;
- }
- mem_allocated += size;
-
- size = sizeof(struct rxd_info) *
- rxd_count[nic->rxd_mode];
- rx_blocks->block_virt_addr = tmp_v_addr;
- rx_blocks->block_dma_addr = tmp_p_addr;
- rx_blocks->rxds = kmalloc(size, GFP_KERNEL);
- if (!rx_blocks->rxds)
- return -ENOMEM;
- mem_allocated += size;
- for (l = 0; l < rxd_count[nic->rxd_mode]; l++) {
- rx_blocks->rxds[l].virt_addr =
- rx_blocks->block_virt_addr +
- (rxd_size[nic->rxd_mode] * l);
- rx_blocks->rxds[l].dma_addr =
- rx_blocks->block_dma_addr +
- (rxd_size[nic->rxd_mode] * l);
- }
- }
- /* Interlinking all Rx Blocks */
- for (j = 0; j < blk_cnt; j++) {
- int next = (j + 1) % blk_cnt;
- tmp_v_addr = ring->rx_blocks[j].block_virt_addr;
- tmp_v_addr_next = ring->rx_blocks[next].block_virt_addr;
- tmp_p_addr = ring->rx_blocks[j].block_dma_addr;
- tmp_p_addr_next = ring->rx_blocks[next].block_dma_addr;
-
- pre_rxd_blk = tmp_v_addr;
- pre_rxd_blk->reserved_2_pNext_RxD_block =
- (unsigned long)tmp_v_addr_next;
- pre_rxd_blk->pNext_RxD_Blk_physical =
- (u64)tmp_p_addr_next;
- }
- }
- if (nic->rxd_mode == RXD_MODE_3B) {
- /*
- * Allocation of Storages for buffer addresses in 2BUFF mode
- * and the buffers as well.
- */
- for (i = 0; i < config->rx_ring_num; i++) {
- struct rx_ring_config *rx_cfg = &config->rx_cfg[i];
- struct ring_info *ring = &mac_control->rings[i];
-
- blk_cnt = rx_cfg->num_rxd /
- (rxd_count[nic->rxd_mode] + 1);
- size = sizeof(struct buffAdd *) * blk_cnt;
- ring->ba = kmalloc(size, GFP_KERNEL);
- if (!ring->ba)
- return -ENOMEM;
- mem_allocated += size;
- for (j = 0; j < blk_cnt; j++) {
- int k = 0;
-
- size = sizeof(struct buffAdd) *
- (rxd_count[nic->rxd_mode] + 1);
- ring->ba[j] = kmalloc(size, GFP_KERNEL);
- if (!ring->ba[j])
- return -ENOMEM;
- mem_allocated += size;
- while (k != rxd_count[nic->rxd_mode]) {
- ba = &ring->ba[j][k];
- size = BUF0_LEN + ALIGN_SIZE;
- ba->ba_0_org = kmalloc(size, GFP_KERNEL);
- if (!ba->ba_0_org)
- return -ENOMEM;
- mem_allocated += size;
- tmp = (unsigned long)ba->ba_0_org;
- tmp += ALIGN_SIZE;
- tmp &= ~((unsigned long)ALIGN_SIZE);
- ba->ba_0 = (void *)tmp;
-
- size = BUF1_LEN + ALIGN_SIZE;
- ba->ba_1_org = kmalloc(size, GFP_KERNEL);
- if (!ba->ba_1_org)
- return -ENOMEM;
- mem_allocated += size;
- tmp = (unsigned long)ba->ba_1_org;
- tmp += ALIGN_SIZE;
- tmp &= ~((unsigned long)ALIGN_SIZE);
- ba->ba_1 = (void *)tmp;
- k++;
- }
- }
- }
- }
-
- /* Allocation and initialization of Statistics block */
- size = sizeof(struct stat_block);
- mac_control->stats_mem =
- dma_alloc_coherent(&nic->pdev->dev, size,
- &mac_control->stats_mem_phy, GFP_KERNEL);
-
- if (!mac_control->stats_mem) {
- /*
- * In case of failure, free_shared_mem() is called, which
- * should free any memory that was alloced till the
- * failure happened.
- */
- return -ENOMEM;
- }
- mem_allocated += size;
- mac_control->stats_mem_sz = size;
-
- tmp_v_addr = mac_control->stats_mem;
- mac_control->stats_info = tmp_v_addr;
- memset(tmp_v_addr, 0, size);
- DBG_PRINT(INIT_DBG, "%s: Ring Mem PHY: 0x%llx\n",
- dev_name(&nic->pdev->dev), (unsigned long long)tmp_p_addr);
- mac_control->stats_info->sw_stat.mem_allocated += mem_allocated;
- return SUCCESS;
-}
-
-/**
- * free_shared_mem - Free the allocated Memory
- * @nic: Device private variable.
- * Description: This function is to free all memory locations allocated by
- * the init_shared_mem() function and return it to the kernel.
- */
-
-static void free_shared_mem(struct s2io_nic *nic)
-{
- int i, j, blk_cnt, size;
- void *tmp_v_addr;
- dma_addr_t tmp_p_addr;
- int lst_size, lst_per_page;
- struct net_device *dev;
- int page_num = 0;
- struct config_param *config;
- struct mac_info *mac_control;
- struct stat_block *stats;
- struct swStat *swstats;
-
- if (!nic)
- return;
-
- dev = nic->dev;
-
- config = &nic->config;
- mac_control = &nic->mac_control;
- stats = mac_control->stats_info;
- swstats = &stats->sw_stat;
-
- lst_size = sizeof(struct TxD) * config->max_txds;
- lst_per_page = PAGE_SIZE / lst_size;
-
- for (i = 0; i < config->tx_fifo_num; i++) {
- struct fifo_info *fifo = &mac_control->fifos[i];
- struct tx_fifo_config *tx_cfg = &config->tx_cfg[i];
-
- page_num = TXD_MEM_PAGE_CNT(tx_cfg->fifo_len, lst_per_page);
- for (j = 0; j < page_num; j++) {
- int mem_blks = (j * lst_per_page);
- struct list_info_hold *fli;
-
- if (!fifo->list_info)
- return;
-
- fli = &fifo->list_info[mem_blks];
- if (!fli->list_virt_addr)
- break;
- dma_free_coherent(&nic->pdev->dev, PAGE_SIZE,
- fli->list_virt_addr,
- fli->list_phy_addr);
- swstats->mem_freed += PAGE_SIZE;
- }
- /* If we got a zero DMA address during allocation,
- * free the page now
- */
- if (mac_control->zerodma_virt_addr) {
- dma_free_coherent(&nic->pdev->dev, PAGE_SIZE,
- mac_control->zerodma_virt_addr,
- (dma_addr_t)0);
- DBG_PRINT(INIT_DBG,
- "%s: Freeing TxDL with zero DMA address. "
- "Virtual address %p\n",
- dev->name, mac_control->zerodma_virt_addr);
- swstats->mem_freed += PAGE_SIZE;
- }
- kfree(fifo->list_info);
- swstats->mem_freed += tx_cfg->fifo_len *
- sizeof(struct list_info_hold);
- }
-
- size = SIZE_OF_BLOCK;
- for (i = 0; i < config->rx_ring_num; i++) {
- struct ring_info *ring = &mac_control->rings[i];
-
- blk_cnt = ring->block_count;
- for (j = 0; j < blk_cnt; j++) {
- tmp_v_addr = ring->rx_blocks[j].block_virt_addr;
- tmp_p_addr = ring->rx_blocks[j].block_dma_addr;
- if (tmp_v_addr == NULL)
- break;
- dma_free_coherent(&nic->pdev->dev, size, tmp_v_addr,
- tmp_p_addr);
- swstats->mem_freed += size;
- kfree(ring->rx_blocks[j].rxds);
- swstats->mem_freed += sizeof(struct rxd_info) *
- rxd_count[nic->rxd_mode];
- }
- }
-
- if (nic->rxd_mode == RXD_MODE_3B) {
- /* Freeing buffer storage addresses in 2BUFF mode. */
- for (i = 0; i < config->rx_ring_num; i++) {
- struct rx_ring_config *rx_cfg = &config->rx_cfg[i];
- struct ring_info *ring = &mac_control->rings[i];
-
- blk_cnt = rx_cfg->num_rxd /
- (rxd_count[nic->rxd_mode] + 1);
- for (j = 0; j < blk_cnt; j++) {
- int k = 0;
- if (!ring->ba[j])
- continue;
- while (k != rxd_count[nic->rxd_mode]) {
- struct buffAdd *ba = &ring->ba[j][k];
- kfree(ba->ba_0_org);
- swstats->mem_freed +=
- BUF0_LEN + ALIGN_SIZE;
- kfree(ba->ba_1_org);
- swstats->mem_freed +=
- BUF1_LEN + ALIGN_SIZE;
- k++;
- }
- kfree(ring->ba[j]);
- swstats->mem_freed += sizeof(struct buffAdd) *
- (rxd_count[nic->rxd_mode] + 1);
- }
- kfree(ring->ba);
- swstats->mem_freed += sizeof(struct buffAdd *) *
- blk_cnt;
- }
- }
-
- for (i = 0; i < nic->config.tx_fifo_num; i++) {
- struct fifo_info *fifo = &mac_control->fifos[i];
- struct tx_fifo_config *tx_cfg = &config->tx_cfg[i];
-
- if (fifo->ufo_in_band_v) {
- swstats->mem_freed += tx_cfg->fifo_len *
- sizeof(u64);
- kfree(fifo->ufo_in_band_v);
- }
- }
-
- if (mac_control->stats_mem) {
- swstats->mem_freed += mac_control->stats_mem_sz;
- dma_free_coherent(&nic->pdev->dev, mac_control->stats_mem_sz,
- mac_control->stats_mem,
- mac_control->stats_mem_phy);
- }
-}
-
-/*
- * s2io_verify_pci_mode -
- */
-
-static int s2io_verify_pci_mode(struct s2io_nic *nic)
-{
- struct XENA_dev_config __iomem *bar0 = nic->bar0;
- register u64 val64 = 0;
- int mode;
-
- val64 = readq(&bar0->pci_mode);
- mode = (u8)GET_PCI_MODE(val64);
-
- if (val64 & PCI_MODE_UNKNOWN_MODE)
- return -1; /* Unknown PCI mode */
- return mode;
-}
-
-#define NEC_VENID 0x1033
-#define NEC_DEVID 0x0125
-static int s2io_on_nec_bridge(struct pci_dev *s2io_pdev)
-{
- struct pci_dev *tdev = NULL;
- for_each_pci_dev(tdev) {
- if (tdev->vendor == NEC_VENID && tdev->device == NEC_DEVID) {
- if (tdev->bus == s2io_pdev->bus->parent) {
- pci_dev_put(tdev);
- return 1;
- }
- }
- }
- return 0;
-}
-
-static int bus_speed[8] = {33, 133, 133, 200, 266, 133, 200, 266};
-/*
- * s2io_print_pci_mode -
- */
-static int s2io_print_pci_mode(struct s2io_nic *nic)
-{
- struct XENA_dev_config __iomem *bar0 = nic->bar0;
- register u64 val64 = 0;
- int mode;
- struct config_param *config = &nic->config;
- const char *pcimode;
-
- val64 = readq(&bar0->pci_mode);
- mode = (u8)GET_PCI_MODE(val64);
-
- if (val64 & PCI_MODE_UNKNOWN_MODE)
- return -1; /* Unknown PCI mode */
-
- config->bus_speed = bus_speed[mode];
-
- if (s2io_on_nec_bridge(nic->pdev)) {
- DBG_PRINT(ERR_DBG, "%s: Device is on PCI-E bus\n",
- nic->dev->name);
- return mode;
- }
-
- switch (mode) {
- case PCI_MODE_PCI_33:
- pcimode = "33MHz PCI bus";
- break;
- case PCI_MODE_PCI_66:
- pcimode = "66MHz PCI bus";
- break;
- case PCI_MODE_PCIX_M1_66:
- pcimode = "66MHz PCIX(M1) bus";
- break;
- case PCI_MODE_PCIX_M1_100:
- pcimode = "100MHz PCIX(M1) bus";
- break;
- case PCI_MODE_PCIX_M1_133:
- pcimode = "133MHz PCIX(M1) bus";
- break;
- case PCI_MODE_PCIX_M2_66:
- pcimode = "133MHz PCIX(M2) bus";
- break;
- case PCI_MODE_PCIX_M2_100:
- pcimode = "200MHz PCIX(M2) bus";
- break;
- case PCI_MODE_PCIX_M2_133:
- pcimode = "266MHz PCIX(M2) bus";
- break;
- default:
- pcimode = "unsupported bus!";
- mode = -1;
- }
-
- DBG_PRINT(ERR_DBG, "%s: Device is on %d bit %s\n",
- nic->dev->name, val64 & PCI_MODE_32_BITS ? 32 : 64, pcimode);
-
- return mode;
-}
-
-/**
- * init_tti - Initialization transmit traffic interrupt scheme
- * @nic: device private variable
- * @link: link status (UP/DOWN) used to enable/disable continuous
- * transmit interrupts
- * @may_sleep: parameter indicates if sleeping when waiting for
- * command complete
- * Description: The function configures transmit traffic interrupts
- * Return Value: SUCCESS on success and
- * '-1' on failure
- */
-
-static int init_tti(struct s2io_nic *nic, int link, bool may_sleep)
-{
- struct XENA_dev_config __iomem *bar0 = nic->bar0;
- register u64 val64 = 0;
- int i;
- struct config_param *config = &nic->config;
-
- for (i = 0; i < config->tx_fifo_num; i++) {
- /*
- * TTI Initialization. Default Tx timer gets us about
- * 250 interrupts per sec. Continuous interrupts are enabled
- * by default.
- */
- if (nic->device_type == XFRAME_II_DEVICE) {
- int count = (nic->config.bus_speed * 125)/2;
- val64 = TTI_DATA1_MEM_TX_TIMER_VAL(count);
- } else
- val64 = TTI_DATA1_MEM_TX_TIMER_VAL(0x2078);
-
- val64 |= TTI_DATA1_MEM_TX_URNG_A(0xA) |
- TTI_DATA1_MEM_TX_URNG_B(0x10) |
- TTI_DATA1_MEM_TX_URNG_C(0x30) |
- TTI_DATA1_MEM_TX_TIMER_AC_EN;
- if (i == 0)
- if (use_continuous_tx_intrs && (link == LINK_UP))
- val64 |= TTI_DATA1_MEM_TX_TIMER_CI_EN;
- writeq(val64, &bar0->tti_data1_mem);
-
- if (nic->config.intr_type == MSI_X) {
- val64 = TTI_DATA2_MEM_TX_UFC_A(0x10) |
- TTI_DATA2_MEM_TX_UFC_B(0x100) |
- TTI_DATA2_MEM_TX_UFC_C(0x200) |
- TTI_DATA2_MEM_TX_UFC_D(0x300);
- } else {
- if ((nic->config.tx_steering_type ==
- TX_DEFAULT_STEERING) &&
- (config->tx_fifo_num > 1) &&
- (i >= nic->udp_fifo_idx) &&
- (i < (nic->udp_fifo_idx +
- nic->total_udp_fifos)))
- val64 = TTI_DATA2_MEM_TX_UFC_A(0x50) |
- TTI_DATA2_MEM_TX_UFC_B(0x80) |
- TTI_DATA2_MEM_TX_UFC_C(0x100) |
- TTI_DATA2_MEM_TX_UFC_D(0x120);
- else
- val64 = TTI_DATA2_MEM_TX_UFC_A(0x10) |
- TTI_DATA2_MEM_TX_UFC_B(0x20) |
- TTI_DATA2_MEM_TX_UFC_C(0x40) |
- TTI_DATA2_MEM_TX_UFC_D(0x80);
- }
-
- writeq(val64, &bar0->tti_data2_mem);
-
- val64 = TTI_CMD_MEM_WE |
- TTI_CMD_MEM_STROBE_NEW_CMD |
- TTI_CMD_MEM_OFFSET(i);
- writeq(val64, &bar0->tti_command_mem);
-
- if (wait_for_cmd_complete(&bar0->tti_command_mem,
- TTI_CMD_MEM_STROBE_NEW_CMD,
- S2IO_BIT_RESET, may_sleep) != SUCCESS)
- return FAILURE;
- }
-
- return SUCCESS;
-}
-
-/**
- * init_nic - Initialization of hardware
- * @nic: device private variable
- * Description: The function sequentially configures every block
- * of the H/W from their reset values.
- * Return Value: SUCCESS on success and
- * '-1' on failure (endian settings incorrect).
- */
-
-static int init_nic(struct s2io_nic *nic)
-{
- struct XENA_dev_config __iomem *bar0 = nic->bar0;
- struct net_device *dev = nic->dev;
- register u64 val64 = 0;
- void __iomem *add;
- u32 time;
- int i, j;
- int dtx_cnt = 0;
- unsigned long long mem_share;
- int mem_size;
- struct config_param *config = &nic->config;
- struct mac_info *mac_control = &nic->mac_control;
-
- /* to set the swapper controle on the card */
- if (s2io_set_swapper(nic)) {
- DBG_PRINT(ERR_DBG, "ERROR: Setting Swapper failed\n");
- return -EIO;
- }
-
- /*
- * Herc requires EOI to be removed from reset before XGXS, so..
- */
- if (nic->device_type & XFRAME_II_DEVICE) {
- val64 = 0xA500000000ULL;
- writeq(val64, &bar0->sw_reset);
- msleep(500);
- val64 = readq(&bar0->sw_reset);
- }
-
- /* Remove XGXS from reset state */
- val64 = 0;
- writeq(val64, &bar0->sw_reset);
- msleep(500);
- val64 = readq(&bar0->sw_reset);
-
- /* Ensure that it's safe to access registers by checking
- * RIC_RUNNING bit is reset. Check is valid only for XframeII.
- */
- if (nic->device_type == XFRAME_II_DEVICE) {
- for (i = 0; i < 50; i++) {
- val64 = readq(&bar0->adapter_status);
- if (!(val64 & ADAPTER_STATUS_RIC_RUNNING))
- break;
- msleep(10);
- }
- if (i == 50)
- return -ENODEV;
- }
-
- /* Enable Receiving broadcasts */
- add = &bar0->mac_cfg;
- val64 = readq(&bar0->mac_cfg);
- val64 |= MAC_RMAC_BCAST_ENABLE;
- writeq(RMAC_CFG_KEY(0x4C0D), &bar0->rmac_cfg_key);
- writel((u32)val64, add);
- writeq(RMAC_CFG_KEY(0x4C0D), &bar0->rmac_cfg_key);
- writel((u32) (val64 >> 32), (add + 4));
-
- /* Read registers in all blocks */
- val64 = readq(&bar0->mac_int_mask);
- val64 = readq(&bar0->mc_int_mask);
- val64 = readq(&bar0->xgxs_int_mask);
-
- /* Set MTU */
- val64 = dev->mtu;
- writeq(vBIT(val64, 2, 14), &bar0->rmac_max_pyld_len);
-
- if (nic->device_type & XFRAME_II_DEVICE) {
- while (herc_act_dtx_cfg[dtx_cnt] != END_SIGN) {
- SPECIAL_REG_WRITE(herc_act_dtx_cfg[dtx_cnt],
- &bar0->dtx_control, UF);
- if (dtx_cnt & 0x1)
- msleep(1); /* Necessary!! */
- dtx_cnt++;
- }
- } else {
- while (xena_dtx_cfg[dtx_cnt] != END_SIGN) {
- SPECIAL_REG_WRITE(xena_dtx_cfg[dtx_cnt],
- &bar0->dtx_control, UF);
- val64 = readq(&bar0->dtx_control);
- dtx_cnt++;
- }
- }
-
- /* Tx DMA Initialization */
- val64 = 0;
- writeq(val64, &bar0->tx_fifo_partition_0);
- writeq(val64, &bar0->tx_fifo_partition_1);
- writeq(val64, &bar0->tx_fifo_partition_2);
- writeq(val64, &bar0->tx_fifo_partition_3);
-
- for (i = 0, j = 0; i < config->tx_fifo_num; i++) {
- struct tx_fifo_config *tx_cfg = &config->tx_cfg[i];
-
- val64 |= vBIT(tx_cfg->fifo_len - 1, ((j * 32) + 19), 13) |
- vBIT(tx_cfg->fifo_priority, ((j * 32) + 5), 3);
-
- if (i == (config->tx_fifo_num - 1)) {
- if (i % 2 == 0)
- i++;
- }
-
- switch (i) {
- case 1:
- writeq(val64, &bar0->tx_fifo_partition_0);
- val64 = 0;
- j = 0;
- break;
- case 3:
- writeq(val64, &bar0->tx_fifo_partition_1);
- val64 = 0;
- j = 0;
- break;
- case 5:
- writeq(val64, &bar0->tx_fifo_partition_2);
- val64 = 0;
- j = 0;
- break;
- case 7:
- writeq(val64, &bar0->tx_fifo_partition_3);
- val64 = 0;
- j = 0;
- break;
- default:
- j++;
- break;
- }
- }
-
- /*
- * Disable 4 PCCs for Xena1, 2 and 3 as per H/W bug
- * SXE-008 TRANSMIT DMA ARBITRATION ISSUE.
- */
- if ((nic->device_type == XFRAME_I_DEVICE) && (nic->pdev->revision < 4))
- writeq(PCC_ENABLE_FOUR, &bar0->pcc_enable);
-
- val64 = readq(&bar0->tx_fifo_partition_0);
- DBG_PRINT(INIT_DBG, "Fifo partition at: 0x%p is: 0x%llx\n",
- &bar0->tx_fifo_partition_0, (unsigned long long)val64);
-
- /*
- * Initialization of Tx_PA_CONFIG register to ignore packet
- * integrity checking.
- */
- val64 = readq(&bar0->tx_pa_cfg);
- val64 |= TX_PA_CFG_IGNORE_FRM_ERR |
- TX_PA_CFG_IGNORE_SNAP_OUI |
- TX_PA_CFG_IGNORE_LLC_CTRL |
- TX_PA_CFG_IGNORE_L2_ERR;
- writeq(val64, &bar0->tx_pa_cfg);
-
- /* Rx DMA initialization. */
- val64 = 0;
- for (i = 0; i < config->rx_ring_num; i++) {
- struct rx_ring_config *rx_cfg = &config->rx_cfg[i];
-
- val64 |= vBIT(rx_cfg->ring_priority, (5 + (i * 8)), 3);
- }
- writeq(val64, &bar0->rx_queue_priority);
-
- /*
- * Allocating equal share of memory to all the
- * configured Rings.
- */
- val64 = 0;
- if (nic->device_type & XFRAME_II_DEVICE)
- mem_size = 32;
- else
- mem_size = 64;
-
- for (i = 0; i < config->rx_ring_num; i++) {
- switch (i) {
- case 0:
- mem_share = (mem_size / config->rx_ring_num +
- mem_size % config->rx_ring_num);
- val64 |= RX_QUEUE_CFG_Q0_SZ(mem_share);
- continue;
- case 1:
- mem_share = (mem_size / config->rx_ring_num);
- val64 |= RX_QUEUE_CFG_Q1_SZ(mem_share);
- continue;
- case 2:
- mem_share = (mem_size / config->rx_ring_num);
- val64 |= RX_QUEUE_CFG_Q2_SZ(mem_share);
- continue;
- case 3:
- mem_share = (mem_size / config->rx_ring_num);
- val64 |= RX_QUEUE_CFG_Q3_SZ(mem_share);
- continue;
- case 4:
- mem_share = (mem_size / config->rx_ring_num);
- val64 |= RX_QUEUE_CFG_Q4_SZ(mem_share);
- continue;
- case 5:
- mem_share = (mem_size / config->rx_ring_num);
- val64 |= RX_QUEUE_CFG_Q5_SZ(mem_share);
- continue;
- case 6:
- mem_share = (mem_size / config->rx_ring_num);
- val64 |= RX_QUEUE_CFG_Q6_SZ(mem_share);
- continue;
- case 7:
- mem_share = (mem_size / config->rx_ring_num);
- val64 |= RX_QUEUE_CFG_Q7_SZ(mem_share);
- continue;
- }
- }
- writeq(val64, &bar0->rx_queue_cfg);
-
- /*
- * Filling Tx round robin registers
- * as per the number of FIFOs for equal scheduling priority
- */
- switch (config->tx_fifo_num) {
- case 1:
- val64 = 0x0;
- writeq(val64, &bar0->tx_w_round_robin_0);
- writeq(val64, &bar0->tx_w_round_robin_1);
- writeq(val64, &bar0->tx_w_round_robin_2);
- writeq(val64, &bar0->tx_w_round_robin_3);
- writeq(val64, &bar0->tx_w_round_robin_4);
- break;
- case 2:
- val64 = 0x0001000100010001ULL;
- writeq(val64, &bar0->tx_w_round_robin_0);
- writeq(val64, &bar0->tx_w_round_robin_1);
- writeq(val64, &bar0->tx_w_round_robin_2);
- writeq(val64, &bar0->tx_w_round_robin_3);
- val64 = 0x0001000100000000ULL;
- writeq(val64, &bar0->tx_w_round_robin_4);
- break;
- case 3:
- val64 = 0x0001020001020001ULL;
- writeq(val64, &bar0->tx_w_round_robin_0);
- val64 = 0x0200010200010200ULL;
- writeq(val64, &bar0->tx_w_round_robin_1);
- val64 = 0x0102000102000102ULL;
- writeq(val64, &bar0->tx_w_round_robin_2);
- val64 = 0x0001020001020001ULL;
- writeq(val64, &bar0->tx_w_round_robin_3);
- val64 = 0x0200010200000000ULL;
- writeq(val64, &bar0->tx_w_round_robin_4);
- break;
- case 4:
- val64 = 0x0001020300010203ULL;
- writeq(val64, &bar0->tx_w_round_robin_0);
- writeq(val64, &bar0->tx_w_round_robin_1);
- writeq(val64, &bar0->tx_w_round_robin_2);
- writeq(val64, &bar0->tx_w_round_robin_3);
- val64 = 0x0001020300000000ULL;
- writeq(val64, &bar0->tx_w_round_robin_4);
- break;
- case 5:
- val64 = 0x0001020304000102ULL;
- writeq(val64, &bar0->tx_w_round_robin_0);
- val64 = 0x0304000102030400ULL;
- writeq(val64, &bar0->tx_w_round_robin_1);
- val64 = 0x0102030400010203ULL;
- writeq(val64, &bar0->tx_w_round_robin_2);
- val64 = 0x0400010203040001ULL;
- writeq(val64, &bar0->tx_w_round_robin_3);
- val64 = 0x0203040000000000ULL;
- writeq(val64, &bar0->tx_w_round_robin_4);
- break;
- case 6:
- val64 = 0x0001020304050001ULL;
- writeq(val64, &bar0->tx_w_round_robin_0);
- val64 = 0x0203040500010203ULL;
- writeq(val64, &bar0->tx_w_round_robin_1);
- val64 = 0x0405000102030405ULL;
- writeq(val64, &bar0->tx_w_round_robin_2);
- val64 = 0x0001020304050001ULL;
- writeq(val64, &bar0->tx_w_round_robin_3);
- val64 = 0x0203040500000000ULL;
- writeq(val64, &bar0->tx_w_round_robin_4);
- break;
- case 7:
- val64 = 0x0001020304050600ULL;
- writeq(val64, &bar0->tx_w_round_robin_0);
- val64 = 0x0102030405060001ULL;
- writeq(val64, &bar0->tx_w_round_robin_1);
- val64 = 0x0203040506000102ULL;
- writeq(val64, &bar0->tx_w_round_robin_2);
- val64 = 0x0304050600010203ULL;
- writeq(val64, &bar0->tx_w_round_robin_3);
- val64 = 0x0405060000000000ULL;
- writeq(val64, &bar0->tx_w_round_robin_4);
- break;
- case 8:
- val64 = 0x0001020304050607ULL;
- writeq(val64, &bar0->tx_w_round_robin_0);
- writeq(val64, &bar0->tx_w_round_robin_1);
- writeq(val64, &bar0->tx_w_round_robin_2);
- writeq(val64, &bar0->tx_w_round_robin_3);
- val64 = 0x0001020300000000ULL;
- writeq(val64, &bar0->tx_w_round_robin_4);
- break;
- }
-
- /* Enable all configured Tx FIFO partitions */
- val64 = readq(&bar0->tx_fifo_partition_0);
- val64 |= (TX_FIFO_PARTITION_EN);
- writeq(val64, &bar0->tx_fifo_partition_0);
-
- /* Filling the Rx round robin registers as per the
- * number of Rings and steering based on QoS with
- * equal priority.
- */
- switch (config->rx_ring_num) {
- case 1:
- val64 = 0x0;
- writeq(val64, &bar0->rx_w_round_robin_0);
- writeq(val64, &bar0->rx_w_round_robin_1);
- writeq(val64, &bar0->rx_w_round_robin_2);
- writeq(val64, &bar0->rx_w_round_robin_3);
- writeq(val64, &bar0->rx_w_round_robin_4);
-
- val64 = 0x8080808080808080ULL;
- writeq(val64, &bar0->rts_qos_steering);
- break;
- case 2:
- val64 = 0x0001000100010001ULL;
- writeq(val64, &bar0->rx_w_round_robin_0);
- writeq(val64, &bar0->rx_w_round_robin_1);
- writeq(val64, &bar0->rx_w_round_robin_2);
- writeq(val64, &bar0->rx_w_round_robin_3);
- val64 = 0x0001000100000000ULL;
- writeq(val64, &bar0->rx_w_round_robin_4);
-
- val64 = 0x8080808040404040ULL;
- writeq(val64, &bar0->rts_qos_steering);
- break;
- case 3:
- val64 = 0x0001020001020001ULL;
- writeq(val64, &bar0->rx_w_round_robin_0);
- val64 = 0x0200010200010200ULL;
- writeq(val64, &bar0->rx_w_round_robin_1);
- val64 = 0x0102000102000102ULL;
- writeq(val64, &bar0->rx_w_round_robin_2);
- val64 = 0x0001020001020001ULL;
- writeq(val64, &bar0->rx_w_round_robin_3);
- val64 = 0x0200010200000000ULL;
- writeq(val64, &bar0->rx_w_round_robin_4);
-
- val64 = 0x8080804040402020ULL;
- writeq(val64, &bar0->rts_qos_steering);
- break;
- case 4:
- val64 = 0x0001020300010203ULL;
- writeq(val64, &bar0->rx_w_round_robin_0);
- writeq(val64, &bar0->rx_w_round_robin_1);
- writeq(val64, &bar0->rx_w_round_robin_2);
- writeq(val64, &bar0->rx_w_round_robin_3);
- val64 = 0x0001020300000000ULL;
- writeq(val64, &bar0->rx_w_round_robin_4);
-
- val64 = 0x8080404020201010ULL;
- writeq(val64, &bar0->rts_qos_steering);
- break;
- case 5:
- val64 = 0x0001020304000102ULL;
- writeq(val64, &bar0->rx_w_round_robin_0);
- val64 = 0x0304000102030400ULL;
- writeq(val64, &bar0->rx_w_round_robin_1);
- val64 = 0x0102030400010203ULL;
- writeq(val64, &bar0->rx_w_round_robin_2);
- val64 = 0x0400010203040001ULL;
- writeq(val64, &bar0->rx_w_round_robin_3);
- val64 = 0x0203040000000000ULL;
- writeq(val64, &bar0->rx_w_round_robin_4);
-
- val64 = 0x8080404020201008ULL;
- writeq(val64, &bar0->rts_qos_steering);
- break;
- case 6:
- val64 = 0x0001020304050001ULL;
- writeq(val64, &bar0->rx_w_round_robin_0);
- val64 = 0x0203040500010203ULL;
- writeq(val64, &bar0->rx_w_round_robin_1);
- val64 = 0x0405000102030405ULL;
- writeq(val64, &bar0->rx_w_round_robin_2);
- val64 = 0x0001020304050001ULL;
- writeq(val64, &bar0->rx_w_round_robin_3);
- val64 = 0x0203040500000000ULL;
- writeq(val64, &bar0->rx_w_round_robin_4);
-
- val64 = 0x8080404020100804ULL;
- writeq(val64, &bar0->rts_qos_steering);
- break;
- case 7:
- val64 = 0x0001020304050600ULL;
- writeq(val64, &bar0->rx_w_round_robin_0);
- val64 = 0x0102030405060001ULL;
- writeq(val64, &bar0->rx_w_round_robin_1);
- val64 = 0x0203040506000102ULL;
- writeq(val64, &bar0->rx_w_round_robin_2);
- val64 = 0x0304050600010203ULL;
- writeq(val64, &bar0->rx_w_round_robin_3);
- val64 = 0x0405060000000000ULL;
- writeq(val64, &bar0->rx_w_round_robin_4);
-
- val64 = 0x8080402010080402ULL;
- writeq(val64, &bar0->rts_qos_steering);
- break;
- case 8:
- val64 = 0x0001020304050607ULL;
- writeq(val64, &bar0->rx_w_round_robin_0);
- writeq(val64, &bar0->rx_w_round_robin_1);
- writeq(val64, &bar0->rx_w_round_robin_2);
- writeq(val64, &bar0->rx_w_round_robin_3);
- val64 = 0x0001020300000000ULL;
- writeq(val64, &bar0->rx_w_round_robin_4);
-
- val64 = 0x8040201008040201ULL;
- writeq(val64, &bar0->rts_qos_steering);
- break;
- }
-
- /* UDP Fix */
- val64 = 0;
- for (i = 0; i < 8; i++)
- writeq(val64, &bar0->rts_frm_len_n[i]);
-
- /* Set the default rts frame length for the rings configured */
- val64 = MAC_RTS_FRM_LEN_SET(dev->mtu+22);
- for (i = 0 ; i < config->rx_ring_num ; i++)
- writeq(val64, &bar0->rts_frm_len_n[i]);
-
- /* Set the frame length for the configured rings
- * desired by the user
- */
- for (i = 0; i < config->rx_ring_num; i++) {
- /* If rts_frm_len[i] == 0 then it is assumed that user not
- * specified frame length steering.
- * If the user provides the frame length then program
- * the rts_frm_len register for those values or else
- * leave it as it is.
- */
- if (rts_frm_len[i] != 0) {
- writeq(MAC_RTS_FRM_LEN_SET(rts_frm_len[i]),
- &bar0->rts_frm_len_n[i]);
- }
- }
-
- /* Disable differentiated services steering logic */
- for (i = 0; i < 64; i++) {
- if (rts_ds_steer(nic, i, 0) == FAILURE) {
- DBG_PRINT(ERR_DBG,
- "%s: rts_ds_steer failed on codepoint %d\n",
- dev->name, i);
- return -ENODEV;
- }
- }
-
- /* Program statistics memory */
- writeq(mac_control->stats_mem_phy, &bar0->stat_addr);
-
- if (nic->device_type == XFRAME_II_DEVICE) {
- val64 = STAT_BC(0x320);
- writeq(val64, &bar0->stat_byte_cnt);
- }
-
- /*
- * Initializing the sampling rate for the device to calculate the
- * bandwidth utilization.
- */
- val64 = MAC_TX_LINK_UTIL_VAL(tmac_util_period) |
- MAC_RX_LINK_UTIL_VAL(rmac_util_period);
- writeq(val64, &bar0->mac_link_util);
-
- /*
- * Initializing the Transmit and Receive Traffic Interrupt
- * Scheme.
- */
-
- /* Initialize TTI */
- if (SUCCESS != init_tti(nic, nic->last_link_state, true))
- return -ENODEV;
-
- /* RTI Initialization */
- if (nic->device_type == XFRAME_II_DEVICE) {
- /*
- * Programmed to generate Apprx 500 Intrs per
- * second
- */
- int count = (nic->config.bus_speed * 125)/4;
- val64 = RTI_DATA1_MEM_RX_TIMER_VAL(count);
- } else
- val64 = RTI_DATA1_MEM_RX_TIMER_VAL(0xFFF);
- val64 |= RTI_DATA1_MEM_RX_URNG_A(0xA) |
- RTI_DATA1_MEM_RX_URNG_B(0x10) |
- RTI_DATA1_MEM_RX_URNG_C(0x30) |
- RTI_DATA1_MEM_RX_TIMER_AC_EN;
-
- writeq(val64, &bar0->rti_data1_mem);
-
- val64 = RTI_DATA2_MEM_RX_UFC_A(0x1) |
- RTI_DATA2_MEM_RX_UFC_B(0x2) ;
- if (nic->config.intr_type == MSI_X)
- val64 |= (RTI_DATA2_MEM_RX_UFC_C(0x20) |
- RTI_DATA2_MEM_RX_UFC_D(0x40));
- else
- val64 |= (RTI_DATA2_MEM_RX_UFC_C(0x40) |
- RTI_DATA2_MEM_RX_UFC_D(0x80));
- writeq(val64, &bar0->rti_data2_mem);
-
- for (i = 0; i < config->rx_ring_num; i++) {
- val64 = RTI_CMD_MEM_WE |
- RTI_CMD_MEM_STROBE_NEW_CMD |
- RTI_CMD_MEM_OFFSET(i);
- writeq(val64, &bar0->rti_command_mem);
-
- /*
- * Once the operation completes, the Strobe bit of the
- * command register will be reset. We poll for this
- * particular condition. We wait for a maximum of 500ms
- * for the operation to complete, if it's not complete
- * by then we return error.
- */
- time = 0;
- while (true) {
- val64 = readq(&bar0->rti_command_mem);
- if (!(val64 & RTI_CMD_MEM_STROBE_NEW_CMD))
- break;
-
- if (time > 10) {
- DBG_PRINT(ERR_DBG, "%s: RTI init failed\n",
- dev->name);
- return -ENODEV;
- }
- time++;
- msleep(50);
- }
- }
-
- /*
- * Initializing proper values as Pause threshold into all
- * the 8 Queues on Rx side.
- */
- writeq(0xffbbffbbffbbffbbULL, &bar0->mc_pause_thresh_q0q3);
- writeq(0xffbbffbbffbbffbbULL, &bar0->mc_pause_thresh_q4q7);
-
- /* Disable RMAC PAD STRIPPING */
- add = &bar0->mac_cfg;
- val64 = readq(&bar0->mac_cfg);
- val64 &= ~(MAC_CFG_RMAC_STRIP_PAD);
- writeq(RMAC_CFG_KEY(0x4C0D), &bar0->rmac_cfg_key);
- writel((u32) (val64), add);
- writeq(RMAC_CFG_KEY(0x4C0D), &bar0->rmac_cfg_key);
- writel((u32) (val64 >> 32), (add + 4));
- val64 = readq(&bar0->mac_cfg);
-
- /* Enable FCS stripping by adapter */
- add = &bar0->mac_cfg;
- val64 = readq(&bar0->mac_cfg);
- val64 |= MAC_CFG_RMAC_STRIP_FCS;
- if (nic->device_type == XFRAME_II_DEVICE)
- writeq(val64, &bar0->mac_cfg);
- else {
- writeq(RMAC_CFG_KEY(0x4C0D), &bar0->rmac_cfg_key);
- writel((u32) (val64), add);
- writeq(RMAC_CFG_KEY(0x4C0D), &bar0->rmac_cfg_key);
- writel((u32) (val64 >> 32), (add + 4));
- }
-
- /*
- * Set the time value to be inserted in the pause frame
- * generated by xena.
- */
- val64 = readq(&bar0->rmac_pause_cfg);
- val64 &= ~(RMAC_PAUSE_HG_PTIME(0xffff));
- val64 |= RMAC_PAUSE_HG_PTIME(nic->mac_control.rmac_pause_time);
- writeq(val64, &bar0->rmac_pause_cfg);
-
- /*
- * Set the Threshold Limit for Generating the pause frame
- * If the amount of data in any Queue exceeds ratio of
- * (mac_control.mc_pause_threshold_q0q3 or q4q7)/256
- * pause frame is generated
- */
- val64 = 0;
- for (i = 0; i < 4; i++) {
- val64 |= (((u64)0xFF00 |
- nic->mac_control.mc_pause_threshold_q0q3)
- << (i * 2 * 8));
- }
- writeq(val64, &bar0->mc_pause_thresh_q0q3);
-
- val64 = 0;
- for (i = 0; i < 4; i++) {
- val64 |= (((u64)0xFF00 |
- nic->mac_control.mc_pause_threshold_q4q7)
- << (i * 2 * 8));
- }
- writeq(val64, &bar0->mc_pause_thresh_q4q7);
-
- /*
- * TxDMA will stop Read request if the number of read split has
- * exceeded the limit pointed by shared_splits
- */
- val64 = readq(&bar0->pic_control);
- val64 |= PIC_CNTL_SHARED_SPLITS(shared_splits);
- writeq(val64, &bar0->pic_control);
-
- if (nic->config.bus_speed == 266) {
- writeq(TXREQTO_VAL(0x7f) | TXREQTO_EN, &bar0->txreqtimeout);
- writeq(0x0, &bar0->read_retry_delay);
- writeq(0x0, &bar0->write_retry_delay);
- }
-
- /*
- * Programming the Herc to split every write transaction
- * that does not start on an ADB to reduce disconnects.
- */
- if (nic->device_type == XFRAME_II_DEVICE) {
- val64 = FAULT_BEHAVIOUR | EXT_REQ_EN |
- MISC_LINK_STABILITY_PRD(3);
- writeq(val64, &bar0->misc_control);
- val64 = readq(&bar0->pic_control2);
- val64 &= ~(s2BIT(13)|s2BIT(14)|s2BIT(15));
- writeq(val64, &bar0->pic_control2);
- }
- if (strstr(nic->product_name, "CX4")) {
- val64 = TMAC_AVG_IPG(0x17);
- writeq(val64, &bar0->tmac_avg_ipg);
- }
-
- return SUCCESS;
-}
-#define LINK_UP_DOWN_INTERRUPT 1
-#define MAC_RMAC_ERR_TIMER 2
-
-static int s2io_link_fault_indication(struct s2io_nic *nic)
-{
- if (nic->device_type == XFRAME_II_DEVICE)
- return LINK_UP_DOWN_INTERRUPT;
- else
- return MAC_RMAC_ERR_TIMER;
-}
-
-/**
- * do_s2io_write_bits - update alarm bits in alarm register
- * @value: alarm bits
- * @flag: interrupt status
- * @addr: address value
- * Description: update alarm bits in alarm register
- * Return Value:
- * NONE.
- */
-static void do_s2io_write_bits(u64 value, int flag, void __iomem *addr)
-{
- u64 temp64;
-
- temp64 = readq(addr);
-
- if (flag == ENABLE_INTRS)
- temp64 &= ~((u64)value);
- else
- temp64 |= ((u64)value);
- writeq(temp64, addr);
-}
-
-static void en_dis_err_alarms(struct s2io_nic *nic, u16 mask, int flag)
-{
- struct XENA_dev_config __iomem *bar0 = nic->bar0;
- register u64 gen_int_mask = 0;
- u64 interruptible;
-
- writeq(DISABLE_ALL_INTRS, &bar0->general_int_mask);
- if (mask & TX_DMA_INTR) {
- gen_int_mask |= TXDMA_INT_M;
-
- do_s2io_write_bits(TXDMA_TDA_INT | TXDMA_PFC_INT |
- TXDMA_PCC_INT | TXDMA_TTI_INT |
- TXDMA_LSO_INT | TXDMA_TPA_INT |
- TXDMA_SM_INT, flag, &bar0->txdma_int_mask);
-
- do_s2io_write_bits(PFC_ECC_DB_ERR | PFC_SM_ERR_ALARM |
- PFC_MISC_0_ERR | PFC_MISC_1_ERR |
- PFC_PCIX_ERR | PFC_ECC_SG_ERR, flag,
- &bar0->pfc_err_mask);
-
- do_s2io_write_bits(TDA_Fn_ECC_DB_ERR | TDA_SM0_ERR_ALARM |
- TDA_SM1_ERR_ALARM | TDA_Fn_ECC_SG_ERR |
- TDA_PCIX_ERR, flag, &bar0->tda_err_mask);
-
- do_s2io_write_bits(PCC_FB_ECC_DB_ERR | PCC_TXB_ECC_DB_ERR |
- PCC_SM_ERR_ALARM | PCC_WR_ERR_ALARM |
- PCC_N_SERR | PCC_6_COF_OV_ERR |
- PCC_7_COF_OV_ERR | PCC_6_LSO_OV_ERR |
- PCC_7_LSO_OV_ERR | PCC_FB_ECC_SG_ERR |
- PCC_TXB_ECC_SG_ERR,
- flag, &bar0->pcc_err_mask);
-
- do_s2io_write_bits(TTI_SM_ERR_ALARM | TTI_ECC_SG_ERR |
- TTI_ECC_DB_ERR, flag, &bar0->tti_err_mask);
-
- do_s2io_write_bits(LSO6_ABORT | LSO7_ABORT |
- LSO6_SM_ERR_ALARM | LSO7_SM_ERR_ALARM |
- LSO6_SEND_OFLOW | LSO7_SEND_OFLOW,
- flag, &bar0->lso_err_mask);
-
- do_s2io_write_bits(TPA_SM_ERR_ALARM | TPA_TX_FRM_DROP,
- flag, &bar0->tpa_err_mask);
-
- do_s2io_write_bits(SM_SM_ERR_ALARM, flag, &bar0->sm_err_mask);
- }
-
- if (mask & TX_MAC_INTR) {
- gen_int_mask |= TXMAC_INT_M;
- do_s2io_write_bits(MAC_INT_STATUS_TMAC_INT, flag,
- &bar0->mac_int_mask);
- do_s2io_write_bits(TMAC_TX_BUF_OVRN | TMAC_TX_SM_ERR |
- TMAC_ECC_SG_ERR | TMAC_ECC_DB_ERR |
- TMAC_DESC_ECC_SG_ERR | TMAC_DESC_ECC_DB_ERR,
- flag, &bar0->mac_tmac_err_mask);
- }
-
- if (mask & TX_XGXS_INTR) {
- gen_int_mask |= TXXGXS_INT_M;
- do_s2io_write_bits(XGXS_INT_STATUS_TXGXS, flag,
- &bar0->xgxs_int_mask);
- do_s2io_write_bits(TXGXS_ESTORE_UFLOW | TXGXS_TX_SM_ERR |
- TXGXS_ECC_SG_ERR | TXGXS_ECC_DB_ERR,
- flag, &bar0->xgxs_txgxs_err_mask);
- }
-
- if (mask & RX_DMA_INTR) {
- gen_int_mask |= RXDMA_INT_M;
- do_s2io_write_bits(RXDMA_INT_RC_INT_M | RXDMA_INT_RPA_INT_M |
- RXDMA_INT_RDA_INT_M | RXDMA_INT_RTI_INT_M,
- flag, &bar0->rxdma_int_mask);
- do_s2io_write_bits(RC_PRCn_ECC_DB_ERR | RC_FTC_ECC_DB_ERR |
- RC_PRCn_SM_ERR_ALARM | RC_FTC_SM_ERR_ALARM |
- RC_PRCn_ECC_SG_ERR | RC_FTC_ECC_SG_ERR |
- RC_RDA_FAIL_WR_Rn, flag, &bar0->rc_err_mask);
- do_s2io_write_bits(PRC_PCI_AB_RD_Rn | PRC_PCI_AB_WR_Rn |
- PRC_PCI_AB_F_WR_Rn | PRC_PCI_DP_RD_Rn |
- PRC_PCI_DP_WR_Rn | PRC_PCI_DP_F_WR_Rn, flag,
- &bar0->prc_pcix_err_mask);
- do_s2io_write_bits(RPA_SM_ERR_ALARM | RPA_CREDIT_ERR |
- RPA_ECC_SG_ERR | RPA_ECC_DB_ERR, flag,
- &bar0->rpa_err_mask);
- do_s2io_write_bits(RDA_RXDn_ECC_DB_ERR | RDA_FRM_ECC_DB_N_AERR |
- RDA_SM1_ERR_ALARM | RDA_SM0_ERR_ALARM |
- RDA_RXD_ECC_DB_SERR | RDA_RXDn_ECC_SG_ERR |
- RDA_FRM_ECC_SG_ERR |
- RDA_MISC_ERR|RDA_PCIX_ERR,
- flag, &bar0->rda_err_mask);
- do_s2io_write_bits(RTI_SM_ERR_ALARM |
- RTI_ECC_SG_ERR | RTI_ECC_DB_ERR,
- flag, &bar0->rti_err_mask);
- }
-
- if (mask & RX_MAC_INTR) {
- gen_int_mask |= RXMAC_INT_M;
- do_s2io_write_bits(MAC_INT_STATUS_RMAC_INT, flag,
- &bar0->mac_int_mask);
- interruptible = (RMAC_RX_BUFF_OVRN | RMAC_RX_SM_ERR |
- RMAC_UNUSED_INT | RMAC_SINGLE_ECC_ERR |
- RMAC_DOUBLE_ECC_ERR);
- if (s2io_link_fault_indication(nic) == MAC_RMAC_ERR_TIMER)
- interruptible |= RMAC_LINK_STATE_CHANGE_INT;
- do_s2io_write_bits(interruptible,
- flag, &bar0->mac_rmac_err_mask);
- }
-
- if (mask & RX_XGXS_INTR) {
- gen_int_mask |= RXXGXS_INT_M;
- do_s2io_write_bits(XGXS_INT_STATUS_RXGXS, flag,
- &bar0->xgxs_int_mask);
- do_s2io_write_bits(RXGXS_ESTORE_OFLOW | RXGXS_RX_SM_ERR, flag,
- &bar0->xgxs_rxgxs_err_mask);
- }
-
- if (mask & MC_INTR) {
- gen_int_mask |= MC_INT_M;
- do_s2io_write_bits(MC_INT_MASK_MC_INT,
- flag, &bar0->mc_int_mask);
- do_s2io_write_bits(MC_ERR_REG_SM_ERR | MC_ERR_REG_ECC_ALL_SNG |
- MC_ERR_REG_ECC_ALL_DBL | PLL_LOCK_N, flag,
- &bar0->mc_err_mask);
- }
- nic->general_int_mask = gen_int_mask;
-
- /* Remove this line when alarm interrupts are enabled */
- nic->general_int_mask = 0;
-}
-
-/**
- * en_dis_able_nic_intrs - Enable or Disable the interrupts
- * @nic: device private variable,
- * @mask: A mask indicating which Intr block must be modified and,
- * @flag: A flag indicating whether to enable or disable the Intrs.
- * Description: This function will either disable or enable the interrupts
- * depending on the flag argument. The mask argument can be used to
- * enable/disable any Intr block.
- * Return Value: NONE.
- */
-
-static void en_dis_able_nic_intrs(struct s2io_nic *nic, u16 mask, int flag)
-{
- struct XENA_dev_config __iomem *bar0 = nic->bar0;
- register u64 temp64 = 0, intr_mask = 0;
-
- intr_mask = nic->general_int_mask;
-
- /* Top level interrupt classification */
- /* PIC Interrupts */
- if (mask & TX_PIC_INTR) {
- /* Enable PIC Intrs in the general intr mask register */
- intr_mask |= TXPIC_INT_M;
- if (flag == ENABLE_INTRS) {
- /*
- * If Hercules adapter enable GPIO otherwise
- * disable all PCIX, Flash, MDIO, IIC and GPIO
- * interrupts for now.
- * TODO
- */
- if (s2io_link_fault_indication(nic) ==
- LINK_UP_DOWN_INTERRUPT) {
- do_s2io_write_bits(PIC_INT_GPIO, flag,
- &bar0->pic_int_mask);
- do_s2io_write_bits(GPIO_INT_MASK_LINK_UP, flag,
- &bar0->gpio_int_mask);
- } else
- writeq(DISABLE_ALL_INTRS, &bar0->pic_int_mask);
- } else if (flag == DISABLE_INTRS) {
- /*
- * Disable PIC Intrs in the general
- * intr mask register
- */
- writeq(DISABLE_ALL_INTRS, &bar0->pic_int_mask);
- }
- }
-
- /* Tx traffic interrupts */
- if (mask & TX_TRAFFIC_INTR) {
- intr_mask |= TXTRAFFIC_INT_M;
- if (flag == ENABLE_INTRS) {
- /*
- * Enable all the Tx side interrupts
- * writing 0 Enables all 64 TX interrupt levels
- */
- writeq(0x0, &bar0->tx_traffic_mask);
- } else if (flag == DISABLE_INTRS) {
- /*
- * Disable Tx Traffic Intrs in the general intr mask
- * register.
- */
- writeq(DISABLE_ALL_INTRS, &bar0->tx_traffic_mask);
- }
- }
-
- /* Rx traffic interrupts */
- if (mask & RX_TRAFFIC_INTR) {
- intr_mask |= RXTRAFFIC_INT_M;
- if (flag == ENABLE_INTRS) {
- /* writing 0 Enables all 8 RX interrupt levels */
- writeq(0x0, &bar0->rx_traffic_mask);
- } else if (flag == DISABLE_INTRS) {
- /*
- * Disable Rx Traffic Intrs in the general intr mask
- * register.
- */
- writeq(DISABLE_ALL_INTRS, &bar0->rx_traffic_mask);
- }
- }
-
- temp64 = readq(&bar0->general_int_mask);
- if (flag == ENABLE_INTRS)
- temp64 &= ~((u64)intr_mask);
- else
- temp64 = DISABLE_ALL_INTRS;
- writeq(temp64, &bar0->general_int_mask);
-
- nic->general_int_mask = readq(&bar0->general_int_mask);
-}
-
-/**
- * verify_pcc_quiescent- Checks for PCC quiescent state
- * @sp : private member of the device structure, which is a pointer to the
- * s2io_nic structure.
- * @flag: boolean controlling function path
- * Return: 1 If PCC is quiescence
- * 0 If PCC is not quiescence
- */
-static int verify_pcc_quiescent(struct s2io_nic *sp, int flag)
-{
- int ret = 0, herc;
- struct XENA_dev_config __iomem *bar0 = sp->bar0;
- u64 val64 = readq(&bar0->adapter_status);
-
- herc = (sp->device_type == XFRAME_II_DEVICE);
-
- if (flag == false) {
- if ((!herc && (sp->pdev->revision >= 4)) || herc) {
- if (!(val64 & ADAPTER_STATUS_RMAC_PCC_IDLE))
- ret = 1;
- } else {
- if (!(val64 & ADAPTER_STATUS_RMAC_PCC_FOUR_IDLE))
- ret = 1;
- }
- } else {
- if ((!herc && (sp->pdev->revision >= 4)) || herc) {
- if (((val64 & ADAPTER_STATUS_RMAC_PCC_IDLE) ==
- ADAPTER_STATUS_RMAC_PCC_IDLE))
- ret = 1;
- } else {
- if (((val64 & ADAPTER_STATUS_RMAC_PCC_FOUR_IDLE) ==
- ADAPTER_STATUS_RMAC_PCC_FOUR_IDLE))
- ret = 1;
- }
- }
-
- return ret;
-}
-/**
- * verify_xena_quiescence - Checks whether the H/W is ready
- * @sp : private member of the device structure, which is a pointer to the
- * s2io_nic structure.
- * Description: Returns whether the H/W is ready to go or not. Depending
- * on whether adapter enable bit was written or not the comparison
- * differs and the calling function passes the input argument flag to
- * indicate this.
- * Return: 1 If xena is quiescence
- * 0 If Xena is not quiescence
- */
-
-static int verify_xena_quiescence(struct s2io_nic *sp)
-{
- int mode;
- struct XENA_dev_config __iomem *bar0 = sp->bar0;
- u64 val64 = readq(&bar0->adapter_status);
- mode = s2io_verify_pci_mode(sp);
-
- if (!(val64 & ADAPTER_STATUS_TDMA_READY)) {
- DBG_PRINT(ERR_DBG, "TDMA is not ready!\n");
- return 0;
- }
- if (!(val64 & ADAPTER_STATUS_RDMA_READY)) {
- DBG_PRINT(ERR_DBG, "RDMA is not ready!\n");
- return 0;
- }
- if (!(val64 & ADAPTER_STATUS_PFC_READY)) {
- DBG_PRINT(ERR_DBG, "PFC is not ready!\n");
- return 0;
- }
- if (!(val64 & ADAPTER_STATUS_TMAC_BUF_EMPTY)) {
- DBG_PRINT(ERR_DBG, "TMAC BUF is not empty!\n");
- return 0;
- }
- if (!(val64 & ADAPTER_STATUS_PIC_QUIESCENT)) {
- DBG_PRINT(ERR_DBG, "PIC is not QUIESCENT!\n");
- return 0;
- }
- if (!(val64 & ADAPTER_STATUS_MC_DRAM_READY)) {
- DBG_PRINT(ERR_DBG, "MC_DRAM is not ready!\n");
- return 0;
- }
- if (!(val64 & ADAPTER_STATUS_MC_QUEUES_READY)) {
- DBG_PRINT(ERR_DBG, "MC_QUEUES is not ready!\n");
- return 0;
- }
- if (!(val64 & ADAPTER_STATUS_M_PLL_LOCK)) {
- DBG_PRINT(ERR_DBG, "M_PLL is not locked!\n");
- return 0;
- }
-
- /*
- * In PCI 33 mode, the P_PLL is not used, and therefore,
- * the P_PLL_LOCK bit in the adapter_status register will
- * not be asserted.
- */
- if (!(val64 & ADAPTER_STATUS_P_PLL_LOCK) &&
- sp->device_type == XFRAME_II_DEVICE &&
- mode != PCI_MODE_PCI_33) {
- DBG_PRINT(ERR_DBG, "P_PLL is not locked!\n");
- return 0;
- }
- if (!((val64 & ADAPTER_STATUS_RC_PRC_QUIESCENT) ==
- ADAPTER_STATUS_RC_PRC_QUIESCENT)) {
- DBG_PRINT(ERR_DBG, "RC_PRC is not QUIESCENT!\n");
- return 0;
- }
- return 1;
-}
-
-/**
- * fix_mac_address - Fix for Mac addr problem on Alpha platforms
- * @sp: Pointer to device specifc structure
- * Description :
- * New procedure to clear mac address reading problems on Alpha platforms
- *
- */
-
-static void fix_mac_address(struct s2io_nic *sp)
-{
- struct XENA_dev_config __iomem *bar0 = sp->bar0;
- int i = 0;
-
- while (fix_mac[i] != END_SIGN) {
- writeq(fix_mac[i++], &bar0->gpio_control);
- udelay(10);
- (void) readq(&bar0->gpio_control);
- }
-}
-
-/**
- * start_nic - Turns the device on
- * @nic : device private variable.
- * Description:
- * This function actually turns the device on. Before this function is
- * called,all Registers are configured from their reset states
- * and shared memory is allocated but the NIC is still quiescent. On
- * calling this function, the device interrupts are cleared and the NIC is
- * literally switched on by writing into the adapter control register.
- * Return Value:
- * SUCCESS on success and -1 on failure.
- */
-
-static int start_nic(struct s2io_nic *nic)
-{
- struct XENA_dev_config __iomem *bar0 = nic->bar0;
- struct net_device *dev = nic->dev;
- register u64 val64 = 0;
- u16 subid, i;
- struct config_param *config = &nic->config;
- struct mac_info *mac_control = &nic->mac_control;
-
- /* PRC Initialization and configuration */
- for (i = 0; i < config->rx_ring_num; i++) {
- struct ring_info *ring = &mac_control->rings[i];
-
- writeq((u64)ring->rx_blocks[0].block_dma_addr,
- &bar0->prc_rxd0_n[i]);
-
- val64 = readq(&bar0->prc_ctrl_n[i]);
- if (nic->rxd_mode == RXD_MODE_1)
- val64 |= PRC_CTRL_RC_ENABLED;
- else
- val64 |= PRC_CTRL_RC_ENABLED | PRC_CTRL_RING_MODE_3;
- if (nic->device_type == XFRAME_II_DEVICE)
- val64 |= PRC_CTRL_GROUP_READS;
- val64 &= ~PRC_CTRL_RXD_BACKOFF_INTERVAL(0xFFFFFF);
- val64 |= PRC_CTRL_RXD_BACKOFF_INTERVAL(0x1000);
- writeq(val64, &bar0->prc_ctrl_n[i]);
- }
-
- if (nic->rxd_mode == RXD_MODE_3B) {
- /* Enabling 2 buffer mode by writing into Rx_pa_cfg reg. */
- val64 = readq(&bar0->rx_pa_cfg);
- val64 |= RX_PA_CFG_IGNORE_L2_ERR;
- writeq(val64, &bar0->rx_pa_cfg);
- }
-
- if (vlan_tag_strip == 0) {
- val64 = readq(&bar0->rx_pa_cfg);
- val64 &= ~RX_PA_CFG_STRIP_VLAN_TAG;
- writeq(val64, &bar0->rx_pa_cfg);
- nic->vlan_strip_flag = 0;
- }
-
- /*
- * Enabling MC-RLDRAM. After enabling the device, we timeout
- * for around 100ms, which is approximately the time required
- * for the device to be ready for operation.
- */
- val64 = readq(&bar0->mc_rldram_mrs);
- val64 |= MC_RLDRAM_QUEUE_SIZE_ENABLE | MC_RLDRAM_MRS_ENABLE;
- SPECIAL_REG_WRITE(val64, &bar0->mc_rldram_mrs, UF);
- val64 = readq(&bar0->mc_rldram_mrs);
-
- msleep(100); /* Delay by around 100 ms. */
-
- /* Enabling ECC Protection. */
- val64 = readq(&bar0->adapter_control);
- val64 &= ~ADAPTER_ECC_EN;
- writeq(val64, &bar0->adapter_control);
-
- /*
- * Verify if the device is ready to be enabled, if so enable
- * it.
- */
- val64 = readq(&bar0->adapter_status);
- if (!verify_xena_quiescence(nic)) {
- DBG_PRINT(ERR_DBG, "%s: device is not ready, "
- "Adapter status reads: 0x%llx\n",
- dev->name, (unsigned long long)val64);
- return FAILURE;
- }
-
- /*
- * With some switches, link might be already up at this point.
- * Because of this weird behavior, when we enable laser,
- * we may not get link. We need to handle this. We cannot
- * figure out which switch is misbehaving. So we are forced to
- * make a global change.
- */
-
- /* Enabling Laser. */
- val64 = readq(&bar0->adapter_control);
- val64 |= ADAPTER_EOI_TX_ON;
- writeq(val64, &bar0->adapter_control);
-
- if (s2io_link_fault_indication(nic) == MAC_RMAC_ERR_TIMER) {
- /*
- * Dont see link state interrupts initially on some switches,
- * so directly scheduling the link state task here.
- */
- schedule_work(&nic->set_link_task);
- }
- /* SXE-002: Initialize link and activity LED */
- subid = nic->pdev->subsystem_device;
- if (((subid & 0xFF) >= 0x07) &&
- (nic->device_type == XFRAME_I_DEVICE)) {
- val64 = readq(&bar0->gpio_control);
- val64 |= 0x0000800000000000ULL;
- writeq(val64, &bar0->gpio_control);
- val64 = 0x0411040400000000ULL;
- writeq(val64, (void __iomem *)bar0 + 0x2700);
- }
-
- return SUCCESS;
-}
-/**
- * s2io_txdl_getskb - Get the skb from txdl, unmap and return skb
- * @fifo_data: fifo data pointer
- * @txdlp: descriptor
- * @get_off: unused
- */
-static struct sk_buff *s2io_txdl_getskb(struct fifo_info *fifo_data,
- struct TxD *txdlp, int get_off)
-{
- struct s2io_nic *nic = fifo_data->nic;
- struct sk_buff *skb;
- struct TxD *txds;
- u16 j, frg_cnt;
-
- txds = txdlp;
- if (txds->Host_Control == (u64)(long)fifo_data->ufo_in_band_v) {
- dma_unmap_single(&nic->pdev->dev,
- (dma_addr_t)txds->Buffer_Pointer,
- sizeof(u64), DMA_TO_DEVICE);
- txds++;
- }
-
- skb = (struct sk_buff *)((unsigned long)txds->Host_Control);
- if (!skb) {
- memset(txdlp, 0, (sizeof(struct TxD) * fifo_data->max_txds));
- return NULL;
- }
- dma_unmap_single(&nic->pdev->dev, (dma_addr_t)txds->Buffer_Pointer,
- skb_headlen(skb), DMA_TO_DEVICE);
- frg_cnt = skb_shinfo(skb)->nr_frags;
- if (frg_cnt) {
- txds++;
- for (j = 0; j < frg_cnt; j++, txds++) {
- const skb_frag_t *frag = &skb_shinfo(skb)->frags[j];
- if (!txds->Buffer_Pointer)
- break;
- dma_unmap_page(&nic->pdev->dev,
- (dma_addr_t)txds->Buffer_Pointer,
- skb_frag_size(frag), DMA_TO_DEVICE);
- }
- }
- memset(txdlp, 0, (sizeof(struct TxD) * fifo_data->max_txds));
- return skb;
-}
-
-/**
- * free_tx_buffers - Free all queued Tx buffers
- * @nic : device private variable.
- * Description:
- * Free all queued Tx buffers.
- * Return Value: void
- */
-
-static void free_tx_buffers(struct s2io_nic *nic)
-{
- struct net_device *dev = nic->dev;
- struct sk_buff *skb;
- struct TxD *txdp;
- int i, j;
- int cnt = 0;
- struct config_param *config = &nic->config;
- struct mac_info *mac_control = &nic->mac_control;
- struct stat_block *stats = mac_control->stats_info;
- struct swStat *swstats = &stats->sw_stat;
-
- for (i = 0; i < config->tx_fifo_num; i++) {
- struct tx_fifo_config *tx_cfg = &config->tx_cfg[i];
- struct fifo_info *fifo = &mac_control->fifos[i];
- unsigned long flags;
-
- spin_lock_irqsave(&fifo->tx_lock, flags);
- for (j = 0; j < tx_cfg->fifo_len; j++) {
- txdp = fifo->list_info[j].list_virt_addr;
- skb = s2io_txdl_getskb(&mac_control->fifos[i], txdp, j);
- if (skb) {
- swstats->mem_freed += skb->truesize;
- dev_kfree_skb_irq(skb);
- cnt++;
- }
- }
- DBG_PRINT(INTR_DBG,
- "%s: forcibly freeing %d skbs on FIFO%d\n",
- dev->name, cnt, i);
- fifo->tx_curr_get_info.offset = 0;
- fifo->tx_curr_put_info.offset = 0;
- spin_unlock_irqrestore(&fifo->tx_lock, flags);
- }
-}
-
-/**
- * stop_nic - To stop the nic
- * @nic : device private variable.
- * Description:
- * This function does exactly the opposite of what the start_nic()
- * function does. This function is called to stop the device.
- * Return Value:
- * void.
- */
-
-static void stop_nic(struct s2io_nic *nic)
-{
- struct XENA_dev_config __iomem *bar0 = nic->bar0;
- register u64 val64 = 0;
- u16 interruptible;
-
- /* Disable all interrupts */
- en_dis_err_alarms(nic, ENA_ALL_INTRS, DISABLE_INTRS);
- interruptible = TX_TRAFFIC_INTR | RX_TRAFFIC_INTR;
- interruptible |= TX_PIC_INTR;
- en_dis_able_nic_intrs(nic, interruptible, DISABLE_INTRS);
-
- /* Clearing Adapter_En bit of ADAPTER_CONTROL Register */
- val64 = readq(&bar0->adapter_control);
- val64 &= ~(ADAPTER_CNTL_EN);
- writeq(val64, &bar0->adapter_control);
-}
-
-/**
- * fill_rx_buffers - Allocates the Rx side skbs
- * @nic : device private variable.
- * @ring: per ring structure
- * @from_card_up: If this is true, we will map the buffer to get
- * the dma address for buf0 and buf1 to give it to the card.
- * Else we will sync the already mapped buffer to give it to the card.
- * Description:
- * The function allocates Rx side skbs and puts the physical
- * address of these buffers into the RxD buffer pointers, so that the NIC
- * can DMA the received frame into these locations.
- * The NIC supports 3 receive modes, viz
- * 1. single buffer,
- * 2. three buffer and
- * 3. Five buffer modes.
- * Each mode defines how many fragments the received frame will be split
- * up into by the NIC. The frame is split into L3 header, L4 Header,
- * L4 payload in three buffer mode and in 5 buffer mode, L4 payload itself
- * is split into 3 fragments. As of now only single buffer mode is
- * supported.
- * Return Value:
- * SUCCESS on success or an appropriate -ve value on failure.
- */
-static int fill_rx_buffers(struct s2io_nic *nic, struct ring_info *ring,
- int from_card_up)
-{
- struct sk_buff *skb;
- struct RxD_t *rxdp;
- int off, size, block_no, block_no1;
- u32 alloc_tab = 0;
- u32 alloc_cnt;
- u64 tmp;
- struct buffAdd *ba;
- struct RxD_t *first_rxdp = NULL;
- u64 Buffer0_ptr = 0, Buffer1_ptr = 0;
- struct RxD1 *rxdp1;
- struct RxD3 *rxdp3;
- struct swStat *swstats = &ring->nic->mac_control.stats_info->sw_stat;
-
- alloc_cnt = ring->pkt_cnt - ring->rx_bufs_left;
-
- block_no1 = ring->rx_curr_get_info.block_index;
- while (alloc_tab < alloc_cnt) {
- block_no = ring->rx_curr_put_info.block_index;
-
- off = ring->rx_curr_put_info.offset;
-
- rxdp = ring->rx_blocks[block_no].rxds[off].virt_addr;
-
- if ((block_no == block_no1) &&
- (off == ring->rx_curr_get_info.offset) &&
- (rxdp->Host_Control)) {
- DBG_PRINT(INTR_DBG, "%s: Get and Put info equated\n",
- ring->dev->name);
- goto end;
- }
- if (off && (off == ring->rxd_count)) {
- ring->rx_curr_put_info.block_index++;
- if (ring->rx_curr_put_info.block_index ==
- ring->block_count)
- ring->rx_curr_put_info.block_index = 0;
- block_no = ring->rx_curr_put_info.block_index;
- off = 0;
- ring->rx_curr_put_info.offset = off;
- rxdp = ring->rx_blocks[block_no].block_virt_addr;
- DBG_PRINT(INTR_DBG, "%s: Next block at: %p\n",
- ring->dev->name, rxdp);
-
- }
-
- if ((rxdp->Control_1 & RXD_OWN_XENA) &&
- ((ring->rxd_mode == RXD_MODE_3B) &&
- (rxdp->Control_2 & s2BIT(0)))) {
- ring->rx_curr_put_info.offset = off;
- goto end;
- }
- /* calculate size of skb based on ring mode */
- size = ring->mtu +
- HEADER_ETHERNET_II_802_3_SIZE +
- HEADER_802_2_SIZE + HEADER_SNAP_SIZE;
- if (ring->rxd_mode == RXD_MODE_1)
- size += NET_IP_ALIGN;
- else
- size = ring->mtu + ALIGN_SIZE + BUF0_LEN + 4;
-
- /* allocate skb */
- skb = netdev_alloc_skb(nic->dev, size);
- if (!skb) {
- DBG_PRINT(INFO_DBG, "%s: Could not allocate skb\n",
- ring->dev->name);
- if (first_rxdp) {
- dma_wmb();
- first_rxdp->Control_1 |= RXD_OWN_XENA;
- }
- swstats->mem_alloc_fail_cnt++;
-
- return -ENOMEM ;
- }
- swstats->mem_allocated += skb->truesize;
-
- if (ring->rxd_mode == RXD_MODE_1) {
- /* 1 buffer mode - normal operation mode */
- rxdp1 = (struct RxD1 *)rxdp;
- memset(rxdp, 0, sizeof(struct RxD1));
- skb_reserve(skb, NET_IP_ALIGN);
- rxdp1->Buffer0_ptr =
- dma_map_single(&ring->pdev->dev, skb->data,
- size - NET_IP_ALIGN,
- DMA_FROM_DEVICE);
- if (dma_mapping_error(&nic->pdev->dev, rxdp1->Buffer0_ptr))
- goto pci_map_failed;
-
- rxdp->Control_2 =
- SET_BUFFER0_SIZE_1(size - NET_IP_ALIGN);
- rxdp->Host_Control = (unsigned long)skb;
- } else if (ring->rxd_mode == RXD_MODE_3B) {
- /*
- * 2 buffer mode -
- * 2 buffer mode provides 128
- * byte aligned receive buffers.
- */
-
- rxdp3 = (struct RxD3 *)rxdp;
- /* save buffer pointers to avoid frequent dma mapping */
- Buffer0_ptr = rxdp3->Buffer0_ptr;
- Buffer1_ptr = rxdp3->Buffer1_ptr;
- memset(rxdp, 0, sizeof(struct RxD3));
- /* restore the buffer pointers for dma sync*/
- rxdp3->Buffer0_ptr = Buffer0_ptr;
- rxdp3->Buffer1_ptr = Buffer1_ptr;
-
- ba = &ring->ba[block_no][off];
- skb_reserve(skb, BUF0_LEN);
- tmp = (u64)(unsigned long)skb->data;
- tmp += ALIGN_SIZE;
- tmp &= ~ALIGN_SIZE;
- skb->data = (void *) (unsigned long)tmp;
- skb_reset_tail_pointer(skb);
-
- if (from_card_up) {
- rxdp3->Buffer0_ptr =
- dma_map_single(&ring->pdev->dev,
- ba->ba_0, BUF0_LEN,
- DMA_FROM_DEVICE);
- if (dma_mapping_error(&nic->pdev->dev, rxdp3->Buffer0_ptr))
- goto pci_map_failed;
- } else
- dma_sync_single_for_device(&ring->pdev->dev,
- (dma_addr_t)rxdp3->Buffer0_ptr,
- BUF0_LEN,
- DMA_FROM_DEVICE);
-
- rxdp->Control_2 = SET_BUFFER0_SIZE_3(BUF0_LEN);
- if (ring->rxd_mode == RXD_MODE_3B) {
- /* Two buffer mode */
-
- /*
- * Buffer2 will have L3/L4 header plus
- * L4 payload
- */
- rxdp3->Buffer2_ptr = dma_map_single(&ring->pdev->dev,
- skb->data,
- ring->mtu + 4,
- DMA_FROM_DEVICE);
-
- if (dma_mapping_error(&nic->pdev->dev, rxdp3->Buffer2_ptr))
- goto pci_map_failed;
-
- if (from_card_up) {
- rxdp3->Buffer1_ptr =
- dma_map_single(&ring->pdev->dev,
- ba->ba_1,
- BUF1_LEN,
- DMA_FROM_DEVICE);
-
- if (dma_mapping_error(&nic->pdev->dev,
- rxdp3->Buffer1_ptr)) {
- dma_unmap_single(&ring->pdev->dev,
- (dma_addr_t)(unsigned long)
- skb->data,
- ring->mtu + 4,
- DMA_FROM_DEVICE);
- goto pci_map_failed;
- }
- }
- rxdp->Control_2 |= SET_BUFFER1_SIZE_3(1);
- rxdp->Control_2 |= SET_BUFFER2_SIZE_3
- (ring->mtu + 4);
- }
- rxdp->Control_2 |= s2BIT(0);
- rxdp->Host_Control = (unsigned long) (skb);
- }
- if (alloc_tab & ((1 << rxsync_frequency) - 1))
- rxdp->Control_1 |= RXD_OWN_XENA;
- off++;
- if (off == (ring->rxd_count + 1))
- off = 0;
- ring->rx_curr_put_info.offset = off;
-
- rxdp->Control_2 |= SET_RXD_MARKER;
- if (!(alloc_tab & ((1 << rxsync_frequency) - 1))) {
- if (first_rxdp) {
- dma_wmb();
- first_rxdp->Control_1 |= RXD_OWN_XENA;
- }
- first_rxdp = rxdp;
- }
- ring->rx_bufs_left += 1;
- alloc_tab++;
- }
-
-end:
- /* Transfer ownership of first descriptor to adapter just before
- * exiting. Before that, use memory barrier so that ownership
- * and other fields are seen by adapter correctly.
- */
- if (first_rxdp) {
- dma_wmb();
- first_rxdp->Control_1 |= RXD_OWN_XENA;
- }
-
- return SUCCESS;
-
-pci_map_failed:
- swstats->pci_map_fail_cnt++;
- swstats->mem_freed += skb->truesize;
- dev_kfree_skb_irq(skb);
- return -ENOMEM;
-}
-
-static void free_rxd_blk(struct s2io_nic *sp, int ring_no, int blk)
-{
- struct net_device *dev = sp->dev;
- int j;
- struct sk_buff *skb;
- struct RxD_t *rxdp;
- struct RxD1 *rxdp1;
- struct RxD3 *rxdp3;
- struct mac_info *mac_control = &sp->mac_control;
- struct stat_block *stats = mac_control->stats_info;
- struct swStat *swstats = &stats->sw_stat;
-
- for (j = 0 ; j < rxd_count[sp->rxd_mode]; j++) {
- rxdp = mac_control->rings[ring_no].
- rx_blocks[blk].rxds[j].virt_addr;
- skb = (struct sk_buff *)((unsigned long)rxdp->Host_Control);
- if (!skb)
- continue;
- if (sp->rxd_mode == RXD_MODE_1) {
- rxdp1 = (struct RxD1 *)rxdp;
- dma_unmap_single(&sp->pdev->dev,
- (dma_addr_t)rxdp1->Buffer0_ptr,
- dev->mtu +
- HEADER_ETHERNET_II_802_3_SIZE +
- HEADER_802_2_SIZE + HEADER_SNAP_SIZE,
- DMA_FROM_DEVICE);
- memset(rxdp, 0, sizeof(struct RxD1));
- } else if (sp->rxd_mode == RXD_MODE_3B) {
- rxdp3 = (struct RxD3 *)rxdp;
- dma_unmap_single(&sp->pdev->dev,
- (dma_addr_t)rxdp3->Buffer0_ptr,
- BUF0_LEN, DMA_FROM_DEVICE);
- dma_unmap_single(&sp->pdev->dev,
- (dma_addr_t)rxdp3->Buffer1_ptr,
- BUF1_LEN, DMA_FROM_DEVICE);
- dma_unmap_single(&sp->pdev->dev,
- (dma_addr_t)rxdp3->Buffer2_ptr,
- dev->mtu + 4, DMA_FROM_DEVICE);
- memset(rxdp, 0, sizeof(struct RxD3));
- }
- swstats->mem_freed += skb->truesize;
- dev_kfree_skb(skb);
- mac_control->rings[ring_no].rx_bufs_left -= 1;
- }
-}
-
-/**
- * free_rx_buffers - Frees all Rx buffers
- * @sp: device private variable.
- * Description:
- * This function will free all Rx buffers allocated by host.
- * Return Value:
- * NONE.
- */
-
-static void free_rx_buffers(struct s2io_nic *sp)
-{
- struct net_device *dev = sp->dev;
- int i, blk = 0, buf_cnt = 0;
- struct config_param *config = &sp->config;
- struct mac_info *mac_control = &sp->mac_control;
-
- for (i = 0; i < config->rx_ring_num; i++) {
- struct ring_info *ring = &mac_control->rings[i];
-
- for (blk = 0; blk < rx_ring_sz[i]; blk++)
- free_rxd_blk(sp, i, blk);
-
- ring->rx_curr_put_info.block_index = 0;
- ring->rx_curr_get_info.block_index = 0;
- ring->rx_curr_put_info.offset = 0;
- ring->rx_curr_get_info.offset = 0;
- ring->rx_bufs_left = 0;
- DBG_PRINT(INIT_DBG, "%s: Freed 0x%x Rx Buffers on ring%d\n",
- dev->name, buf_cnt, i);
- }
-}
-
-static int s2io_chk_rx_buffers(struct s2io_nic *nic, struct ring_info *ring)
-{
- if (fill_rx_buffers(nic, ring, 0) == -ENOMEM) {
- DBG_PRINT(INFO_DBG, "%s: Out of memory in Rx Intr!!\n",
- ring->dev->name);
- }
- return 0;
-}
-
-/**
- * s2io_poll_msix - Rx interrupt handler for NAPI support
- * @napi : pointer to the napi structure.
- * @budget : The number of packets that were budgeted to be processed
- * during one pass through the 'Poll" function.
- * Description:
- * Comes into picture only if NAPI support has been incorporated. It does
- * the same thing that rx_intr_handler does, but not in a interrupt context
- * also It will process only a given number of packets.
- * Return value:
- * 0 on success and 1 if there are No Rx packets to be processed.
- */
-
-static int s2io_poll_msix(struct napi_struct *napi, int budget)
-{
- struct ring_info *ring = container_of(napi, struct ring_info, napi);
- struct net_device *dev = ring->dev;
- int pkts_processed = 0;
- u8 __iomem *addr = NULL;
- u8 val8 = 0;
- struct s2io_nic *nic = netdev_priv(dev);
- struct XENA_dev_config __iomem *bar0 = nic->bar0;
- int budget_org = budget;
-
- if (unlikely(!is_s2io_card_up(nic)))
- return 0;
-
- pkts_processed = rx_intr_handler(ring, budget);
- s2io_chk_rx_buffers(nic, ring);
-
- if (pkts_processed < budget_org) {
- napi_complete_done(napi, pkts_processed);
- /*Re Enable MSI-Rx Vector*/
- addr = (u8 __iomem *)&bar0->xmsi_mask_reg;
- addr += 7 - ring->ring_no;
- val8 = (ring->ring_no == 0) ? 0x3f : 0xbf;
- writeb(val8, addr);
- val8 = readb(addr);
- }
- return pkts_processed;
-}
-
-static int s2io_poll_inta(struct napi_struct *napi, int budget)
-{
- struct s2io_nic *nic = container_of(napi, struct s2io_nic, napi);
- int pkts_processed = 0;
- int ring_pkts_processed, i;
- struct XENA_dev_config __iomem *bar0 = nic->bar0;
- int budget_org = budget;
- struct config_param *config = &nic->config;
- struct mac_info *mac_control = &nic->mac_control;
-
- if (unlikely(!is_s2io_card_up(nic)))
- return 0;
-
- for (i = 0; i < config->rx_ring_num; i++) {
- struct ring_info *ring = &mac_control->rings[i];
- ring_pkts_processed = rx_intr_handler(ring, budget);
- s2io_chk_rx_buffers(nic, ring);
- pkts_processed += ring_pkts_processed;
- budget -= ring_pkts_processed;
- if (budget <= 0)
- break;
- }
- if (pkts_processed < budget_org) {
- napi_complete_done(napi, pkts_processed);
- /* Re enable the Rx interrupts for the ring */
- writeq(0, &bar0->rx_traffic_mask);
- readl(&bar0->rx_traffic_mask);
- }
- return pkts_processed;
-}
-
-#ifdef CONFIG_NET_POLL_CONTROLLER
-/**
- * s2io_netpoll - netpoll event handler entry point
- * @dev : pointer to the device structure.
- * Description:
- * This function will be called by upper layer to check for events on the
- * interface in situations where interrupts are disabled. It is used for
- * specific in-kernel networking tasks, such as remote consoles and kernel
- * debugging over the network (example netdump in RedHat).
- */
-static void s2io_netpoll(struct net_device *dev)
-{
- struct s2io_nic *nic = netdev_priv(dev);
- const int irq = nic->pdev->irq;
- struct XENA_dev_config __iomem *bar0 = nic->bar0;
- u64 val64 = 0xFFFFFFFFFFFFFFFFULL;
- int i;
- struct config_param *config = &nic->config;
- struct mac_info *mac_control = &nic->mac_control;
-
- if (pci_channel_offline(nic->pdev))
- return;
-
- disable_irq(irq);
-
- writeq(val64, &bar0->rx_traffic_int);
- writeq(val64, &bar0->tx_traffic_int);
-
- /* we need to free up the transmitted skbufs or else netpoll will
- * run out of skbs and will fail and eventually netpoll application such
- * as netdump will fail.
- */
- for (i = 0; i < config->tx_fifo_num; i++)
- tx_intr_handler(&mac_control->fifos[i]);
-
- /* check for received packet and indicate up to network */
- for (i = 0; i < config->rx_ring_num; i++) {
- struct ring_info *ring = &mac_control->rings[i];
-
- rx_intr_handler(ring, 0);
- }
-
- for (i = 0; i < config->rx_ring_num; i++) {
- struct ring_info *ring = &mac_control->rings[i];
-
- if (fill_rx_buffers(nic, ring, 0) == -ENOMEM) {
- DBG_PRINT(INFO_DBG,
- "%s: Out of memory in Rx Netpoll!!\n",
- dev->name);
- break;
- }
- }
- enable_irq(irq);
-}
-#endif
-
-/**
- * rx_intr_handler - Rx interrupt handler
- * @ring_data: per ring structure.
- * @budget: budget for napi processing.
- * Description:
- * If the interrupt is because of a received frame or if the
- * receive ring contains fresh as yet un-processed frames,this function is
- * called. It picks out the RxD at which place the last Rx processing had
- * stopped and sends the skb to the OSM's Rx handler and then increments
- * the offset.
- * Return Value:
- * No. of napi packets processed.
- */
-static int rx_intr_handler(struct ring_info *ring_data, int budget)
-{
- int get_block, put_block;
- struct rx_curr_get_info get_info, put_info;
- struct RxD_t *rxdp;
- struct sk_buff *skb;
- int pkt_cnt = 0, napi_pkts = 0;
- int i;
- struct RxD1 *rxdp1;
- struct RxD3 *rxdp3;
-
- if (budget <= 0)
- return napi_pkts;
-
- get_info = ring_data->rx_curr_get_info;
- get_block = get_info.block_index;
- memcpy(&put_info, &ring_data->rx_curr_put_info, sizeof(put_info));
- put_block = put_info.block_index;
- rxdp = ring_data->rx_blocks[get_block].rxds[get_info.offset].virt_addr;
-
- while (RXD_IS_UP2DT(rxdp)) {
- /*
- * If your are next to put index then it's
- * FIFO full condition
- */
- if ((get_block == put_block) &&
- (get_info.offset + 1) == put_info.offset) {
- DBG_PRINT(INTR_DBG, "%s: Ring Full\n",
- ring_data->dev->name);
- break;
- }
- skb = (struct sk_buff *)((unsigned long)rxdp->Host_Control);
- if (skb == NULL) {
- DBG_PRINT(ERR_DBG, "%s: NULL skb in Rx Intr\n",
- ring_data->dev->name);
- return 0;
- }
- if (ring_data->rxd_mode == RXD_MODE_1) {
- rxdp1 = (struct RxD1 *)rxdp;
- dma_unmap_single(&ring_data->pdev->dev,
- (dma_addr_t)rxdp1->Buffer0_ptr,
- ring_data->mtu +
- HEADER_ETHERNET_II_802_3_SIZE +
- HEADER_802_2_SIZE +
- HEADER_SNAP_SIZE,
- DMA_FROM_DEVICE);
- } else if (ring_data->rxd_mode == RXD_MODE_3B) {
- rxdp3 = (struct RxD3 *)rxdp;
- dma_sync_single_for_cpu(&ring_data->pdev->dev,
- (dma_addr_t)rxdp3->Buffer0_ptr,
- BUF0_LEN, DMA_FROM_DEVICE);
- dma_unmap_single(&ring_data->pdev->dev,
- (dma_addr_t)rxdp3->Buffer2_ptr,
- ring_data->mtu + 4, DMA_FROM_DEVICE);
- }
- prefetch(skb->data);
- rx_osm_handler(ring_data, rxdp);
- get_info.offset++;
- ring_data->rx_curr_get_info.offset = get_info.offset;
- rxdp = ring_data->rx_blocks[get_block].
- rxds[get_info.offset].virt_addr;
- if (get_info.offset == rxd_count[ring_data->rxd_mode]) {
- get_info.offset = 0;
- ring_data->rx_curr_get_info.offset = get_info.offset;
- get_block++;
- if (get_block == ring_data->block_count)
- get_block = 0;
- ring_data->rx_curr_get_info.block_index = get_block;
- rxdp = ring_data->rx_blocks[get_block].block_virt_addr;
- }
-
- if (ring_data->nic->config.napi) {
- budget--;
- napi_pkts++;
- if (!budget)
- break;
- }
- pkt_cnt++;
- if ((indicate_max_pkts) && (pkt_cnt > indicate_max_pkts))
- break;
- }
- if (ring_data->lro) {
- /* Clear all LRO sessions before exiting */
- for (i = 0; i < MAX_LRO_SESSIONS; i++) {
- struct lro *lro = &ring_data->lro0_n[i];
- if (lro->in_use) {
- update_L3L4_header(ring_data->nic, lro);
- queue_rx_frame(lro->parent, lro->vlan_tag);
- clear_lro_session(lro);
- }
- }
- }
- return napi_pkts;
-}
-
-/**
- * tx_intr_handler - Transmit interrupt handler
- * @fifo_data : fifo data pointer
- * Description:
- * If an interrupt was raised to indicate DMA complete of the
- * Tx packet, this function is called. It identifies the last TxD
- * whose buffer was freed and frees all skbs whose data have already
- * DMA'ed into the NICs internal memory.
- * Return Value:
- * NONE
- */
-
-static void tx_intr_handler(struct fifo_info *fifo_data)
-{
- struct s2io_nic *nic = fifo_data->nic;
- struct tx_curr_get_info get_info, put_info;
- struct sk_buff *skb = NULL;
- struct TxD *txdlp;
- int pkt_cnt = 0;
- unsigned long flags = 0;
- u8 err_mask;
- struct stat_block *stats = nic->mac_control.stats_info;
- struct swStat *swstats = &stats->sw_stat;
-
- if (!spin_trylock_irqsave(&fifo_data->tx_lock, flags))
- return;
-
- get_info = fifo_data->tx_curr_get_info;
- memcpy(&put_info, &fifo_data->tx_curr_put_info, sizeof(put_info));
- txdlp = fifo_data->list_info[get_info.offset].list_virt_addr;
- while ((!(txdlp->Control_1 & TXD_LIST_OWN_XENA)) &&
- (get_info.offset != put_info.offset) &&
- (txdlp->Host_Control)) {
- /* Check for TxD errors */
- if (txdlp->Control_1 & TXD_T_CODE) {
- unsigned long long err;
- err = txdlp->Control_1 & TXD_T_CODE;
- if (err & 0x1) {
- swstats->parity_err_cnt++;
- }
-
- /* update t_code statistics */
- err_mask = err >> 48;
- switch (err_mask) {
- case 2:
- swstats->tx_buf_abort_cnt++;
- break;
-
- case 3:
- swstats->tx_desc_abort_cnt++;
- break;
-
- case 7:
- swstats->tx_parity_err_cnt++;
- break;
-
- case 10:
- swstats->tx_link_loss_cnt++;
- break;
-
- case 15:
- swstats->tx_list_proc_err_cnt++;
- break;
- }
- }
-
- skb = s2io_txdl_getskb(fifo_data, txdlp, get_info.offset);
- if (skb == NULL) {
- spin_unlock_irqrestore(&fifo_data->tx_lock, flags);
- DBG_PRINT(ERR_DBG, "%s: NULL skb in Tx Free Intr\n",
- __func__);
- return;
- }
- pkt_cnt++;
-
- /* Updating the statistics block */
- swstats->mem_freed += skb->truesize;
- dev_consume_skb_irq(skb);
-
- get_info.offset++;
- if (get_info.offset == get_info.fifo_len + 1)
- get_info.offset = 0;
- txdlp = fifo_data->list_info[get_info.offset].list_virt_addr;
- fifo_data->tx_curr_get_info.offset = get_info.offset;
- }
-
- s2io_wake_tx_queue(fifo_data, pkt_cnt, nic->config.multiq);
-
- spin_unlock_irqrestore(&fifo_data->tx_lock, flags);
-}
-
-/**
- * s2io_mdio_write - Function to write in to MDIO registers
- * @mmd_type : MMD type value (PMA/PMD/WIS/PCS/PHYXS)
- * @addr : address value
- * @value : data value
- * @dev : pointer to net_device structure
- * Description:
- * This function is used to write values to the MDIO registers
- * NONE
- */
-static void s2io_mdio_write(u32 mmd_type, u64 addr, u16 value,
- struct net_device *dev)
-{
- u64 val64;
- struct s2io_nic *sp = netdev_priv(dev);
- struct XENA_dev_config __iomem *bar0 = sp->bar0;
-
- /* address transaction */
- val64 = MDIO_MMD_INDX_ADDR(addr) |
- MDIO_MMD_DEV_ADDR(mmd_type) |
- MDIO_MMS_PRT_ADDR(0x0);
- writeq(val64, &bar0->mdio_control);
- val64 = val64 | MDIO_CTRL_START_TRANS(0xE);
- writeq(val64, &bar0->mdio_control);
- udelay(100);
-
- /* Data transaction */
- val64 = MDIO_MMD_INDX_ADDR(addr) |
- MDIO_MMD_DEV_ADDR(mmd_type) |
- MDIO_MMS_PRT_ADDR(0x0) |
- MDIO_MDIO_DATA(value) |
- MDIO_OP(MDIO_OP_WRITE_TRANS);
- writeq(val64, &bar0->mdio_control);
- val64 = val64 | MDIO_CTRL_START_TRANS(0xE);
- writeq(val64, &bar0->mdio_control);
- udelay(100);
-
- val64 = MDIO_MMD_INDX_ADDR(addr) |
- MDIO_MMD_DEV_ADDR(mmd_type) |
- MDIO_MMS_PRT_ADDR(0x0) |
- MDIO_OP(MDIO_OP_READ_TRANS);
- writeq(val64, &bar0->mdio_control);
- val64 = val64 | MDIO_CTRL_START_TRANS(0xE);
- writeq(val64, &bar0->mdio_control);
- udelay(100);
-}
-
-/**
- * s2io_mdio_read - Function to write in to MDIO registers
- * @mmd_type : MMD type value (PMA/PMD/WIS/PCS/PHYXS)
- * @addr : address value
- * @dev : pointer to net_device structure
- * Description:
- * This function is used to read values to the MDIO registers
- * NONE
- */
-static u64 s2io_mdio_read(u32 mmd_type, u64 addr, struct net_device *dev)
-{
- u64 val64 = 0x0;
- u64 rval64 = 0x0;
- struct s2io_nic *sp = netdev_priv(dev);
- struct XENA_dev_config __iomem *bar0 = sp->bar0;
-
- /* address transaction */
- val64 = val64 | (MDIO_MMD_INDX_ADDR(addr)
- | MDIO_MMD_DEV_ADDR(mmd_type)
- | MDIO_MMS_PRT_ADDR(0x0));
- writeq(val64, &bar0->mdio_control);
- val64 = val64 | MDIO_CTRL_START_TRANS(0xE);
- writeq(val64, &bar0->mdio_control);
- udelay(100);
-
- /* Data transaction */
- val64 = MDIO_MMD_INDX_ADDR(addr) |
- MDIO_MMD_DEV_ADDR(mmd_type) |
- MDIO_MMS_PRT_ADDR(0x0) |
- MDIO_OP(MDIO_OP_READ_TRANS);
- writeq(val64, &bar0->mdio_control);
- val64 = val64 | MDIO_CTRL_START_TRANS(0xE);
- writeq(val64, &bar0->mdio_control);
- udelay(100);
-
- /* Read the value from regs */
- rval64 = readq(&bar0->mdio_control);
- rval64 = rval64 & 0xFFFF0000;
- rval64 = rval64 >> 16;
- return rval64;
-}
-
-/**
- * s2io_chk_xpak_counter - Function to check the status of the xpak counters
- * @counter : counter value to be updated
- * @regs_stat : registers status
- * @index : index
- * @flag : flag to indicate the status
- * @type : counter type
- * Description:
- * This function is to check the status of the xpak counters value
- * NONE
- */
-
-static void s2io_chk_xpak_counter(u64 *counter, u64 * regs_stat, u32 index,
- u16 flag, u16 type)
-{
- u64 mask = 0x3;
- u64 val64;
- int i;
- for (i = 0; i < index; i++)
- mask = mask << 0x2;
-
- if (flag > 0) {
- *counter = *counter + 1;
- val64 = *regs_stat & mask;
- val64 = val64 >> (index * 0x2);
- val64 = val64 + 1;
- if (val64 == 3) {
- switch (type) {
- case 1:
- DBG_PRINT(ERR_DBG,
- "Take Xframe NIC out of service.\n");
- DBG_PRINT(ERR_DBG,
-"Excessive temperatures may result in premature transceiver failure.\n");
- break;
- case 2:
- DBG_PRINT(ERR_DBG,
- "Take Xframe NIC out of service.\n");
- DBG_PRINT(ERR_DBG,
-"Excessive bias currents may indicate imminent laser diode failure.\n");
- break;
- case 3:
- DBG_PRINT(ERR_DBG,
- "Take Xframe NIC out of service.\n");
- DBG_PRINT(ERR_DBG,
-"Excessive laser output power may saturate far-end receiver.\n");
- break;
- default:
- DBG_PRINT(ERR_DBG,
- "Incorrect XPAK Alarm type\n");
- }
- val64 = 0x0;
- }
- val64 = val64 << (index * 0x2);
- *regs_stat = (*regs_stat & (~mask)) | (val64);
-
- } else {
- *regs_stat = *regs_stat & (~mask);
- }
-}
-
-/**
- * s2io_updt_xpak_counter - Function to update the xpak counters
- * @dev : pointer to net_device struct
- * Description:
- * This function is to upate the status of the xpak counters value
- * NONE
- */
-static void s2io_updt_xpak_counter(struct net_device *dev)
-{
- u16 flag = 0x0;
- u16 type = 0x0;
- u16 val16 = 0x0;
- u64 val64 = 0x0;
- u64 addr = 0x0;
-
- struct s2io_nic *sp = netdev_priv(dev);
- struct stat_block *stats = sp->mac_control.stats_info;
- struct xpakStat *xstats = &stats->xpak_stat;
-
- /* Check the communication with the MDIO slave */
- addr = MDIO_CTRL1;
- val64 = 0x0;
- val64 = s2io_mdio_read(MDIO_MMD_PMAPMD, addr, dev);
- if ((val64 == 0xFFFF) || (val64 == 0x0000)) {
- DBG_PRINT(ERR_DBG,
- "ERR: MDIO slave access failed - Returned %llx\n",
- (unsigned long long)val64);
- return;
- }
-
- /* Check for the expected value of control reg 1 */
- if (val64 != MDIO_CTRL1_SPEED10G) {
- DBG_PRINT(ERR_DBG, "Incorrect value at PMA address 0x0000 - "
- "Returned: %llx- Expected: 0x%x\n",
- (unsigned long long)val64, MDIO_CTRL1_SPEED10G);
- return;
- }
-
- /* Loading the DOM register to MDIO register */
- addr = 0xA100;
- s2io_mdio_write(MDIO_MMD_PMAPMD, addr, val16, dev);
- val64 = s2io_mdio_read(MDIO_MMD_PMAPMD, addr, dev);
-
- /* Reading the Alarm flags */
- addr = 0xA070;
- val64 = 0x0;
- val64 = s2io_mdio_read(MDIO_MMD_PMAPMD, addr, dev);
-
- flag = CHECKBIT(val64, 0x7);
- type = 1;
- s2io_chk_xpak_counter(&xstats->alarm_transceiver_temp_high,
- &xstats->xpak_regs_stat,
- 0x0, flag, type);
-
- if (CHECKBIT(val64, 0x6))
- xstats->alarm_transceiver_temp_low++;
-
- flag = CHECKBIT(val64, 0x3);
- type = 2;
- s2io_chk_xpak_counter(&xstats->alarm_laser_bias_current_high,
- &xstats->xpak_regs_stat,
- 0x2, flag, type);
-
- if (CHECKBIT(val64, 0x2))
- xstats->alarm_laser_bias_current_low++;
-
- flag = CHECKBIT(val64, 0x1);
- type = 3;
- s2io_chk_xpak_counter(&xstats->alarm_laser_output_power_high,
- &xstats->xpak_regs_stat,
- 0x4, flag, type);
-
- if (CHECKBIT(val64, 0x0))
- xstats->alarm_laser_output_power_low++;
-
- /* Reading the Warning flags */
- addr = 0xA074;
- val64 = 0x0;
- val64 = s2io_mdio_read(MDIO_MMD_PMAPMD, addr, dev);
-
- if (CHECKBIT(val64, 0x7))
- xstats->warn_transceiver_temp_high++;
-
- if (CHECKBIT(val64, 0x6))
- xstats->warn_transceiver_temp_low++;
-
- if (CHECKBIT(val64, 0x3))
- xstats->warn_laser_bias_current_high++;
-
- if (CHECKBIT(val64, 0x2))
- xstats->warn_laser_bias_current_low++;
-
- if (CHECKBIT(val64, 0x1))
- xstats->warn_laser_output_power_high++;
-
- if (CHECKBIT(val64, 0x0))
- xstats->warn_laser_output_power_low++;
-}
-
-/**
- * wait_for_cmd_complete - waits for a command to complete.
- * @addr: address
- * @busy_bit: bit to check for busy
- * @bit_state: state to check
- * @may_sleep: parameter indicates if sleeping when waiting for
- * command complete
- * Description: Function that waits for a command to Write into RMAC
- * ADDR DATA registers to be completed and returns either success or
- * error depending on whether the command was complete or not.
- * Return value:
- * SUCCESS on success and FAILURE on failure.
- */
-
-static int wait_for_cmd_complete(void __iomem *addr, u64 busy_bit,
- int bit_state, bool may_sleep)
-{
- int ret = FAILURE, cnt = 0, delay = 1;
- u64 val64;
-
- if ((bit_state != S2IO_BIT_RESET) && (bit_state != S2IO_BIT_SET))
- return FAILURE;
-
- do {
- val64 = readq(addr);
- if (bit_state == S2IO_BIT_RESET) {
- if (!(val64 & busy_bit)) {
- ret = SUCCESS;
- break;
- }
- } else {
- if (val64 & busy_bit) {
- ret = SUCCESS;
- break;
- }
- }
-
- if (!may_sleep)
- mdelay(delay);
- else
- msleep(delay);
-
- if (++cnt >= 10)
- delay = 50;
- } while (cnt < 20);
- return ret;
-}
-/**
- * check_pci_device_id - Checks if the device id is supported
- * @id : device id
- * Description: Function to check if the pci device id is supported by driver.
- * Return value: Actual device id if supported else PCI_ANY_ID
- */
-static u16 check_pci_device_id(u16 id)
-{
- switch (id) {
- case PCI_DEVICE_ID_HERC_WIN:
- case PCI_DEVICE_ID_HERC_UNI:
- return XFRAME_II_DEVICE;
- case PCI_DEVICE_ID_S2IO_UNI:
- case PCI_DEVICE_ID_S2IO_WIN:
- return XFRAME_I_DEVICE;
- default:
- return PCI_ANY_ID;
- }
-}
-
-/**
- * s2io_reset - Resets the card.
- * @sp : private member of the device structure.
- * Description: Function to Reset the card. This function then also
- * restores the previously saved PCI configuration space registers as
- * the card reset also resets the configuration space.
- * Return value:
- * void.
- */
-
-static void s2io_reset(struct s2io_nic *sp)
-{
- struct XENA_dev_config __iomem *bar0 = sp->bar0;
- u64 val64;
- u16 subid, pci_cmd;
- int i;
- u16 val16;
- unsigned long long up_cnt, down_cnt, up_time, down_time, reset_cnt;
- unsigned long long mem_alloc_cnt, mem_free_cnt, watchdog_cnt;
- struct stat_block *stats;
- struct swStat *swstats;
-
- DBG_PRINT(INIT_DBG, "%s: Resetting XFrame card %s\n",
- __func__, pci_name(sp->pdev));
-
- /* Back up the PCI-X CMD reg, dont want to lose MMRBC, OST settings */
- pci_read_config_word(sp->pdev, PCIX_COMMAND_REGISTER, &(pci_cmd));
-
- val64 = SW_RESET_ALL;
- writeq(val64, &bar0->sw_reset);
- if (strstr(sp->product_name, "CX4"))
- msleep(750);
- msleep(250);
- for (i = 0; i < S2IO_MAX_PCI_CONFIG_SPACE_REINIT; i++) {
-
- /* Restore the PCI state saved during initialization. */
- pci_restore_state(sp->pdev);
- pci_read_config_word(sp->pdev, 0x2, &val16);
- if (check_pci_device_id(val16) != (u16)PCI_ANY_ID)
- break;
- msleep(200);
- }
-
- if (check_pci_device_id(val16) == (u16)PCI_ANY_ID)
- DBG_PRINT(ERR_DBG, "%s SW_Reset failed!\n", __func__);
-
- pci_write_config_word(sp->pdev, PCIX_COMMAND_REGISTER, pci_cmd);
-
- s2io_init_pci(sp);
-
- /* Set swapper to enable I/O register access */
- s2io_set_swapper(sp);
-
- /* restore mac_addr entries */
- do_s2io_restore_unicast_mc(sp);
-
- /* Restore the MSIX table entries from local variables */
- restore_xmsi_data(sp);
-
- /* Clear certain PCI/PCI-X fields after reset */
- if (sp->device_type == XFRAME_II_DEVICE) {
- /* Clear "detected parity error" bit */
- pci_write_config_word(sp->pdev, PCI_STATUS, 0x8000);
-
- /* Clearing PCIX Ecc status register */
- pci_write_config_dword(sp->pdev, 0x68, 0x7C);
-
- /* Clearing PCI_STATUS error reflected here */
- writeq(s2BIT(62), &bar0->txpic_int_reg);
- }
-
- /* Reset device statistics maintained by OS */
- memset(&sp->stats, 0, sizeof(struct net_device_stats));
-
- stats = sp->mac_control.stats_info;
- swstats = &stats->sw_stat;
-
- /* save link up/down time/cnt, reset/memory/watchdog cnt */
- up_cnt = swstats->link_up_cnt;
- down_cnt = swstats->link_down_cnt;
- up_time = swstats->link_up_time;
- down_time = swstats->link_down_time;
- reset_cnt = swstats->soft_reset_cnt;
- mem_alloc_cnt = swstats->mem_allocated;
- mem_free_cnt = swstats->mem_freed;
- watchdog_cnt = swstats->watchdog_timer_cnt;
-
- memset(stats, 0, sizeof(struct stat_block));
-
- /* restore link up/down time/cnt, reset/memory/watchdog cnt */
- swstats->link_up_cnt = up_cnt;
- swstats->link_down_cnt = down_cnt;
- swstats->link_up_time = up_time;
- swstats->link_down_time = down_time;
- swstats->soft_reset_cnt = reset_cnt;
- swstats->mem_allocated = mem_alloc_cnt;
- swstats->mem_freed = mem_free_cnt;
- swstats->watchdog_timer_cnt = watchdog_cnt;
-
- /* SXE-002: Configure link and activity LED to turn it off */
- subid = sp->pdev->subsystem_device;
- if (((subid & 0xFF) >= 0x07) &&
- (sp->device_type == XFRAME_I_DEVICE)) {
- val64 = readq(&bar0->gpio_control);
- val64 |= 0x0000800000000000ULL;
- writeq(val64, &bar0->gpio_control);
- val64 = 0x0411040400000000ULL;
- writeq(val64, (void __iomem *)bar0 + 0x2700);
- }
-
- /*
- * Clear spurious ECC interrupts that would have occurred on
- * XFRAME II cards after reset.
- */
- if (sp->device_type == XFRAME_II_DEVICE) {
- val64 = readq(&bar0->pcc_err_reg);
- writeq(val64, &bar0->pcc_err_reg);
- }
-
- sp->device_enabled_once = false;
-}
-
-/**
- * s2io_set_swapper - to set the swapper controle on the card
- * @sp : private member of the device structure,
- * pointer to the s2io_nic structure.
- * Description: Function to set the swapper control on the card
- * correctly depending on the 'endianness' of the system.
- * Return value:
- * SUCCESS on success and FAILURE on failure.
- */
-
-static int s2io_set_swapper(struct s2io_nic *sp)
-{
- struct net_device *dev = sp->dev;
- struct XENA_dev_config __iomem *bar0 = sp->bar0;
- u64 val64, valt, valr;
-
- /*
- * Set proper endian settings and verify the same by reading
- * the PIF Feed-back register.
- */
-
- val64 = readq(&bar0->pif_rd_swapper_fb);
- if (val64 != 0x0123456789ABCDEFULL) {
- int i = 0;
- static const u64 value[] = {
- 0xC30000C3C30000C3ULL, /* FE=1, SE=1 */
- 0x8100008181000081ULL, /* FE=1, SE=0 */
- 0x4200004242000042ULL, /* FE=0, SE=1 */
- 0 /* FE=0, SE=0 */
- };
-
- while (i < 4) {
- writeq(value[i], &bar0->swapper_ctrl);
- val64 = readq(&bar0->pif_rd_swapper_fb);
- if (val64 == 0x0123456789ABCDEFULL)
- break;
- i++;
- }
- if (i == 4) {
- DBG_PRINT(ERR_DBG, "%s: Endian settings are wrong, "
- "feedback read %llx\n",
- dev->name, (unsigned long long)val64);
- return FAILURE;
- }
- valr = value[i];
- } else {
- valr = readq(&bar0->swapper_ctrl);
- }
-
- valt = 0x0123456789ABCDEFULL;
- writeq(valt, &bar0->xmsi_address);
- val64 = readq(&bar0->xmsi_address);
-
- if (val64 != valt) {
- int i = 0;
- static const u64 value[] = {
- 0x00C3C30000C3C300ULL, /* FE=1, SE=1 */
- 0x0081810000818100ULL, /* FE=1, SE=0 */
- 0x0042420000424200ULL, /* FE=0, SE=1 */
- 0 /* FE=0, SE=0 */
- };
-
- while (i < 4) {
- writeq((value[i] | valr), &bar0->swapper_ctrl);
- writeq(valt, &bar0->xmsi_address);
- val64 = readq(&bar0->xmsi_address);
- if (val64 == valt)
- break;
- i++;
- }
- if (i == 4) {
- unsigned long long x = val64;
- DBG_PRINT(ERR_DBG,
- "Write failed, Xmsi_addr reads:0x%llx\n", x);
- return FAILURE;
- }
- }
- val64 = readq(&bar0->swapper_ctrl);
- val64 &= 0xFFFF000000000000ULL;
-
-#ifdef __BIG_ENDIAN
- /*
- * The device by default set to a big endian format, so a
- * big endian driver need not set anything.
- */
- val64 |= (SWAPPER_CTRL_TXP_FE |
- SWAPPER_CTRL_TXP_SE |
- SWAPPER_CTRL_TXD_R_FE |
- SWAPPER_CTRL_TXD_W_FE |
- SWAPPER_CTRL_TXF_R_FE |
- SWAPPER_CTRL_RXD_R_FE |
- SWAPPER_CTRL_RXD_W_FE |
- SWAPPER_CTRL_RXF_W_FE |
- SWAPPER_CTRL_XMSI_FE |
- SWAPPER_CTRL_STATS_FE |
- SWAPPER_CTRL_STATS_SE);
- if (sp->config.intr_type == INTA)
- val64 |= SWAPPER_CTRL_XMSI_SE;
- writeq(val64, &bar0->swapper_ctrl);
-#else
- /*
- * Initially we enable all bits to make it accessible by the
- * driver, then we selectively enable only those bits that
- * we want to set.
- */
- val64 |= (SWAPPER_CTRL_TXP_FE |
- SWAPPER_CTRL_TXP_SE |
- SWAPPER_CTRL_TXD_R_FE |
- SWAPPER_CTRL_TXD_R_SE |
- SWAPPER_CTRL_TXD_W_FE |
- SWAPPER_CTRL_TXD_W_SE |
- SWAPPER_CTRL_TXF_R_FE |
- SWAPPER_CTRL_RXD_R_FE |
- SWAPPER_CTRL_RXD_R_SE |
- SWAPPER_CTRL_RXD_W_FE |
- SWAPPER_CTRL_RXD_W_SE |
- SWAPPER_CTRL_RXF_W_FE |
- SWAPPER_CTRL_XMSI_FE |
- SWAPPER_CTRL_STATS_FE |
- SWAPPER_CTRL_STATS_SE);
- if (sp->config.intr_type == INTA)
- val64 |= SWAPPER_CTRL_XMSI_SE;
- writeq(val64, &bar0->swapper_ctrl);
-#endif
- val64 = readq(&bar0->swapper_ctrl);
-
- /*
- * Verifying if endian settings are accurate by reading a
- * feedback register.
- */
- val64 = readq(&bar0->pif_rd_swapper_fb);
- if (val64 != 0x0123456789ABCDEFULL) {
- /* Endian settings are incorrect, calls for another dekko. */
- DBG_PRINT(ERR_DBG,
- "%s: Endian settings are wrong, feedback read %llx\n",
- dev->name, (unsigned long long)val64);
- return FAILURE;
- }
-
- return SUCCESS;
-}
-
-static int wait_for_msix_trans(struct s2io_nic *nic, int i)
-{
- struct XENA_dev_config __iomem *bar0 = nic->bar0;
- u64 val64;
- int ret = 0, cnt = 0;
-
- do {
- val64 = readq(&bar0->xmsi_access);
- if (!(val64 & s2BIT(15)))
- break;
- mdelay(1);
- cnt++;
- } while (cnt < 5);
- if (cnt == 5) {
- DBG_PRINT(ERR_DBG, "XMSI # %d Access failed\n", i);
- ret = 1;
- }
-
- return ret;
-}
-
-static void restore_xmsi_data(struct s2io_nic *nic)
-{
- struct XENA_dev_config __iomem *bar0 = nic->bar0;
- u64 val64;
- int i, msix_index;
-
- if (nic->device_type == XFRAME_I_DEVICE)
- return;
-
- for (i = 0; i < MAX_REQUESTED_MSI_X; i++) {
- msix_index = (i) ? ((i-1) * 8 + 1) : 0;
- writeq(nic->msix_info[i].addr, &bar0->xmsi_address);
- writeq(nic->msix_info[i].data, &bar0->xmsi_data);
- val64 = (s2BIT(7) | s2BIT(15) | vBIT(msix_index, 26, 6));
- writeq(val64, &bar0->xmsi_access);
- if (wait_for_msix_trans(nic, msix_index))
- DBG_PRINT(ERR_DBG, "%s: index: %d failed\n",
- __func__, msix_index);
- }
-}
-
-static void store_xmsi_data(struct s2io_nic *nic)
-{
- struct XENA_dev_config __iomem *bar0 = nic->bar0;
- u64 val64, addr, data;
- int i, msix_index;
-
- if (nic->device_type == XFRAME_I_DEVICE)
- return;
-
- /* Store and display */
- for (i = 0; i < MAX_REQUESTED_MSI_X; i++) {
- msix_index = (i) ? ((i-1) * 8 + 1) : 0;
- val64 = (s2BIT(15) | vBIT(msix_index, 26, 6));
- writeq(val64, &bar0->xmsi_access);
- if (wait_for_msix_trans(nic, msix_index)) {
- DBG_PRINT(ERR_DBG, "%s: index: %d failed\n",
- __func__, msix_index);
- continue;
- }
- addr = readq(&bar0->xmsi_address);
- data = readq(&bar0->xmsi_data);
- if (addr && data) {
- nic->msix_info[i].addr = addr;
- nic->msix_info[i].data = data;
- }
- }
-}
-
-static int s2io_enable_msi_x(struct s2io_nic *nic)
-{
- struct XENA_dev_config __iomem *bar0 = nic->bar0;
- u64 rx_mat;
- u16 msi_control; /* Temp variable */
- int ret, i, j, msix_indx = 1;
- int size;
- struct stat_block *stats = nic->mac_control.stats_info;
- struct swStat *swstats = &stats->sw_stat;
-
- size = nic->num_entries * sizeof(struct msix_entry);
- nic->entries = kzalloc(size, GFP_KERNEL);
- if (!nic->entries) {
- DBG_PRINT(INFO_DBG, "%s: Memory allocation failed\n",
- __func__);
- swstats->mem_alloc_fail_cnt++;
- return -ENOMEM;
- }
- swstats->mem_allocated += size;
-
- size = nic->num_entries * sizeof(struct s2io_msix_entry);
- nic->s2io_entries = kzalloc(size, GFP_KERNEL);
- if (!nic->s2io_entries) {
- DBG_PRINT(INFO_DBG, "%s: Memory allocation failed\n",
- __func__);
- swstats->mem_alloc_fail_cnt++;
- kfree(nic->entries);
- swstats->mem_freed
- += (nic->num_entries * sizeof(struct msix_entry));
- return -ENOMEM;
- }
- swstats->mem_allocated += size;
-
- nic->entries[0].entry = 0;
- nic->s2io_entries[0].entry = 0;
- nic->s2io_entries[0].in_use = MSIX_FLG;
- nic->s2io_entries[0].type = MSIX_ALARM_TYPE;
- nic->s2io_entries[0].arg = &nic->mac_control.fifos;
-
- for (i = 1; i < nic->num_entries; i++) {
- nic->entries[i].entry = ((i - 1) * 8) + 1;
- nic->s2io_entries[i].entry = ((i - 1) * 8) + 1;
- nic->s2io_entries[i].arg = NULL;
- nic->s2io_entries[i].in_use = 0;
- }
-
- rx_mat = readq(&bar0->rx_mat);
- for (j = 0; j < nic->config.rx_ring_num; j++) {
- rx_mat |= RX_MAT_SET(j, msix_indx);
- nic->s2io_entries[j+1].arg = &nic->mac_control.rings[j];
- nic->s2io_entries[j+1].type = MSIX_RING_TYPE;
- nic->s2io_entries[j+1].in_use = MSIX_FLG;
- msix_indx += 8;
- }
- writeq(rx_mat, &bar0->rx_mat);
- readq(&bar0->rx_mat);
-
- ret = pci_enable_msix_range(nic->pdev, nic->entries,
- nic->num_entries, nic->num_entries);
- /* We fail init if error or we get less vectors than min required */
- if (ret < 0) {
- DBG_PRINT(ERR_DBG, "Enabling MSI-X failed\n");
- kfree(nic->entries);
- swstats->mem_freed += nic->num_entries *
- sizeof(struct msix_entry);
- kfree(nic->s2io_entries);
- swstats->mem_freed += nic->num_entries *
- sizeof(struct s2io_msix_entry);
- nic->entries = NULL;
- nic->s2io_entries = NULL;
- return -ENOMEM;
- }
-
- /*
- * To enable MSI-X, MSI also needs to be enabled, due to a bug
- * in the herc NIC. (Temp change, needs to be removed later)
- */
- pci_read_config_word(nic->pdev, 0x42, &msi_control);
- msi_control |= 0x1; /* Enable MSI */
- pci_write_config_word(nic->pdev, 0x42, msi_control);
-
- return 0;
-}
-
-/* Handle software interrupt used during MSI(X) test */
-static irqreturn_t s2io_test_intr(int irq, void *dev_id)
-{
- struct s2io_nic *sp = dev_id;
-
- sp->msi_detected = 1;
- wake_up(&sp->msi_wait);
-
- return IRQ_HANDLED;
-}
-
-/* Test interrupt path by forcing a software IRQ */
-static int s2io_test_msi(struct s2io_nic *sp)
-{
- struct pci_dev *pdev = sp->pdev;
- struct XENA_dev_config __iomem *bar0 = sp->bar0;
- int err;
- u64 val64, saved64;
-
- err = request_irq(sp->entries[1].vector, s2io_test_intr, 0,
- sp->name, sp);
- if (err) {
- DBG_PRINT(ERR_DBG, "%s: PCI %s: cannot assign irq %d\n",
- sp->dev->name, pci_name(pdev), pdev->irq);
- return err;
- }
-
- init_waitqueue_head(&sp->msi_wait);
- sp->msi_detected = 0;
-
- saved64 = val64 = readq(&bar0->scheduled_int_ctrl);
- val64 |= SCHED_INT_CTRL_ONE_SHOT;
- val64 |= SCHED_INT_CTRL_TIMER_EN;
- val64 |= SCHED_INT_CTRL_INT2MSI(1);
- writeq(val64, &bar0->scheduled_int_ctrl);
-
- wait_event_timeout(sp->msi_wait, sp->msi_detected, HZ/10);
-
- if (!sp->msi_detected) {
- /* MSI(X) test failed, go back to INTx mode */
- DBG_PRINT(ERR_DBG, "%s: PCI %s: No interrupt was generated "
- "using MSI(X) during test\n",
- sp->dev->name, pci_name(pdev));
-
- err = -EOPNOTSUPP;
- }
-
- free_irq(sp->entries[1].vector, sp);
-
- writeq(saved64, &bar0->scheduled_int_ctrl);
-
- return err;
-}
-
-static void remove_msix_isr(struct s2io_nic *sp)
-{
- int i;
- u16 msi_control;
-
- for (i = 0; i < sp->num_entries; i++) {
- if (sp->s2io_entries[i].in_use == MSIX_REGISTERED_SUCCESS) {
- int vector = sp->entries[i].vector;
- void *arg = sp->s2io_entries[i].arg;
- free_irq(vector, arg);
- }
- }
-
- kfree(sp->entries);
- kfree(sp->s2io_entries);
- sp->entries = NULL;
- sp->s2io_entries = NULL;
-
- pci_read_config_word(sp->pdev, 0x42, &msi_control);
- msi_control &= 0xFFFE; /* Disable MSI */
- pci_write_config_word(sp->pdev, 0x42, msi_control);
-
- pci_disable_msix(sp->pdev);
-}
-
-static void remove_inta_isr(struct s2io_nic *sp)
-{
- free_irq(sp->pdev->irq, sp->dev);
-}
-
-/* ********************************************************* *
- * Functions defined below concern the OS part of the driver *
- * ********************************************************* */
-
-/**
- * s2io_open - open entry point of the driver
- * @dev : pointer to the device structure.
- * Description:
- * This function is the open entry point of the driver. It mainly calls a
- * function to allocate Rx buffers and inserts them into the buffer
- * descriptors and then enables the Rx part of the NIC.
- * Return value:
- * 0 on success and an appropriate (-)ve integer as defined in errno.h
- * file on failure.
- */
-
-static int s2io_open(struct net_device *dev)
-{
- struct s2io_nic *sp = netdev_priv(dev);
- struct swStat *swstats = &sp->mac_control.stats_info->sw_stat;
- int err = 0;
-
- /*
- * Make sure you have link off by default every time
- * Nic is initialized
- */
- netif_carrier_off(dev);
- sp->last_link_state = 0;
-
- /* Initialize H/W and enable interrupts */
- err = s2io_card_up(sp);
- if (err) {
- DBG_PRINT(ERR_DBG, "%s: H/W initialization failed\n",
- dev->name);
- goto hw_init_failed;
- }
-
- if (do_s2io_prog_unicast(dev, dev->dev_addr) == FAILURE) {
- DBG_PRINT(ERR_DBG, "Set Mac Address Failed\n");
- s2io_card_down(sp);
- err = -ENODEV;
- goto hw_init_failed;
- }
- s2io_start_all_tx_queue(sp);
- return 0;
-
-hw_init_failed:
- if (sp->config.intr_type == MSI_X) {
- if (sp->entries) {
- kfree(sp->entries);
- swstats->mem_freed += sp->num_entries *
- sizeof(struct msix_entry);
- }
- if (sp->s2io_entries) {
- kfree(sp->s2io_entries);
- swstats->mem_freed += sp->num_entries *
- sizeof(struct s2io_msix_entry);
- }
- }
- return err;
-}
-
-/**
- * s2io_close -close entry point of the driver
- * @dev : device pointer.
- * Description:
- * This is the stop entry point of the driver. It needs to undo exactly
- * whatever was done by the open entry point,thus it's usually referred to
- * as the close function.Among other things this function mainly stops the
- * Rx side of the NIC and frees all the Rx buffers in the Rx rings.
- * Return value:
- * 0 on success and an appropriate (-)ve integer as defined in errno.h
- * file on failure.
- */
-
-static int s2io_close(struct net_device *dev)
-{
- struct s2io_nic *sp = netdev_priv(dev);
- struct config_param *config = &sp->config;
- u64 tmp64;
- int offset;
-
- /* Return if the device is already closed *
- * Can happen when s2io_card_up failed in change_mtu *
- */
- if (!is_s2io_card_up(sp))
- return 0;
-
- s2io_stop_all_tx_queue(sp);
- /* delete all populated mac entries */
- for (offset = 1; offset < config->max_mc_addr; offset++) {
- tmp64 = do_s2io_read_unicast_mc(sp, offset);
- if (tmp64 != S2IO_DISABLE_MAC_ENTRY)
- do_s2io_delete_unicast_mc(sp, tmp64);
- }
-
- s2io_card_down(sp);
-
- return 0;
-}
-
-/**
- * s2io_xmit - Tx entry point of te driver
- * @skb : the socket buffer containing the Tx data.
- * @dev : device pointer.
- * Description :
- * This function is the Tx entry point of the driver. S2IO NIC supports
- * certain protocol assist features on Tx side, namely CSO, S/G, LSO.
- * NOTE: when device can't queue the pkt,just the trans_start variable will
- * not be upadted.
- * Return value:
- * 0 on success & 1 on failure.
- */
-
-static netdev_tx_t s2io_xmit(struct sk_buff *skb, struct net_device *dev)
-{
- struct s2io_nic *sp = netdev_priv(dev);
- u16 frg_cnt, frg_len, i, queue, queue_len, put_off, get_off;
- register u64 val64;
- struct TxD *txdp;
- struct TxFIFO_element __iomem *tx_fifo;
- unsigned long flags = 0;
- u16 vlan_tag = 0;
- struct fifo_info *fifo = NULL;
- int offload_type;
- int enable_per_list_interrupt = 0;
- struct config_param *config = &sp->config;
- struct mac_info *mac_control = &sp->mac_control;
- struct stat_block *stats = mac_control->stats_info;
- struct swStat *swstats = &stats->sw_stat;
-
- DBG_PRINT(TX_DBG, "%s: In Neterion Tx routine\n", dev->name);
-
- if (unlikely(skb->len <= 0)) {
- DBG_PRINT(TX_DBG, "%s: Buffer has no data..\n", dev->name);
- dev_kfree_skb_any(skb);
- return NETDEV_TX_OK;
- }
-
- if (!is_s2io_card_up(sp)) {
- DBG_PRINT(TX_DBG, "%s: Card going down for reset\n",
- dev->name);
- dev_kfree_skb_any(skb);
- return NETDEV_TX_OK;
- }
-
- queue = 0;
- if (skb_vlan_tag_present(skb))
- vlan_tag = skb_vlan_tag_get(skb);
- if (sp->config.tx_steering_type == TX_DEFAULT_STEERING) {
- if (skb->protocol == htons(ETH_P_IP)) {
- struct iphdr *ip;
- struct tcphdr *th;
- ip = ip_hdr(skb);
-
- if (!ip_is_fragment(ip)) {
- th = (struct tcphdr *)(((unsigned char *)ip) +
- ip->ihl*4);
-
- if (ip->protocol == IPPROTO_TCP) {
- queue_len = sp->total_tcp_fifos;
- queue = (ntohs(th->source) +
- ntohs(th->dest)) &
- sp->fifo_selector[queue_len - 1];
- if (queue >= queue_len)
- queue = queue_len - 1;
- } else if (ip->protocol == IPPROTO_UDP) {
- queue_len = sp->total_udp_fifos;
- queue = (ntohs(th->source) +
- ntohs(th->dest)) &
- sp->fifo_selector[queue_len - 1];
- if (queue >= queue_len)
- queue = queue_len - 1;
- queue += sp->udp_fifo_idx;
- if (skb->len > 1024)
- enable_per_list_interrupt = 1;
- }
- }
- }
- } else if (sp->config.tx_steering_type == TX_PRIORITY_STEERING)
- /* get fifo number based on skb->priority value */
- queue = config->fifo_mapping
- [skb->priority & (MAX_TX_FIFOS - 1)];
- fifo = &mac_control->fifos[queue];
-
- spin_lock_irqsave(&fifo->tx_lock, flags);
-
- if (sp->config.multiq) {
- if (__netif_subqueue_stopped(dev, fifo->fifo_no)) {
- spin_unlock_irqrestore(&fifo->tx_lock, flags);
- return NETDEV_TX_BUSY;
- }
- } else if (unlikely(fifo->queue_state == FIFO_QUEUE_STOP)) {
- if (netif_queue_stopped(dev)) {
- spin_unlock_irqrestore(&fifo->tx_lock, flags);
- return NETDEV_TX_BUSY;
- }
- }
-
- put_off = (u16)fifo->tx_curr_put_info.offset;
- get_off = (u16)fifo->tx_curr_get_info.offset;
- txdp = fifo->list_info[put_off].list_virt_addr;
-
- queue_len = fifo->tx_curr_put_info.fifo_len + 1;
- /* Avoid "put" pointer going beyond "get" pointer */
- if (txdp->Host_Control ||
- ((put_off+1) == queue_len ? 0 : (put_off+1)) == get_off) {
- DBG_PRINT(TX_DBG, "Error in xmit, No free TXDs.\n");
- s2io_stop_tx_queue(sp, fifo->fifo_no);
- dev_kfree_skb_any(skb);
- spin_unlock_irqrestore(&fifo->tx_lock, flags);
- return NETDEV_TX_OK;
- }
-
- offload_type = s2io_offload_type(skb);
- if (offload_type & (SKB_GSO_TCPV4 | SKB_GSO_TCPV6)) {
- txdp->Control_1 |= TXD_TCP_LSO_EN;
- txdp->Control_1 |= TXD_TCP_LSO_MSS(s2io_tcp_mss(skb));
- }
- if (skb->ip_summed == CHECKSUM_PARTIAL) {
- txdp->Control_2 |= (TXD_TX_CKO_IPV4_EN |
- TXD_TX_CKO_TCP_EN |
- TXD_TX_CKO_UDP_EN);
- }
- txdp->Control_1 |= TXD_GATHER_CODE_FIRST;
- txdp->Control_1 |= TXD_LIST_OWN_XENA;
- txdp->Control_2 |= TXD_INT_NUMBER(fifo->fifo_no);
- if (enable_per_list_interrupt)
- if (put_off & (queue_len >> 5))
- txdp->Control_2 |= TXD_INT_TYPE_PER_LIST;
- if (vlan_tag) {
- txdp->Control_2 |= TXD_VLAN_ENABLE;
- txdp->Control_2 |= TXD_VLAN_TAG(vlan_tag);
- }
-
- frg_len = skb_headlen(skb);
- txdp->Buffer_Pointer = dma_map_single(&sp->pdev->dev, skb->data,
- frg_len, DMA_TO_DEVICE);
- if (dma_mapping_error(&sp->pdev->dev, txdp->Buffer_Pointer))
- goto pci_map_failed;
-
- txdp->Host_Control = (unsigned long)skb;
- txdp->Control_1 |= TXD_BUFFER0_SIZE(frg_len);
-
- frg_cnt = skb_shinfo(skb)->nr_frags;
- /* For fragmented SKB. */
- for (i = 0; i < frg_cnt; i++) {
- const skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
- /* A '0' length fragment will be ignored */
- if (!skb_frag_size(frag))
- continue;
- txdp++;
- txdp->Buffer_Pointer = (u64)skb_frag_dma_map(&sp->pdev->dev,
- frag, 0,
- skb_frag_size(frag),
- DMA_TO_DEVICE);
- txdp->Control_1 = TXD_BUFFER0_SIZE(skb_frag_size(frag));
- }
- txdp->Control_1 |= TXD_GATHER_CODE_LAST;
-
- tx_fifo = mac_control->tx_FIFO_start[queue];
- val64 = fifo->list_info[put_off].list_phy_addr;
- writeq(val64, &tx_fifo->TxDL_Pointer);
-
- val64 = (TX_FIFO_LAST_TXD_NUM(frg_cnt) | TX_FIFO_FIRST_LIST |
- TX_FIFO_LAST_LIST);
- if (offload_type)
- val64 |= TX_FIFO_SPECIAL_FUNC;
-
- writeq(val64, &tx_fifo->List_Control);
-
- put_off++;
- if (put_off == fifo->tx_curr_put_info.fifo_len + 1)
- put_off = 0;
- fifo->tx_curr_put_info.offset = put_off;
-
- /* Avoid "put" pointer going beyond "get" pointer */
- if (((put_off+1) == queue_len ? 0 : (put_off+1)) == get_off) {
- swstats->fifo_full_cnt++;
- DBG_PRINT(TX_DBG,
- "No free TxDs for xmit, Put: 0x%x Get:0x%x\n",
- put_off, get_off);
- s2io_stop_tx_queue(sp, fifo->fifo_no);
- }
- swstats->mem_allocated += skb->truesize;
- spin_unlock_irqrestore(&fifo->tx_lock, flags);
-
- if (sp->config.intr_type == MSI_X)
- tx_intr_handler(fifo);
-
- return NETDEV_TX_OK;
-
-pci_map_failed:
- swstats->pci_map_fail_cnt++;
- s2io_stop_tx_queue(sp, fifo->fifo_no);
- swstats->mem_freed += skb->truesize;
- dev_kfree_skb_any(skb);
- spin_unlock_irqrestore(&fifo->tx_lock, flags);
- return NETDEV_TX_OK;
-}
-
-static void
-s2io_alarm_handle(struct timer_list *t)
-{
- struct s2io_nic *sp = timer_container_of(sp, t, alarm_timer);
- struct net_device *dev = sp->dev;
-
- s2io_handle_errors(dev);
- mod_timer(&sp->alarm_timer, jiffies + HZ / 2);
-}
-
-static irqreturn_t s2io_msix_ring_handle(int irq, void *dev_id)
-{
- struct ring_info *ring = (struct ring_info *)dev_id;
- struct s2io_nic *sp = ring->nic;
- struct XENA_dev_config __iomem *bar0 = sp->bar0;
-
- if (unlikely(!is_s2io_card_up(sp)))
- return IRQ_HANDLED;
-
- if (sp->config.napi) {
- u8 __iomem *addr = NULL;
- u8 val8 = 0;
-
- addr = (u8 __iomem *)&bar0->xmsi_mask_reg;
- addr += (7 - ring->ring_no);
- val8 = (ring->ring_no == 0) ? 0x7f : 0xff;
- writeb(val8, addr);
- val8 = readb(addr);
- napi_schedule(&ring->napi);
- } else {
- rx_intr_handler(ring, 0);
- s2io_chk_rx_buffers(sp, ring);
- }
-
- return IRQ_HANDLED;
-}
-
-static irqreturn_t s2io_msix_fifo_handle(int irq, void *dev_id)
-{
- int i;
- struct fifo_info *fifos = (struct fifo_info *)dev_id;
- struct s2io_nic *sp = fifos->nic;
- struct XENA_dev_config __iomem *bar0 = sp->bar0;
- struct config_param *config = &sp->config;
- u64 reason;
-
- if (unlikely(!is_s2io_card_up(sp)))
- return IRQ_NONE;
-
- reason = readq(&bar0->general_int_status);
- if (unlikely(reason == S2IO_MINUS_ONE))
- /* Nothing much can be done. Get out */
- return IRQ_HANDLED;
-
- if (reason & (GEN_INTR_TXPIC | GEN_INTR_TXTRAFFIC)) {
- writeq(S2IO_MINUS_ONE, &bar0->general_int_mask);
-
- if (reason & GEN_INTR_TXPIC)
- s2io_txpic_intr_handle(sp);
-
- if (reason & GEN_INTR_TXTRAFFIC)
- writeq(S2IO_MINUS_ONE, &bar0->tx_traffic_int);
-
- for (i = 0; i < config->tx_fifo_num; i++)
- tx_intr_handler(&fifos[i]);
-
- writeq(sp->general_int_mask, &bar0->general_int_mask);
- readl(&bar0->general_int_status);
- return IRQ_HANDLED;
- }
- /* The interrupt was not raised by us */
- return IRQ_NONE;
-}
-
-static void s2io_txpic_intr_handle(struct s2io_nic *sp)
-{
- struct XENA_dev_config __iomem *bar0 = sp->bar0;
- u64 val64;
-
- val64 = readq(&bar0->pic_int_status);
- if (val64 & PIC_INT_GPIO) {
- val64 = readq(&bar0->gpio_int_reg);
- if ((val64 & GPIO_INT_REG_LINK_DOWN) &&
- (val64 & GPIO_INT_REG_LINK_UP)) {
- /*
- * This is unstable state so clear both up/down
- * interrupt and adapter to re-evaluate the link state.
- */
- val64 |= GPIO_INT_REG_LINK_DOWN;
- val64 |= GPIO_INT_REG_LINK_UP;
- writeq(val64, &bar0->gpio_int_reg);
- val64 = readq(&bar0->gpio_int_mask);
- val64 &= ~(GPIO_INT_MASK_LINK_UP |
- GPIO_INT_MASK_LINK_DOWN);
- writeq(val64, &bar0->gpio_int_mask);
- } else if (val64 & GPIO_INT_REG_LINK_UP) {
- val64 = readq(&bar0->adapter_status);
- /* Enable Adapter */
- val64 = readq(&bar0->adapter_control);
- val64 |= ADAPTER_CNTL_EN;
- writeq(val64, &bar0->adapter_control);
- val64 |= ADAPTER_LED_ON;
- writeq(val64, &bar0->adapter_control);
- if (!sp->device_enabled_once)
- sp->device_enabled_once = 1;
-
- s2io_link(sp, LINK_UP);
- /*
- * unmask link down interrupt and mask link-up
- * intr
- */
- val64 = readq(&bar0->gpio_int_mask);
- val64 &= ~GPIO_INT_MASK_LINK_DOWN;
- val64 |= GPIO_INT_MASK_LINK_UP;
- writeq(val64, &bar0->gpio_int_mask);
-
- } else if (val64 & GPIO_INT_REG_LINK_DOWN) {
- val64 = readq(&bar0->adapter_status);
- s2io_link(sp, LINK_DOWN);
- /* Link is down so unmaks link up interrupt */
- val64 = readq(&bar0->gpio_int_mask);
- val64 &= ~GPIO_INT_MASK_LINK_UP;
- val64 |= GPIO_INT_MASK_LINK_DOWN;
- writeq(val64, &bar0->gpio_int_mask);
-
- /* turn off LED */
- val64 = readq(&bar0->adapter_control);
- val64 = val64 & (~ADAPTER_LED_ON);
- writeq(val64, &bar0->adapter_control);
- }
- }
- val64 = readq(&bar0->gpio_int_mask);
-}
-
-/**
- * do_s2io_chk_alarm_bit - Check for alarm and incrment the counter
- * @value: alarm bits
- * @addr: address value
- * @cnt: counter variable
- * Description: Check for alarm and increment the counter
- * Return Value:
- * 1 - if alarm bit set
- * 0 - if alarm bit is not set
- */
-static int do_s2io_chk_alarm_bit(u64 value, void __iomem *addr,
- unsigned long long *cnt)
-{
- u64 val64;
- val64 = readq(addr);
- if (val64 & value) {
- writeq(val64, addr);
- (*cnt)++;
- return 1;
- }
- return 0;
-
-}
-
-/**
- * s2io_handle_errors - Xframe error indication handler
- * @dev_id: opaque handle to dev
- * Description: Handle alarms such as loss of link, single or
- * double ECC errors, critical and serious errors.
- * Return Value:
- * NONE
- */
-static void s2io_handle_errors(void *dev_id)
-{
- struct net_device *dev = (struct net_device *)dev_id;
- struct s2io_nic *sp = netdev_priv(dev);
- struct XENA_dev_config __iomem *bar0 = sp->bar0;
- u64 temp64 = 0, val64 = 0;
- int i = 0;
-
- struct swStat *sw_stat = &sp->mac_control.stats_info->sw_stat;
- struct xpakStat *stats = &sp->mac_control.stats_info->xpak_stat;
-
- if (!is_s2io_card_up(sp))
- return;
-
- if (pci_channel_offline(sp->pdev))
- return;
-
- memset(&sw_stat->ring_full_cnt, 0,
- sizeof(sw_stat->ring_full_cnt));
-
- /* Handling the XPAK counters update */
- if (stats->xpak_timer_count < 72000) {
- /* waiting for an hour */
- stats->xpak_timer_count++;
- } else {
- s2io_updt_xpak_counter(dev);
- /* reset the count to zero */
- stats->xpak_timer_count = 0;
- }
-
- /* Handling link status change error Intr */
- if (s2io_link_fault_indication(sp) == MAC_RMAC_ERR_TIMER) {
- val64 = readq(&bar0->mac_rmac_err_reg);
- writeq(val64, &bar0->mac_rmac_err_reg);
- if (val64 & RMAC_LINK_STATE_CHANGE_INT)
- schedule_work(&sp->set_link_task);
- }
-
- /* In case of a serious error, the device will be Reset. */
- if (do_s2io_chk_alarm_bit(SERR_SOURCE_ANY, &bar0->serr_source,
- &sw_stat->serious_err_cnt))
- goto reset;
-
- /* Check for data parity error */
- if (do_s2io_chk_alarm_bit(GPIO_INT_REG_DP_ERR_INT, &bar0->gpio_int_reg,
- &sw_stat->parity_err_cnt))
- goto reset;
-
- /* Check for ring full counter */
- if (sp->device_type == XFRAME_II_DEVICE) {
- val64 = readq(&bar0->ring_bump_counter1);
- for (i = 0; i < 4; i++) {
- temp64 = (val64 & vBIT(0xFFFF, (i*16), 16));
- temp64 >>= 64 - ((i+1)*16);
- sw_stat->ring_full_cnt[i] += temp64;
- }
-
- val64 = readq(&bar0->ring_bump_counter2);
- for (i = 0; i < 4; i++) {
- temp64 = (val64 & vBIT(0xFFFF, (i*16), 16));
- temp64 >>= 64 - ((i+1)*16);
- sw_stat->ring_full_cnt[i+4] += temp64;
- }
- }
-
- val64 = readq(&bar0->txdma_int_status);
- /*check for pfc_err*/
- if (val64 & TXDMA_PFC_INT) {
- if (do_s2io_chk_alarm_bit(PFC_ECC_DB_ERR | PFC_SM_ERR_ALARM |
- PFC_MISC_0_ERR | PFC_MISC_1_ERR |
- PFC_PCIX_ERR,
- &bar0->pfc_err_reg,
- &sw_stat->pfc_err_cnt))
- goto reset;
- do_s2io_chk_alarm_bit(PFC_ECC_SG_ERR,
- &bar0->pfc_err_reg,
- &sw_stat->pfc_err_cnt);
- }
-
- /*check for tda_err*/
- if (val64 & TXDMA_TDA_INT) {
- if (do_s2io_chk_alarm_bit(TDA_Fn_ECC_DB_ERR |
- TDA_SM0_ERR_ALARM |
- TDA_SM1_ERR_ALARM,
- &bar0->tda_err_reg,
- &sw_stat->tda_err_cnt))
- goto reset;
- do_s2io_chk_alarm_bit(TDA_Fn_ECC_SG_ERR | TDA_PCIX_ERR,
- &bar0->tda_err_reg,
- &sw_stat->tda_err_cnt);
- }
- /*check for pcc_err*/
- if (val64 & TXDMA_PCC_INT) {
- if (do_s2io_chk_alarm_bit(PCC_SM_ERR_ALARM | PCC_WR_ERR_ALARM |
- PCC_N_SERR | PCC_6_COF_OV_ERR |
- PCC_7_COF_OV_ERR | PCC_6_LSO_OV_ERR |
- PCC_7_LSO_OV_ERR | PCC_FB_ECC_DB_ERR |
- PCC_TXB_ECC_DB_ERR,
- &bar0->pcc_err_reg,
- &sw_stat->pcc_err_cnt))
- goto reset;
- do_s2io_chk_alarm_bit(PCC_FB_ECC_SG_ERR | PCC_TXB_ECC_SG_ERR,
- &bar0->pcc_err_reg,
- &sw_stat->pcc_err_cnt);
- }
-
- /*check for tti_err*/
- if (val64 & TXDMA_TTI_INT) {
- if (do_s2io_chk_alarm_bit(TTI_SM_ERR_ALARM,
- &bar0->tti_err_reg,
- &sw_stat->tti_err_cnt))
- goto reset;
- do_s2io_chk_alarm_bit(TTI_ECC_SG_ERR | TTI_ECC_DB_ERR,
- &bar0->tti_err_reg,
- &sw_stat->tti_err_cnt);
- }
-
- /*check for lso_err*/
- if (val64 & TXDMA_LSO_INT) {
- if (do_s2io_chk_alarm_bit(LSO6_ABORT | LSO7_ABORT |
- LSO6_SM_ERR_ALARM | LSO7_SM_ERR_ALARM,
- &bar0->lso_err_reg,
- &sw_stat->lso_err_cnt))
- goto reset;
- do_s2io_chk_alarm_bit(LSO6_SEND_OFLOW | LSO7_SEND_OFLOW,
- &bar0->lso_err_reg,
- &sw_stat->lso_err_cnt);
- }
-
- /*check for tpa_err*/
- if (val64 & TXDMA_TPA_INT) {
- if (do_s2io_chk_alarm_bit(TPA_SM_ERR_ALARM,
- &bar0->tpa_err_reg,
- &sw_stat->tpa_err_cnt))
- goto reset;
- do_s2io_chk_alarm_bit(TPA_TX_FRM_DROP,
- &bar0->tpa_err_reg,
- &sw_stat->tpa_err_cnt);
- }
-
- /*check for sm_err*/
- if (val64 & TXDMA_SM_INT) {
- if (do_s2io_chk_alarm_bit(SM_SM_ERR_ALARM,
- &bar0->sm_err_reg,
- &sw_stat->sm_err_cnt))
- goto reset;
- }
-
- val64 = readq(&bar0->mac_int_status);
- if (val64 & MAC_INT_STATUS_TMAC_INT) {
- if (do_s2io_chk_alarm_bit(TMAC_TX_BUF_OVRN | TMAC_TX_SM_ERR,
- &bar0->mac_tmac_err_reg,
- &sw_stat->mac_tmac_err_cnt))
- goto reset;
- do_s2io_chk_alarm_bit(TMAC_ECC_SG_ERR | TMAC_ECC_DB_ERR |
- TMAC_DESC_ECC_SG_ERR |
- TMAC_DESC_ECC_DB_ERR,
- &bar0->mac_tmac_err_reg,
- &sw_stat->mac_tmac_err_cnt);
- }
-
- val64 = readq(&bar0->xgxs_int_status);
- if (val64 & XGXS_INT_STATUS_TXGXS) {
- if (do_s2io_chk_alarm_bit(TXGXS_ESTORE_UFLOW | TXGXS_TX_SM_ERR,
- &bar0->xgxs_txgxs_err_reg,
- &sw_stat->xgxs_txgxs_err_cnt))
- goto reset;
- do_s2io_chk_alarm_bit(TXGXS_ECC_SG_ERR | TXGXS_ECC_DB_ERR,
- &bar0->xgxs_txgxs_err_reg,
- &sw_stat->xgxs_txgxs_err_cnt);
- }
-
- val64 = readq(&bar0->rxdma_int_status);
- if (val64 & RXDMA_INT_RC_INT_M) {
- if (do_s2io_chk_alarm_bit(RC_PRCn_ECC_DB_ERR |
- RC_FTC_ECC_DB_ERR |
- RC_PRCn_SM_ERR_ALARM |
- RC_FTC_SM_ERR_ALARM,
- &bar0->rc_err_reg,
- &sw_stat->rc_err_cnt))
- goto reset;
- do_s2io_chk_alarm_bit(RC_PRCn_ECC_SG_ERR |
- RC_FTC_ECC_SG_ERR |
- RC_RDA_FAIL_WR_Rn, &bar0->rc_err_reg,
- &sw_stat->rc_err_cnt);
- if (do_s2io_chk_alarm_bit(PRC_PCI_AB_RD_Rn |
- PRC_PCI_AB_WR_Rn |
- PRC_PCI_AB_F_WR_Rn,
- &bar0->prc_pcix_err_reg,
- &sw_stat->prc_pcix_err_cnt))
- goto reset;
- do_s2io_chk_alarm_bit(PRC_PCI_DP_RD_Rn |
- PRC_PCI_DP_WR_Rn |
- PRC_PCI_DP_F_WR_Rn,
- &bar0->prc_pcix_err_reg,
- &sw_stat->prc_pcix_err_cnt);
- }
-
- if (val64 & RXDMA_INT_RPA_INT_M) {
- if (do_s2io_chk_alarm_bit(RPA_SM_ERR_ALARM | RPA_CREDIT_ERR,
- &bar0->rpa_err_reg,
- &sw_stat->rpa_err_cnt))
- goto reset;
- do_s2io_chk_alarm_bit(RPA_ECC_SG_ERR | RPA_ECC_DB_ERR,
- &bar0->rpa_err_reg,
- &sw_stat->rpa_err_cnt);
- }
-
- if (val64 & RXDMA_INT_RDA_INT_M) {
- if (do_s2io_chk_alarm_bit(RDA_RXDn_ECC_DB_ERR |
- RDA_FRM_ECC_DB_N_AERR |
- RDA_SM1_ERR_ALARM |
- RDA_SM0_ERR_ALARM |
- RDA_RXD_ECC_DB_SERR,
- &bar0->rda_err_reg,
- &sw_stat->rda_err_cnt))
- goto reset;
- do_s2io_chk_alarm_bit(RDA_RXDn_ECC_SG_ERR |
- RDA_FRM_ECC_SG_ERR |
- RDA_MISC_ERR |
- RDA_PCIX_ERR,
- &bar0->rda_err_reg,
- &sw_stat->rda_err_cnt);
- }
-
- if (val64 & RXDMA_INT_RTI_INT_M) {
- if (do_s2io_chk_alarm_bit(RTI_SM_ERR_ALARM,
- &bar0->rti_err_reg,
- &sw_stat->rti_err_cnt))
- goto reset;
- do_s2io_chk_alarm_bit(RTI_ECC_SG_ERR | RTI_ECC_DB_ERR,
- &bar0->rti_err_reg,
- &sw_stat->rti_err_cnt);
- }
-
- val64 = readq(&bar0->mac_int_status);
- if (val64 & MAC_INT_STATUS_RMAC_INT) {
- if (do_s2io_chk_alarm_bit(RMAC_RX_BUFF_OVRN | RMAC_RX_SM_ERR,
- &bar0->mac_rmac_err_reg,
- &sw_stat->mac_rmac_err_cnt))
- goto reset;
- do_s2io_chk_alarm_bit(RMAC_UNUSED_INT |
- RMAC_SINGLE_ECC_ERR |
- RMAC_DOUBLE_ECC_ERR,
- &bar0->mac_rmac_err_reg,
- &sw_stat->mac_rmac_err_cnt);
- }
-
- val64 = readq(&bar0->xgxs_int_status);
- if (val64 & XGXS_INT_STATUS_RXGXS) {
- if (do_s2io_chk_alarm_bit(RXGXS_ESTORE_OFLOW | RXGXS_RX_SM_ERR,
- &bar0->xgxs_rxgxs_err_reg,
- &sw_stat->xgxs_rxgxs_err_cnt))
- goto reset;
- }
-
- val64 = readq(&bar0->mc_int_status);
- if (val64 & MC_INT_STATUS_MC_INT) {
- if (do_s2io_chk_alarm_bit(MC_ERR_REG_SM_ERR,
- &bar0->mc_err_reg,
- &sw_stat->mc_err_cnt))
- goto reset;
-
- /* Handling Ecc errors */
- if (val64 & (MC_ERR_REG_ECC_ALL_SNG | MC_ERR_REG_ECC_ALL_DBL)) {
- writeq(val64, &bar0->mc_err_reg);
- if (val64 & MC_ERR_REG_ECC_ALL_DBL) {
- sw_stat->double_ecc_errs++;
- if (sp->device_type != XFRAME_II_DEVICE) {
- /*
- * Reset XframeI only if critical error
- */
- if (val64 &
- (MC_ERR_REG_MIRI_ECC_DB_ERR_0 |
- MC_ERR_REG_MIRI_ECC_DB_ERR_1))
- goto reset;
- }
- } else
- sw_stat->single_ecc_errs++;
- }
- }
- return;
-
-reset:
- s2io_stop_all_tx_queue(sp);
- schedule_work(&sp->rst_timer_task);
- sw_stat->soft_reset_cnt++;
-}
-
-/**
- * s2io_isr - ISR handler of the device .
- * @irq: the irq of the device.
- * @dev_id: a void pointer to the dev structure of the NIC.
- * Description: This function is the ISR handler of the device. It
- * identifies the reason for the interrupt and calls the relevant
- * service routines. As a contongency measure, this ISR allocates the
- * recv buffers, if their numbers are below the panic value which is
- * presently set to 25% of the original number of rcv buffers allocated.
- * Return value:
- * IRQ_HANDLED: will be returned if IRQ was handled by this routine
- * IRQ_NONE: will be returned if interrupt is not from our device
- */
-static irqreturn_t s2io_isr(int irq, void *dev_id)
-{
- struct net_device *dev = (struct net_device *)dev_id;
- struct s2io_nic *sp = netdev_priv(dev);
- struct XENA_dev_config __iomem *bar0 = sp->bar0;
- int i;
- u64 reason = 0;
- struct mac_info *mac_control;
- struct config_param *config;
-
- /* Pretend we handled any irq's from a disconnected card */
- if (pci_channel_offline(sp->pdev))
- return IRQ_NONE;
-
- if (!is_s2io_card_up(sp))
- return IRQ_NONE;
-
- config = &sp->config;
- mac_control = &sp->mac_control;
-
- /*
- * Identify the cause for interrupt and call the appropriate
- * interrupt handler. Causes for the interrupt could be;
- * 1. Rx of packet.
- * 2. Tx complete.
- * 3. Link down.
- */
- reason = readq(&bar0->general_int_status);
-
- if (unlikely(reason == S2IO_MINUS_ONE))
- return IRQ_HANDLED; /* Nothing much can be done. Get out */
-
- if (reason &
- (GEN_INTR_RXTRAFFIC | GEN_INTR_TXTRAFFIC | GEN_INTR_TXPIC)) {
- writeq(S2IO_MINUS_ONE, &bar0->general_int_mask);
-
- if (config->napi) {
- if (reason & GEN_INTR_RXTRAFFIC) {
- napi_schedule(&sp->napi);
- writeq(S2IO_MINUS_ONE, &bar0->rx_traffic_mask);
- writeq(S2IO_MINUS_ONE, &bar0->rx_traffic_int);
- readl(&bar0->rx_traffic_int);
- }
- } else {
- /*
- * rx_traffic_int reg is an R1 register, writing all 1's
- * will ensure that the actual interrupt causing bit
- * gets cleared and hence a read can be avoided.
- */
- if (reason & GEN_INTR_RXTRAFFIC)
- writeq(S2IO_MINUS_ONE, &bar0->rx_traffic_int);
-
- for (i = 0; i < config->rx_ring_num; i++) {
- struct ring_info *ring = &mac_control->rings[i];
-
- rx_intr_handler(ring, 0);
- }
- }
-
- /*
- * tx_traffic_int reg is an R1 register, writing all 1's
- * will ensure that the actual interrupt causing bit gets
- * cleared and hence a read can be avoided.
- */
- if (reason & GEN_INTR_TXTRAFFIC)
- writeq(S2IO_MINUS_ONE, &bar0->tx_traffic_int);
-
- for (i = 0; i < config->tx_fifo_num; i++)
- tx_intr_handler(&mac_control->fifos[i]);
-
- if (reason & GEN_INTR_TXPIC)
- s2io_txpic_intr_handle(sp);
-
- /*
- * Reallocate the buffers from the interrupt handler itself.
- */
- if (!config->napi) {
- for (i = 0; i < config->rx_ring_num; i++) {
- struct ring_info *ring = &mac_control->rings[i];
-
- s2io_chk_rx_buffers(sp, ring);
- }
- }
- writeq(sp->general_int_mask, &bar0->general_int_mask);
- readl(&bar0->general_int_status);
-
- return IRQ_HANDLED;
-
- } else if (!reason) {
- /* The interrupt was not raised by us */
- return IRQ_NONE;
- }
-
- return IRQ_HANDLED;
-}
-
-/*
- * s2io_updt_stats -
- */
-static void s2io_updt_stats(struct s2io_nic *sp)
-{
- struct XENA_dev_config __iomem *bar0 = sp->bar0;
- u64 val64;
- int cnt = 0;
-
- if (is_s2io_card_up(sp)) {
- /* Apprx 30us on a 133 MHz bus */
- val64 = SET_UPDT_CLICKS(10) |
- STAT_CFG_ONE_SHOT_EN | STAT_CFG_STAT_EN;
- writeq(val64, &bar0->stat_cfg);
- do {
- udelay(100);
- val64 = readq(&bar0->stat_cfg);
- if (!(val64 & s2BIT(0)))
- break;
- cnt++;
- if (cnt == 5)
- break; /* Updt failed */
- } while (1);
- }
-}
-
-/**
- * s2io_get_stats - Updates the device statistics structure.
- * @dev : pointer to the device structure.
- * Description:
- * This function updates the device statistics structure in the s2io_nic
- * structure and returns a pointer to the same.
- * Return value:
- * pointer to the updated net_device_stats structure.
- */
-static struct net_device_stats *s2io_get_stats(struct net_device *dev)
-{
- struct s2io_nic *sp = netdev_priv(dev);
- struct mac_info *mac_control = &sp->mac_control;
- struct stat_block *stats = mac_control->stats_info;
- u64 delta;
-
- /* Configure Stats for immediate updt */
- s2io_updt_stats(sp);
-
- /* A device reset will cause the on-adapter statistics to be zero'ed.
- * This can be done while running by changing the MTU. To prevent the
- * system from having the stats zero'ed, the driver keeps a copy of the
- * last update to the system (which is also zero'ed on reset). This
- * enables the driver to accurately know the delta between the last
- * update and the current update.
- */
- delta = ((u64) le32_to_cpu(stats->rmac_vld_frms_oflow) << 32 |
- le32_to_cpu(stats->rmac_vld_frms)) - sp->stats.rx_packets;
- sp->stats.rx_packets += delta;
- dev->stats.rx_packets += delta;
-
- delta = ((u64) le32_to_cpu(stats->tmac_frms_oflow) << 32 |
- le32_to_cpu(stats->tmac_frms)) - sp->stats.tx_packets;
- sp->stats.tx_packets += delta;
- dev->stats.tx_packets += delta;
-
- delta = ((u64) le32_to_cpu(stats->rmac_data_octets_oflow) << 32 |
- le32_to_cpu(stats->rmac_data_octets)) - sp->stats.rx_bytes;
- sp->stats.rx_bytes += delta;
- dev->stats.rx_bytes += delta;
-
- delta = ((u64) le32_to_cpu(stats->tmac_data_octets_oflow) << 32 |
- le32_to_cpu(stats->tmac_data_octets)) - sp->stats.tx_bytes;
- sp->stats.tx_bytes += delta;
- dev->stats.tx_bytes += delta;
-
- delta = le64_to_cpu(stats->rmac_drop_frms) - sp->stats.rx_errors;
- sp->stats.rx_errors += delta;
- dev->stats.rx_errors += delta;
-
- delta = ((u64) le32_to_cpu(stats->tmac_any_err_frms_oflow) << 32 |
- le32_to_cpu(stats->tmac_any_err_frms)) - sp->stats.tx_errors;
- sp->stats.tx_errors += delta;
- dev->stats.tx_errors += delta;
-
- delta = le64_to_cpu(stats->rmac_drop_frms) - sp->stats.rx_dropped;
- sp->stats.rx_dropped += delta;
- dev->stats.rx_dropped += delta;
-
- delta = le64_to_cpu(stats->tmac_drop_frms) - sp->stats.tx_dropped;
- sp->stats.tx_dropped += delta;
- dev->stats.tx_dropped += delta;
-
- /* The adapter MAC interprets pause frames as multicast packets, but
- * does not pass them up. This erroneously increases the multicast
- * packet count and needs to be deducted when the multicast frame count
- * is queried.
- */
- delta = (u64) le32_to_cpu(stats->rmac_vld_mcst_frms_oflow) << 32 |
- le32_to_cpu(stats->rmac_vld_mcst_frms);
- delta -= le64_to_cpu(stats->rmac_pause_ctrl_frms);
- delta -= sp->stats.multicast;
- sp->stats.multicast += delta;
- dev->stats.multicast += delta;
-
- delta = ((u64) le32_to_cpu(stats->rmac_usized_frms_oflow) << 32 |
- le32_to_cpu(stats->rmac_usized_frms)) +
- le64_to_cpu(stats->rmac_long_frms) - sp->stats.rx_length_errors;
- sp->stats.rx_length_errors += delta;
- dev->stats.rx_length_errors += delta;
-
- delta = le64_to_cpu(stats->rmac_fcs_err_frms) - sp->stats.rx_crc_errors;
- sp->stats.rx_crc_errors += delta;
- dev->stats.rx_crc_errors += delta;
-
- return &dev->stats;
-}
-
-/**
- * s2io_set_multicast - entry point for multicast address enable/disable.
- * @dev : pointer to the device structure
- * @may_sleep: parameter indicates if sleeping when waiting for command
- * complete
- * Description:
- * This function is a driver entry point which gets called by the kernel
- * whenever multicast addresses must be enabled/disabled. This also gets
- * called to set/reset promiscuous mode. Depending on the deivce flag, we
- * determine, if multicast address must be enabled or if promiscuous mode
- * is to be disabled etc.
- * Return value:
- * void.
- */
-static void s2io_set_multicast(struct net_device *dev, bool may_sleep)
-{
- int i, j, prev_cnt;
- struct netdev_hw_addr *ha;
- struct s2io_nic *sp = netdev_priv(dev);
- struct XENA_dev_config __iomem *bar0 = sp->bar0;
- u64 val64 = 0, multi_mac = 0x010203040506ULL, mask =
- 0xfeffffffffffULL;
- u64 dis_addr = S2IO_DISABLE_MAC_ENTRY, mac_addr = 0;
- void __iomem *add;
- struct config_param *config = &sp->config;
-
- if ((dev->flags & IFF_ALLMULTI) && (!sp->m_cast_flg)) {
- /* Enable all Multicast addresses */
- writeq(RMAC_ADDR_DATA0_MEM_ADDR(multi_mac),
- &bar0->rmac_addr_data0_mem);
- writeq(RMAC_ADDR_DATA1_MEM_MASK(mask),
- &bar0->rmac_addr_data1_mem);
- val64 = RMAC_ADDR_CMD_MEM_WE |
- RMAC_ADDR_CMD_MEM_STROBE_NEW_CMD |
- RMAC_ADDR_CMD_MEM_OFFSET(config->max_mc_addr - 1);
- writeq(val64, &bar0->rmac_addr_cmd_mem);
- /* Wait till command completes */
- wait_for_cmd_complete(&bar0->rmac_addr_cmd_mem,
- RMAC_ADDR_CMD_MEM_STROBE_CMD_EXECUTING,
- S2IO_BIT_RESET, may_sleep);
-
- sp->m_cast_flg = 1;
- sp->all_multi_pos = config->max_mc_addr - 1;
- } else if ((dev->flags & IFF_ALLMULTI) && (sp->m_cast_flg)) {
- /* Disable all Multicast addresses */
- writeq(RMAC_ADDR_DATA0_MEM_ADDR(dis_addr),
- &bar0->rmac_addr_data0_mem);
- writeq(RMAC_ADDR_DATA1_MEM_MASK(0x0),
- &bar0->rmac_addr_data1_mem);
- val64 = RMAC_ADDR_CMD_MEM_WE |
- RMAC_ADDR_CMD_MEM_STROBE_NEW_CMD |
- RMAC_ADDR_CMD_MEM_OFFSET(sp->all_multi_pos);
- writeq(val64, &bar0->rmac_addr_cmd_mem);
- /* Wait till command completes */
- wait_for_cmd_complete(&bar0->rmac_addr_cmd_mem,
- RMAC_ADDR_CMD_MEM_STROBE_CMD_EXECUTING,
- S2IO_BIT_RESET, may_sleep);
-
- sp->m_cast_flg = 0;
- sp->all_multi_pos = 0;
- }
-
- if ((dev->flags & IFF_PROMISC) && (!sp->promisc_flg)) {
- /* Put the NIC into promiscuous mode */
- add = &bar0->mac_cfg;
- val64 = readq(&bar0->mac_cfg);
- val64 |= MAC_CFG_RMAC_PROM_ENABLE;
-
- writeq(RMAC_CFG_KEY(0x4C0D), &bar0->rmac_cfg_key);
- writel((u32)val64, add);
- writeq(RMAC_CFG_KEY(0x4C0D), &bar0->rmac_cfg_key);
- writel((u32) (val64 >> 32), (add + 4));
-
- if (vlan_tag_strip != 1) {
- val64 = readq(&bar0->rx_pa_cfg);
- val64 &= ~RX_PA_CFG_STRIP_VLAN_TAG;
- writeq(val64, &bar0->rx_pa_cfg);
- sp->vlan_strip_flag = 0;
- }
-
- val64 = readq(&bar0->mac_cfg);
- sp->promisc_flg = 1;
- DBG_PRINT(INFO_DBG, "%s: entered promiscuous mode\n",
- dev->name);
- } else if (!(dev->flags & IFF_PROMISC) && (sp->promisc_flg)) {
- /* Remove the NIC from promiscuous mode */
- add = &bar0->mac_cfg;
- val64 = readq(&bar0->mac_cfg);
- val64 &= ~MAC_CFG_RMAC_PROM_ENABLE;
-
- writeq(RMAC_CFG_KEY(0x4C0D), &bar0->rmac_cfg_key);
- writel((u32)val64, add);
- writeq(RMAC_CFG_KEY(0x4C0D), &bar0->rmac_cfg_key);
- writel((u32) (val64 >> 32), (add + 4));
-
- if (vlan_tag_strip != 0) {
- val64 = readq(&bar0->rx_pa_cfg);
- val64 |= RX_PA_CFG_STRIP_VLAN_TAG;
- writeq(val64, &bar0->rx_pa_cfg);
- sp->vlan_strip_flag = 1;
- }
-
- val64 = readq(&bar0->mac_cfg);
- sp->promisc_flg = 0;
- DBG_PRINT(INFO_DBG, "%s: left promiscuous mode\n", dev->name);
- }
-
- /* Update individual M_CAST address list */
- if ((!sp->m_cast_flg) && netdev_mc_count(dev)) {
- if (netdev_mc_count(dev) >
- (config->max_mc_addr - config->max_mac_addr)) {
- DBG_PRINT(ERR_DBG,
- "%s: No more Rx filters can be added - "
- "please enable ALL_MULTI instead\n",
- dev->name);
- return;
- }
-
- prev_cnt = sp->mc_addr_count;
- sp->mc_addr_count = netdev_mc_count(dev);
-
- /* Clear out the previous list of Mc in the H/W. */
- for (i = 0; i < prev_cnt; i++) {
- writeq(RMAC_ADDR_DATA0_MEM_ADDR(dis_addr),
- &bar0->rmac_addr_data0_mem);
- writeq(RMAC_ADDR_DATA1_MEM_MASK(0ULL),
- &bar0->rmac_addr_data1_mem);
- val64 = RMAC_ADDR_CMD_MEM_WE |
- RMAC_ADDR_CMD_MEM_STROBE_NEW_CMD |
- RMAC_ADDR_CMD_MEM_OFFSET
- (config->mc_start_offset + i);
- writeq(val64, &bar0->rmac_addr_cmd_mem);
-
- /* Wait for command completes */
- if (wait_for_cmd_complete(&bar0->rmac_addr_cmd_mem,
- RMAC_ADDR_CMD_MEM_STROBE_CMD_EXECUTING,
- S2IO_BIT_RESET, may_sleep)) {
- DBG_PRINT(ERR_DBG,
- "%s: Adding Multicasts failed\n",
- dev->name);
- return;
- }
- }
-
- /* Create the new Rx filter list and update the same in H/W. */
- i = 0;
- netdev_for_each_mc_addr(ha, dev) {
- mac_addr = 0;
- for (j = 0; j < ETH_ALEN; j++) {
- mac_addr |= ha->addr[j];
- mac_addr <<= 8;
- }
- mac_addr >>= 8;
- writeq(RMAC_ADDR_DATA0_MEM_ADDR(mac_addr),
- &bar0->rmac_addr_data0_mem);
- writeq(RMAC_ADDR_DATA1_MEM_MASK(0ULL),
- &bar0->rmac_addr_data1_mem);
- val64 = RMAC_ADDR_CMD_MEM_WE |
- RMAC_ADDR_CMD_MEM_STROBE_NEW_CMD |
- RMAC_ADDR_CMD_MEM_OFFSET
- (i + config->mc_start_offset);
- writeq(val64, &bar0->rmac_addr_cmd_mem);
-
- /* Wait for command completes */
- if (wait_for_cmd_complete(&bar0->rmac_addr_cmd_mem,
- RMAC_ADDR_CMD_MEM_STROBE_CMD_EXECUTING,
- S2IO_BIT_RESET, may_sleep)) {
- DBG_PRINT(ERR_DBG,
- "%s: Adding Multicasts failed\n",
- dev->name);
- return;
- }
- i++;
- }
- }
-}
-
-/* NDO wrapper for s2io_set_multicast */
-static void s2io_ndo_set_multicast(struct net_device *dev)
-{
- s2io_set_multicast(dev, false);
-}
-
-/* read from CAM unicast & multicast addresses and store it in
- * def_mac_addr structure
- */
-static void do_s2io_store_unicast_mc(struct s2io_nic *sp)
-{
- int offset;
- u64 mac_addr = 0x0;
- struct config_param *config = &sp->config;
-
- /* store unicast & multicast mac addresses */
- for (offset = 0; offset < config->max_mc_addr; offset++) {
- mac_addr = do_s2io_read_unicast_mc(sp, offset);
- /* if read fails disable the entry */
- if (mac_addr == FAILURE)
- mac_addr = S2IO_DISABLE_MAC_ENTRY;
- do_s2io_copy_mac_addr(sp, offset, mac_addr);
- }
-}
-
-/* restore unicast & multicast MAC to CAM from def_mac_addr structure */
-static void do_s2io_restore_unicast_mc(struct s2io_nic *sp)
-{
- int offset;
- struct config_param *config = &sp->config;
- /* restore unicast mac address */
- for (offset = 0; offset < config->max_mac_addr; offset++)
- do_s2io_prog_unicast(sp->dev,
- sp->def_mac_addr[offset].mac_addr);
-
- /* restore multicast mac address */
- for (offset = config->mc_start_offset;
- offset < config->max_mc_addr; offset++)
- do_s2io_add_mc(sp, sp->def_mac_addr[offset].mac_addr);
-}
-
-/* add a multicast MAC address to CAM */
-static int do_s2io_add_mc(struct s2io_nic *sp, u8 *addr)
-{
- int i;
- u64 mac_addr;
- struct config_param *config = &sp->config;
-
- mac_addr = ether_addr_to_u64(addr);
- if ((0ULL == mac_addr) || (mac_addr == S2IO_DISABLE_MAC_ENTRY))
- return SUCCESS;
-
- /* check if the multicast mac already preset in CAM */
- for (i = config->mc_start_offset; i < config->max_mc_addr; i++) {
- u64 tmp64;
- tmp64 = do_s2io_read_unicast_mc(sp, i);
- if (tmp64 == S2IO_DISABLE_MAC_ENTRY) /* CAM entry is empty */
- break;
-
- if (tmp64 == mac_addr)
- return SUCCESS;
- }
- if (i == config->max_mc_addr) {
- DBG_PRINT(ERR_DBG,
- "CAM full no space left for multicast MAC\n");
- return FAILURE;
- }
- /* Update the internal structure with this new mac address */
- do_s2io_copy_mac_addr(sp, i, mac_addr);
-
- return do_s2io_add_mac(sp, mac_addr, i);
-}
-
-/* add MAC address to CAM */
-static int do_s2io_add_mac(struct s2io_nic *sp, u64 addr, int off)
-{
- u64 val64;
- struct XENA_dev_config __iomem *bar0 = sp->bar0;
-
- writeq(RMAC_ADDR_DATA0_MEM_ADDR(addr),
- &bar0->rmac_addr_data0_mem);
-
- val64 = RMAC_ADDR_CMD_MEM_WE | RMAC_ADDR_CMD_MEM_STROBE_NEW_CMD |
- RMAC_ADDR_CMD_MEM_OFFSET(off);
- writeq(val64, &bar0->rmac_addr_cmd_mem);
-
- /* Wait till command completes */
- if (wait_for_cmd_complete(&bar0->rmac_addr_cmd_mem,
- RMAC_ADDR_CMD_MEM_STROBE_CMD_EXECUTING,
- S2IO_BIT_RESET, true)) {
- DBG_PRINT(INFO_DBG, "do_s2io_add_mac failed\n");
- return FAILURE;
- }
- return SUCCESS;
-}
-/* deletes a specified unicast/multicast mac entry from CAM */
-static int do_s2io_delete_unicast_mc(struct s2io_nic *sp, u64 addr)
-{
- int offset;
- u64 dis_addr = S2IO_DISABLE_MAC_ENTRY, tmp64;
- struct config_param *config = &sp->config;
-
- for (offset = 1;
- offset < config->max_mc_addr; offset++) {
- tmp64 = do_s2io_read_unicast_mc(sp, offset);
- if (tmp64 == addr) {
- /* disable the entry by writing 0xffffffffffffULL */
- if (do_s2io_add_mac(sp, dis_addr, offset) == FAILURE)
- return FAILURE;
- /* store the new mac list from CAM */
- do_s2io_store_unicast_mc(sp);
- return SUCCESS;
- }
- }
- DBG_PRINT(ERR_DBG, "MAC address 0x%llx not found in CAM\n",
- (unsigned long long)addr);
- return FAILURE;
-}
-
-/* read mac entries from CAM */
-static u64 do_s2io_read_unicast_mc(struct s2io_nic *sp, int offset)
-{
- u64 tmp64, val64;
- struct XENA_dev_config __iomem *bar0 = sp->bar0;
-
- /* read mac addr */
- val64 = RMAC_ADDR_CMD_MEM_RD | RMAC_ADDR_CMD_MEM_STROBE_NEW_CMD |
- RMAC_ADDR_CMD_MEM_OFFSET(offset);
- writeq(val64, &bar0->rmac_addr_cmd_mem);
-
- /* Wait till command completes */
- if (wait_for_cmd_complete(&bar0->rmac_addr_cmd_mem,
- RMAC_ADDR_CMD_MEM_STROBE_CMD_EXECUTING,
- S2IO_BIT_RESET, true)) {
- DBG_PRINT(INFO_DBG, "do_s2io_read_unicast_mc failed\n");
- return FAILURE;
- }
- tmp64 = readq(&bar0->rmac_addr_data0_mem);
-
- return tmp64 >> 16;
-}
-
-/*
- * s2io_set_mac_addr - driver entry point
- */
-
-static int s2io_set_mac_addr(struct net_device *dev, void *p)
-{
- struct sockaddr *addr = p;
-
- if (!is_valid_ether_addr(addr->sa_data))
- return -EADDRNOTAVAIL;
-
- eth_hw_addr_set(dev, addr->sa_data);
-
- /* store the MAC address in CAM */
- return do_s2io_prog_unicast(dev, dev->dev_addr);
-}
-/**
- * do_s2io_prog_unicast - Programs the Xframe mac address
- * @dev : pointer to the device structure.
- * @addr: a uchar pointer to the new mac address which is to be set.
- * Description : This procedure will program the Xframe to receive
- * frames with new Mac Address
- * Return value: SUCCESS on success and an appropriate (-)ve integer
- * as defined in errno.h file on failure.
- */
-
-static int do_s2io_prog_unicast(struct net_device *dev, const u8 *addr)
-{
- struct s2io_nic *sp = netdev_priv(dev);
- register u64 mac_addr, perm_addr;
- int i;
- u64 tmp64;
- struct config_param *config = &sp->config;
-
- /*
- * Set the new MAC address as the new unicast filter and reflect this
- * change on the device address registered with the OS. It will be
- * at offset 0.
- */
- mac_addr = ether_addr_to_u64(addr);
- perm_addr = ether_addr_to_u64(sp->def_mac_addr[0].mac_addr);
-
- /* check if the dev_addr is different than perm_addr */
- if (mac_addr == perm_addr)
- return SUCCESS;
-
- /* check if the mac already preset in CAM */
- for (i = 1; i < config->max_mac_addr; i++) {
- tmp64 = do_s2io_read_unicast_mc(sp, i);
- if (tmp64 == S2IO_DISABLE_MAC_ENTRY) /* CAM entry is empty */
- break;
-
- if (tmp64 == mac_addr) {
- DBG_PRINT(INFO_DBG,
- "MAC addr:0x%llx already present in CAM\n",
- (unsigned long long)mac_addr);
- return SUCCESS;
- }
- }
- if (i == config->max_mac_addr) {
- DBG_PRINT(ERR_DBG, "CAM full no space left for Unicast MAC\n");
- return FAILURE;
- }
- /* Update the internal structure with this new mac address */
- do_s2io_copy_mac_addr(sp, i, mac_addr);
-
- return do_s2io_add_mac(sp, mac_addr, i);
-}
-
-/**
- * s2io_ethtool_set_link_ksettings - Sets different link parameters.
- * @dev : pointer to netdev
- * @cmd: pointer to the structure with parameters given by ethtool to set
- * link information.
- * Description:
- * The function sets different link parameters provided by the user onto
- * the NIC.
- * Return value:
- * 0 on success.
- */
-
-static int
-s2io_ethtool_set_link_ksettings(struct net_device *dev,
- const struct ethtool_link_ksettings *cmd)
-{
- struct s2io_nic *sp = netdev_priv(dev);
- if ((cmd->base.autoneg == AUTONEG_ENABLE) ||
- (cmd->base.speed != SPEED_10000) ||
- (cmd->base.duplex != DUPLEX_FULL))
- return -EINVAL;
- else {
- s2io_close(sp->dev);
- s2io_open(sp->dev);
- }
-
- return 0;
-}
-
-/**
- * s2io_ethtool_get_link_ksettings - Return link specific information.
- * @dev: pointer to netdev
- * @cmd : pointer to the structure with parameters given by ethtool
- * to return link information.
- * Description:
- * Returns link specific information like speed, duplex etc.. to ethtool.
- * Return value :
- * return 0 on success.
- */
-
-static int
-s2io_ethtool_get_link_ksettings(struct net_device *dev,
- struct ethtool_link_ksettings *cmd)
-{
- struct s2io_nic *sp = netdev_priv(dev);
-
- ethtool_link_ksettings_zero_link_mode(cmd, supported);
- ethtool_link_ksettings_add_link_mode(cmd, supported, 10000baseT_Full);
- ethtool_link_ksettings_add_link_mode(cmd, supported, FIBRE);
-
- ethtool_link_ksettings_zero_link_mode(cmd, advertising);
- ethtool_link_ksettings_add_link_mode(cmd, advertising, 10000baseT_Full);
- ethtool_link_ksettings_add_link_mode(cmd, advertising, FIBRE);
-
- cmd->base.port = PORT_FIBRE;
-
- if (netif_carrier_ok(sp->dev)) {
- cmd->base.speed = SPEED_10000;
- cmd->base.duplex = DUPLEX_FULL;
- } else {
- cmd->base.speed = SPEED_UNKNOWN;
- cmd->base.duplex = DUPLEX_UNKNOWN;
- }
-
- cmd->base.autoneg = AUTONEG_DISABLE;
- return 0;
-}
-
-/**
- * s2io_ethtool_gdrvinfo - Returns driver specific information.
- * @dev: pointer to netdev
- * @info : pointer to the structure with parameters given by ethtool to
- * return driver information.
- * Description:
- * Returns driver specefic information like name, version etc.. to ethtool.
- * Return value:
- * void
- */
-
-static void s2io_ethtool_gdrvinfo(struct net_device *dev,
- struct ethtool_drvinfo *info)
-{
- struct s2io_nic *sp = netdev_priv(dev);
-
- strscpy(info->driver, s2io_driver_name, sizeof(info->driver));
- strscpy(info->version, s2io_driver_version, sizeof(info->version));
- strscpy(info->bus_info, pci_name(sp->pdev), sizeof(info->bus_info));
-}
-
-/**
- * s2io_ethtool_gregs - dumps the entire space of Xfame into the buffer.
- * @dev: pointer to netdev
- * @regs : pointer to the structure with parameters given by ethtool for
- * dumping the registers.
- * @space: The input argument into which all the registers are dumped.
- * Description:
- * Dumps the entire register space of xFrame NIC into the user given
- * buffer area.
- * Return value :
- * void .
- */
-
-static void s2io_ethtool_gregs(struct net_device *dev,
- struct ethtool_regs *regs, void *space)
-{
- int i;
- u64 reg;
- u8 *reg_space = (u8 *)space;
- struct s2io_nic *sp = netdev_priv(dev);
-
- regs->len = XENA_REG_SPACE;
- regs->version = sp->pdev->subsystem_device;
-
- for (i = 0; i < regs->len; i += 8) {
- reg = readq(sp->bar0 + i);
- memcpy((reg_space + i), ®, 8);
- }
-}
-
-/*
- * s2io_set_led - control NIC led
- */
-static void s2io_set_led(struct s2io_nic *sp, bool on)
-{
- struct XENA_dev_config __iomem *bar0 = sp->bar0;
- u16 subid = sp->pdev->subsystem_device;
- u64 val64;
-
- if ((sp->device_type == XFRAME_II_DEVICE) ||
- ((subid & 0xFF) >= 0x07)) {
- val64 = readq(&bar0->gpio_control);
- if (on)
- val64 |= GPIO_CTRL_GPIO_0;
- else
- val64 &= ~GPIO_CTRL_GPIO_0;
-
- writeq(val64, &bar0->gpio_control);
- } else {
- val64 = readq(&bar0->adapter_control);
- if (on)
- val64 |= ADAPTER_LED_ON;
- else
- val64 &= ~ADAPTER_LED_ON;
-
- writeq(val64, &bar0->adapter_control);
- }
-
-}
-
-/**
- * s2io_ethtool_set_led - To physically identify the nic on the system.
- * @dev : network device
- * @state: led setting
- *
- * Description: Used to physically identify the NIC on the system.
- * The Link LED will blink for a time specified by the user for
- * identification.
- * NOTE: The Link has to be Up to be able to blink the LED. Hence
- * identification is possible only if it's link is up.
- */
-
-static int s2io_ethtool_set_led(struct net_device *dev,
- enum ethtool_phys_id_state state)
-{
- struct s2io_nic *sp = netdev_priv(dev);
- struct XENA_dev_config __iomem *bar0 = sp->bar0;
- u16 subid = sp->pdev->subsystem_device;
-
- if ((sp->device_type == XFRAME_I_DEVICE) && ((subid & 0xFF) < 0x07)) {
- u64 val64 = readq(&bar0->adapter_control);
- if (!(val64 & ADAPTER_CNTL_EN)) {
- pr_err("Adapter Link down, cannot blink LED\n");
- return -EAGAIN;
- }
- }
-
- switch (state) {
- case ETHTOOL_ID_ACTIVE:
- sp->adapt_ctrl_org = readq(&bar0->gpio_control);
- return 1; /* cycle on/off once per second */
-
- case ETHTOOL_ID_ON:
- s2io_set_led(sp, true);
- break;
-
- case ETHTOOL_ID_OFF:
- s2io_set_led(sp, false);
- break;
-
- case ETHTOOL_ID_INACTIVE:
- if (CARDS_WITH_FAULTY_LINK_INDICATORS(sp->device_type, subid))
- writeq(sp->adapt_ctrl_org, &bar0->gpio_control);
- }
-
- return 0;
-}
-
-static void
-s2io_ethtool_gringparam(struct net_device *dev,
- struct ethtool_ringparam *ering,
- struct kernel_ethtool_ringparam *kernel_ering,
- struct netlink_ext_ack *extack)
-{
- struct s2io_nic *sp = netdev_priv(dev);
- int i, tx_desc_count = 0, rx_desc_count = 0;
-
- if (sp->rxd_mode == RXD_MODE_1) {
- ering->rx_max_pending = MAX_RX_DESC_1;
- ering->rx_jumbo_max_pending = MAX_RX_DESC_1;
- } else {
- ering->rx_max_pending = MAX_RX_DESC_2;
- ering->rx_jumbo_max_pending = MAX_RX_DESC_2;
- }
-
- ering->tx_max_pending = MAX_TX_DESC;
-
- for (i = 0; i < sp->config.rx_ring_num; i++)
- rx_desc_count += sp->config.rx_cfg[i].num_rxd;
- ering->rx_pending = rx_desc_count;
- ering->rx_jumbo_pending = rx_desc_count;
-
- for (i = 0; i < sp->config.tx_fifo_num; i++)
- tx_desc_count += sp->config.tx_cfg[i].fifo_len;
- ering->tx_pending = tx_desc_count;
- DBG_PRINT(INFO_DBG, "max txds: %d\n", sp->config.max_txds);
-}
-
-/**
- * s2io_ethtool_getpause_data -Pause frame generation and reception.
- * @dev: pointer to netdev
- * @ep : pointer to the structure with pause parameters given by ethtool.
- * Description:
- * Returns the Pause frame generation and reception capability of the NIC.
- * Return value:
- * void
- */
-static void s2io_ethtool_getpause_data(struct net_device *dev,
- struct ethtool_pauseparam *ep)
-{
- u64 val64;
- struct s2io_nic *sp = netdev_priv(dev);
- struct XENA_dev_config __iomem *bar0 = sp->bar0;
-
- val64 = readq(&bar0->rmac_pause_cfg);
- if (val64 & RMAC_PAUSE_GEN_ENABLE)
- ep->tx_pause = true;
- if (val64 & RMAC_PAUSE_RX_ENABLE)
- ep->rx_pause = true;
- ep->autoneg = false;
-}
-
-/**
- * s2io_ethtool_setpause_data - set/reset pause frame generation.
- * @dev: pointer to netdev
- * @ep : pointer to the structure with pause parameters given by ethtool.
- * Description:
- * It can be used to set or reset Pause frame generation or reception
- * support of the NIC.
- * Return value:
- * int, returns 0 on Success
- */
-
-static int s2io_ethtool_setpause_data(struct net_device *dev,
- struct ethtool_pauseparam *ep)
-{
- u64 val64;
- struct s2io_nic *sp = netdev_priv(dev);
- struct XENA_dev_config __iomem *bar0 = sp->bar0;
-
- val64 = readq(&bar0->rmac_pause_cfg);
- if (ep->tx_pause)
- val64 |= RMAC_PAUSE_GEN_ENABLE;
- else
- val64 &= ~RMAC_PAUSE_GEN_ENABLE;
- if (ep->rx_pause)
- val64 |= RMAC_PAUSE_RX_ENABLE;
- else
- val64 &= ~RMAC_PAUSE_RX_ENABLE;
- writeq(val64, &bar0->rmac_pause_cfg);
- return 0;
-}
-
-#define S2IO_DEV_ID 5
-/**
- * read_eeprom - reads 4 bytes of data from user given offset.
- * @sp : private member of the device structure, which is a pointer to the
- * s2io_nic structure.
- * @off : offset at which the data must be written
- * @data : Its an output parameter where the data read at the given
- * offset is stored.
- * Description:
- * Will read 4 bytes of data from the user given offset and return the
- * read data.
- * NOTE: Will allow to read only part of the EEPROM visible through the
- * I2C bus.
- * Return value:
- * -1 on failure and 0 on success.
- */
-static int read_eeprom(struct s2io_nic *sp, int off, u64 *data)
-{
- int ret = -1;
- u32 exit_cnt = 0;
- u64 val64;
- struct XENA_dev_config __iomem *bar0 = sp->bar0;
-
- if (sp->device_type == XFRAME_I_DEVICE) {
- val64 = I2C_CONTROL_DEV_ID(S2IO_DEV_ID) |
- I2C_CONTROL_ADDR(off) |
- I2C_CONTROL_BYTE_CNT(0x3) |
- I2C_CONTROL_READ |
- I2C_CONTROL_CNTL_START;
- SPECIAL_REG_WRITE(val64, &bar0->i2c_control, LF);
-
- while (exit_cnt < 5) {
- val64 = readq(&bar0->i2c_control);
- if (I2C_CONTROL_CNTL_END(val64)) {
- *data = I2C_CONTROL_GET_DATA(val64);
- ret = 0;
- break;
- }
- msleep(50);
- exit_cnt++;
- }
- }
-
- if (sp->device_type == XFRAME_II_DEVICE) {
- val64 = SPI_CONTROL_KEY(0x9) | SPI_CONTROL_SEL1 |
- SPI_CONTROL_BYTECNT(0x3) |
- SPI_CONTROL_CMD(0x3) | SPI_CONTROL_ADDR(off);
- SPECIAL_REG_WRITE(val64, &bar0->spi_control, LF);
- val64 |= SPI_CONTROL_REQ;
- SPECIAL_REG_WRITE(val64, &bar0->spi_control, LF);
- while (exit_cnt < 5) {
- val64 = readq(&bar0->spi_control);
- if (val64 & SPI_CONTROL_NACK) {
- ret = 1;
- break;
- } else if (val64 & SPI_CONTROL_DONE) {
- *data = readq(&bar0->spi_data);
- *data &= 0xffffff;
- ret = 0;
- break;
- }
- msleep(50);
- exit_cnt++;
- }
- }
- return ret;
-}
-
-/**
- * write_eeprom - actually writes the relevant part of the data value.
- * @sp : private member of the device structure, which is a pointer to the
- * s2io_nic structure.
- * @off : offset at which the data must be written
- * @data : The data that is to be written
- * @cnt : Number of bytes of the data that are actually to be written into
- * the Eeprom. (max of 3)
- * Description:
- * Actually writes the relevant part of the data value into the Eeprom
- * through the I2C bus.
- * Return value:
- * 0 on success, -1 on failure.
- */
-
-static int write_eeprom(struct s2io_nic *sp, int off, u64 data, int cnt)
-{
- int exit_cnt = 0, ret = -1;
- u64 val64;
- struct XENA_dev_config __iomem *bar0 = sp->bar0;
-
- if (sp->device_type == XFRAME_I_DEVICE) {
- val64 = I2C_CONTROL_DEV_ID(S2IO_DEV_ID) |
- I2C_CONTROL_ADDR(off) |
- I2C_CONTROL_BYTE_CNT(cnt) |
- I2C_CONTROL_SET_DATA((u32)data) |
- I2C_CONTROL_CNTL_START;
- SPECIAL_REG_WRITE(val64, &bar0->i2c_control, LF);
-
- while (exit_cnt < 5) {
- val64 = readq(&bar0->i2c_control);
- if (I2C_CONTROL_CNTL_END(val64)) {
- if (!(val64 & I2C_CONTROL_NACK))
- ret = 0;
- break;
- }
- msleep(50);
- exit_cnt++;
- }
- }
-
- if (sp->device_type == XFRAME_II_DEVICE) {
- int write_cnt = (cnt == 8) ? 0 : cnt;
- writeq(SPI_DATA_WRITE(data, (cnt << 3)), &bar0->spi_data);
-
- val64 = SPI_CONTROL_KEY(0x9) | SPI_CONTROL_SEL1 |
- SPI_CONTROL_BYTECNT(write_cnt) |
- SPI_CONTROL_CMD(0x2) | SPI_CONTROL_ADDR(off);
- SPECIAL_REG_WRITE(val64, &bar0->spi_control, LF);
- val64 |= SPI_CONTROL_REQ;
- SPECIAL_REG_WRITE(val64, &bar0->spi_control, LF);
- while (exit_cnt < 5) {
- val64 = readq(&bar0->spi_control);
- if (val64 & SPI_CONTROL_NACK) {
- ret = 1;
- break;
- } else if (val64 & SPI_CONTROL_DONE) {
- ret = 0;
- break;
- }
- msleep(50);
- exit_cnt++;
- }
- }
- return ret;
-}
-static void s2io_vpd_read(struct s2io_nic *nic)
-{
- u8 *vpd_data;
- u8 data;
- int i = 0, cnt, len, fail = 0;
- int vpd_addr = 0x80;
- struct swStat *swstats = &nic->mac_control.stats_info->sw_stat;
-
- if (nic->device_type == XFRAME_II_DEVICE) {
- strcpy(nic->product_name, "Xframe II 10GbE network adapter");
- vpd_addr = 0x80;
- } else {
- strcpy(nic->product_name, "Xframe I 10GbE network adapter");
- vpd_addr = 0x50;
- }
- strcpy(nic->serial_num, "NOT AVAILABLE");
-
- vpd_data = kmalloc(256, GFP_KERNEL);
- if (!vpd_data) {
- swstats->mem_alloc_fail_cnt++;
- return;
- }
- swstats->mem_allocated += 256;
-
- for (i = 0; i < 256; i += 4) {
- pci_write_config_byte(nic->pdev, (vpd_addr + 2), i);
- pci_read_config_byte(nic->pdev, (vpd_addr + 2), &data);
- pci_write_config_byte(nic->pdev, (vpd_addr + 3), 0);
- for (cnt = 0; cnt < 5; cnt++) {
- msleep(2);
- pci_read_config_byte(nic->pdev, (vpd_addr + 3), &data);
- if (data == 0x80)
- break;
- }
- if (cnt >= 5) {
- DBG_PRINT(ERR_DBG, "Read of VPD data failed\n");
- fail = 1;
- break;
- }
- pci_read_config_dword(nic->pdev, (vpd_addr + 4),
- (u32 *)&vpd_data[i]);
- }
-
- if (!fail) {
- /* read serial number of adapter */
- for (cnt = 0; cnt < 252; cnt++) {
- if ((vpd_data[cnt] == 'S') &&
- (vpd_data[cnt+1] == 'N')) {
- len = vpd_data[cnt+2];
- if (len < min(VPD_STRING_LEN, 256-cnt-2)) {
- memcpy(nic->serial_num,
- &vpd_data[cnt + 3],
- len);
- memset(nic->serial_num+len,
- 0,
- VPD_STRING_LEN-len);
- break;
- }
- }
- }
- }
-
- if ((!fail) && (vpd_data[1] < VPD_STRING_LEN)) {
- len = vpd_data[1];
- memcpy(nic->product_name, &vpd_data[3], len);
- nic->product_name[len] = 0;
- }
- kfree(vpd_data);
- swstats->mem_freed += 256;
-}
-
-/**
- * s2io_ethtool_geeprom - reads the value stored in the Eeprom.
- * @dev: pointer to netdev
- * @eeprom : pointer to the user level structure provided by ethtool,
- * containing all relevant information.
- * @data_buf : user defined value to be written into Eeprom.
- * Description: Reads the values stored in the Eeprom at given offset
- * for a given length. Stores these values int the input argument data
- * buffer 'data_buf' and returns these to the caller (ethtool.)
- * Return value:
- * int 0 on success
- */
-
-static int s2io_ethtool_geeprom(struct net_device *dev,
- struct ethtool_eeprom *eeprom, u8 * data_buf)
-{
- u32 i, valid;
- u64 data;
- struct s2io_nic *sp = netdev_priv(dev);
-
- eeprom->magic = sp->pdev->vendor | (sp->pdev->device << 16);
-
- if ((eeprom->offset + eeprom->len) > (XENA_EEPROM_SPACE))
- eeprom->len = XENA_EEPROM_SPACE - eeprom->offset;
-
- for (i = 0; i < eeprom->len; i += 4) {
- if (read_eeprom(sp, (eeprom->offset + i), &data)) {
- DBG_PRINT(ERR_DBG, "Read of EEPROM failed\n");
- return -EFAULT;
- }
- valid = INV(data);
- memcpy((data_buf + i), &valid, 4);
- }
- return 0;
-}
-
-/**
- * s2io_ethtool_seeprom - tries to write the user provided value in Eeprom
- * @dev: pointer to netdev
- * @eeprom : pointer to the user level structure provided by ethtool,
- * containing all relevant information.
- * @data_buf : user defined value to be written into Eeprom.
- * Description:
- * Tries to write the user provided value in the Eeprom, at the offset
- * given by the user.
- * Return value:
- * 0 on success, -EFAULT on failure.
- */
-
-static int s2io_ethtool_seeprom(struct net_device *dev,
- struct ethtool_eeprom *eeprom,
- u8 *data_buf)
-{
- int len = eeprom->len, cnt = 0;
- u64 valid = 0, data;
- struct s2io_nic *sp = netdev_priv(dev);
-
- if (eeprom->magic != (sp->pdev->vendor | (sp->pdev->device << 16))) {
- DBG_PRINT(ERR_DBG,
- "ETHTOOL_WRITE_EEPROM Err: "
- "Magic value is wrong, it is 0x%x should be 0x%x\n",
- (sp->pdev->vendor | (sp->pdev->device << 16)),
- eeprom->magic);
- return -EFAULT;
- }
-
- while (len) {
- data = (u32)data_buf[cnt] & 0x000000FF;
- if (data)
- valid = (u32)(data << 24);
- else
- valid = data;
-
- if (write_eeprom(sp, (eeprom->offset + cnt), valid, 0)) {
- DBG_PRINT(ERR_DBG,
- "ETHTOOL_WRITE_EEPROM Err: "
- "Cannot write into the specified offset\n");
- return -EFAULT;
- }
- cnt++;
- len--;
- }
-
- return 0;
-}
-
-/**
- * s2io_register_test - reads and writes into all clock domains.
- * @sp : private member of the device structure, which is a pointer to the
- * s2io_nic structure.
- * @data : variable that returns the result of each of the test conducted b
- * by the driver.
- * Description:
- * Read and write into all clock domains. The NIC has 3 clock domains,
- * see that registers in all the three regions are accessible.
- * Return value:
- * 0 on success.
- */
-
-static int s2io_register_test(struct s2io_nic *sp, uint64_t *data)
-{
- struct XENA_dev_config __iomem *bar0 = sp->bar0;
- u64 val64 = 0, exp_val;
- int fail = 0;
-
- val64 = readq(&bar0->pif_rd_swapper_fb);
- if (val64 != 0x123456789abcdefULL) {
- fail = 1;
- DBG_PRINT(INFO_DBG, "Read Test level %d fails\n", 1);
- }
-
- val64 = readq(&bar0->rmac_pause_cfg);
- if (val64 != 0xc000ffff00000000ULL) {
- fail = 1;
- DBG_PRINT(INFO_DBG, "Read Test level %d fails\n", 2);
- }
-
- val64 = readq(&bar0->rx_queue_cfg);
- if (sp->device_type == XFRAME_II_DEVICE)
- exp_val = 0x0404040404040404ULL;
- else
- exp_val = 0x0808080808080808ULL;
- if (val64 != exp_val) {
- fail = 1;
- DBG_PRINT(INFO_DBG, "Read Test level %d fails\n", 3);
- }
-
- val64 = readq(&bar0->xgxs_efifo_cfg);
- if (val64 != 0x000000001923141EULL) {
- fail = 1;
- DBG_PRINT(INFO_DBG, "Read Test level %d fails\n", 4);
- }
-
- val64 = 0x5A5A5A5A5A5A5A5AULL;
- writeq(val64, &bar0->xmsi_data);
- val64 = readq(&bar0->xmsi_data);
- if (val64 != 0x5A5A5A5A5A5A5A5AULL) {
- fail = 1;
- DBG_PRINT(ERR_DBG, "Write Test level %d fails\n", 1);
- }
-
- val64 = 0xA5A5A5A5A5A5A5A5ULL;
- writeq(val64, &bar0->xmsi_data);
- val64 = readq(&bar0->xmsi_data);
- if (val64 != 0xA5A5A5A5A5A5A5A5ULL) {
- fail = 1;
- DBG_PRINT(ERR_DBG, "Write Test level %d fails\n", 2);
- }
-
- *data = fail;
- return fail;
-}
-
-/**
- * s2io_eeprom_test - to verify that EEprom in the xena can be programmed.
- * @sp : private member of the device structure, which is a pointer to the
- * s2io_nic structure.
- * @data:variable that returns the result of each of the test conducted by
- * the driver.
- * Description:
- * Verify that EEPROM in the xena can be programmed using I2C_CONTROL
- * register.
- * Return value:
- * 0 on success.
- */
-
-static int s2io_eeprom_test(struct s2io_nic *sp, uint64_t *data)
-{
- int fail = 0;
- u64 ret_data, org_4F0, org_7F0;
- u8 saved_4F0 = 0, saved_7F0 = 0;
- struct net_device *dev = sp->dev;
-
- /* Test Write Error at offset 0 */
- /* Note that SPI interface allows write access to all areas
- * of EEPROM. Hence doing all negative testing only for Xframe I.
- */
- if (sp->device_type == XFRAME_I_DEVICE)
- if (!write_eeprom(sp, 0, 0, 3))
- fail = 1;
-
- /* Save current values at offsets 0x4F0 and 0x7F0 */
- if (!read_eeprom(sp, 0x4F0, &org_4F0))
- saved_4F0 = 1;
- if (!read_eeprom(sp, 0x7F0, &org_7F0))
- saved_7F0 = 1;
-
- /* Test Write at offset 4f0 */
- if (write_eeprom(sp, 0x4F0, 0x012345, 3))
- fail = 1;
- if (read_eeprom(sp, 0x4F0, &ret_data))
- fail = 1;
-
- if (ret_data != 0x012345) {
- DBG_PRINT(ERR_DBG, "%s: eeprom test error at offset 0x4F0. "
- "Data written %llx Data read %llx\n",
- dev->name, (unsigned long long)0x12345,
- (unsigned long long)ret_data);
- fail = 1;
- }
-
- /* Reset the EEPROM data go FFFF */
- write_eeprom(sp, 0x4F0, 0xFFFFFF, 3);
-
- /* Test Write Request Error at offset 0x7c */
- if (sp->device_type == XFRAME_I_DEVICE)
- if (!write_eeprom(sp, 0x07C, 0, 3))
- fail = 1;
-
- /* Test Write Request at offset 0x7f0 */
- if (write_eeprom(sp, 0x7F0, 0x012345, 3))
- fail = 1;
- if (read_eeprom(sp, 0x7F0, &ret_data))
- fail = 1;
-
- if (ret_data != 0x012345) {
- DBG_PRINT(ERR_DBG, "%s: eeprom test error at offset 0x7F0. "
- "Data written %llx Data read %llx\n",
- dev->name, (unsigned long long)0x12345,
- (unsigned long long)ret_data);
- fail = 1;
- }
-
- /* Reset the EEPROM data go FFFF */
- write_eeprom(sp, 0x7F0, 0xFFFFFF, 3);
-
- if (sp->device_type == XFRAME_I_DEVICE) {
- /* Test Write Error at offset 0x80 */
- if (!write_eeprom(sp, 0x080, 0, 3))
- fail = 1;
-
- /* Test Write Error at offset 0xfc */
- if (!write_eeprom(sp, 0x0FC, 0, 3))
- fail = 1;
-
- /* Test Write Error at offset 0x100 */
- if (!write_eeprom(sp, 0x100, 0, 3))
- fail = 1;
-
- /* Test Write Error at offset 4ec */
- if (!write_eeprom(sp, 0x4EC, 0, 3))
- fail = 1;
- }
-
- /* Restore values at offsets 0x4F0 and 0x7F0 */
- if (saved_4F0)
- write_eeprom(sp, 0x4F0, org_4F0, 3);
- if (saved_7F0)
- write_eeprom(sp, 0x7F0, org_7F0, 3);
-
- *data = fail;
- return fail;
-}
-
-/**
- * s2io_bist_test - invokes the MemBist test of the card .
- * @sp : private member of the device structure, which is a pointer to the
- * s2io_nic structure.
- * @data:variable that returns the result of each of the test conducted by
- * the driver.
- * Description:
- * This invokes the MemBist test of the card. We give around
- * 2 secs time for the Test to complete. If it's still not complete
- * within this peiod, we consider that the test failed.
- * Return value:
- * 0 on success and -1 on failure.
- */
-
-static int s2io_bist_test(struct s2io_nic *sp, uint64_t *data)
-{
- u8 bist = 0;
- int cnt = 0, ret = -1;
-
- pci_read_config_byte(sp->pdev, PCI_BIST, &bist);
- bist |= PCI_BIST_START;
- pci_write_config_word(sp->pdev, PCI_BIST, bist);
-
- while (cnt < 20) {
- pci_read_config_byte(sp->pdev, PCI_BIST, &bist);
- if (!(bist & PCI_BIST_START)) {
- *data = (bist & PCI_BIST_CODE_MASK);
- ret = 0;
- break;
- }
- msleep(100);
- cnt++;
- }
-
- return ret;
-}
-
-/**
- * s2io_link_test - verifies the link state of the nic
- * @sp: private member of the device structure, which is a pointer to the
- * s2io_nic structure.
- * @data: variable that returns the result of each of the test conducted by
- * the driver.
- * Description:
- * The function verifies the link state of the NIC and updates the input
- * argument 'data' appropriately.
- * Return value:
- * 0 on success.
- */
-
-static int s2io_link_test(struct s2io_nic *sp, uint64_t *data)
-{
- struct XENA_dev_config __iomem *bar0 = sp->bar0;
- u64 val64;
-
- val64 = readq(&bar0->adapter_status);
- if (!(LINK_IS_UP(val64)))
- *data = 1;
- else
- *data = 0;
-
- return *data;
-}
-
-/**
- * s2io_rldram_test - offline test for access to the RldRam chip on the NIC
- * @sp: private member of the device structure, which is a pointer to the
- * s2io_nic structure.
- * @data: variable that returns the result of each of the test
- * conducted by the driver.
- * Description:
- * This is one of the offline test that tests the read and write
- * access to the RldRam chip on the NIC.
- * Return value:
- * 0 on success.
- */
-
-static int s2io_rldram_test(struct s2io_nic *sp, uint64_t *data)
-{
- struct XENA_dev_config __iomem *bar0 = sp->bar0;
- u64 val64;
- int cnt, iteration = 0, test_fail = 0;
-
- val64 = readq(&bar0->adapter_control);
- val64 &= ~ADAPTER_ECC_EN;
- writeq(val64, &bar0->adapter_control);
-
- val64 = readq(&bar0->mc_rldram_test_ctrl);
- val64 |= MC_RLDRAM_TEST_MODE;
- SPECIAL_REG_WRITE(val64, &bar0->mc_rldram_test_ctrl, LF);
-
- val64 = readq(&bar0->mc_rldram_mrs);
- val64 |= MC_RLDRAM_QUEUE_SIZE_ENABLE;
- SPECIAL_REG_WRITE(val64, &bar0->mc_rldram_mrs, UF);
-
- val64 |= MC_RLDRAM_MRS_ENABLE;
- SPECIAL_REG_WRITE(val64, &bar0->mc_rldram_mrs, UF);
-
- while (iteration < 2) {
- val64 = 0x55555555aaaa0000ULL;
- if (iteration == 1)
- val64 ^= 0xFFFFFFFFFFFF0000ULL;
- writeq(val64, &bar0->mc_rldram_test_d0);
-
- val64 = 0xaaaa5a5555550000ULL;
- if (iteration == 1)
- val64 ^= 0xFFFFFFFFFFFF0000ULL;
- writeq(val64, &bar0->mc_rldram_test_d1);
-
- val64 = 0x55aaaaaaaa5a0000ULL;
- if (iteration == 1)
- val64 ^= 0xFFFFFFFFFFFF0000ULL;
- writeq(val64, &bar0->mc_rldram_test_d2);
-
- val64 = (u64) (0x0000003ffffe0100ULL);
- writeq(val64, &bar0->mc_rldram_test_add);
-
- val64 = MC_RLDRAM_TEST_MODE |
- MC_RLDRAM_TEST_WRITE |
- MC_RLDRAM_TEST_GO;
- SPECIAL_REG_WRITE(val64, &bar0->mc_rldram_test_ctrl, LF);
-
- for (cnt = 0; cnt < 5; cnt++) {
- val64 = readq(&bar0->mc_rldram_test_ctrl);
- if (val64 & MC_RLDRAM_TEST_DONE)
- break;
- msleep(200);
- }
-
- if (cnt == 5)
- break;
-
- val64 = MC_RLDRAM_TEST_MODE | MC_RLDRAM_TEST_GO;
- SPECIAL_REG_WRITE(val64, &bar0->mc_rldram_test_ctrl, LF);
-
- for (cnt = 0; cnt < 5; cnt++) {
- val64 = readq(&bar0->mc_rldram_test_ctrl);
- if (val64 & MC_RLDRAM_TEST_DONE)
- break;
- msleep(500);
- }
-
- if (cnt == 5)
- break;
-
- val64 = readq(&bar0->mc_rldram_test_ctrl);
- if (!(val64 & MC_RLDRAM_TEST_PASS))
- test_fail = 1;
-
- iteration++;
- }
-
- *data = test_fail;
-
- /* Bring the adapter out of test mode */
- SPECIAL_REG_WRITE(0, &bar0->mc_rldram_test_ctrl, LF);
-
- return test_fail;
-}
-
-/**
- * s2io_ethtool_test - conducts 6 tsets to determine the health of card.
- * @dev: pointer to netdev
- * @ethtest : pointer to a ethtool command specific structure that will be
- * returned to the user.
- * @data : variable that returns the result of each of the test
- * conducted by the driver.
- * Description:
- * This function conducts 6 tests ( 4 offline and 2 online) to determine
- * the health of the card.
- * Return value:
- * void
- */
-
-static void s2io_ethtool_test(struct net_device *dev,
- struct ethtool_test *ethtest,
- uint64_t *data)
-{
- struct s2io_nic *sp = netdev_priv(dev);
- int orig_state = netif_running(sp->dev);
-
- if (ethtest->flags == ETH_TEST_FL_OFFLINE) {
- /* Offline Tests. */
- if (orig_state)
- s2io_close(sp->dev);
-
- if (s2io_register_test(sp, &data[0]))
- ethtest->flags |= ETH_TEST_FL_FAILED;
-
- s2io_reset(sp);
-
- if (s2io_rldram_test(sp, &data[3]))
- ethtest->flags |= ETH_TEST_FL_FAILED;
-
- s2io_reset(sp);
-
- if (s2io_eeprom_test(sp, &data[1]))
- ethtest->flags |= ETH_TEST_FL_FAILED;
-
- if (s2io_bist_test(sp, &data[4]))
- ethtest->flags |= ETH_TEST_FL_FAILED;
-
- if (orig_state)
- s2io_open(sp->dev);
-
- data[2] = 0;
- } else {
- /* Online Tests. */
- if (!orig_state) {
- DBG_PRINT(ERR_DBG, "%s: is not up, cannot run test\n",
- dev->name);
- data[0] = -1;
- data[1] = -1;
- data[2] = -1;
- data[3] = -1;
- data[4] = -1;
- }
-
- if (s2io_link_test(sp, &data[2]))
- ethtest->flags |= ETH_TEST_FL_FAILED;
-
- data[0] = 0;
- data[1] = 0;
- data[3] = 0;
- data[4] = 0;
- }
-}
-
-static void s2io_get_ethtool_stats(struct net_device *dev,
- struct ethtool_stats *estats,
- u64 *tmp_stats)
-{
- int i = 0, k;
- struct s2io_nic *sp = netdev_priv(dev);
- struct stat_block *stats = sp->mac_control.stats_info;
- struct swStat *swstats = &stats->sw_stat;
- struct xpakStat *xstats = &stats->xpak_stat;
-
- s2io_updt_stats(sp);
- tmp_stats[i++] =
- (u64)le32_to_cpu(stats->tmac_frms_oflow) << 32 |
- le32_to_cpu(stats->tmac_frms);
- tmp_stats[i++] =
- (u64)le32_to_cpu(stats->tmac_data_octets_oflow) << 32 |
- le32_to_cpu(stats->tmac_data_octets);
- tmp_stats[i++] = le64_to_cpu(stats->tmac_drop_frms);
- tmp_stats[i++] =
- (u64)le32_to_cpu(stats->tmac_mcst_frms_oflow) << 32 |
- le32_to_cpu(stats->tmac_mcst_frms);
- tmp_stats[i++] =
- (u64)le32_to_cpu(stats->tmac_bcst_frms_oflow) << 32 |
- le32_to_cpu(stats->tmac_bcst_frms);
- tmp_stats[i++] = le64_to_cpu(stats->tmac_pause_ctrl_frms);
- tmp_stats[i++] =
- (u64)le32_to_cpu(stats->tmac_ttl_octets_oflow) << 32 |
- le32_to_cpu(stats->tmac_ttl_octets);
- tmp_stats[i++] =
- (u64)le32_to_cpu(stats->tmac_ucst_frms_oflow) << 32 |
- le32_to_cpu(stats->tmac_ucst_frms);
- tmp_stats[i++] =
- (u64)le32_to_cpu(stats->tmac_nucst_frms_oflow) << 32 |
- le32_to_cpu(stats->tmac_nucst_frms);
- tmp_stats[i++] =
- (u64)le32_to_cpu(stats->tmac_any_err_frms_oflow) << 32 |
- le32_to_cpu(stats->tmac_any_err_frms);
- tmp_stats[i++] = le64_to_cpu(stats->tmac_ttl_less_fb_octets);
- tmp_stats[i++] = le64_to_cpu(stats->tmac_vld_ip_octets);
- tmp_stats[i++] =
- (u64)le32_to_cpu(stats->tmac_vld_ip_oflow) << 32 |
- le32_to_cpu(stats->tmac_vld_ip);
- tmp_stats[i++] =
- (u64)le32_to_cpu(stats->tmac_drop_ip_oflow) << 32 |
- le32_to_cpu(stats->tmac_drop_ip);
- tmp_stats[i++] =
- (u64)le32_to_cpu(stats->tmac_icmp_oflow) << 32 |
- le32_to_cpu(stats->tmac_icmp);
- tmp_stats[i++] =
- (u64)le32_to_cpu(stats->tmac_rst_tcp_oflow) << 32 |
- le32_to_cpu(stats->tmac_rst_tcp);
- tmp_stats[i++] = le64_to_cpu(stats->tmac_tcp);
- tmp_stats[i++] = (u64)le32_to_cpu(stats->tmac_udp_oflow) << 32 |
- le32_to_cpu(stats->tmac_udp);
- tmp_stats[i++] =
- (u64)le32_to_cpu(stats->rmac_vld_frms_oflow) << 32 |
- le32_to_cpu(stats->rmac_vld_frms);
- tmp_stats[i++] =
- (u64)le32_to_cpu(stats->rmac_data_octets_oflow) << 32 |
- le32_to_cpu(stats->rmac_data_octets);
- tmp_stats[i++] = le64_to_cpu(stats->rmac_fcs_err_frms);
- tmp_stats[i++] = le64_to_cpu(stats->rmac_drop_frms);
- tmp_stats[i++] =
- (u64)le32_to_cpu(stats->rmac_vld_mcst_frms_oflow) << 32 |
- le32_to_cpu(stats->rmac_vld_mcst_frms);
- tmp_stats[i++] =
- (u64)le32_to_cpu(stats->rmac_vld_bcst_frms_oflow) << 32 |
- le32_to_cpu(stats->rmac_vld_bcst_frms);
- tmp_stats[i++] = le32_to_cpu(stats->rmac_in_rng_len_err_frms);
- tmp_stats[i++] = le32_to_cpu(stats->rmac_out_rng_len_err_frms);
- tmp_stats[i++] = le64_to_cpu(stats->rmac_long_frms);
- tmp_stats[i++] = le64_to_cpu(stats->rmac_pause_ctrl_frms);
- tmp_stats[i++] = le64_to_cpu(stats->rmac_unsup_ctrl_frms);
- tmp_stats[i++] =
- (u64)le32_to_cpu(stats->rmac_ttl_octets_oflow) << 32 |
- le32_to_cpu(stats->rmac_ttl_octets);
- tmp_stats[i++] =
- (u64)le32_to_cpu(stats->rmac_accepted_ucst_frms_oflow) << 32
- | le32_to_cpu(stats->rmac_accepted_ucst_frms);
- tmp_stats[i++] =
- (u64)le32_to_cpu(stats->rmac_accepted_nucst_frms_oflow)
- << 32 | le32_to_cpu(stats->rmac_accepted_nucst_frms);
- tmp_stats[i++] =
- (u64)le32_to_cpu(stats->rmac_discarded_frms_oflow) << 32 |
- le32_to_cpu(stats->rmac_discarded_frms);
- tmp_stats[i++] =
- (u64)le32_to_cpu(stats->rmac_drop_events_oflow)
- << 32 | le32_to_cpu(stats->rmac_drop_events);
- tmp_stats[i++] = le64_to_cpu(stats->rmac_ttl_less_fb_octets);
- tmp_stats[i++] = le64_to_cpu(stats->rmac_ttl_frms);
- tmp_stats[i++] =
- (u64)le32_to_cpu(stats->rmac_usized_frms_oflow) << 32 |
- le32_to_cpu(stats->rmac_usized_frms);
- tmp_stats[i++] =
- (u64)le32_to_cpu(stats->rmac_osized_frms_oflow) << 32 |
- le32_to_cpu(stats->rmac_osized_frms);
- tmp_stats[i++] =
- (u64)le32_to_cpu(stats->rmac_frag_frms_oflow) << 32 |
- le32_to_cpu(stats->rmac_frag_frms);
- tmp_stats[i++] =
- (u64)le32_to_cpu(stats->rmac_jabber_frms_oflow) << 32 |
- le32_to_cpu(stats->rmac_jabber_frms);
- tmp_stats[i++] = le64_to_cpu(stats->rmac_ttl_64_frms);
- tmp_stats[i++] = le64_to_cpu(stats->rmac_ttl_65_127_frms);
- tmp_stats[i++] = le64_to_cpu(stats->rmac_ttl_128_255_frms);
- tmp_stats[i++] = le64_to_cpu(stats->rmac_ttl_256_511_frms);
- tmp_stats[i++] = le64_to_cpu(stats->rmac_ttl_512_1023_frms);
- tmp_stats[i++] = le64_to_cpu(stats->rmac_ttl_1024_1518_frms);
- tmp_stats[i++] =
- (u64)le32_to_cpu(stats->rmac_ip_oflow) << 32 |
- le32_to_cpu(stats->rmac_ip);
- tmp_stats[i++] = le64_to_cpu(stats->rmac_ip_octets);
- tmp_stats[i++] = le32_to_cpu(stats->rmac_hdr_err_ip);
- tmp_stats[i++] =
- (u64)le32_to_cpu(stats->rmac_drop_ip_oflow) << 32 |
- le32_to_cpu(stats->rmac_drop_ip);
- tmp_stats[i++] =
- (u64)le32_to_cpu(stats->rmac_icmp_oflow) << 32 |
- le32_to_cpu(stats->rmac_icmp);
- tmp_stats[i++] = le64_to_cpu(stats->rmac_tcp);
- tmp_stats[i++] =
- (u64)le32_to_cpu(stats->rmac_udp_oflow) << 32 |
- le32_to_cpu(stats->rmac_udp);
- tmp_stats[i++] =
- (u64)le32_to_cpu(stats->rmac_err_drp_udp_oflow) << 32 |
- le32_to_cpu(stats->rmac_err_drp_udp);
- tmp_stats[i++] = le64_to_cpu(stats->rmac_xgmii_err_sym);
- tmp_stats[i++] = le64_to_cpu(stats->rmac_frms_q0);
- tmp_stats[i++] = le64_to_cpu(stats->rmac_frms_q1);
- tmp_stats[i++] = le64_to_cpu(stats->rmac_frms_q2);
- tmp_stats[i++] = le64_to_cpu(stats->rmac_frms_q3);
- tmp_stats[i++] = le64_to_cpu(stats->rmac_frms_q4);
- tmp_stats[i++] = le64_to_cpu(stats->rmac_frms_q5);
- tmp_stats[i++] = le64_to_cpu(stats->rmac_frms_q6);
- tmp_stats[i++] = le64_to_cpu(stats->rmac_frms_q7);
- tmp_stats[i++] = le16_to_cpu(stats->rmac_full_q0);
- tmp_stats[i++] = le16_to_cpu(stats->rmac_full_q1);
- tmp_stats[i++] = le16_to_cpu(stats->rmac_full_q2);
- tmp_stats[i++] = le16_to_cpu(stats->rmac_full_q3);
- tmp_stats[i++] = le16_to_cpu(stats->rmac_full_q4);
- tmp_stats[i++] = le16_to_cpu(stats->rmac_full_q5);
- tmp_stats[i++] = le16_to_cpu(stats->rmac_full_q6);
- tmp_stats[i++] = le16_to_cpu(stats->rmac_full_q7);
- tmp_stats[i++] =
- (u64)le32_to_cpu(stats->rmac_pause_cnt_oflow) << 32 |
- le32_to_cpu(stats->rmac_pause_cnt);
- tmp_stats[i++] = le64_to_cpu(stats->rmac_xgmii_data_err_cnt);
- tmp_stats[i++] = le64_to_cpu(stats->rmac_xgmii_ctrl_err_cnt);
- tmp_stats[i++] =
- (u64)le32_to_cpu(stats->rmac_accepted_ip_oflow) << 32 |
- le32_to_cpu(stats->rmac_accepted_ip);
- tmp_stats[i++] = le32_to_cpu(stats->rmac_err_tcp);
- tmp_stats[i++] = le32_to_cpu(stats->rd_req_cnt);
- tmp_stats[i++] = le32_to_cpu(stats->new_rd_req_cnt);
- tmp_stats[i++] = le32_to_cpu(stats->new_rd_req_rtry_cnt);
- tmp_stats[i++] = le32_to_cpu(stats->rd_rtry_cnt);
- tmp_stats[i++] = le32_to_cpu(stats->wr_rtry_rd_ack_cnt);
- tmp_stats[i++] = le32_to_cpu(stats->wr_req_cnt);
- tmp_stats[i++] = le32_to_cpu(stats->new_wr_req_cnt);
- tmp_stats[i++] = le32_to_cpu(stats->new_wr_req_rtry_cnt);
- tmp_stats[i++] = le32_to_cpu(stats->wr_rtry_cnt);
- tmp_stats[i++] = le32_to_cpu(stats->wr_disc_cnt);
- tmp_stats[i++] = le32_to_cpu(stats->rd_rtry_wr_ack_cnt);
- tmp_stats[i++] = le32_to_cpu(stats->txp_wr_cnt);
- tmp_stats[i++] = le32_to_cpu(stats->txd_rd_cnt);
- tmp_stats[i++] = le32_to_cpu(stats->txd_wr_cnt);
- tmp_stats[i++] = le32_to_cpu(stats->rxd_rd_cnt);
- tmp_stats[i++] = le32_to_cpu(stats->rxd_wr_cnt);
- tmp_stats[i++] = le32_to_cpu(stats->txf_rd_cnt);
- tmp_stats[i++] = le32_to_cpu(stats->rxf_wr_cnt);
-
- /* Enhanced statistics exist only for Hercules */
- if (sp->device_type == XFRAME_II_DEVICE) {
- tmp_stats[i++] =
- le64_to_cpu(stats->rmac_ttl_1519_4095_frms);
- tmp_stats[i++] =
- le64_to_cpu(stats->rmac_ttl_4096_8191_frms);
- tmp_stats[i++] =
- le64_to_cpu(stats->rmac_ttl_8192_max_frms);
- tmp_stats[i++] = le64_to_cpu(stats->rmac_ttl_gt_max_frms);
- tmp_stats[i++] = le64_to_cpu(stats->rmac_osized_alt_frms);
- tmp_stats[i++] = le64_to_cpu(stats->rmac_jabber_alt_frms);
- tmp_stats[i++] = le64_to_cpu(stats->rmac_gt_max_alt_frms);
- tmp_stats[i++] = le64_to_cpu(stats->rmac_vlan_frms);
- tmp_stats[i++] = le32_to_cpu(stats->rmac_len_discard);
- tmp_stats[i++] = le32_to_cpu(stats->rmac_fcs_discard);
- tmp_stats[i++] = le32_to_cpu(stats->rmac_pf_discard);
- tmp_stats[i++] = le32_to_cpu(stats->rmac_da_discard);
- tmp_stats[i++] = le32_to_cpu(stats->rmac_red_discard);
- tmp_stats[i++] = le32_to_cpu(stats->rmac_rts_discard);
- tmp_stats[i++] = le32_to_cpu(stats->rmac_ingm_full_discard);
- tmp_stats[i++] = le32_to_cpu(stats->link_fault_cnt);
- }
-
- tmp_stats[i++] = 0;
- tmp_stats[i++] = swstats->single_ecc_errs;
- tmp_stats[i++] = swstats->double_ecc_errs;
- tmp_stats[i++] = swstats->parity_err_cnt;
- tmp_stats[i++] = swstats->serious_err_cnt;
- tmp_stats[i++] = swstats->soft_reset_cnt;
- tmp_stats[i++] = swstats->fifo_full_cnt;
- for (k = 0; k < MAX_RX_RINGS; k++)
- tmp_stats[i++] = swstats->ring_full_cnt[k];
- tmp_stats[i++] = xstats->alarm_transceiver_temp_high;
- tmp_stats[i++] = xstats->alarm_transceiver_temp_low;
- tmp_stats[i++] = xstats->alarm_laser_bias_current_high;
- tmp_stats[i++] = xstats->alarm_laser_bias_current_low;
- tmp_stats[i++] = xstats->alarm_laser_output_power_high;
- tmp_stats[i++] = xstats->alarm_laser_output_power_low;
- tmp_stats[i++] = xstats->warn_transceiver_temp_high;
- tmp_stats[i++] = xstats->warn_transceiver_temp_low;
- tmp_stats[i++] = xstats->warn_laser_bias_current_high;
- tmp_stats[i++] = xstats->warn_laser_bias_current_low;
- tmp_stats[i++] = xstats->warn_laser_output_power_high;
- tmp_stats[i++] = xstats->warn_laser_output_power_low;
- tmp_stats[i++] = swstats->clubbed_frms_cnt;
- tmp_stats[i++] = swstats->sending_both;
- tmp_stats[i++] = swstats->outof_sequence_pkts;
- tmp_stats[i++] = swstats->flush_max_pkts;
- if (swstats->num_aggregations) {
- u64 tmp = swstats->sum_avg_pkts_aggregated;
- int count = 0;
- /*
- * Since 64-bit divide does not work on all platforms,
- * do repeated subtraction.
- */
- while (tmp >= swstats->num_aggregations) {
- tmp -= swstats->num_aggregations;
- count++;
- }
- tmp_stats[i++] = count;
- } else
- tmp_stats[i++] = 0;
- tmp_stats[i++] = swstats->mem_alloc_fail_cnt;
- tmp_stats[i++] = swstats->pci_map_fail_cnt;
- tmp_stats[i++] = swstats->watchdog_timer_cnt;
- tmp_stats[i++] = swstats->mem_allocated;
- tmp_stats[i++] = swstats->mem_freed;
- tmp_stats[i++] = swstats->link_up_cnt;
- tmp_stats[i++] = swstats->link_down_cnt;
- tmp_stats[i++] = swstats->link_up_time;
- tmp_stats[i++] = swstats->link_down_time;
-
- tmp_stats[i++] = swstats->tx_buf_abort_cnt;
- tmp_stats[i++] = swstats->tx_desc_abort_cnt;
- tmp_stats[i++] = swstats->tx_parity_err_cnt;
- tmp_stats[i++] = swstats->tx_link_loss_cnt;
- tmp_stats[i++] = swstats->tx_list_proc_err_cnt;
-
- tmp_stats[i++] = swstats->rx_parity_err_cnt;
- tmp_stats[i++] = swstats->rx_abort_cnt;
- tmp_stats[i++] = swstats->rx_parity_abort_cnt;
- tmp_stats[i++] = swstats->rx_rda_fail_cnt;
- tmp_stats[i++] = swstats->rx_unkn_prot_cnt;
- tmp_stats[i++] = swstats->rx_fcs_err_cnt;
- tmp_stats[i++] = swstats->rx_buf_size_err_cnt;
- tmp_stats[i++] = swstats->rx_rxd_corrupt_cnt;
- tmp_stats[i++] = swstats->rx_unkn_err_cnt;
- tmp_stats[i++] = swstats->tda_err_cnt;
- tmp_stats[i++] = swstats->pfc_err_cnt;
- tmp_stats[i++] = swstats->pcc_err_cnt;
- tmp_stats[i++] = swstats->tti_err_cnt;
- tmp_stats[i++] = swstats->tpa_err_cnt;
- tmp_stats[i++] = swstats->sm_err_cnt;
- tmp_stats[i++] = swstats->lso_err_cnt;
- tmp_stats[i++] = swstats->mac_tmac_err_cnt;
- tmp_stats[i++] = swstats->mac_rmac_err_cnt;
- tmp_stats[i++] = swstats->xgxs_txgxs_err_cnt;
- tmp_stats[i++] = swstats->xgxs_rxgxs_err_cnt;
- tmp_stats[i++] = swstats->rc_err_cnt;
- tmp_stats[i++] = swstats->prc_pcix_err_cnt;
- tmp_stats[i++] = swstats->rpa_err_cnt;
- tmp_stats[i++] = swstats->rda_err_cnt;
- tmp_stats[i++] = swstats->rti_err_cnt;
- tmp_stats[i++] = swstats->mc_err_cnt;
-}
-
-static int s2io_ethtool_get_regs_len(struct net_device *dev)
-{
- return XENA_REG_SPACE;
-}
-
-
-static int s2io_get_eeprom_len(struct net_device *dev)
-{
- return XENA_EEPROM_SPACE;
-}
-
-static int s2io_get_sset_count(struct net_device *dev, int sset)
-{
- struct s2io_nic *sp = netdev_priv(dev);
-
- switch (sset) {
- case ETH_SS_TEST:
- return S2IO_TEST_LEN;
- case ETH_SS_STATS:
- switch (sp->device_type) {
- case XFRAME_I_DEVICE:
- return XFRAME_I_STAT_LEN;
- case XFRAME_II_DEVICE:
- return XFRAME_II_STAT_LEN;
- default:
- return 0;
- }
- default:
- return -EOPNOTSUPP;
- }
-}
-
-static void s2io_ethtool_get_strings(struct net_device *dev,
- u32 stringset, u8 *data)
-{
- int stat_size = 0;
- struct s2io_nic *sp = netdev_priv(dev);
-
- switch (stringset) {
- case ETH_SS_TEST:
- memcpy(data, s2io_gstrings, S2IO_STRINGS_LEN);
- break;
- case ETH_SS_STATS:
- stat_size = sizeof(ethtool_xena_stats_keys);
- memcpy(data, ðtool_xena_stats_keys, stat_size);
- if (sp->device_type == XFRAME_II_DEVICE) {
- memcpy(data + stat_size,
- ðtool_enhanced_stats_keys,
- sizeof(ethtool_enhanced_stats_keys));
- stat_size += sizeof(ethtool_enhanced_stats_keys);
- }
-
- memcpy(data + stat_size, ðtool_driver_stats_keys,
- sizeof(ethtool_driver_stats_keys));
- }
-}
-
-static int s2io_set_features(struct net_device *dev, netdev_features_t features)
-{
- struct s2io_nic *sp = netdev_priv(dev);
- netdev_features_t changed = (features ^ dev->features) & NETIF_F_LRO;
-
- if (changed && netif_running(dev)) {
- int rc;
-
- s2io_stop_all_tx_queue(sp);
- s2io_card_down(sp);
- dev->features = features;
- rc = s2io_card_up(sp);
- if (rc)
- s2io_reset(sp);
- else
- s2io_start_all_tx_queue(sp);
-
- return rc ? rc : 1;
- }
-
- return 0;
-}
-
-static const struct ethtool_ops netdev_ethtool_ops = {
- .get_drvinfo = s2io_ethtool_gdrvinfo,
- .get_regs_len = s2io_ethtool_get_regs_len,
- .get_regs = s2io_ethtool_gregs,
- .get_link = ethtool_op_get_link,
- .get_eeprom_len = s2io_get_eeprom_len,
- .get_eeprom = s2io_ethtool_geeprom,
- .set_eeprom = s2io_ethtool_seeprom,
- .get_ringparam = s2io_ethtool_gringparam,
- .get_pauseparam = s2io_ethtool_getpause_data,
- .set_pauseparam = s2io_ethtool_setpause_data,
- .self_test = s2io_ethtool_test,
- .get_strings = s2io_ethtool_get_strings,
- .set_phys_id = s2io_ethtool_set_led,
- .get_ethtool_stats = s2io_get_ethtool_stats,
- .get_sset_count = s2io_get_sset_count,
- .get_link_ksettings = s2io_ethtool_get_link_ksettings,
- .set_link_ksettings = s2io_ethtool_set_link_ksettings,
-};
-
-/**
- * s2io_ioctl - Entry point for the Ioctl
- * @dev : Device pointer.
- * @rq : An IOCTL specefic structure, that can contain a pointer to
- * a proprietary structure used to pass information to the driver.
- * @cmd : This is used to distinguish between the different commands that
- * can be passed to the IOCTL functions.
- * Description:
- * Currently there are no special functionality supported in IOCTL, hence
- * function always return EOPNOTSUPPORTED
- */
-
-static int s2io_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
-{
- return -EOPNOTSUPP;
-}
-
-/**
- * s2io_change_mtu - entry point to change MTU size for the device.
- * @dev : device pointer.
- * @new_mtu : the new MTU size for the device.
- * Description: A driver entry point to change MTU size for the device.
- * Before changing the MTU the device must be stopped.
- * Return value:
- * 0 on success and an appropriate (-)ve integer as defined in errno.h
- * file on failure.
- */
-
-static int s2io_change_mtu(struct net_device *dev, int new_mtu)
-{
- struct s2io_nic *sp = netdev_priv(dev);
- int ret = 0;
-
- WRITE_ONCE(dev->mtu, new_mtu);
- if (netif_running(dev)) {
- s2io_stop_all_tx_queue(sp);
- s2io_card_down(sp);
- ret = s2io_card_up(sp);
- if (ret) {
- DBG_PRINT(ERR_DBG, "%s: Device bring up failed\n",
- __func__);
- return ret;
- }
- s2io_wake_all_tx_queue(sp);
- } else { /* Device is down */
- struct XENA_dev_config __iomem *bar0 = sp->bar0;
- u64 val64 = new_mtu;
-
- writeq(vBIT(val64, 2, 14), &bar0->rmac_max_pyld_len);
- }
-
- return ret;
-}
-
-/**
- * s2io_set_link - Set the LInk status
- * @work: work struct containing a pointer to device private structure
- * Description: Sets the link status for the adapter
- */
-
-static void s2io_set_link(struct work_struct *work)
-{
- struct s2io_nic *nic = container_of(work, struct s2io_nic,
- set_link_task);
- struct net_device *dev = nic->dev;
- struct XENA_dev_config __iomem *bar0 = nic->bar0;
- register u64 val64;
- u16 subid;
-
- rtnl_lock();
-
- if (!netif_running(dev))
- goto out_unlock;
-
- if (test_and_set_bit(__S2IO_STATE_LINK_TASK, &(nic->state))) {
- /* The card is being reset, no point doing anything */
- goto out_unlock;
- }
-
- subid = nic->pdev->subsystem_device;
- if (s2io_link_fault_indication(nic) == MAC_RMAC_ERR_TIMER) {
- /*
- * Allow a small delay for the NICs self initiated
- * cleanup to complete.
- */
- msleep(100);
- }
-
- val64 = readq(&bar0->adapter_status);
- if (LINK_IS_UP(val64)) {
- if (!(readq(&bar0->adapter_control) & ADAPTER_CNTL_EN)) {
- if (verify_xena_quiescence(nic)) {
- val64 = readq(&bar0->adapter_control);
- val64 |= ADAPTER_CNTL_EN;
- writeq(val64, &bar0->adapter_control);
- if (CARDS_WITH_FAULTY_LINK_INDICATORS(
- nic->device_type, subid)) {
- val64 = readq(&bar0->gpio_control);
- val64 |= GPIO_CTRL_GPIO_0;
- writeq(val64, &bar0->gpio_control);
- val64 = readq(&bar0->gpio_control);
- } else {
- val64 |= ADAPTER_LED_ON;
- writeq(val64, &bar0->adapter_control);
- }
- nic->device_enabled_once = true;
- } else {
- DBG_PRINT(ERR_DBG,
- "%s: Error: device is not Quiescent\n",
- dev->name);
- s2io_stop_all_tx_queue(nic);
- }
- }
- val64 = readq(&bar0->adapter_control);
- val64 |= ADAPTER_LED_ON;
- writeq(val64, &bar0->adapter_control);
- s2io_link(nic, LINK_UP);
- } else {
- if (CARDS_WITH_FAULTY_LINK_INDICATORS(nic->device_type,
- subid)) {
- val64 = readq(&bar0->gpio_control);
- val64 &= ~GPIO_CTRL_GPIO_0;
- writeq(val64, &bar0->gpio_control);
- val64 = readq(&bar0->gpio_control);
- }
- /* turn off LED */
- val64 = readq(&bar0->adapter_control);
- val64 = val64 & (~ADAPTER_LED_ON);
- writeq(val64, &bar0->adapter_control);
- s2io_link(nic, LINK_DOWN);
- }
- clear_bit(__S2IO_STATE_LINK_TASK, &(nic->state));
-
-out_unlock:
- rtnl_unlock();
-}
-
-static int set_rxd_buffer_pointer(struct s2io_nic *sp, struct RxD_t *rxdp,
- struct buffAdd *ba,
- struct sk_buff **skb, u64 *temp0, u64 *temp1,
- u64 *temp2, int size)
-{
- struct net_device *dev = sp->dev;
- struct swStat *stats = &sp->mac_control.stats_info->sw_stat;
-
- if ((sp->rxd_mode == RXD_MODE_1) && (rxdp->Host_Control == 0)) {
- struct RxD1 *rxdp1 = (struct RxD1 *)rxdp;
- /* allocate skb */
- if (*skb) {
- DBG_PRINT(INFO_DBG, "SKB is not NULL\n");
- /*
- * As Rx frame are not going to be processed,
- * using same mapped address for the Rxd
- * buffer pointer
- */
- rxdp1->Buffer0_ptr = *temp0;
- } else {
- *skb = netdev_alloc_skb(dev, size);
- if (!(*skb)) {
- DBG_PRINT(INFO_DBG,
- "%s: Out of memory to allocate %s\n",
- dev->name, "1 buf mode SKBs");
- stats->mem_alloc_fail_cnt++;
- return -ENOMEM ;
- }
- stats->mem_allocated += (*skb)->truesize;
- /* storing the mapped addr in a temp variable
- * such it will be used for next rxd whose
- * Host Control is NULL
- */
- rxdp1->Buffer0_ptr = *temp0 =
- dma_map_single(&sp->pdev->dev, (*skb)->data,
- size - NET_IP_ALIGN,
- DMA_FROM_DEVICE);
- if (dma_mapping_error(&sp->pdev->dev, rxdp1->Buffer0_ptr))
- goto memalloc_failed;
- rxdp->Host_Control = (unsigned long) (*skb);
- }
- } else if ((sp->rxd_mode == RXD_MODE_3B) && (rxdp->Host_Control == 0)) {
- struct RxD3 *rxdp3 = (struct RxD3 *)rxdp;
- /* Two buffer Mode */
- if (*skb) {
- rxdp3->Buffer2_ptr = *temp2;
- rxdp3->Buffer0_ptr = *temp0;
- rxdp3->Buffer1_ptr = *temp1;
- } else {
- *skb = netdev_alloc_skb(dev, size);
- if (!(*skb)) {
- DBG_PRINT(INFO_DBG,
- "%s: Out of memory to allocate %s\n",
- dev->name,
- "2 buf mode SKBs");
- stats->mem_alloc_fail_cnt++;
- return -ENOMEM;
- }
- stats->mem_allocated += (*skb)->truesize;
- rxdp3->Buffer2_ptr = *temp2 =
- dma_map_single(&sp->pdev->dev, (*skb)->data,
- dev->mtu + 4, DMA_FROM_DEVICE);
- if (dma_mapping_error(&sp->pdev->dev, rxdp3->Buffer2_ptr))
- goto memalloc_failed;
- rxdp3->Buffer0_ptr = *temp0 =
- dma_map_single(&sp->pdev->dev, ba->ba_0,
- BUF0_LEN, DMA_FROM_DEVICE);
- if (dma_mapping_error(&sp->pdev->dev, rxdp3->Buffer0_ptr)) {
- dma_unmap_single(&sp->pdev->dev,
- (dma_addr_t)rxdp3->Buffer2_ptr,
- dev->mtu + 4,
- DMA_FROM_DEVICE);
- goto memalloc_failed;
- }
- rxdp->Host_Control = (unsigned long) (*skb);
-
- /* Buffer-1 will be dummy buffer not used */
- rxdp3->Buffer1_ptr = *temp1 =
- dma_map_single(&sp->pdev->dev, ba->ba_1,
- BUF1_LEN, DMA_FROM_DEVICE);
- if (dma_mapping_error(&sp->pdev->dev, rxdp3->Buffer1_ptr)) {
- dma_unmap_single(&sp->pdev->dev,
- (dma_addr_t)rxdp3->Buffer0_ptr,
- BUF0_LEN, DMA_FROM_DEVICE);
- dma_unmap_single(&sp->pdev->dev,
- (dma_addr_t)rxdp3->Buffer2_ptr,
- dev->mtu + 4,
- DMA_FROM_DEVICE);
- goto memalloc_failed;
- }
- }
- }
- return 0;
-
-memalloc_failed:
- stats->pci_map_fail_cnt++;
- stats->mem_freed += (*skb)->truesize;
- dev_kfree_skb(*skb);
- return -ENOMEM;
-}
-
-static void set_rxd_buffer_size(struct s2io_nic *sp, struct RxD_t *rxdp,
- int size)
-{
- struct net_device *dev = sp->dev;
- if (sp->rxd_mode == RXD_MODE_1) {
- rxdp->Control_2 = SET_BUFFER0_SIZE_1(size - NET_IP_ALIGN);
- } else if (sp->rxd_mode == RXD_MODE_3B) {
- rxdp->Control_2 = SET_BUFFER0_SIZE_3(BUF0_LEN);
- rxdp->Control_2 |= SET_BUFFER1_SIZE_3(1);
- rxdp->Control_2 |= SET_BUFFER2_SIZE_3(dev->mtu + 4);
- }
-}
-
-static int rxd_owner_bit_reset(struct s2io_nic *sp)
-{
- int i, j, k, blk_cnt = 0, size;
- struct config_param *config = &sp->config;
- struct mac_info *mac_control = &sp->mac_control;
- struct net_device *dev = sp->dev;
- struct RxD_t *rxdp = NULL;
- struct sk_buff *skb = NULL;
- struct buffAdd *ba = NULL;
- u64 temp0_64 = 0, temp1_64 = 0, temp2_64 = 0;
-
- /* Calculate the size based on ring mode */
- size = dev->mtu + HEADER_ETHERNET_II_802_3_SIZE +
- HEADER_802_2_SIZE + HEADER_SNAP_SIZE;
- if (sp->rxd_mode == RXD_MODE_1)
- size += NET_IP_ALIGN;
- else if (sp->rxd_mode == RXD_MODE_3B)
- size = dev->mtu + ALIGN_SIZE + BUF0_LEN + 4;
-
- for (i = 0; i < config->rx_ring_num; i++) {
- struct rx_ring_config *rx_cfg = &config->rx_cfg[i];
- struct ring_info *ring = &mac_control->rings[i];
-
- blk_cnt = rx_cfg->num_rxd / (rxd_count[sp->rxd_mode] + 1);
-
- for (j = 0; j < blk_cnt; j++) {
- for (k = 0; k < rxd_count[sp->rxd_mode]; k++) {
- rxdp = ring->rx_blocks[j].rxds[k].virt_addr;
- if (sp->rxd_mode == RXD_MODE_3B)
- ba = &ring->ba[j][k];
- if (set_rxd_buffer_pointer(sp, rxdp, ba, &skb,
- &temp0_64,
- &temp1_64,
- &temp2_64,
- size) == -ENOMEM) {
- return 0;
- }
-
- set_rxd_buffer_size(sp, rxdp, size);
- dma_wmb();
- /* flip the Ownership bit to Hardware */
- rxdp->Control_1 |= RXD_OWN_XENA;
- }
- }
- }
- return 0;
-
-}
-
-static int s2io_add_isr(struct s2io_nic *sp)
-{
- int ret = 0;
- struct net_device *dev = sp->dev;
- int err = 0;
-
- if (sp->config.intr_type == MSI_X)
- ret = s2io_enable_msi_x(sp);
- if (ret) {
- DBG_PRINT(ERR_DBG, "%s: Defaulting to INTA\n", dev->name);
- sp->config.intr_type = INTA;
- }
-
- /*
- * Store the values of the MSIX table in
- * the struct s2io_nic structure
- */
- store_xmsi_data(sp);
-
- /* After proper initialization of H/W, register ISR */
- if (sp->config.intr_type == MSI_X) {
- int i, msix_rx_cnt = 0;
-
- for (i = 0; i < sp->num_entries; i++) {
- if (sp->s2io_entries[i].in_use == MSIX_FLG) {
- if (sp->s2io_entries[i].type ==
- MSIX_RING_TYPE) {
- snprintf(sp->desc[i],
- sizeof(sp->desc[i]),
- "%s:MSI-X-%d-RX",
- dev->name, i);
- err = request_irq(sp->entries[i].vector,
- s2io_msix_ring_handle,
- 0,
- sp->desc[i],
- sp->s2io_entries[i].arg);
- } else if (sp->s2io_entries[i].type ==
- MSIX_ALARM_TYPE) {
- snprintf(sp->desc[i],
- sizeof(sp->desc[i]),
- "%s:MSI-X-%d-TX",
- dev->name, i);
- err = request_irq(sp->entries[i].vector,
- s2io_msix_fifo_handle,
- 0,
- sp->desc[i],
- sp->s2io_entries[i].arg);
-
- }
- /* if either data or addr is zero print it. */
- if (!(sp->msix_info[i].addr &&
- sp->msix_info[i].data)) {
- DBG_PRINT(ERR_DBG,
- "%s @Addr:0x%llx Data:0x%llx\n",
- sp->desc[i],
- (unsigned long long)
- sp->msix_info[i].addr,
- (unsigned long long)
- ntohl(sp->msix_info[i].data));
- } else
- msix_rx_cnt++;
- if (err) {
- remove_msix_isr(sp);
-
- DBG_PRINT(ERR_DBG,
- "%s:MSI-X-%d registration "
- "failed\n", dev->name, i);
-
- DBG_PRINT(ERR_DBG,
- "%s: Defaulting to INTA\n",
- dev->name);
- sp->config.intr_type = INTA;
- break;
- }
- sp->s2io_entries[i].in_use =
- MSIX_REGISTERED_SUCCESS;
- }
- }
- if (!err) {
- pr_info("MSI-X-RX %d entries enabled\n", --msix_rx_cnt);
- DBG_PRINT(INFO_DBG,
- "MSI-X-TX entries enabled through alarm vector\n");
- }
- }
- if (sp->config.intr_type == INTA) {
- err = request_irq(sp->pdev->irq, s2io_isr, IRQF_SHARED,
- sp->name, dev);
- if (err) {
- DBG_PRINT(ERR_DBG, "%s: ISR registration failed\n",
- dev->name);
- return -1;
- }
- }
- return 0;
-}
-
-static void s2io_rem_isr(struct s2io_nic *sp)
-{
- if (sp->config.intr_type == MSI_X)
- remove_msix_isr(sp);
- else
- remove_inta_isr(sp);
-}
-
-static void do_s2io_card_down(struct s2io_nic *sp, int do_io)
-{
- int cnt = 0;
- struct XENA_dev_config __iomem *bar0 = sp->bar0;
- register u64 val64 = 0;
- struct config_param *config;
- config = &sp->config;
-
- if (!is_s2io_card_up(sp))
- return;
-
- timer_delete_sync(&sp->alarm_timer);
- /* If s2io_set_link task is executing, wait till it completes. */
- while (test_and_set_bit(__S2IO_STATE_LINK_TASK, &(sp->state)))
- msleep(50);
- clear_bit(__S2IO_STATE_CARD_UP, &sp->state);
-
- /* Disable napi */
- if (sp->config.napi) {
- int off = 0;
- if (config->intr_type == MSI_X) {
- for (; off < sp->config.rx_ring_num; off++)
- napi_disable(&sp->mac_control.rings[off].napi);
- }
- else
- napi_disable(&sp->napi);
- }
-
- /* disable Tx and Rx traffic on the NIC */
- if (do_io)
- stop_nic(sp);
-
- s2io_rem_isr(sp);
-
- /* stop the tx queue, indicate link down */
- s2io_link(sp, LINK_DOWN);
-
- /* Check if the device is Quiescent and then Reset the NIC */
- while (do_io) {
- /* As per the HW requirement we need to replenish the
- * receive buffer to avoid the ring bump. Since there is
- * no intention of processing the Rx frame at this pointwe are
- * just setting the ownership bit of rxd in Each Rx
- * ring to HW and set the appropriate buffer size
- * based on the ring mode
- */
- rxd_owner_bit_reset(sp);
-
- val64 = readq(&bar0->adapter_status);
- if (verify_xena_quiescence(sp)) {
- if (verify_pcc_quiescent(sp, sp->device_enabled_once))
- break;
- }
-
- msleep(50);
- cnt++;
- if (cnt == 10) {
- DBG_PRINT(ERR_DBG, "Device not Quiescent - "
- "adapter status reads 0x%llx\n",
- (unsigned long long)val64);
- break;
- }
- }
- if (do_io)
- s2io_reset(sp);
-
- /* Free all Tx buffers */
- free_tx_buffers(sp);
-
- /* Free all Rx buffers */
- free_rx_buffers(sp);
-
- clear_bit(__S2IO_STATE_LINK_TASK, &(sp->state));
-}
-
-static void s2io_card_down(struct s2io_nic *sp)
-{
- do_s2io_card_down(sp, 1);
-}
-
-static int s2io_card_up(struct s2io_nic *sp)
-{
- int i, ret = 0;
- struct config_param *config;
- struct mac_info *mac_control;
- struct net_device *dev = sp->dev;
- u16 interruptible;
-
- /* Initialize the H/W I/O registers */
- ret = init_nic(sp);
- if (ret != 0) {
- DBG_PRINT(ERR_DBG, "%s: H/W initialization failed\n",
- dev->name);
- if (ret != -EIO)
- s2io_reset(sp);
- return ret;
- }
-
- /*
- * Initializing the Rx buffers. For now we are considering only 1
- * Rx ring and initializing buffers into 30 Rx blocks
- */
- config = &sp->config;
- mac_control = &sp->mac_control;
-
- for (i = 0; i < config->rx_ring_num; i++) {
- struct ring_info *ring = &mac_control->rings[i];
-
- ring->mtu = dev->mtu;
- ring->lro = !!(dev->features & NETIF_F_LRO);
- ret = fill_rx_buffers(sp, ring, 1);
- if (ret) {
- DBG_PRINT(ERR_DBG, "%s: Out of memory in Open\n",
- dev->name);
- ret = -ENOMEM;
- goto err_fill_buff;
- }
- DBG_PRINT(INFO_DBG, "Buf in ring:%d is %d:\n", i,
- ring->rx_bufs_left);
- }
-
- /* Initialise napi */
- if (config->napi) {
- if (config->intr_type == MSI_X) {
- for (i = 0; i < sp->config.rx_ring_num; i++)
- napi_enable(&sp->mac_control.rings[i].napi);
- } else {
- napi_enable(&sp->napi);
- }
- }
-
- /* Maintain the state prior to the open */
- if (sp->promisc_flg)
- sp->promisc_flg = 0;
- if (sp->m_cast_flg) {
- sp->m_cast_flg = 0;
- sp->all_multi_pos = 0;
- }
-
- /* Setting its receive mode */
- s2io_set_multicast(dev, true);
-
- if (dev->features & NETIF_F_LRO) {
- /* Initialize max aggregatable pkts per session based on MTU */
- sp->lro_max_aggr_per_sess = ((1<<16) - 1) / dev->mtu;
- /* Check if we can use (if specified) user provided value */
- if (lro_max_pkts < sp->lro_max_aggr_per_sess)
- sp->lro_max_aggr_per_sess = lro_max_pkts;
- }
-
- /* Enable Rx Traffic and interrupts on the NIC */
- if (start_nic(sp)) {
- DBG_PRINT(ERR_DBG, "%s: Starting NIC failed\n", dev->name);
- ret = -ENODEV;
- goto err_out;
- }
-
- /* Add interrupt service routine */
- if (s2io_add_isr(sp) != 0) {
- if (sp->config.intr_type == MSI_X)
- s2io_rem_isr(sp);
- ret = -ENODEV;
- goto err_out;
- }
-
- timer_setup(&sp->alarm_timer, s2io_alarm_handle, 0);
- mod_timer(&sp->alarm_timer, jiffies + HZ / 2);
-
- set_bit(__S2IO_STATE_CARD_UP, &sp->state);
-
- /* Enable select interrupts */
- en_dis_err_alarms(sp, ENA_ALL_INTRS, ENABLE_INTRS);
- if (sp->config.intr_type != INTA) {
- interruptible = TX_TRAFFIC_INTR | TX_PIC_INTR;
- en_dis_able_nic_intrs(sp, interruptible, ENABLE_INTRS);
- } else {
- interruptible = TX_TRAFFIC_INTR | RX_TRAFFIC_INTR;
- interruptible |= TX_PIC_INTR;
- en_dis_able_nic_intrs(sp, interruptible, ENABLE_INTRS);
- }
-
- return 0;
-
-err_out:
- if (config->napi) {
- if (config->intr_type == MSI_X) {
- for (i = 0; i < sp->config.rx_ring_num; i++)
- napi_disable(&sp->mac_control.rings[i].napi);
- } else {
- napi_disable(&sp->napi);
- }
- }
-err_fill_buff:
- s2io_reset(sp);
- free_rx_buffers(sp);
- return ret;
-}
-
-/**
- * s2io_restart_nic - Resets the NIC.
- * @work : work struct containing a pointer to the device private structure
- * Description:
- * This function is scheduled to be run by the s2io_tx_watchdog
- * function after 0.5 secs to reset the NIC. The idea is to reduce
- * the run time of the watch dog routine which is run holding a
- * spin lock.
- */
-
-static void s2io_restart_nic(struct work_struct *work)
-{
- struct s2io_nic *sp = container_of(work, struct s2io_nic, rst_timer_task);
- struct net_device *dev = sp->dev;
-
- rtnl_lock();
-
- if (!netif_running(dev))
- goto out_unlock;
-
- s2io_card_down(sp);
- if (s2io_card_up(sp)) {
- DBG_PRINT(ERR_DBG, "%s: Device bring up failed\n", dev->name);
- }
- s2io_wake_all_tx_queue(sp);
- DBG_PRINT(ERR_DBG, "%s: was reset by Tx watchdog timer\n", dev->name);
-out_unlock:
- rtnl_unlock();
-}
-
-/**
- * s2io_tx_watchdog - Watchdog for transmit side.
- * @dev : Pointer to net device structure
- * @txqueue: index of the hanging queue
- * Description:
- * This function is triggered if the Tx Queue is stopped
- * for a pre-defined amount of time when the Interface is still up.
- * If the Interface is jammed in such a situation, the hardware is
- * reset (by s2io_close) and restarted again (by s2io_open) to
- * overcome any problem that might have been caused in the hardware.
- * Return value:
- * void
- */
-
-static void s2io_tx_watchdog(struct net_device *dev, unsigned int txqueue)
-{
- struct s2io_nic *sp = netdev_priv(dev);
- struct swStat *swstats = &sp->mac_control.stats_info->sw_stat;
-
- if (netif_carrier_ok(dev)) {
- swstats->watchdog_timer_cnt++;
- schedule_work(&sp->rst_timer_task);
- swstats->soft_reset_cnt++;
- }
-}
-
-/**
- * rx_osm_handler - To perform some OS related operations on SKB.
- * @ring_data : the ring from which this RxD was extracted.
- * @rxdp: descriptor
- * Description:
- * This function is called by the Rx interrupt serivce routine to perform
- * some OS related operations on the SKB before passing it to the upper
- * layers. It mainly checks if the checksum is OK, if so adds it to the
- * SKBs cksum variable, increments the Rx packet count and passes the SKB
- * to the upper layer. If the checksum is wrong, it increments the Rx
- * packet error count, frees the SKB and returns error.
- * Return value:
- * SUCCESS on success and -1 on failure.
- */
-static int rx_osm_handler(struct ring_info *ring_data, struct RxD_t * rxdp)
-{
- struct s2io_nic *sp = ring_data->nic;
- struct net_device *dev = ring_data->dev;
- struct sk_buff *skb = (struct sk_buff *)
- ((unsigned long)rxdp->Host_Control);
- int ring_no = ring_data->ring_no;
- u16 l3_csum, l4_csum;
- unsigned long long err = rxdp->Control_1 & RXD_T_CODE;
- struct lro *lro;
- u8 err_mask;
- struct swStat *swstats = &sp->mac_control.stats_info->sw_stat;
-
- skb->dev = dev;
-
- if (err) {
- /* Check for parity error */
- if (err & 0x1)
- swstats->parity_err_cnt++;
-
- err_mask = err >> 48;
- switch (err_mask) {
- case 1:
- swstats->rx_parity_err_cnt++;
- break;
-
- case 2:
- swstats->rx_abort_cnt++;
- break;
-
- case 3:
- swstats->rx_parity_abort_cnt++;
- break;
-
- case 4:
- swstats->rx_rda_fail_cnt++;
- break;
-
- case 5:
- swstats->rx_unkn_prot_cnt++;
- break;
-
- case 6:
- swstats->rx_fcs_err_cnt++;
- break;
-
- case 7:
- swstats->rx_buf_size_err_cnt++;
- break;
-
- case 8:
- swstats->rx_rxd_corrupt_cnt++;
- break;
-
- case 15:
- swstats->rx_unkn_err_cnt++;
- break;
- }
- /*
- * Drop the packet if bad transfer code. Exception being
- * 0x5, which could be due to unsupported IPv6 extension header.
- * In this case, we let stack handle the packet.
- * Note that in this case, since checksum will be incorrect,
- * stack will validate the same.
- */
- if (err_mask != 0x5) {
- DBG_PRINT(ERR_DBG, "%s: Rx error Value: 0x%x\n",
- dev->name, err_mask);
- dev->stats.rx_crc_errors++;
- swstats->mem_freed
- += skb->truesize;
- dev_kfree_skb(skb);
- ring_data->rx_bufs_left -= 1;
- rxdp->Host_Control = 0;
- return 0;
- }
- }
-
- rxdp->Host_Control = 0;
- if (sp->rxd_mode == RXD_MODE_1) {
- int len = RXD_GET_BUFFER0_SIZE_1(rxdp->Control_2);
-
- skb_put(skb, len);
- } else if (sp->rxd_mode == RXD_MODE_3B) {
- int get_block = ring_data->rx_curr_get_info.block_index;
- int get_off = ring_data->rx_curr_get_info.offset;
- int buf0_len = RXD_GET_BUFFER0_SIZE_3(rxdp->Control_2);
- int buf2_len = RXD_GET_BUFFER2_SIZE_3(rxdp->Control_2);
-
- struct buffAdd *ba = &ring_data->ba[get_block][get_off];
- skb_put_data(skb, ba->ba_0, buf0_len);
- skb_put(skb, buf2_len);
- }
-
- if ((rxdp->Control_1 & TCP_OR_UDP_FRAME) &&
- ((!ring_data->lro) ||
- (!(rxdp->Control_1 & RXD_FRAME_IP_FRAG))) &&
- (dev->features & NETIF_F_RXCSUM)) {
- l3_csum = RXD_GET_L3_CKSUM(rxdp->Control_1);
- l4_csum = RXD_GET_L4_CKSUM(rxdp->Control_1);
- if ((l3_csum == L3_CKSUM_OK) && (l4_csum == L4_CKSUM_OK)) {
- /*
- * NIC verifies if the Checksum of the received
- * frame is Ok or not and accordingly returns
- * a flag in the RxD.
- */
- skb->ip_summed = CHECKSUM_UNNECESSARY;
- if (ring_data->lro) {
- u32 tcp_len = 0;
- u8 *tcp;
- int ret = 0;
-
- ret = s2io_club_tcp_session(ring_data,
- skb->data, &tcp,
- &tcp_len, &lro,
- rxdp, sp);
- switch (ret) {
- case 3: /* Begin anew */
- lro->parent = skb;
- goto aggregate;
- case 1: /* Aggregate */
- lro_append_pkt(sp, lro, skb, tcp_len);
- goto aggregate;
- case 4: /* Flush session */
- lro_append_pkt(sp, lro, skb, tcp_len);
- queue_rx_frame(lro->parent,
- lro->vlan_tag);
- clear_lro_session(lro);
- swstats->flush_max_pkts++;
- goto aggregate;
- case 2: /* Flush both */
- lro->parent->data_len = lro->frags_len;
- swstats->sending_both++;
- queue_rx_frame(lro->parent,
- lro->vlan_tag);
- clear_lro_session(lro);
- goto send_up;
- case 0: /* sessions exceeded */
- case -1: /* non-TCP or not L2 aggregatable */
- case 5: /*
- * First pkt in session not
- * L3/L4 aggregatable
- */
- break;
- default:
- DBG_PRINT(ERR_DBG,
- "%s: Samadhana!!\n",
- __func__);
- BUG();
- }
- }
- } else {
- /*
- * Packet with erroneous checksum, let the
- * upper layers deal with it.
- */
- skb_checksum_none_assert(skb);
- }
- } else
- skb_checksum_none_assert(skb);
-
- swstats->mem_freed += skb->truesize;
-send_up:
- skb_record_rx_queue(skb, ring_no);
- queue_rx_frame(skb, RXD_GET_VLAN_TAG(rxdp->Control_2));
-aggregate:
- sp->mac_control.rings[ring_no].rx_bufs_left -= 1;
- return SUCCESS;
-}
-
-/**
- * s2io_link - stops/starts the Tx queue.
- * @sp : private member of the device structure, which is a pointer to the
- * s2io_nic structure.
- * @link : inidicates whether link is UP/DOWN.
- * Description:
- * This function stops/starts the Tx queue depending on whether the link
- * status of the NIC is down or up. This is called by the Alarm
- * interrupt handler whenever a link change interrupt comes up.
- * Return value:
- * void.
- */
-
-static void s2io_link(struct s2io_nic *sp, int link)
-{
- struct net_device *dev = sp->dev;
- struct swStat *swstats = &sp->mac_control.stats_info->sw_stat;
-
- if (link != sp->last_link_state) {
- init_tti(sp, link, false);
- if (link == LINK_DOWN) {
- DBG_PRINT(ERR_DBG, "%s: Link down\n", dev->name);
- s2io_stop_all_tx_queue(sp);
- netif_carrier_off(dev);
- if (swstats->link_up_cnt)
- swstats->link_up_time =
- jiffies - sp->start_time;
- swstats->link_down_cnt++;
- } else {
- DBG_PRINT(ERR_DBG, "%s: Link Up\n", dev->name);
- if (swstats->link_down_cnt)
- swstats->link_down_time =
- jiffies - sp->start_time;
- swstats->link_up_cnt++;
- netif_carrier_on(dev);
- s2io_wake_all_tx_queue(sp);
- }
- }
- sp->last_link_state = link;
- sp->start_time = jiffies;
-}
-
-/**
- * s2io_init_pci -Initialization of PCI and PCI-X configuration registers .
- * @sp : private member of the device structure, which is a pointer to the
- * s2io_nic structure.
- * Description:
- * This function initializes a few of the PCI and PCI-X configuration registers
- * with recommended values.
- * Return value:
- * void
- */
-
-static void s2io_init_pci(struct s2io_nic *sp)
-{
- u16 pci_cmd = 0, pcix_cmd = 0;
-
- /* Enable Data Parity Error Recovery in PCI-X command register. */
- pci_read_config_word(sp->pdev, PCIX_COMMAND_REGISTER,
- &(pcix_cmd));
- pci_write_config_word(sp->pdev, PCIX_COMMAND_REGISTER,
- (pcix_cmd | 1));
- pci_read_config_word(sp->pdev, PCIX_COMMAND_REGISTER,
- &(pcix_cmd));
-
- /* Set the PErr Response bit in PCI command register. */
- pci_read_config_word(sp->pdev, PCI_COMMAND, &pci_cmd);
- pci_write_config_word(sp->pdev, PCI_COMMAND,
- (pci_cmd | PCI_COMMAND_PARITY));
- pci_read_config_word(sp->pdev, PCI_COMMAND, &pci_cmd);
-}
-
-static int s2io_verify_parm(struct pci_dev *pdev, u8 *dev_intr_type,
- u8 *dev_multiq)
-{
- int i;
-
- if ((tx_fifo_num > MAX_TX_FIFOS) || (tx_fifo_num < 1)) {
- DBG_PRINT(ERR_DBG, "Requested number of tx fifos "
- "(%d) not supported\n", tx_fifo_num);
-
- if (tx_fifo_num < 1)
- tx_fifo_num = 1;
- else
- tx_fifo_num = MAX_TX_FIFOS;
-
- DBG_PRINT(ERR_DBG, "Default to %d tx fifos\n", tx_fifo_num);
- }
-
- if (multiq)
- *dev_multiq = multiq;
-
- if (tx_steering_type && (1 == tx_fifo_num)) {
- if (tx_steering_type != TX_DEFAULT_STEERING)
- DBG_PRINT(ERR_DBG,
- "Tx steering is not supported with "
- "one fifo. Disabling Tx steering.\n");
- tx_steering_type = NO_STEERING;
- }
-
- if ((tx_steering_type < NO_STEERING) ||
- (tx_steering_type > TX_DEFAULT_STEERING)) {
- DBG_PRINT(ERR_DBG,
- "Requested transmit steering not supported\n");
- DBG_PRINT(ERR_DBG, "Disabling transmit steering\n");
- tx_steering_type = NO_STEERING;
- }
-
- if (rx_ring_num > MAX_RX_RINGS) {
- DBG_PRINT(ERR_DBG,
- "Requested number of rx rings not supported\n");
- DBG_PRINT(ERR_DBG, "Default to %d rx rings\n",
- MAX_RX_RINGS);
- rx_ring_num = MAX_RX_RINGS;
- }
-
- if ((*dev_intr_type != INTA) && (*dev_intr_type != MSI_X)) {
- DBG_PRINT(ERR_DBG, "Wrong intr_type requested. "
- "Defaulting to INTA\n");
- *dev_intr_type = INTA;
- }
-
- if ((*dev_intr_type == MSI_X) &&
- ((pdev->device != PCI_DEVICE_ID_HERC_WIN) &&
- (pdev->device != PCI_DEVICE_ID_HERC_UNI))) {
- DBG_PRINT(ERR_DBG, "Xframe I does not support MSI_X. "
- "Defaulting to INTA\n");
- *dev_intr_type = INTA;
- }
-
- if ((rx_ring_mode != 1) && (rx_ring_mode != 2)) {
- DBG_PRINT(ERR_DBG, "Requested ring mode not supported\n");
- DBG_PRINT(ERR_DBG, "Defaulting to 1-buffer mode\n");
- rx_ring_mode = 1;
- }
-
- for (i = 0; i < MAX_RX_RINGS; i++)
- if (rx_ring_sz[i] > MAX_RX_BLOCKS_PER_RING) {
- DBG_PRINT(ERR_DBG, "Requested rx ring size not "
- "supported\nDefaulting to %d\n",
- MAX_RX_BLOCKS_PER_RING);
- rx_ring_sz[i] = MAX_RX_BLOCKS_PER_RING;
- }
-
- return SUCCESS;
-}
-
-/**
- * rts_ds_steer - Receive traffic steering based on IPv4 or IPv6 TOS or Traffic class respectively.
- * @nic: device private variable
- * @ds_codepoint: data
- * @ring: ring index
- * Description: The function configures the receive steering to
- * desired receive ring.
- * Return Value: SUCCESS on success and
- * '-1' on failure (endian settings incorrect).
- */
-static int rts_ds_steer(struct s2io_nic *nic, u8 ds_codepoint, u8 ring)
-{
- struct XENA_dev_config __iomem *bar0 = nic->bar0;
- register u64 val64 = 0;
-
- if (ds_codepoint > 63)
- return FAILURE;
-
- val64 = RTS_DS_MEM_DATA(ring);
- writeq(val64, &bar0->rts_ds_mem_data);
-
- val64 = RTS_DS_MEM_CTRL_WE |
- RTS_DS_MEM_CTRL_STROBE_NEW_CMD |
- RTS_DS_MEM_CTRL_OFFSET(ds_codepoint);
-
- writeq(val64, &bar0->rts_ds_mem_ctrl);
-
- return wait_for_cmd_complete(&bar0->rts_ds_mem_ctrl,
- RTS_DS_MEM_CTRL_STROBE_CMD_BEING_EXECUTED,
- S2IO_BIT_RESET, true);
-}
-
-static const struct net_device_ops s2io_netdev_ops = {
- .ndo_open = s2io_open,
- .ndo_stop = s2io_close,
- .ndo_get_stats = s2io_get_stats,
- .ndo_start_xmit = s2io_xmit,
- .ndo_validate_addr = eth_validate_addr,
- .ndo_set_rx_mode = s2io_ndo_set_multicast,
- .ndo_eth_ioctl = s2io_ioctl,
- .ndo_set_mac_address = s2io_set_mac_addr,
- .ndo_change_mtu = s2io_change_mtu,
- .ndo_set_features = s2io_set_features,
- .ndo_tx_timeout = s2io_tx_watchdog,
-#ifdef CONFIG_NET_POLL_CONTROLLER
- .ndo_poll_controller = s2io_netpoll,
-#endif
-};
-
-/**
- * s2io_init_nic - Initialization of the adapter .
- * @pdev : structure containing the PCI related information of the device.
- * @pre: List of PCI devices supported by the driver listed in s2io_tbl.
- * Description:
- * The function initializes an adapter identified by the pci_dec structure.
- * All OS related initialization including memory and device structure and
- * initlaization of the device private variable is done. Also the swapper
- * control register is initialized to enable read and write into the I/O
- * registers of the device.
- * Return value:
- * returns 0 on success and negative on failure.
- */
-
-static int
-s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre)
-{
- struct s2io_nic *sp;
- struct net_device *dev;
- int i, j, ret;
- u32 mac_up, mac_down;
- u64 val64 = 0, tmp64 = 0;
- struct XENA_dev_config __iomem *bar0 = NULL;
- u16 subid;
- struct config_param *config;
- struct mac_info *mac_control;
- int mode;
- u8 dev_intr_type = intr_type;
- u8 dev_multiq = 0;
-
- ret = s2io_verify_parm(pdev, &dev_intr_type, &dev_multiq);
- if (ret)
- return ret;
-
- ret = pci_enable_device(pdev);
- if (ret) {
- DBG_PRINT(ERR_DBG,
- "%s: pci_enable_device failed\n", __func__);
- return ret;
- }
-
- if (!dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(64))) {
- DBG_PRINT(INIT_DBG, "%s: Using 64bit DMA\n", __func__);
- } else {
- pci_disable_device(pdev);
- return -ENOMEM;
- }
- ret = pci_request_regions(pdev, s2io_driver_name);
- if (ret) {
- DBG_PRINT(ERR_DBG, "%s: Request Regions failed - %x\n",
- __func__, ret);
- pci_disable_device(pdev);
- return -ENODEV;
- }
- if (dev_multiq)
- dev = alloc_etherdev_mq(sizeof(struct s2io_nic), tx_fifo_num);
- else
- dev = alloc_etherdev(sizeof(struct s2io_nic));
- if (dev == NULL) {
- pci_disable_device(pdev);
- pci_release_regions(pdev);
- return -ENODEV;
- }
-
- pci_set_master(pdev);
- pci_set_drvdata(pdev, dev);
- SET_NETDEV_DEV(dev, &pdev->dev);
-
- /* Private member variable initialized to s2io NIC structure */
- sp = netdev_priv(dev);
- sp->dev = dev;
- sp->pdev = pdev;
- sp->device_enabled_once = false;
- if (rx_ring_mode == 1)
- sp->rxd_mode = RXD_MODE_1;
- if (rx_ring_mode == 2)
- sp->rxd_mode = RXD_MODE_3B;
-
- sp->config.intr_type = dev_intr_type;
-
- if ((pdev->device == PCI_DEVICE_ID_HERC_WIN) ||
- (pdev->device == PCI_DEVICE_ID_HERC_UNI))
- sp->device_type = XFRAME_II_DEVICE;
- else
- sp->device_type = XFRAME_I_DEVICE;
-
-
- /* Initialize some PCI/PCI-X fields of the NIC. */
- s2io_init_pci(sp);
-
- /*
- * Setting the device configuration parameters.
- * Most of these parameters can be specified by the user during
- * module insertion as they are module loadable parameters. If
- * these parameters are not specified during load time, they
- * are initialized with default values.
- */
- config = &sp->config;
- mac_control = &sp->mac_control;
-
- config->napi = napi;
- config->tx_steering_type = tx_steering_type;
-
- /* Tx side parameters. */
- if (config->tx_steering_type == TX_PRIORITY_STEERING)
- config->tx_fifo_num = MAX_TX_FIFOS;
- else
- config->tx_fifo_num = tx_fifo_num;
-
- /* Initialize the fifos used for tx steering */
- if (config->tx_fifo_num < 5) {
- if (config->tx_fifo_num == 1)
- sp->total_tcp_fifos = 1;
- else
- sp->total_tcp_fifos = config->tx_fifo_num - 1;
- sp->udp_fifo_idx = config->tx_fifo_num - 1;
- sp->total_udp_fifos = 1;
- sp->other_fifo_idx = sp->total_tcp_fifos - 1;
- } else {
- sp->total_tcp_fifos = (tx_fifo_num - FIFO_UDP_MAX_NUM -
- FIFO_OTHER_MAX_NUM);
- sp->udp_fifo_idx = sp->total_tcp_fifos;
- sp->total_udp_fifos = FIFO_UDP_MAX_NUM;
- sp->other_fifo_idx = sp->udp_fifo_idx + FIFO_UDP_MAX_NUM;
- }
-
- config->multiq = dev_multiq;
- for (i = 0; i < config->tx_fifo_num; i++) {
- struct tx_fifo_config *tx_cfg = &config->tx_cfg[i];
-
- tx_cfg->fifo_len = tx_fifo_len[i];
- tx_cfg->fifo_priority = i;
- }
-
- /* mapping the QoS priority to the configured fifos */
- for (i = 0; i < MAX_TX_FIFOS; i++)
- config->fifo_mapping[i] = fifo_map[config->tx_fifo_num - 1][i];
-
- /* map the hashing selector table to the configured fifos */
- for (i = 0; i < config->tx_fifo_num; i++)
- sp->fifo_selector[i] = fifo_selector[i];
-
-
- config->tx_intr_type = TXD_INT_TYPE_UTILZ;
- for (i = 0; i < config->tx_fifo_num; i++) {
- struct tx_fifo_config *tx_cfg = &config->tx_cfg[i];
-
- tx_cfg->f_no_snoop = (NO_SNOOP_TXD | NO_SNOOP_TXD_BUFFER);
- if (tx_cfg->fifo_len < 65) {
- config->tx_intr_type = TXD_INT_TYPE_PER_LIST;
- break;
- }
- }
- /* + 2 because one Txd for skb->data and one Txd for UFO */
- config->max_txds = MAX_SKB_FRAGS + 2;
-
- /* Rx side parameters. */
- config->rx_ring_num = rx_ring_num;
- for (i = 0; i < config->rx_ring_num; i++) {
- struct rx_ring_config *rx_cfg = &config->rx_cfg[i];
- struct ring_info *ring = &mac_control->rings[i];
-
- rx_cfg->num_rxd = rx_ring_sz[i] * (rxd_count[sp->rxd_mode] + 1);
- rx_cfg->ring_priority = i;
- ring->rx_bufs_left = 0;
- ring->rxd_mode = sp->rxd_mode;
- ring->rxd_count = rxd_count[sp->rxd_mode];
- ring->pdev = sp->pdev;
- ring->dev = sp->dev;
- }
-
- for (i = 0; i < rx_ring_num; i++) {
- struct rx_ring_config *rx_cfg = &config->rx_cfg[i];
-
- rx_cfg->ring_org = RING_ORG_BUFF1;
- rx_cfg->f_no_snoop = (NO_SNOOP_RXD | NO_SNOOP_RXD_BUFFER);
- }
-
- /* Setting Mac Control parameters */
- mac_control->rmac_pause_time = rmac_pause_time;
- mac_control->mc_pause_threshold_q0q3 = mc_pause_threshold_q0q3;
- mac_control->mc_pause_threshold_q4q7 = mc_pause_threshold_q4q7;
-
-
- /* initialize the shared memory used by the NIC and the host */
- if (init_shared_mem(sp)) {
- DBG_PRINT(ERR_DBG, "%s: Memory allocation failed\n", dev->name);
- ret = -ENOMEM;
- goto mem_alloc_failed;
- }
-
- sp->bar0 = pci_ioremap_bar(pdev, 0);
- if (!sp->bar0) {
- DBG_PRINT(ERR_DBG, "%s: Neterion: cannot remap io mem1\n",
- dev->name);
- ret = -ENOMEM;
- goto bar0_remap_failed;
- }
-
- sp->bar1 = pci_ioremap_bar(pdev, 2);
- if (!sp->bar1) {
- DBG_PRINT(ERR_DBG, "%s: Neterion: cannot remap io mem2\n",
- dev->name);
- ret = -ENOMEM;
- goto bar1_remap_failed;
- }
-
- /* Initializing the BAR1 address as the start of the FIFO pointer. */
- for (j = 0; j < MAX_TX_FIFOS; j++) {
- mac_control->tx_FIFO_start[j] = sp->bar1 + (j * 0x00020000);
- }
-
- /* Driver entry points */
- dev->netdev_ops = &s2io_netdev_ops;
- dev->ethtool_ops = &netdev_ethtool_ops;
- dev->hw_features = NETIF_F_SG | NETIF_F_IP_CSUM |
- NETIF_F_TSO | NETIF_F_TSO6 |
- NETIF_F_RXCSUM | NETIF_F_LRO;
- dev->features |= dev->hw_features |
- NETIF_F_HW_VLAN_CTAG_TX | NETIF_F_HW_VLAN_CTAG_RX |
- NETIF_F_HIGHDMA;
- dev->watchdog_timeo = WATCH_DOG_TIMEOUT;
- INIT_WORK(&sp->rst_timer_task, s2io_restart_nic);
- INIT_WORK(&sp->set_link_task, s2io_set_link);
-
- pci_save_state(sp->pdev);
-
- /* Setting swapper control on the NIC, for proper reset operation */
- if (s2io_set_swapper(sp)) {
- DBG_PRINT(ERR_DBG, "%s: swapper settings are wrong\n",
- dev->name);
- ret = -EAGAIN;
- goto set_swap_failed;
- }
-
- /* Verify if the Herc works on the slot its placed into */
- if (sp->device_type & XFRAME_II_DEVICE) {
- mode = s2io_verify_pci_mode(sp);
- if (mode < 0) {
- DBG_PRINT(ERR_DBG, "%s: Unsupported PCI bus mode\n",
- __func__);
- ret = -EBADSLT;
- goto set_swap_failed;
- }
- }
-
- if (sp->config.intr_type == MSI_X) {
- sp->num_entries = config->rx_ring_num + 1;
- ret = s2io_enable_msi_x(sp);
-
- if (!ret) {
- ret = s2io_test_msi(sp);
- /* rollback MSI-X, will re-enable during add_isr() */
- remove_msix_isr(sp);
- }
- if (ret) {
-
- DBG_PRINT(ERR_DBG,
- "MSI-X requested but failed to enable\n");
- sp->config.intr_type = INTA;
- }
- }
-
- if (config->intr_type == MSI_X) {
- for (i = 0; i < config->rx_ring_num ; i++) {
- struct ring_info *ring = &mac_control->rings[i];
-
- netif_napi_add(dev, &ring->napi, s2io_poll_msix);
- }
- } else {
- netif_napi_add(dev, &sp->napi, s2io_poll_inta);
- }
-
- /* Not needed for Herc */
- if (sp->device_type & XFRAME_I_DEVICE) {
- /*
- * Fix for all "FFs" MAC address problems observed on
- * Alpha platforms
- */
- fix_mac_address(sp);
- s2io_reset(sp);
- }
-
- /*
- * MAC address initialization.
- * For now only one mac address will be read and used.
- */
- bar0 = sp->bar0;
- val64 = RMAC_ADDR_CMD_MEM_RD | RMAC_ADDR_CMD_MEM_STROBE_NEW_CMD |
- RMAC_ADDR_CMD_MEM_OFFSET(0 + S2IO_MAC_ADDR_START_OFFSET);
- writeq(val64, &bar0->rmac_addr_cmd_mem);
- wait_for_cmd_complete(&bar0->rmac_addr_cmd_mem,
- RMAC_ADDR_CMD_MEM_STROBE_CMD_EXECUTING,
- S2IO_BIT_RESET, true);
- tmp64 = readq(&bar0->rmac_addr_data0_mem);
- mac_down = (u32)tmp64;
- mac_up = (u32) (tmp64 >> 32);
-
- sp->def_mac_addr[0].mac_addr[3] = (u8) (mac_up);
- sp->def_mac_addr[0].mac_addr[2] = (u8) (mac_up >> 8);
- sp->def_mac_addr[0].mac_addr[1] = (u8) (mac_up >> 16);
- sp->def_mac_addr[0].mac_addr[0] = (u8) (mac_up >> 24);
- sp->def_mac_addr[0].mac_addr[5] = (u8) (mac_down >> 16);
- sp->def_mac_addr[0].mac_addr[4] = (u8) (mac_down >> 24);
-
- /* Set the factory defined MAC address initially */
- dev->addr_len = ETH_ALEN;
- eth_hw_addr_set(dev, sp->def_mac_addr[0].mac_addr);
-
- /* initialize number of multicast & unicast MAC entries variables */
- if (sp->device_type == XFRAME_I_DEVICE) {
- config->max_mc_addr = S2IO_XENA_MAX_MC_ADDRESSES;
- config->max_mac_addr = S2IO_XENA_MAX_MAC_ADDRESSES;
- config->mc_start_offset = S2IO_XENA_MC_ADDR_START_OFFSET;
- } else if (sp->device_type == XFRAME_II_DEVICE) {
- config->max_mc_addr = S2IO_HERC_MAX_MC_ADDRESSES;
- config->max_mac_addr = S2IO_HERC_MAX_MAC_ADDRESSES;
- config->mc_start_offset = S2IO_HERC_MC_ADDR_START_OFFSET;
- }
-
- /* MTU range: 46 - 9600 */
- dev->min_mtu = MIN_MTU;
- dev->max_mtu = S2IO_JUMBO_SIZE;
-
- /* store mac addresses from CAM to s2io_nic structure */
- do_s2io_store_unicast_mc(sp);
-
- /* Configure MSIX vector for number of rings configured plus one */
- if ((sp->device_type == XFRAME_II_DEVICE) &&
- (config->intr_type == MSI_X))
- sp->num_entries = config->rx_ring_num + 1;
-
- /* Store the values of the MSIX table in the s2io_nic structure */
- store_xmsi_data(sp);
- /* reset Nic and bring it to known state */
- s2io_reset(sp);
-
- /*
- * Initialize link state flags
- * and the card state parameter
- */
- sp->state = 0;
-
- /* Initialize spinlocks */
- for (i = 0; i < sp->config.tx_fifo_num; i++) {
- struct fifo_info *fifo = &mac_control->fifos[i];
-
- spin_lock_init(&fifo->tx_lock);
- }
-
- /*
- * SXE-002: Configure link and activity LED to init state
- * on driver load.
- */
- subid = sp->pdev->subsystem_device;
- if ((subid & 0xFF) >= 0x07) {
- val64 = readq(&bar0->gpio_control);
- val64 |= 0x0000800000000000ULL;
- writeq(val64, &bar0->gpio_control);
- val64 = 0x0411040400000000ULL;
- writeq(val64, (void __iomem *)bar0 + 0x2700);
- val64 = readq(&bar0->gpio_control);
- }
-
- sp->rx_csum = 1; /* Rx chksum verify enabled by default */
-
- if (register_netdev(dev)) {
- DBG_PRINT(ERR_DBG, "Device registration failed\n");
- ret = -ENODEV;
- goto register_failed;
- }
- s2io_vpd_read(sp);
- DBG_PRINT(ERR_DBG, "Copyright(c) 2002-2010 Exar Corp.\n");
- DBG_PRINT(ERR_DBG, "%s: Neterion %s (rev %d)\n", dev->name,
- sp->product_name, pdev->revision);
- DBG_PRINT(ERR_DBG, "%s: Driver version %s\n", dev->name,
- s2io_driver_version);
- DBG_PRINT(ERR_DBG, "%s: MAC Address: %pM\n", dev->name, dev->dev_addr);
- DBG_PRINT(ERR_DBG, "Serial number: %s\n", sp->serial_num);
- if (sp->device_type & XFRAME_II_DEVICE) {
- mode = s2io_print_pci_mode(sp);
- if (mode < 0) {
- ret = -EBADSLT;
- unregister_netdev(dev);
- goto set_swap_failed;
- }
- }
- switch (sp->rxd_mode) {
- case RXD_MODE_1:
- DBG_PRINT(ERR_DBG, "%s: 1-Buffer receive mode enabled\n",
- dev->name);
- break;
- case RXD_MODE_3B:
- DBG_PRINT(ERR_DBG, "%s: 2-Buffer receive mode enabled\n",
- dev->name);
- break;
- }
-
- switch (sp->config.napi) {
- case 0:
- DBG_PRINT(ERR_DBG, "%s: NAPI disabled\n", dev->name);
- break;
- case 1:
- DBG_PRINT(ERR_DBG, "%s: NAPI enabled\n", dev->name);
- break;
- }
-
- DBG_PRINT(ERR_DBG, "%s: Using %d Tx fifo(s)\n", dev->name,
- sp->config.tx_fifo_num);
-
- DBG_PRINT(ERR_DBG, "%s: Using %d Rx ring(s)\n", dev->name,
- sp->config.rx_ring_num);
-
- switch (sp->config.intr_type) {
- case INTA:
- DBG_PRINT(ERR_DBG, "%s: Interrupt type INTA\n", dev->name);
- break;
- case MSI_X:
- DBG_PRINT(ERR_DBG, "%s: Interrupt type MSI-X\n", dev->name);
- break;
- }
- if (sp->config.multiq) {
- for (i = 0; i < sp->config.tx_fifo_num; i++) {
- struct fifo_info *fifo = &mac_control->fifos[i];
-
- fifo->multiq = config->multiq;
- }
- DBG_PRINT(ERR_DBG, "%s: Multiqueue support enabled\n",
- dev->name);
- } else
- DBG_PRINT(ERR_DBG, "%s: Multiqueue support disabled\n",
- dev->name);
-
- switch (sp->config.tx_steering_type) {
- case NO_STEERING:
- DBG_PRINT(ERR_DBG, "%s: No steering enabled for transmit\n",
- dev->name);
- break;
- case TX_PRIORITY_STEERING:
- DBG_PRINT(ERR_DBG,
- "%s: Priority steering enabled for transmit\n",
- dev->name);
- break;
- case TX_DEFAULT_STEERING:
- DBG_PRINT(ERR_DBG,
- "%s: Default steering enabled for transmit\n",
- dev->name);
- }
-
- DBG_PRINT(ERR_DBG, "%s: Large receive offload enabled\n",
- dev->name);
- /* Initialize device name */
- snprintf(sp->name, sizeof(sp->name), "%s Neterion %s", dev->name,
- sp->product_name);
-
- if (vlan_tag_strip)
- sp->vlan_strip_flag = 1;
- else
- sp->vlan_strip_flag = 0;
-
- /*
- * Make Link state as off at this point, when the Link change
- * interrupt comes the state will be automatically changed to
- * the right state.
- */
- netif_carrier_off(dev);
-
- return 0;
-
-register_failed:
-set_swap_failed:
- iounmap(sp->bar1);
-bar1_remap_failed:
- iounmap(sp->bar0);
-bar0_remap_failed:
-mem_alloc_failed:
- free_shared_mem(sp);
- pci_disable_device(pdev);
- pci_release_regions(pdev);
- free_netdev(dev);
-
- return ret;
-}
-
-/**
- * s2io_rem_nic - Free the PCI device
- * @pdev: structure containing the PCI related information of the device.
- * Description: This function is called by the Pci subsystem to release a
- * PCI device and free up all resource held up by the device. This could
- * be in response to a Hot plug event or when the driver is to be removed
- * from memory.
- */
-
-static void s2io_rem_nic(struct pci_dev *pdev)
-{
- struct net_device *dev = pci_get_drvdata(pdev);
- struct s2io_nic *sp;
-
- if (dev == NULL) {
- DBG_PRINT(ERR_DBG, "Driver Data is NULL!!\n");
- return;
- }
-
- sp = netdev_priv(dev);
-
- cancel_work_sync(&sp->rst_timer_task);
- cancel_work_sync(&sp->set_link_task);
-
- unregister_netdev(dev);
-
- free_shared_mem(sp);
- iounmap(sp->bar0);
- iounmap(sp->bar1);
- pci_release_regions(pdev);
- free_netdev(dev);
- pci_disable_device(pdev);
-}
-
-module_pci_driver(s2io_driver);
-
-static int check_L2_lro_capable(u8 *buffer, struct iphdr **ip,
- struct tcphdr **tcp, struct RxD_t *rxdp,
- struct s2io_nic *sp)
-{
- int ip_off;
- u8 l2_type = (u8)((rxdp->Control_1 >> 37) & 0x7), ip_len;
-
- if (!(rxdp->Control_1 & RXD_FRAME_PROTO_TCP)) {
- DBG_PRINT(INIT_DBG,
- "%s: Non-TCP frames not supported for LRO\n",
- __func__);
- return -1;
- }
-
- /* Checking for DIX type or DIX type with VLAN */
- if ((l2_type == 0) || (l2_type == 4)) {
- ip_off = HEADER_ETHERNET_II_802_3_SIZE;
- /*
- * If vlan stripping is disabled and the frame is VLAN tagged,
- * shift the offset by the VLAN header size bytes.
- */
- if ((!sp->vlan_strip_flag) &&
- (rxdp->Control_1 & RXD_FRAME_VLAN_TAG))
- ip_off += HEADER_VLAN_SIZE;
- } else {
- /* LLC, SNAP etc are considered non-mergeable */
- return -1;
- }
-
- *ip = (struct iphdr *)(buffer + ip_off);
- ip_len = (u8)((*ip)->ihl);
- ip_len <<= 2;
- *tcp = (struct tcphdr *)((unsigned long)*ip + ip_len);
-
- return 0;
-}
-
-static int check_for_socket_match(struct lro *lro, struct iphdr *ip,
- struct tcphdr *tcp)
-{
- DBG_PRINT(INFO_DBG, "%s: Been here...\n", __func__);
- if ((lro->iph->saddr != ip->saddr) ||
- (lro->iph->daddr != ip->daddr) ||
- (lro->tcph->source != tcp->source) ||
- (lro->tcph->dest != tcp->dest))
- return -1;
- return 0;
-}
-
-static inline int get_l4_pyld_length(struct iphdr *ip, struct tcphdr *tcp)
-{
- return ntohs(ip->tot_len) - (ip->ihl << 2) - (tcp->doff << 2);
-}
-
-static void initiate_new_session(struct lro *lro, u8 *l2h,
- struct iphdr *ip, struct tcphdr *tcp,
- u32 tcp_pyld_len, u16 vlan_tag)
-{
- DBG_PRINT(INFO_DBG, "%s: Been here...\n", __func__);
- lro->l2h = l2h;
- lro->iph = ip;
- lro->tcph = tcp;
- lro->tcp_next_seq = tcp_pyld_len + ntohl(tcp->seq);
- lro->tcp_ack = tcp->ack_seq;
- lro->sg_num = 1;
- lro->total_len = ntohs(ip->tot_len);
- lro->frags_len = 0;
- lro->vlan_tag = vlan_tag;
- /*
- * Check if we saw TCP timestamp.
- * Other consistency checks have already been done.
- */
- if (tcp->doff == 8) {
- __be32 *ptr;
- ptr = (__be32 *)(tcp+1);
- lro->saw_ts = 1;
- lro->cur_tsval = ntohl(*(ptr+1));
- lro->cur_tsecr = *(ptr+2);
- }
- lro->in_use = 1;
-}
-
-static void update_L3L4_header(struct s2io_nic *sp, struct lro *lro)
-{
- struct iphdr *ip = lro->iph;
- struct tcphdr *tcp = lro->tcph;
- struct swStat *swstats = &sp->mac_control.stats_info->sw_stat;
-
- DBG_PRINT(INFO_DBG, "%s: Been here...\n", __func__);
-
- /* Update L3 header */
- csum_replace2(&ip->check, ip->tot_len, htons(lro->total_len));
- ip->tot_len = htons(lro->total_len);
-
- /* Update L4 header */
- tcp->ack_seq = lro->tcp_ack;
- tcp->window = lro->window;
-
- /* Update tsecr field if this session has timestamps enabled */
- if (lro->saw_ts) {
- __be32 *ptr = (__be32 *)(tcp + 1);
- *(ptr+2) = lro->cur_tsecr;
- }
-
- /* Update counters required for calculation of
- * average no. of packets aggregated.
- */
- swstats->sum_avg_pkts_aggregated += lro->sg_num;
- swstats->num_aggregations++;
-}
-
-static void aggregate_new_rx(struct lro *lro, struct iphdr *ip,
- struct tcphdr *tcp, u32 l4_pyld)
-{
- DBG_PRINT(INFO_DBG, "%s: Been here...\n", __func__);
- lro->total_len += l4_pyld;
- lro->frags_len += l4_pyld;
- lro->tcp_next_seq += l4_pyld;
- lro->sg_num++;
-
- /* Update ack seq no. and window ad(from this pkt) in LRO object */
- lro->tcp_ack = tcp->ack_seq;
- lro->window = tcp->window;
-
- if (lro->saw_ts) {
- __be32 *ptr;
- /* Update tsecr and tsval from this packet */
- ptr = (__be32 *)(tcp+1);
- lro->cur_tsval = ntohl(*(ptr+1));
- lro->cur_tsecr = *(ptr + 2);
- }
-}
-
-static int verify_l3_l4_lro_capable(struct lro *l_lro, struct iphdr *ip,
- struct tcphdr *tcp, u32 tcp_pyld_len)
-{
- u8 *ptr;
-
- DBG_PRINT(INFO_DBG, "%s: Been here...\n", __func__);
-
- if (!tcp_pyld_len) {
- /* Runt frame or a pure ack */
- return -1;
- }
-
- if (ip->ihl != 5) /* IP has options */
- return -1;
-
- /* If we see CE codepoint in IP header, packet is not mergeable */
- if (INET_ECN_is_ce(ipv4_get_dsfield(ip)))
- return -1;
-
- /* If we see ECE or CWR flags in TCP header, packet is not mergeable */
- if (tcp->urg || tcp->psh || tcp->rst ||
- tcp->syn || tcp->fin ||
- tcp->ece || tcp->cwr || !tcp->ack) {
- /*
- * Currently recognize only the ack control word and
- * any other control field being set would result in
- * flushing the LRO session
- */
- return -1;
- }
-
- /*
- * Allow only one TCP timestamp option. Don't aggregate if
- * any other options are detected.
- */
- if (tcp->doff != 5 && tcp->doff != 8)
- return -1;
-
- if (tcp->doff == 8) {
- ptr = (u8 *)(tcp + 1);
- while (*ptr == TCPOPT_NOP)
- ptr++;
- if (*ptr != TCPOPT_TIMESTAMP || *(ptr+1) != TCPOLEN_TIMESTAMP)
- return -1;
-
- /* Ensure timestamp value increases monotonically */
- if (l_lro)
- if (l_lro->cur_tsval > ntohl(*((__be32 *)(ptr+2))))
- return -1;
-
- /* timestamp echo reply should be non-zero */
- if (*((__be32 *)(ptr+6)) == 0)
- return -1;
- }
-
- return 0;
-}
-
-static int s2io_club_tcp_session(struct ring_info *ring_data, u8 *buffer,
- u8 **tcp, u32 *tcp_len, struct lro **lro,
- struct RxD_t *rxdp, struct s2io_nic *sp)
-{
- struct iphdr *ip;
- struct tcphdr *tcph;
- int ret = 0, i;
- u16 vlan_tag = 0;
- struct swStat *swstats = &sp->mac_control.stats_info->sw_stat;
-
- ret = check_L2_lro_capable(buffer, &ip, (struct tcphdr **)tcp,
- rxdp, sp);
- if (ret)
- return ret;
-
- DBG_PRINT(INFO_DBG, "IP Saddr: %x Daddr: %x\n", ip->saddr, ip->daddr);
-
- vlan_tag = RXD_GET_VLAN_TAG(rxdp->Control_2);
- tcph = (struct tcphdr *)*tcp;
- *tcp_len = get_l4_pyld_length(ip, tcph);
- for (i = 0; i < MAX_LRO_SESSIONS; i++) {
- struct lro *l_lro = &ring_data->lro0_n[i];
- if (l_lro->in_use) {
- if (check_for_socket_match(l_lro, ip, tcph))
- continue;
- /* Sock pair matched */
- *lro = l_lro;
-
- if ((*lro)->tcp_next_seq != ntohl(tcph->seq)) {
- DBG_PRINT(INFO_DBG, "%s: Out of sequence. "
- "expected 0x%x, actual 0x%x\n",
- __func__,
- (*lro)->tcp_next_seq,
- ntohl(tcph->seq));
-
- swstats->outof_sequence_pkts++;
- ret = 2;
- break;
- }
-
- if (!verify_l3_l4_lro_capable(l_lro, ip, tcph,
- *tcp_len))
- ret = 1; /* Aggregate */
- else
- ret = 2; /* Flush both */
- break;
- }
- }
-
- if (ret == 0) {
- /* Before searching for available LRO objects,
- * check if the pkt is L3/L4 aggregatable. If not
- * don't create new LRO session. Just send this
- * packet up.
- */
- if (verify_l3_l4_lro_capable(NULL, ip, tcph, *tcp_len))
- return 5;
-
- for (i = 0; i < MAX_LRO_SESSIONS; i++) {
- struct lro *l_lro = &ring_data->lro0_n[i];
- if (!(l_lro->in_use)) {
- *lro = l_lro;
- ret = 3; /* Begin anew */
- break;
- }
- }
- }
-
- if (ret == 0) { /* sessions exceeded */
- DBG_PRINT(INFO_DBG, "%s: All LRO sessions already in use\n",
- __func__);
- *lro = NULL;
- return ret;
- }
-
- switch (ret) {
- case 3:
- initiate_new_session(*lro, buffer, ip, tcph, *tcp_len,
- vlan_tag);
- break;
- case 2:
- update_L3L4_header(sp, *lro);
- break;
- case 1:
- aggregate_new_rx(*lro, ip, tcph, *tcp_len);
- if ((*lro)->sg_num == sp->lro_max_aggr_per_sess) {
- update_L3L4_header(sp, *lro);
- ret = 4; /* Flush the LRO */
- }
- break;
- default:
- DBG_PRINT(ERR_DBG, "%s: Don't know, can't say!!\n", __func__);
- break;
- }
-
- return ret;
-}
-
-static void clear_lro_session(struct lro *lro)
-{
- static u16 lro_struct_size = sizeof(struct lro);
-
- memset(lro, 0, lro_struct_size);
-}
-
-static void queue_rx_frame(struct sk_buff *skb, u16 vlan_tag)
-{
- struct net_device *dev = skb->dev;
- struct s2io_nic *sp = netdev_priv(dev);
-
- skb->protocol = eth_type_trans(skb, dev);
- if (vlan_tag && sp->vlan_strip_flag)
- __vlan_hwaccel_put_tag(skb, htons(ETH_P_8021Q), vlan_tag);
- if (sp->config.napi)
- netif_receive_skb(skb);
- else
- netif_rx(skb);
-}
-
-static void lro_append_pkt(struct s2io_nic *sp, struct lro *lro,
- struct sk_buff *skb, u32 tcp_len)
-{
- struct sk_buff *first = lro->parent;
- struct swStat *swstats = &sp->mac_control.stats_info->sw_stat;
-
- first->len += tcp_len;
- first->data_len = lro->frags_len;
- skb_pull(skb, (skb->len - tcp_len));
- if (skb_shinfo(first)->frag_list)
- lro->last_frag->next = skb;
- else
- skb_shinfo(first)->frag_list = skb;
- first->truesize += skb->truesize;
- lro->last_frag = skb;
- swstats->clubbed_frms_cnt++;
-}
-
-/**
- * s2io_io_error_detected - called when PCI error is detected
- * @pdev: Pointer to PCI device
- * @state: The current pci connection state
- *
- * This function is called after a PCI bus error affecting
- * this device has been detected.
- */
-static pci_ers_result_t s2io_io_error_detected(struct pci_dev *pdev,
- pci_channel_state_t state)
-{
- struct net_device *netdev = pci_get_drvdata(pdev);
- struct s2io_nic *sp = netdev_priv(netdev);
-
- netif_device_detach(netdev);
-
- if (state == pci_channel_io_perm_failure)
- return PCI_ERS_RESULT_DISCONNECT;
-
- if (netif_running(netdev)) {
- /* Bring down the card, while avoiding PCI I/O */
- do_s2io_card_down(sp, 0);
- }
- pci_disable_device(pdev);
-
- return PCI_ERS_RESULT_NEED_RESET;
-}
-
-/**
- * s2io_io_slot_reset - called after the pci bus has been reset.
- * @pdev: Pointer to PCI device
- *
- * Restart the card from scratch, as if from a cold-boot.
- * At this point, the card has experienced a hard reset,
- * followed by fixups by BIOS, and has its config space
- * set up identically to what it was at cold boot.
- */
-static pci_ers_result_t s2io_io_slot_reset(struct pci_dev *pdev)
-{
- struct net_device *netdev = pci_get_drvdata(pdev);
- struct s2io_nic *sp = netdev_priv(netdev);
-
- if (pci_enable_device(pdev)) {
- pr_err("Cannot re-enable PCI device after reset.\n");
- return PCI_ERS_RESULT_DISCONNECT;
- }
-
- pci_set_master(pdev);
- s2io_reset(sp);
-
- return PCI_ERS_RESULT_RECOVERED;
-}
-
-/**
- * s2io_io_resume - called when traffic can start flowing again.
- * @pdev: Pointer to PCI device
- *
- * This callback is called when the error recovery driver tells
- * us that its OK to resume normal operation.
- */
-static void s2io_io_resume(struct pci_dev *pdev)
-{
- struct net_device *netdev = pci_get_drvdata(pdev);
- struct s2io_nic *sp = netdev_priv(netdev);
-
- if (netif_running(netdev)) {
- if (s2io_card_up(sp)) {
- pr_err("Can't bring device back up after reset.\n");
- return;
- }
-
- if (do_s2io_prog_unicast(netdev, netdev->dev_addr) == FAILURE) {
- s2io_card_down(sp);
- pr_err("Can't restore mac addr after reset.\n");
- return;
- }
- }
-
- netif_device_attach(netdev);
- netif_tx_wake_all_queues(netdev);
-}
diff --git a/drivers/net/ethernet/neterion/s2io.h b/drivers/net/ethernet/neterion/s2io.h
deleted file mode 100644
index cb7080eb5912..000000000000
--- a/drivers/net/ethernet/neterion/s2io.h
+++ /dev/null
@@ -1,1124 +0,0 @@
-/************************************************************************
- * s2io.h: A Linux PCI-X Ethernet driver for Neterion 10GbE Server NIC
- * Copyright(c) 2002-2010 Exar Corp.
-
- * This software may be used and distributed according to the terms of
- * the GNU General Public License (GPL), incorporated herein by reference.
- * Drivers based on or derived from this code fall under the GPL and must
- * retain the authorship, copyright and license notice. This file is not
- * a complete program and may only be used when the entire operating
- * system is licensed under the GPL.
- * See the file COPYING in this distribution for more information.
- ************************************************************************/
-#include <linux/io-64-nonatomic-lo-hi.h>
-#ifndef _S2IO_H
-#define _S2IO_H
-
-#define TBD 0
-#define s2BIT(loc) (0x8000000000000000ULL >> (loc))
-#define vBIT(val, loc, sz) (((u64)val) << (64-loc-sz))
-#define INV(d) ((d&0xff)<<24) | (((d>>8)&0xff)<<16) | (((d>>16)&0xff)<<8)| ((d>>24)&0xff)
-
-#undef SUCCESS
-#define SUCCESS 0
-#define FAILURE -1
-#define S2IO_MINUS_ONE 0xFFFFFFFFFFFFFFFFULL
-#define S2IO_DISABLE_MAC_ENTRY 0xFFFFFFFFFFFFULL
-#define S2IO_MAX_PCI_CONFIG_SPACE_REINIT 100
-#define S2IO_BIT_RESET 1
-#define S2IO_BIT_SET 2
-#define CHECKBIT(value, nbit) (value & (1 << nbit))
-
-/* Maximum time to flicker LED when asked to identify NIC using ethtool */
-#define MAX_FLICKER_TIME 60000 /* 60 Secs */
-
-/* Maximum outstanding splits to be configured into xena. */
-enum {
- XENA_ONE_SPLIT_TRANSACTION = 0,
- XENA_TWO_SPLIT_TRANSACTION = 1,
- XENA_THREE_SPLIT_TRANSACTION = 2,
- XENA_FOUR_SPLIT_TRANSACTION = 3,
- XENA_EIGHT_SPLIT_TRANSACTION = 4,
- XENA_TWELVE_SPLIT_TRANSACTION = 5,
- XENA_SIXTEEN_SPLIT_TRANSACTION = 6,
- XENA_THIRTYTWO_SPLIT_TRANSACTION = 7
-};
-#define XENA_MAX_OUTSTANDING_SPLITS(n) (n << 4)
-
-/* OS concerned variables and constants */
-#define WATCH_DOG_TIMEOUT 15*HZ
-#define EFILL 0x1234
-#define ALIGN_SIZE 127
-#define PCIX_COMMAND_REGISTER 0x62
-
-/*
- * Debug related variables.
- */
-/* different debug levels. */
-#define ERR_DBG 0
-#define INIT_DBG 1
-#define INFO_DBG 2
-#define TX_DBG 3
-#define INTR_DBG 4
-
-/* Global variable that defines the present debug level of the driver. */
-static int debug_level = ERR_DBG;
-
-/* DEBUG message print. */
-#define DBG_PRINT(dbg_level, fmt, args...) do { \
- if (dbg_level <= debug_level) \
- pr_info(fmt, ##args); \
- } while (0)
-
-/* Protocol assist features of the NIC */
-#define L3_CKSUM_OK 0xFFFF
-#define L4_CKSUM_OK 0xFFFF
-#define S2IO_JUMBO_SIZE 9600
-
-/* Driver statistics maintained by driver */
-struct swStat {
- unsigned long long single_ecc_errs;
- unsigned long long double_ecc_errs;
- unsigned long long parity_err_cnt;
- unsigned long long serious_err_cnt;
- unsigned long long soft_reset_cnt;
- unsigned long long fifo_full_cnt;
- unsigned long long ring_full_cnt[8];
- /* LRO statistics */
- unsigned long long clubbed_frms_cnt;
- unsigned long long sending_both;
- unsigned long long outof_sequence_pkts;
- unsigned long long flush_max_pkts;
- unsigned long long sum_avg_pkts_aggregated;
- unsigned long long num_aggregations;
- /* Other statistics */
- unsigned long long mem_alloc_fail_cnt;
- unsigned long long pci_map_fail_cnt;
- unsigned long long watchdog_timer_cnt;
- unsigned long long mem_allocated;
- unsigned long long mem_freed;
- unsigned long long link_up_cnt;
- unsigned long long link_down_cnt;
- unsigned long long link_up_time;
- unsigned long long link_down_time;
-
- /* Transfer Code statistics */
- unsigned long long tx_buf_abort_cnt;
- unsigned long long tx_desc_abort_cnt;
- unsigned long long tx_parity_err_cnt;
- unsigned long long tx_link_loss_cnt;
- unsigned long long tx_list_proc_err_cnt;
-
- unsigned long long rx_parity_err_cnt;
- unsigned long long rx_abort_cnt;
- unsigned long long rx_parity_abort_cnt;
- unsigned long long rx_rda_fail_cnt;
- unsigned long long rx_unkn_prot_cnt;
- unsigned long long rx_fcs_err_cnt;
- unsigned long long rx_buf_size_err_cnt;
- unsigned long long rx_rxd_corrupt_cnt;
- unsigned long long rx_unkn_err_cnt;
-
- /* Error/alarm statistics*/
- unsigned long long tda_err_cnt;
- unsigned long long pfc_err_cnt;
- unsigned long long pcc_err_cnt;
- unsigned long long tti_err_cnt;
- unsigned long long lso_err_cnt;
- unsigned long long tpa_err_cnt;
- unsigned long long sm_err_cnt;
- unsigned long long mac_tmac_err_cnt;
- unsigned long long mac_rmac_err_cnt;
- unsigned long long xgxs_txgxs_err_cnt;
- unsigned long long xgxs_rxgxs_err_cnt;
- unsigned long long rc_err_cnt;
- unsigned long long prc_pcix_err_cnt;
- unsigned long long rpa_err_cnt;
- unsigned long long rda_err_cnt;
- unsigned long long rti_err_cnt;
- unsigned long long mc_err_cnt;
-
-};
-
-/* Xpak releated alarm and warnings */
-struct xpakStat {
- u64 alarm_transceiver_temp_high;
- u64 alarm_transceiver_temp_low;
- u64 alarm_laser_bias_current_high;
- u64 alarm_laser_bias_current_low;
- u64 alarm_laser_output_power_high;
- u64 alarm_laser_output_power_low;
- u64 warn_transceiver_temp_high;
- u64 warn_transceiver_temp_low;
- u64 warn_laser_bias_current_high;
- u64 warn_laser_bias_current_low;
- u64 warn_laser_output_power_high;
- u64 warn_laser_output_power_low;
- u64 xpak_regs_stat;
- u32 xpak_timer_count;
-};
-
-
-/* The statistics block of Xena */
-struct stat_block {
-/* Tx MAC statistics counters. */
- __le32 tmac_data_octets;
- __le32 tmac_frms;
- __le64 tmac_drop_frms;
- __le32 tmac_bcst_frms;
- __le32 tmac_mcst_frms;
- __le64 tmac_pause_ctrl_frms;
- __le32 tmac_ucst_frms;
- __le32 tmac_ttl_octets;
- __le32 tmac_any_err_frms;
- __le32 tmac_nucst_frms;
- __le64 tmac_ttl_less_fb_octets;
- __le64 tmac_vld_ip_octets;
- __le32 tmac_drop_ip;
- __le32 tmac_vld_ip;
- __le32 tmac_rst_tcp;
- __le32 tmac_icmp;
- __le64 tmac_tcp;
- __le32 reserved_0;
- __le32 tmac_udp;
-
-/* Rx MAC Statistics counters. */
- __le32 rmac_data_octets;
- __le32 rmac_vld_frms;
- __le64 rmac_fcs_err_frms;
- __le64 rmac_drop_frms;
- __le32 rmac_vld_bcst_frms;
- __le32 rmac_vld_mcst_frms;
- __le32 rmac_out_rng_len_err_frms;
- __le32 rmac_in_rng_len_err_frms;
- __le64 rmac_long_frms;
- __le64 rmac_pause_ctrl_frms;
- __le64 rmac_unsup_ctrl_frms;
- __le32 rmac_accepted_ucst_frms;
- __le32 rmac_ttl_octets;
- __le32 rmac_discarded_frms;
- __le32 rmac_accepted_nucst_frms;
- __le32 reserved_1;
- __le32 rmac_drop_events;
- __le64 rmac_ttl_less_fb_octets;
- __le64 rmac_ttl_frms;
- __le64 reserved_2;
- __le32 rmac_usized_frms;
- __le32 reserved_3;
- __le32 rmac_frag_frms;
- __le32 rmac_osized_frms;
- __le32 reserved_4;
- __le32 rmac_jabber_frms;
- __le64 rmac_ttl_64_frms;
- __le64 rmac_ttl_65_127_frms;
- __le64 reserved_5;
- __le64 rmac_ttl_128_255_frms;
- __le64 rmac_ttl_256_511_frms;
- __le64 reserved_6;
- __le64 rmac_ttl_512_1023_frms;
- __le64 rmac_ttl_1024_1518_frms;
- __le32 rmac_ip;
- __le32 reserved_7;
- __le64 rmac_ip_octets;
- __le32 rmac_drop_ip;
- __le32 rmac_hdr_err_ip;
- __le32 reserved_8;
- __le32 rmac_icmp;
- __le64 rmac_tcp;
- __le32 rmac_err_drp_udp;
- __le32 rmac_udp;
- __le64 rmac_xgmii_err_sym;
- __le64 rmac_frms_q0;
- __le64 rmac_frms_q1;
- __le64 rmac_frms_q2;
- __le64 rmac_frms_q3;
- __le64 rmac_frms_q4;
- __le64 rmac_frms_q5;
- __le64 rmac_frms_q6;
- __le64 rmac_frms_q7;
- __le16 rmac_full_q3;
- __le16 rmac_full_q2;
- __le16 rmac_full_q1;
- __le16 rmac_full_q0;
- __le16 rmac_full_q7;
- __le16 rmac_full_q6;
- __le16 rmac_full_q5;
- __le16 rmac_full_q4;
- __le32 reserved_9;
- __le32 rmac_pause_cnt;
- __le64 rmac_xgmii_data_err_cnt;
- __le64 rmac_xgmii_ctrl_err_cnt;
- __le32 rmac_err_tcp;
- __le32 rmac_accepted_ip;
-
-/* PCI/PCI-X Read transaction statistics. */
- __le32 new_rd_req_cnt;
- __le32 rd_req_cnt;
- __le32 rd_rtry_cnt;
- __le32 new_rd_req_rtry_cnt;
-
-/* PCI/PCI-X Write/Read transaction statistics. */
- __le32 wr_req_cnt;
- __le32 wr_rtry_rd_ack_cnt;
- __le32 new_wr_req_rtry_cnt;
- __le32 new_wr_req_cnt;
- __le32 wr_disc_cnt;
- __le32 wr_rtry_cnt;
-
-/* PCI/PCI-X Write / DMA Transaction statistics. */
- __le32 txp_wr_cnt;
- __le32 rd_rtry_wr_ack_cnt;
- __le32 txd_wr_cnt;
- __le32 txd_rd_cnt;
- __le32 rxd_wr_cnt;
- __le32 rxd_rd_cnt;
- __le32 rxf_wr_cnt;
- __le32 txf_rd_cnt;
-
-/* Tx MAC statistics overflow counters. */
- __le32 tmac_data_octets_oflow;
- __le32 tmac_frms_oflow;
- __le32 tmac_bcst_frms_oflow;
- __le32 tmac_mcst_frms_oflow;
- __le32 tmac_ucst_frms_oflow;
- __le32 tmac_ttl_octets_oflow;
- __le32 tmac_any_err_frms_oflow;
- __le32 tmac_nucst_frms_oflow;
- __le64 tmac_vlan_frms;
- __le32 tmac_drop_ip_oflow;
- __le32 tmac_vld_ip_oflow;
- __le32 tmac_rst_tcp_oflow;
- __le32 tmac_icmp_oflow;
- __le32 tpa_unknown_protocol;
- __le32 tmac_udp_oflow;
- __le32 reserved_10;
- __le32 tpa_parse_failure;
-
-/* Rx MAC Statistics overflow counters. */
- __le32 rmac_data_octets_oflow;
- __le32 rmac_vld_frms_oflow;
- __le32 rmac_vld_bcst_frms_oflow;
- __le32 rmac_vld_mcst_frms_oflow;
- __le32 rmac_accepted_ucst_frms_oflow;
- __le32 rmac_ttl_octets_oflow;
- __le32 rmac_discarded_frms_oflow;
- __le32 rmac_accepted_nucst_frms_oflow;
- __le32 rmac_usized_frms_oflow;
- __le32 rmac_drop_events_oflow;
- __le32 rmac_frag_frms_oflow;
- __le32 rmac_osized_frms_oflow;
- __le32 rmac_ip_oflow;
- __le32 rmac_jabber_frms_oflow;
- __le32 rmac_icmp_oflow;
- __le32 rmac_drop_ip_oflow;
- __le32 rmac_err_drp_udp_oflow;
- __le32 rmac_udp_oflow;
- __le32 reserved_11;
- __le32 rmac_pause_cnt_oflow;
- __le64 rmac_ttl_1519_4095_frms;
- __le64 rmac_ttl_4096_8191_frms;
- __le64 rmac_ttl_8192_max_frms;
- __le64 rmac_ttl_gt_max_frms;
- __le64 rmac_osized_alt_frms;
- __le64 rmac_jabber_alt_frms;
- __le64 rmac_gt_max_alt_frms;
- __le64 rmac_vlan_frms;
- __le32 rmac_len_discard;
- __le32 rmac_fcs_discard;
- __le32 rmac_pf_discard;
- __le32 rmac_da_discard;
- __le32 rmac_red_discard;
- __le32 rmac_rts_discard;
- __le32 reserved_12;
- __le32 rmac_ingm_full_discard;
- __le32 reserved_13;
- __le32 rmac_accepted_ip_oflow;
- __le32 reserved_14;
- __le32 link_fault_cnt;
- u8 buffer[20];
- struct swStat sw_stat;
- struct xpakStat xpak_stat;
-};
-
-/* Default value for 'vlan_strip_tag' configuration parameter */
-#define NO_STRIP_IN_PROMISC 2
-
-/*
- * Structures representing different init time configuration
- * parameters of the NIC.
- */
-
-#define MAX_TX_FIFOS 8
-#define MAX_RX_RINGS 8
-
-#define FIFO_DEFAULT_NUM 5
-#define FIFO_UDP_MAX_NUM 2 /* 0 - even, 1 -odd ports */
-#define FIFO_OTHER_MAX_NUM 1
-
-
-#define MAX_RX_DESC_1 (MAX_RX_RINGS * MAX_RX_BLOCKS_PER_RING * 128)
-#define MAX_RX_DESC_2 (MAX_RX_RINGS * MAX_RX_BLOCKS_PER_RING * 86)
-#define MAX_TX_DESC (MAX_AVAILABLE_TXDS)
-
-/* FIFO mappings for all possible number of fifos configured */
-static const int fifo_map[][MAX_TX_FIFOS] = {
- {0, 0, 0, 0, 0, 0, 0, 0},
- {0, 0, 0, 0, 1, 1, 1, 1},
- {0, 0, 0, 1, 1, 1, 2, 2},
- {0, 0, 1, 1, 2, 2, 3, 3},
- {0, 0, 1, 1, 2, 2, 3, 4},
- {0, 0, 1, 1, 2, 3, 4, 5},
- {0, 0, 1, 2, 3, 4, 5, 6},
- {0, 1, 2, 3, 4, 5, 6, 7},
-};
-
-static const u16 fifo_selector[MAX_TX_FIFOS] = {0, 1, 3, 3, 7, 7, 7, 7};
-
-/* Maintains Per FIFO related information. */
-struct tx_fifo_config {
-#define MAX_AVAILABLE_TXDS 8192
- u32 fifo_len; /* specifies len of FIFO up to 8192, ie no of TxDLs */
-/* Priority definition */
-#define TX_FIFO_PRI_0 0 /*Highest */
-#define TX_FIFO_PRI_1 1
-#define TX_FIFO_PRI_2 2
-#define TX_FIFO_PRI_3 3
-#define TX_FIFO_PRI_4 4
-#define TX_FIFO_PRI_5 5
-#define TX_FIFO_PRI_6 6
-#define TX_FIFO_PRI_7 7 /*lowest */
- u8 fifo_priority; /* specifies pointer level for FIFO */
- /* user should not set twos fifos with same pri */
- u8 f_no_snoop;
-#define NO_SNOOP_TXD 0x01
-#define NO_SNOOP_TXD_BUFFER 0x02
-};
-
-
-/* Maintains per Ring related information */
-struct rx_ring_config {
- u32 num_rxd; /*No of RxDs per Rx Ring */
-#define RX_RING_PRI_0 0 /* highest */
-#define RX_RING_PRI_1 1
-#define RX_RING_PRI_2 2
-#define RX_RING_PRI_3 3
-#define RX_RING_PRI_4 4
-#define RX_RING_PRI_5 5
-#define RX_RING_PRI_6 6
-#define RX_RING_PRI_7 7 /* lowest */
-
- u8 ring_priority; /*Specifies service priority of ring */
- /* OSM should not set any two rings with same priority */
- u8 ring_org; /*Organization of ring */
-#define RING_ORG_BUFF1 0x01
-#define RX_RING_ORG_BUFF3 0x03
-#define RX_RING_ORG_BUFF5 0x05
-
- u8 f_no_snoop;
-#define NO_SNOOP_RXD 0x01
-#define NO_SNOOP_RXD_BUFFER 0x02
-};
-
-/* This structure provides contains values of the tunable parameters
- * of the H/W
- */
-struct config_param {
-/* Tx Side */
- u32 tx_fifo_num; /*Number of Tx FIFOs */
-
- /* 0-No steering, 1-Priority steering, 2-Default fifo map */
-#define NO_STEERING 0
-#define TX_PRIORITY_STEERING 0x1
-#define TX_DEFAULT_STEERING 0x2
- u8 tx_steering_type;
-
- u8 fifo_mapping[MAX_TX_FIFOS];
- struct tx_fifo_config tx_cfg[MAX_TX_FIFOS]; /*Per-Tx FIFO config */
- u32 max_txds; /*Max no. of Tx buffer descriptor per TxDL */
- u64 tx_intr_type;
-#define INTA 0
-#define MSI_X 2
- u8 intr_type;
- u8 napi;
-
- /* Specifies if Tx Intr is UTILZ or PER_LIST type. */
-
-/* Rx Side */
- u32 rx_ring_num; /*Number of receive rings */
-#define MAX_RX_BLOCKS_PER_RING 150
-
- struct rx_ring_config rx_cfg[MAX_RX_RINGS]; /*Per-Rx Ring config */
-
-#define HEADER_ETHERNET_II_802_3_SIZE 14
-#define HEADER_802_2_SIZE 3
-#define HEADER_SNAP_SIZE 5
-#define HEADER_VLAN_SIZE 4
-
-#define MIN_MTU 46
-#define MAX_PYLD 1500
-#define MAX_MTU (MAX_PYLD+18)
-#define MAX_MTU_VLAN (MAX_PYLD+22)
-#define MAX_PYLD_JUMBO 9600
-#define MAX_MTU_JUMBO (MAX_PYLD_JUMBO+18)
-#define MAX_MTU_JUMBO_VLAN (MAX_PYLD_JUMBO+22)
- u16 bus_speed;
- int max_mc_addr; /* xena=64 herc=256 */
- int max_mac_addr; /* xena=16 herc=64 */
- int mc_start_offset; /* xena=16 herc=64 */
- u8 multiq;
-};
-
-/* Structure representing MAC Addrs */
-struct mac_addr {
- u8 mac_addr[ETH_ALEN];
-};
-
-/* Structure that represent every FIFO element in the BAR1
- * Address location.
- */
-struct TxFIFO_element {
- u64 TxDL_Pointer;
-
- u64 List_Control;
-#define TX_FIFO_LAST_TXD_NUM( val) vBIT(val,0,8)
-#define TX_FIFO_FIRST_LIST s2BIT(14)
-#define TX_FIFO_LAST_LIST s2BIT(15)
-#define TX_FIFO_FIRSTNLAST_LIST vBIT(3,14,2)
-#define TX_FIFO_SPECIAL_FUNC s2BIT(23)
-#define TX_FIFO_DS_NO_SNOOP s2BIT(31)
-#define TX_FIFO_BUFF_NO_SNOOP s2BIT(30)
-};
-
-/* Tx descriptor structure */
-struct TxD {
- u64 Control_1;
-/* bit mask */
-#define TXD_LIST_OWN_XENA s2BIT(7)
-#define TXD_T_CODE (s2BIT(12)|s2BIT(13)|s2BIT(14)|s2BIT(15))
-#define TXD_T_CODE_OK(val) (|(val & TXD_T_CODE))
-#define GET_TXD_T_CODE(val) ((val & TXD_T_CODE)<<12)
-#define TXD_GATHER_CODE (s2BIT(22) | s2BIT(23))
-#define TXD_GATHER_CODE_FIRST s2BIT(22)
-#define TXD_GATHER_CODE_LAST s2BIT(23)
-#define TXD_TCP_LSO_EN s2BIT(30)
-#define TXD_UDP_COF_EN s2BIT(31)
-#define TXD_UFO_EN s2BIT(31) | s2BIT(30)
-#define TXD_TCP_LSO_MSS(val) vBIT(val,34,14)
-#define TXD_UFO_MSS(val) vBIT(val,34,14)
-#define TXD_BUFFER0_SIZE(val) vBIT(val,48,16)
-
- u64 Control_2;
-#define TXD_TX_CKO_CONTROL (s2BIT(5)|s2BIT(6)|s2BIT(7))
-#define TXD_TX_CKO_IPV4_EN s2BIT(5)
-#define TXD_TX_CKO_TCP_EN s2BIT(6)
-#define TXD_TX_CKO_UDP_EN s2BIT(7)
-#define TXD_VLAN_ENABLE s2BIT(15)
-#define TXD_VLAN_TAG(val) vBIT(val,16,16)
-#define TXD_INT_NUMBER(val) vBIT(val,34,6)
-#define TXD_INT_TYPE_PER_LIST s2BIT(47)
-#define TXD_INT_TYPE_UTILZ s2BIT(46)
-#define TXD_SET_MARKER vBIT(0x6,0,4)
-
- u64 Buffer_Pointer;
- u64 Host_Control; /* reserved for host */
-};
-
-/* Structure to hold the phy and virt addr of every TxDL. */
-struct list_info_hold {
- dma_addr_t list_phy_addr;
- void *list_virt_addr;
-};
-
-/* Rx descriptor structure for 1 buffer mode */
-struct RxD_t {
- u64 Host_Control; /* reserved for host */
- u64 Control_1;
-#define RXD_OWN_XENA s2BIT(7)
-#define RXD_T_CODE (s2BIT(12)|s2BIT(13)|s2BIT(14)|s2BIT(15))
-#define RXD_FRAME_PROTO vBIT(0xFFFF,24,8)
-#define RXD_FRAME_VLAN_TAG s2BIT(24)
-#define RXD_FRAME_PROTO_IPV4 s2BIT(27)
-#define RXD_FRAME_PROTO_IPV6 s2BIT(28)
-#define RXD_FRAME_IP_FRAG s2BIT(29)
-#define RXD_FRAME_PROTO_TCP s2BIT(30)
-#define RXD_FRAME_PROTO_UDP s2BIT(31)
-#define TCP_OR_UDP_FRAME (RXD_FRAME_PROTO_TCP | RXD_FRAME_PROTO_UDP)
-#define RXD_GET_L3_CKSUM(val) ((u16)(val>> 16) & 0xFFFF)
-#define RXD_GET_L4_CKSUM(val) ((u16)(val) & 0xFFFF)
-
- u64 Control_2;
-#define THE_RXD_MARK 0x3
-#define SET_RXD_MARKER vBIT(THE_RXD_MARK, 0, 2)
-#define GET_RXD_MARKER(ctrl) ((ctrl & SET_RXD_MARKER) >> 62)
-
-#define MASK_VLAN_TAG vBIT(0xFFFF,48,16)
-#define SET_VLAN_TAG(val) vBIT(val,48,16)
-#define SET_NUM_TAG(val) vBIT(val,16,32)
-
-
-};
-/* Rx descriptor structure for 1 buffer mode */
-struct RxD1 {
- struct RxD_t h;
-
-#define MASK_BUFFER0_SIZE_1 vBIT(0x3FFF,2,14)
-#define SET_BUFFER0_SIZE_1(val) vBIT(val,2,14)
-#define RXD_GET_BUFFER0_SIZE_1(_Control_2) \
- (u16)((_Control_2 & MASK_BUFFER0_SIZE_1) >> 48)
- u64 Buffer0_ptr;
-};
-/* Rx descriptor structure for 3 or 2 buffer mode */
-
-struct RxD3 {
- struct RxD_t h;
-
-#define MASK_BUFFER0_SIZE_3 vBIT(0xFF,2,14)
-#define MASK_BUFFER1_SIZE_3 vBIT(0xFFFF,16,16)
-#define MASK_BUFFER2_SIZE_3 vBIT(0xFFFF,32,16)
-#define SET_BUFFER0_SIZE_3(val) vBIT(val,8,8)
-#define SET_BUFFER1_SIZE_3(val) vBIT(val,16,16)
-#define SET_BUFFER2_SIZE_3(val) vBIT(val,32,16)
-#define RXD_GET_BUFFER0_SIZE_3(Control_2) \
- (u8)((Control_2 & MASK_BUFFER0_SIZE_3) >> 48)
-#define RXD_GET_BUFFER1_SIZE_3(Control_2) \
- (u16)((Control_2 & MASK_BUFFER1_SIZE_3) >> 32)
-#define RXD_GET_BUFFER2_SIZE_3(Control_2) \
- (u16)((Control_2 & MASK_BUFFER2_SIZE_3) >> 16)
-#define BUF0_LEN 40
-#define BUF1_LEN 1
-
- u64 Buffer0_ptr;
- u64 Buffer1_ptr;
- u64 Buffer2_ptr;
-};
-
-
-/* Structure that represents the Rx descriptor block which contains
- * 128 Rx descriptors.
- */
-struct RxD_block {
-#define MAX_RXDS_PER_BLOCK_1 127
- struct RxD1 rxd[MAX_RXDS_PER_BLOCK_1];
-
- u64 reserved_0;
-#define END_OF_BLOCK 0xFEFFFFFFFFFFFFFFULL
- u64 reserved_1; /* 0xFEFFFFFFFFFFFFFF to mark last
- * Rxd in this blk */
- u64 reserved_2_pNext_RxD_block; /* Logical ptr to next */
- u64 pNext_RxD_Blk_physical; /* Buff0_ptr.In a 32 bit arch
- * the upper 32 bits should
- * be 0 */
-};
-
-#define SIZE_OF_BLOCK 4096
-
-#define RXD_MODE_1 0 /* One Buffer mode */
-#define RXD_MODE_3B 1 /* Two Buffer mode */
-
-/* Structure to hold virtual addresses of Buf0 and Buf1 in
- * 2buf mode. */
-struct buffAdd {
- void *ba_0_org;
- void *ba_1_org;
- void *ba_0;
- void *ba_1;
-};
-
-/* Structure which stores all the MAC control parameters */
-
-/* This structure stores the offset of the RxD in the ring
- * from which the Rx Interrupt processor can start picking
- * up the RxDs for processing.
- */
-struct rx_curr_get_info {
- u32 block_index;
- u32 offset;
- u32 ring_len;
-};
-
-struct rx_curr_put_info {
- u32 block_index;
- u32 offset;
- u32 ring_len;
-};
-
-/* This structure stores the offset of the TxDl in the FIFO
- * from which the Tx Interrupt processor can start picking
- * up the TxDLs for send complete interrupt processing.
- */
-struct tx_curr_get_info {
- u32 offset;
- u32 fifo_len;
-};
-
-struct tx_curr_put_info {
- u32 offset;
- u32 fifo_len;
-};
-
-struct rxd_info {
- void *virt_addr;
- dma_addr_t dma_addr;
-};
-
-/* Structure that holds the Phy and virt addresses of the Blocks */
-struct rx_block_info {
- void *block_virt_addr;
- dma_addr_t block_dma_addr;
- struct rxd_info *rxds;
-};
-
-/* Data structure to represent a LRO session */
-struct lro {
- struct sk_buff *parent;
- struct sk_buff *last_frag;
- u8 *l2h;
- struct iphdr *iph;
- struct tcphdr *tcph;
- u32 tcp_next_seq;
- __be32 tcp_ack;
- int total_len;
- int frags_len;
- int sg_num;
- int in_use;
- __be16 window;
- u16 vlan_tag;
- u32 cur_tsval;
- __be32 cur_tsecr;
- u8 saw_ts;
-} ____cacheline_aligned;
-
-/* Ring specific structure */
-struct ring_info {
- /* The ring number */
- int ring_no;
-
- /* per-ring buffer counter */
- u32 rx_bufs_left;
-
-#define MAX_LRO_SESSIONS 32
- struct lro lro0_n[MAX_LRO_SESSIONS];
- u8 lro;
-
- /* copy of sp->rxd_mode flag */
- int rxd_mode;
-
- /* Number of rxds per block for the rxd_mode */
- int rxd_count;
-
- /* copy of sp pointer */
- struct s2io_nic *nic;
-
- /* copy of sp->dev pointer */
- struct net_device *dev;
-
- /* copy of sp->pdev pointer */
- struct pci_dev *pdev;
-
- /* Per ring napi struct */
- struct napi_struct napi;
-
- unsigned long interrupt_count;
-
- /*
- * Place holders for the virtual and physical addresses of
- * all the Rx Blocks
- */
- struct rx_block_info rx_blocks[MAX_RX_BLOCKS_PER_RING];
- int block_count;
- int pkt_cnt;
-
- /*
- * Put pointer info which indictes which RxD has to be replenished
- * with a new buffer.
- */
- struct rx_curr_put_info rx_curr_put_info;
-
- /*
- * Get pointer info which indictes which is the last RxD that was
- * processed by the driver.
- */
- struct rx_curr_get_info rx_curr_get_info;
-
- /* interface MTU value */
- unsigned mtu;
-
- /* Buffer Address store. */
- struct buffAdd **ba;
-} ____cacheline_aligned;
-
-/* Fifo specific structure */
-struct fifo_info {
- /* FIFO number */
- int fifo_no;
-
- /* Maximum TxDs per TxDL */
- int max_txds;
-
- /* Place holder of all the TX List's Phy and Virt addresses. */
- struct list_info_hold *list_info;
-
- /*
- * Current offset within the tx FIFO where driver would write
- * new Tx frame
- */
- struct tx_curr_put_info tx_curr_put_info;
-
- /*
- * Current offset within tx FIFO from where the driver would start freeing
- * the buffers
- */
- struct tx_curr_get_info tx_curr_get_info;
-#define FIFO_QUEUE_START 0
-#define FIFO_QUEUE_STOP 1
- int queue_state;
-
- /* copy of sp->dev pointer */
- struct net_device *dev;
-
- /* copy of multiq status */
- u8 multiq;
-
- /* Per fifo lock */
- spinlock_t tx_lock;
-
- /* Per fifo UFO in band structure */
- u64 *ufo_in_band_v;
-
- struct s2io_nic *nic;
-} ____cacheline_aligned;
-
-/* Information related to the Tx and Rx FIFOs and Rings of Xena
- * is maintained in this structure.
- */
-struct mac_info {
-/* tx side stuff */
- /* logical pointer of start of each Tx FIFO */
- struct TxFIFO_element __iomem *tx_FIFO_start[MAX_TX_FIFOS];
-
- /* Fifo specific structure */
- struct fifo_info fifos[MAX_TX_FIFOS];
-
- /* Save virtual address of TxD page with zero DMA addr(if any) */
- void *zerodma_virt_addr;
-
-/* rx side stuff */
- /* Ring specific structure */
- struct ring_info rings[MAX_RX_RINGS];
-
- u16 rmac_pause_time;
- u16 mc_pause_threshold_q0q3;
- u16 mc_pause_threshold_q4q7;
-
- void *stats_mem; /* orignal pointer to allocated mem */
- dma_addr_t stats_mem_phy; /* Physical address of the stat block */
- u32 stats_mem_sz;
- struct stat_block *stats_info; /* Logical address of the stat block */
-};
-
-/* Default Tunable parameters of the NIC. */
-#define DEFAULT_FIFO_0_LEN 4096
-#define DEFAULT_FIFO_1_7_LEN 512
-#define SMALL_BLK_CNT 30
-#define LARGE_BLK_CNT 100
-
-/*
- * Structure to keep track of the MSI-X vectors and the corresponding
- * argument registered against each vector
- */
-#define MAX_REQUESTED_MSI_X 9
-struct s2io_msix_entry
-{
- u16 vector;
- u16 entry;
- void *arg;
-
- u8 type;
-#define MSIX_ALARM_TYPE 1
-#define MSIX_RING_TYPE 2
-
- u8 in_use;
-#define MSIX_REGISTERED_SUCCESS 0xAA
-};
-
-struct msix_info_st {
- u64 addr;
- u64 data;
-};
-
-/* These flags represent the devices temporary state */
-enum s2io_device_state_t
-{
- __S2IO_STATE_LINK_TASK=0,
- __S2IO_STATE_CARD_UP
-};
-
-/* Structure representing one instance of the NIC */
-struct s2io_nic {
- int rxd_mode;
- /*
- * Count of packets to be processed in a given iteration, it will be indicated
- * by the quota field of the device structure when NAPI is enabled.
- */
- int pkts_to_process;
- struct net_device *dev;
- struct mac_info mac_control;
- struct config_param config;
- struct pci_dev *pdev;
- void __iomem *bar0;
- void __iomem *bar1;
-#define MAX_MAC_SUPPORTED 16
-#define MAX_SUPPORTED_MULTICASTS MAX_MAC_SUPPORTED
-
- struct mac_addr def_mac_addr[256];
-
- struct net_device_stats stats;
- int device_enabled_once;
-
- char name[60];
-
- /* Timer that handles I/O errors/exceptions */
- struct timer_list alarm_timer;
-
- /* Space to back up the PCI config space */
- u32 config_space[256 / sizeof(u32)];
-
-#define PROMISC 1
-#define ALL_MULTI 2
-
-#define MAX_ADDRS_SUPPORTED 64
- u16 mc_addr_count;
-
- u16 m_cast_flg;
- u16 all_multi_pos;
- u16 promisc_flg;
-
- /* Restart timer, used to restart NIC if the device is stuck and
- * a schedule task that will set the correct Link state once the
- * NIC's PHY has stabilized after a state change.
- */
- struct work_struct rst_timer_task;
- struct work_struct set_link_task;
-
- /* Flag that can be used to turn on or turn off the Rx checksum
- * offload feature.
- */
- int rx_csum;
-
- /* Below variables are used for fifo selection to transmit a packet */
- u16 fifo_selector[MAX_TX_FIFOS];
-
- /* Total fifos for tcp packets */
- u8 total_tcp_fifos;
-
- /*
- * Beginning index of udp for udp packets
- * Value will be equal to
- * (tx_fifo_num - FIFO_UDP_MAX_NUM - FIFO_OTHER_MAX_NUM)
- */
- u8 udp_fifo_idx;
-
- u8 total_udp_fifos;
-
- /*
- * Beginning index of fifo for all other packets
- * Value will be equal to (tx_fifo_num - FIFO_OTHER_MAX_NUM)
- */
- u8 other_fifo_idx;
-
- struct napi_struct napi;
- /* after blink, the adapter must be restored with original
- * values.
- */
- u64 adapt_ctrl_org;
-
- /* Last known link state. */
- u16 last_link_state;
-#define LINK_DOWN 1
-#define LINK_UP 2
-
- int task_flag;
- unsigned long long start_time;
- int vlan_strip_flag;
-#define MSIX_FLG 0xA5
- int num_entries;
- struct msix_entry *entries;
- int msi_detected;
- wait_queue_head_t msi_wait;
- struct s2io_msix_entry *s2io_entries;
- char desc[MAX_REQUESTED_MSI_X][25];
-
- int avail_msix_vectors; /* No. of MSI-X vectors granted by system */
-
- struct msix_info_st msix_info[0x3f];
-
-#define XFRAME_I_DEVICE 1
-#define XFRAME_II_DEVICE 2
- u8 device_type;
-
- unsigned long clubbed_frms_cnt;
- unsigned long sending_both;
- u16 lro_max_aggr_per_sess;
- volatile unsigned long state;
- u64 general_int_mask;
-
-#define VPD_STRING_LEN 80
- u8 product_name[VPD_STRING_LEN];
- u8 serial_num[VPD_STRING_LEN];
-};
-
-#define RESET_ERROR 1
-#define CMD_ERROR 2
-
-/*
- * Some registers have to be written in a particular order to
- * expect correct hardware operation. The macro SPECIAL_REG_WRITE
- * is used to perform such ordered writes. Defines UF (Upper First)
- * and LF (Lower First) will be used to specify the required write order.
- */
-#define UF 1
-#define LF 2
-static inline void SPECIAL_REG_WRITE(u64 val, void __iomem *addr, int order)
-{
- if (order == LF) {
- writel((u32) (val), addr);
- (void) readl(addr);
- writel((u32) (val >> 32), (addr + 4));
- (void) readl(addr + 4);
- } else {
- writel((u32) (val >> 32), (addr + 4));
- (void) readl(addr + 4);
- writel((u32) (val), addr);
- (void) readl(addr);
- }
-}
-
-/* Interrupt related values of Xena */
-
-#define ENABLE_INTRS 1
-#define DISABLE_INTRS 2
-
-/* Highest level interrupt blocks */
-#define TX_PIC_INTR (0x0001<<0)
-#define TX_DMA_INTR (0x0001<<1)
-#define TX_MAC_INTR (0x0001<<2)
-#define TX_XGXS_INTR (0x0001<<3)
-#define TX_TRAFFIC_INTR (0x0001<<4)
-#define RX_PIC_INTR (0x0001<<5)
-#define RX_DMA_INTR (0x0001<<6)
-#define RX_MAC_INTR (0x0001<<7)
-#define RX_XGXS_INTR (0x0001<<8)
-#define RX_TRAFFIC_INTR (0x0001<<9)
-#define MC_INTR (0x0001<<10)
-#define ENA_ALL_INTRS ( TX_PIC_INTR | \
- TX_DMA_INTR | \
- TX_MAC_INTR | \
- TX_XGXS_INTR | \
- TX_TRAFFIC_INTR | \
- RX_PIC_INTR | \
- RX_DMA_INTR | \
- RX_MAC_INTR | \
- RX_XGXS_INTR | \
- RX_TRAFFIC_INTR | \
- MC_INTR )
-
-/* Interrupt masks for the general interrupt mask register */
-#define DISABLE_ALL_INTRS 0xFFFFFFFFFFFFFFFFULL
-
-#define TXPIC_INT_M s2BIT(0)
-#define TXDMA_INT_M s2BIT(1)
-#define TXMAC_INT_M s2BIT(2)
-#define TXXGXS_INT_M s2BIT(3)
-#define TXTRAFFIC_INT_M s2BIT(8)
-#define PIC_RX_INT_M s2BIT(32)
-#define RXDMA_INT_M s2BIT(33)
-#define RXMAC_INT_M s2BIT(34)
-#define MC_INT_M s2BIT(35)
-#define RXXGXS_INT_M s2BIT(36)
-#define RXTRAFFIC_INT_M s2BIT(40)
-
-/* PIC level Interrupts TODO*/
-
-/* DMA level Inressupts */
-#define TXDMA_PFC_INT_M s2BIT(0)
-#define TXDMA_PCC_INT_M s2BIT(2)
-
-/* PFC block interrupts */
-#define PFC_MISC_ERR_1 s2BIT(0) /* Interrupt to indicate FIFO full */
-
-/* PCC block interrupts. */
-#define PCC_FB_ECC_ERR vBIT(0xff, 16, 8) /* Interrupt to indicate
- PCC_FB_ECC Error. */
-
-#define RXD_GET_VLAN_TAG(Control_2) (u16)(Control_2 & MASK_VLAN_TAG)
-/*
- * Prototype declaration.
- */
-static int s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre);
-static void s2io_rem_nic(struct pci_dev *pdev);
-static int init_shared_mem(struct s2io_nic *sp);
-static void free_shared_mem(struct s2io_nic *sp);
-static int init_nic(struct s2io_nic *nic);
-static int rx_intr_handler(struct ring_info *ring_data, int budget);
-static void s2io_txpic_intr_handle(struct s2io_nic *sp);
-static void tx_intr_handler(struct fifo_info *fifo_data);
-static void s2io_handle_errors(void * dev_id);
-
-static void s2io_tx_watchdog(struct net_device *dev, unsigned int txqueue);
-static void s2io_set_multicast(struct net_device *dev, bool may_sleep);
-static int rx_osm_handler(struct ring_info *ring_data, struct RxD_t * rxdp);
-static void s2io_link(struct s2io_nic * sp, int link);
-static void s2io_reset(struct s2io_nic * sp);
-static int s2io_poll_msix(struct napi_struct *napi, int budget);
-static int s2io_poll_inta(struct napi_struct *napi, int budget);
-static void s2io_init_pci(struct s2io_nic * sp);
-static int do_s2io_prog_unicast(struct net_device *dev, const u8 *addr);
-static void s2io_alarm_handle(struct timer_list *t);
-static irqreturn_t
-s2io_msix_ring_handle(int irq, void *dev_id);
-static irqreturn_t
-s2io_msix_fifo_handle(int irq, void *dev_id);
-static irqreturn_t s2io_isr(int irq, void *dev_id);
-static int verify_xena_quiescence(struct s2io_nic *sp);
-static const struct ethtool_ops netdev_ethtool_ops;
-static void s2io_set_link(struct work_struct *work);
-static int s2io_set_swapper(struct s2io_nic * sp);
-static void s2io_card_down(struct s2io_nic *nic);
-static int s2io_card_up(struct s2io_nic *nic);
-static int wait_for_cmd_complete(void __iomem *addr, u64 busy_bit,
- int bit_state, bool may_sleep);
-static int s2io_add_isr(struct s2io_nic * sp);
-static void s2io_rem_isr(struct s2io_nic * sp);
-
-static void restore_xmsi_data(struct s2io_nic *nic);
-static void do_s2io_store_unicast_mc(struct s2io_nic *sp);
-static void do_s2io_restore_unicast_mc(struct s2io_nic *sp);
-static u64 do_s2io_read_unicast_mc(struct s2io_nic *sp, int offset);
-static int do_s2io_add_mc(struct s2io_nic *sp, u8 *addr);
-static int do_s2io_add_mac(struct s2io_nic *sp, u64 addr, int offset);
-static int do_s2io_delete_unicast_mc(struct s2io_nic *sp, u64 addr);
-
-static int s2io_club_tcp_session(struct ring_info *ring_data, u8 *buffer,
- u8 **tcp, u32 *tcp_len, struct lro **lro, struct RxD_t *rxdp,
- struct s2io_nic *sp);
-static void clear_lro_session(struct lro *lro);
-static void queue_rx_frame(struct sk_buff *skb, u16 vlan_tag);
-static void update_L3L4_header(struct s2io_nic *sp, struct lro *lro);
-static void lro_append_pkt(struct s2io_nic *sp, struct lro *lro,
- struct sk_buff *skb, u32 tcp_len);
-static int rts_ds_steer(struct s2io_nic *nic, u8 ds_codepoint, u8 ring);
-
-static pci_ers_result_t s2io_io_error_detected(struct pci_dev *pdev,
- pci_channel_state_t state);
-static pci_ers_result_t s2io_io_slot_reset(struct pci_dev *pdev);
-static void s2io_io_resume(struct pci_dev *pdev);
-
-#define s2io_tcp_mss(skb) skb_shinfo(skb)->gso_size
-#define s2io_udp_mss(skb) skb_shinfo(skb)->gso_size
-#define s2io_offload_type(skb) skb_shinfo(skb)->gso_type
-
-#define S2IO_PARM_INT(X, def_val) \
- static unsigned int X = def_val;\
- module_param(X , uint, 0);
-
-#endif /* _S2IO_H */
diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h
index 91704f20d7da..25aecf5b3671 100644
--- a/include/linux/pci_ids.h
+++ b/include/linux/pci_ids.h
@@ -2445,12 +2445,6 @@
#define PCI_DEVICE_ID_ARECA_1680 0x1680
#define PCI_DEVICE_ID_ARECA_1681 0x1681
-#define PCI_VENDOR_ID_S2IO 0x17d5
-#define PCI_DEVICE_ID_S2IO_WIN 0x5731
-#define PCI_DEVICE_ID_S2IO_UNI 0x5831
-#define PCI_DEVICE_ID_HERC_WIN 0x5732
-#define PCI_DEVICE_ID_HERC_UNI 0x5832
-
#define PCI_VENDOR_ID_SITECOM 0x182d
#define PCI_DEVICE_ID_SITECOM_DC105V2 0x3069
diff --git a/rust/kernel/pci/id.rs b/rust/kernel/pci/id.rs
index 42ffb1bbf87c..9cc8952ba4fd 100644
--- a/rust/kernel/pci/id.rs
+++ b/rust/kernel/pci/id.rs
@@ -513,7 +513,6 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
QCOM = bindings::PCI_VENDOR_ID_QCOM, // 0x17cb
CDNS = bindings::PCI_VENDOR_ID_CDNS, // 0x17cd
ARECA = bindings::PCI_VENDOR_ID_ARECA, // 0x17d3
- S2IO = bindings::PCI_VENDOR_ID_S2IO, // 0x17d5
SITECOM = bindings::PCI_VENDOR_ID_SITECOM, // 0x182d
TOPSPIN = bindings::PCI_VENDOR_ID_TOPSPIN, // 0x1867
COMMTECH = bindings::PCI_VENDOR_ID_COMMTECH, // 0x18f7
--
2.43.0
Powered by blists - more mailing lists