forked from Minki/linux
Merge branch 'davem-next' of master.kernel.org:/pub/scm/linux/kernel/git/jgarzik/netdev-2.6
This commit is contained in:
commit
925068dcdc
@ -1,7 +1,7 @@
|
||||
Linux* Base Driver for the Intel(R) PRO/10GbE Family of Adapters
|
||||
================================================================
|
||||
Linux Base Driver for 10 Gigabit Intel(R) Network Connection
|
||||
=============================================================
|
||||
|
||||
November 17, 2004
|
||||
October 9, 2007
|
||||
|
||||
|
||||
Contents
|
||||
@ -9,65 +9,122 @@ Contents
|
||||
|
||||
- In This Release
|
||||
- Identifying Your Adapter
|
||||
- Building and Installation
|
||||
- Command Line Parameters
|
||||
- Improving Performance
|
||||
- Additional Configurations
|
||||
- Known Issues/Troubleshooting
|
||||
- Support
|
||||
|
||||
|
||||
|
||||
In This Release
|
||||
===============
|
||||
|
||||
This file describes the Linux* Base Driver for the Intel(R) PRO/10GbE Family
|
||||
of Adapters, version 1.0.x.
|
||||
This file describes the ixgb Linux Base Driver for the 10 Gigabit Intel(R)
|
||||
Network Connection. This driver includes support for Itanium(R)2-based
|
||||
systems.
|
||||
|
||||
For questions related to hardware requirements, refer to the documentation
|
||||
supplied with your Intel PRO/10GbE adapter. All hardware requirements listed
|
||||
apply to use with Linux.
|
||||
supplied with your 10 Gigabit adapter. All hardware requirements listed apply
|
||||
to use with Linux.
|
||||
|
||||
The following features are available in this kernel:
|
||||
- Native VLANs
|
||||
- Channel Bonding (teaming)
|
||||
- SNMP
|
||||
|
||||
Channel Bonding documentation can be found in the Linux kernel source:
|
||||
/Documentation/networking/bonding.txt
|
||||
|
||||
The driver information previously displayed in the /proc filesystem is not
|
||||
supported in this release. Alternatively, you can use ethtool (version 1.6
|
||||
or later), lspci, and ifconfig to obtain the same information.
|
||||
|
||||
Instructions on updating ethtool can be found in the section "Additional
|
||||
Configurations" later in this document.
|
||||
|
||||
|
||||
Identifying Your Adapter
|
||||
========================
|
||||
|
||||
To verify your Intel adapter is supported, find the board ID number on the
|
||||
adapter. Look for a label that has a barcode and a number in the format
|
||||
A12345-001.
|
||||
The following Intel network adapters are compatible with the drivers in this
|
||||
release:
|
||||
|
||||
Use the above information and the Adapter & Driver ID Guide at:
|
||||
Controller Adapter Name Physical Layer
|
||||
---------- ------------ --------------
|
||||
82597EX Intel(R) PRO/10GbE LR/SR/CX4 10G Base-LR (1310 nm optical fiber)
|
||||
Server Adapters 10G Base-SR (850 nm optical fiber)
|
||||
10G Base-CX4(twin-axial copper cabling)
|
||||
|
||||
http://support.intel.com/support/network/adapter/pro100/21397.htm
|
||||
For more information on how to identify your adapter, go to the Adapter &
|
||||
Driver ID Guide at:
|
||||
|
||||
For the latest Intel network drivers for Linux, go to:
|
||||
http://support.intel.com/support/network/sb/CS-012904.htm
|
||||
|
||||
|
||||
Building and Installation
|
||||
=========================
|
||||
|
||||
select m for "Intel(R) PRO/10GbE support" located at:
|
||||
Location:
|
||||
-> Device Drivers
|
||||
-> Network device support (NETDEVICES [=y])
|
||||
-> Ethernet (10000 Mbit) (NETDEV_10000 [=y])
|
||||
1. make modules && make modules_install
|
||||
|
||||
2. Load the module:
|
||||
|
||||
modprobe ixgb <parameter>=<value>
|
||||
|
||||
The insmod command can be used if the full
|
||||
path to the driver module is specified. For example:
|
||||
|
||||
insmod /lib/modules/<KERNEL VERSION>/kernel/drivers/net/ixgb/ixgb.ko
|
||||
|
||||
With 2.6 based kernels also make sure that older ixgb drivers are
|
||||
removed from the kernel, before loading the new module:
|
||||
|
||||
rmmod ixgb; modprobe ixgb
|
||||
|
||||
3. Assign an IP address to the interface by entering the following, where
|
||||
x is the interface number:
|
||||
|
||||
ifconfig ethx <IP_address>
|
||||
|
||||
4. Verify that the interface works. Enter the following, where <IP_address>
|
||||
is the IP address for another machine on the same subnet as the interface
|
||||
that is being tested:
|
||||
|
||||
ping <IP_address>
|
||||
|
||||
http://downloadfinder.intel.com/scripts-df/support_intel.asp
|
||||
|
||||
Command Line Parameters
|
||||
=======================
|
||||
|
||||
If the driver is built as a module, the following optional parameters are
|
||||
used by entering them on the command line with the modprobe or insmod command
|
||||
using this syntax:
|
||||
used by entering them on the command line with the modprobe command using
|
||||
this syntax:
|
||||
|
||||
modprobe ixgb [<option>=<VAL1>,<VAL2>,...]
|
||||
|
||||
insmod ixgb [<option>=<VAL1>,<VAL2>,...]
|
||||
For example, with two 10GbE PCI adapters, entering:
|
||||
|
||||
For example, with two PRO/10GbE PCI adapters, entering:
|
||||
|
||||
insmod ixgb TxDescriptors=80,128
|
||||
modprobe ixgb TxDescriptors=80,128
|
||||
|
||||
loads the ixgb driver with 80 TX resources for the first adapter and 128 TX
|
||||
resources for the second adapter.
|
||||
|
||||
The default value for each parameter is generally the recommended setting,
|
||||
unless otherwise noted. Also, if the driver is statically built into the
|
||||
kernel, the driver is loaded with the default values for all the parameters.
|
||||
Ethtool can be used to change some of the parameters at runtime.
|
||||
unless otherwise noted.
|
||||
|
||||
FlowControl
|
||||
Valid Range: 0-3 (0=none, 1=Rx only, 2=Tx only, 3=Rx&Tx)
|
||||
Default: Read from the EEPROM
|
||||
If EEPROM is not detected, default is 3
|
||||
If EEPROM is not detected, default is 1
|
||||
This parameter controls the automatic generation(Tx) and response(Rx) to
|
||||
Ethernet PAUSE frames.
|
||||
Ethernet PAUSE frames. There are hardware bugs associated with enabling
|
||||
Tx flow control so beware.
|
||||
|
||||
RxDescriptors
|
||||
Valid Range: 64-512
|
||||
@ -83,7 +140,7 @@ Default Value: 512
|
||||
|
||||
RxIntDelay
|
||||
Valid Range: 0-65535 (0=off)
|
||||
Default Value: 6
|
||||
Default Value: 72
|
||||
This value delays the generation of receive interrupts in units of
|
||||
0.8192 microseconds. Receive interrupt reduction can improve CPU
|
||||
efficiency if properly tuned for specific network traffic. Increasing
|
||||
@ -105,22 +162,16 @@ Default Value: 1
|
||||
A value of '1' indicates that the driver should enable IP checksum
|
||||
offload for received packets (both UDP and TCP) to the adapter hardware.
|
||||
|
||||
XsumTX
|
||||
Valid Range: 0-1
|
||||
Default Value: 1
|
||||
A value of '1' indicates that the driver should enable IP checksum
|
||||
offload for transmitted packets (both UDP and TCP) to the adapter
|
||||
hardware.
|
||||
|
||||
Improving Performance
|
||||
=====================
|
||||
|
||||
With the Intel PRO/10 GbE adapter, the default Linux configuration will very
|
||||
likely limit the total available throughput artificially. There is a set of
|
||||
things that when applied together increase the ability of Linux to transmit
|
||||
and receive data. The following enhancements were originally acquired from
|
||||
settings published at http://www.spec.org/web99 for various submitted results
|
||||
using Linux.
|
||||
With the 10 Gigabit server adapters, the default Linux configuration will
|
||||
very likely limit the total available throughput artificially. There is a set
|
||||
of configuration changes that, when applied together, will increase the ability
|
||||
of Linux to transmit and receive data. The following enhancements were
|
||||
originally acquired from settings published at http://www.spec.org/web99/ for
|
||||
various submitted results using Linux.
|
||||
|
||||
NOTE: These changes are only suggestions, and serve as a starting point for
|
||||
tuning your network performance.
|
||||
@ -134,17 +185,21 @@ The changes are made in three major ways, listed in order of greatest effect:
|
||||
|
||||
NOTE: setpci modifies the adapter's configuration registers to allow it to read
|
||||
up to 4k bytes at a time (for transmits). However, for some systems the
|
||||
behavior after modifying this register may be undefined (possibly errors of some
|
||||
kind). A power-cycle, hard reset or explicitly setting the e6 register back to
|
||||
22 (setpci -d 8086:1048 e6.b=22) may be required to get back to a stable
|
||||
configuration.
|
||||
behavior after modifying this register may be undefined (possibly errors of
|
||||
some kind). A power-cycle, hard reset or explicitly setting the e6 register
|
||||
back to 22 (setpci -d 8086:1a48 e6.b=22) may be required to get back to a
|
||||
stable configuration.
|
||||
|
||||
- COPY these lines and paste them into ixgb_perf.sh:
|
||||
#!/bin/bash
|
||||
echo "configuring network performance , edit this file to change the interface"
|
||||
echo "configuring network performance , edit this file to change the interface
|
||||
or device ID of 10GbE card"
|
||||
# set mmrbc to 4k reads, modify only Intel 10GbE device IDs
|
||||
setpci -d 8086:1048 e6.b=2e
|
||||
# set the MTU (max transmission unit) - it requires your switch and clients to change too!
|
||||
# replace 1a48 with appropriate 10GbE device's ID installed on the system,
|
||||
# if needed.
|
||||
setpci -d 8086:1a48 e6.b=2e
|
||||
# set the MTU (max transmission unit) - it requires your switch and clients
|
||||
# to change as well.
|
||||
# set the txqueuelen
|
||||
# your ixgb adapter should be loaded as eth1 for this to work, change if needed
|
||||
ifconfig eth1 mtu 9000 txqueuelen 1000 up
|
||||
@ -159,24 +214,36 @@ sysctl -p ./sysctl_ixgb.conf
|
||||
# several network benchmark tests, your mileage may vary
|
||||
|
||||
### IPV4 specific settings
|
||||
net.ipv4.tcp_timestamps = 0 # turns TCP timestamp support off, default 1, reduces CPU use
|
||||
net.ipv4.tcp_sack = 0 # turn SACK support off, default on
|
||||
# turn TCP timestamp support off, default 1, reduces CPU use
|
||||
net.ipv4.tcp_timestamps = 0
|
||||
# turn SACK support off, default on
|
||||
# on systems with a VERY fast bus -> memory interface this is the big gainer
|
||||
net.ipv4.tcp_rmem = 10000000 10000000 10000000 # sets min/default/max TCP read buffer, default 4096 87380 174760
|
||||
net.ipv4.tcp_wmem = 10000000 10000000 10000000 # sets min/pressure/max TCP write buffer, default 4096 16384 131072
|
||||
net.ipv4.tcp_mem = 10000000 10000000 10000000 # sets min/pressure/max TCP buffer space, default 31744 32256 32768
|
||||
net.ipv4.tcp_sack = 0
|
||||
# set min/default/max TCP read buffer, default 4096 87380 174760
|
||||
net.ipv4.tcp_rmem = 10000000 10000000 10000000
|
||||
# set min/pressure/max TCP write buffer, default 4096 16384 131072
|
||||
net.ipv4.tcp_wmem = 10000000 10000000 10000000
|
||||
# set min/pressure/max TCP buffer space, default 31744 32256 32768
|
||||
net.ipv4.tcp_mem = 10000000 10000000 10000000
|
||||
|
||||
### CORE settings (mostly for socket and UDP effect)
|
||||
net.core.rmem_max = 524287 # maximum receive socket buffer size, default 131071
|
||||
net.core.wmem_max = 524287 # maximum send socket buffer size, default 131071
|
||||
net.core.rmem_default = 524287 # default receive socket buffer size, default 65535
|
||||
net.core.wmem_default = 524287 # default send socket buffer size, default 65535
|
||||
net.core.optmem_max = 524287 # maximum amount of option memory buffers, default 10240
|
||||
net.core.netdev_max_backlog = 300000 # number of unprocessed input packets before kernel starts dropping them, default 300
|
||||
# set maximum receive socket buffer size, default 131071
|
||||
net.core.rmem_max = 524287
|
||||
# set maximum send socket buffer size, default 131071
|
||||
net.core.wmem_max = 524287
|
||||
# set default receive socket buffer size, default 65535
|
||||
net.core.rmem_default = 524287
|
||||
# set default send socket buffer size, default 65535
|
||||
net.core.wmem_default = 524287
|
||||
# set maximum amount of option memory buffers, default 10240
|
||||
net.core.optmem_max = 524287
|
||||
# set number of unprocessed input packets before kernel starts dropping them; default 300
|
||||
net.core.netdev_max_backlog = 300000
|
||||
- END sysctl_ixgb.conf
|
||||
|
||||
Edit the ixgb_perf.sh script if necessary to change eth1 to whatever interface
|
||||
your ixgb driver is using.
|
||||
your ixgb driver is using and/or replace '1a48' with appropriate 10GbE device's
|
||||
ID installed on the system.
|
||||
|
||||
NOTE: Unless these scripts are added to the boot process, these changes will
|
||||
only last only until the next system reboot.
|
||||
@ -184,7 +251,6 @@ only last only until the next system reboot.
|
||||
|
||||
Resolving Slow UDP Traffic
|
||||
--------------------------
|
||||
|
||||
If your server does not seem to be able to receive UDP traffic as fast as it
|
||||
can receive TCP traffic, it could be because Linux, by default, does not set
|
||||
the network stack buffers as large as they need to be to support high UDP
|
||||
@ -200,13 +266,168 @@ defaults of max=131071 (128k - 1) and default=65535 (64k - 1). These variables
|
||||
will increase the amount of memory used by the network stack for receives, and
|
||||
can be increased significantly more if necessary for your application.
|
||||
|
||||
|
||||
Additional Configurations
|
||||
=========================
|
||||
|
||||
Configuring the Driver on Different Distributions
|
||||
-------------------------------------------------
|
||||
Configuring a network driver to load properly when the system is started is
|
||||
distribution dependent. Typically, the configuration process involves adding
|
||||
an alias line to /etc/modprobe.conf as well as editing other system startup
|
||||
scripts and/or configuration files. Many popular Linux distributions ship
|
||||
with tools to make these changes for you. To learn the proper way to
|
||||
configure a network device for your system, refer to your distribution
|
||||
documentation. If during this process you are asked for the driver or module
|
||||
name, the name for the Linux Base Driver for the Intel 10GbE Family of
|
||||
Adapters is ixgb.
|
||||
|
||||
Viewing Link Messages
|
||||
---------------------
|
||||
Link messages will not be displayed to the console if the distribution is
|
||||
restricting system messages. In order to see network driver link messages on
|
||||
your console, set dmesg to eight by entering the following:
|
||||
|
||||
dmesg -n 8
|
||||
|
||||
NOTE: This setting is not saved across reboots.
|
||||
|
||||
|
||||
Jumbo Frames
|
||||
------------
|
||||
The driver supports Jumbo Frames for all adapters. Jumbo Frames support is
|
||||
enabled by changing the MTU to a value larger than the default of 1500.
|
||||
The maximum value for the MTU is 16114. Use the ifconfig command to
|
||||
increase the MTU size. For example:
|
||||
|
||||
ifconfig ethx mtu 9000 up
|
||||
|
||||
The maximum MTU setting for Jumbo Frames is 16114. This value coincides
|
||||
with the maximum Jumbo Frames size of 16128.
|
||||
|
||||
|
||||
Ethtool
|
||||
-------
|
||||
The driver utilizes the ethtool interface for driver configuration and
|
||||
diagnostics, as well as displaying statistical information. Ethtool
|
||||
version 1.6 or later is required for this functionality.
|
||||
|
||||
The latest release of ethtool can be found from
|
||||
http://sourceforge.net/projects/gkernel
|
||||
|
||||
NOTE: Ethtool 1.6 only supports a limited set of ethtool options. Support
|
||||
for a more complete ethtool feature set can be enabled by upgrading
|
||||
to the latest version.
|
||||
|
||||
|
||||
NAPI
|
||||
----
|
||||
|
||||
NAPI (Rx polling mode) is supported in the ixgb driver. NAPI is enabled
|
||||
or disabled based on the configuration of the kernel. see CONFIG_IXGB_NAPI
|
||||
|
||||
See www.cyberus.ca/~hadi/usenix-paper.tgz for more information on NAPI.
|
||||
|
||||
|
||||
Known Issues/Troubleshooting
|
||||
============================
|
||||
|
||||
NOTE: After installing the driver, if your Intel Network Connection is not
|
||||
working, verify in the "In This Release" section of the readme that you have
|
||||
installed the correct driver.
|
||||
|
||||
Intel(R) PRO/10GbE CX4 Server Adapter Cable Interoperability Issue with
|
||||
Fujitsu XENPAK Module in SmartBits Chassis
|
||||
---------------------------------------------------------------------
|
||||
Excessive CRC errors may be observed if the Intel(R) PRO/10GbE CX4
|
||||
Server adapter is connected to a Fujitsu XENPAK CX4 module in a SmartBits
|
||||
chassis using 15 m/24AWG cable assemblies manufactured by Fujitsu or Leoni.
|
||||
The CRC errors may be received either by the Intel(R) PRO/10GbE CX4
|
||||
Server adapter or the SmartBits. If this situation occurs using a different
|
||||
cable assembly may resolve the issue.
|
||||
|
||||
CX4 Server Adapter Cable Interoperability Issues with HP Procurve 3400cl
|
||||
Switch Port
|
||||
------------------------------------------------------------------------
|
||||
Excessive CRC errors may be observed if the Intel(R) PRO/10GbE CX4 Server
|
||||
adapter is connected to an HP Procurve 3400cl switch port using short cables
|
||||
(1 m or shorter). If this situation occurs, using a longer cable may resolve
|
||||
the issue.
|
||||
|
||||
Excessive CRC errors may be observed using Fujitsu 24AWG cable assemblies that
|
||||
Are 10 m or longer or where using a Leoni 15 m/24AWG cable assembly. The CRC
|
||||
errors may be received either by the CX4 Server adapter or at the switch. If
|
||||
this situation occurs, using a different cable assembly may resolve the issue.
|
||||
|
||||
|
||||
Jumbo Frames System Requirement
|
||||
-------------------------------
|
||||
Memory allocation failures have been observed on Linux systems with 64 MB
|
||||
of RAM or less that are running Jumbo Frames. If you are using Jumbo
|
||||
Frames, your system may require more than the advertised minimum
|
||||
requirement of 64 MB of system memory.
|
||||
|
||||
|
||||
Performance Degradation with Jumbo Frames
|
||||
-----------------------------------------
|
||||
Degradation in throughput performance may be observed in some Jumbo frames
|
||||
environments. If this is observed, increasing the application's socket buffer
|
||||
size and/or increasing the /proc/sys/net/ipv4/tcp_*mem entry values may help.
|
||||
See the specific application manual and /usr/src/linux*/Documentation/
|
||||
networking/ip-sysctl.txt for more details.
|
||||
|
||||
|
||||
Allocating Rx Buffers when Using Jumbo Frames
|
||||
---------------------------------------------
|
||||
Allocating Rx buffers when using Jumbo Frames on 2.6.x kernels may fail if
|
||||
the available memory is heavily fragmented. This issue may be seen with PCI-X
|
||||
adapters or with packet split disabled. This can be reduced or eliminated
|
||||
by changing the amount of available memory for receive buffer allocation, by
|
||||
increasing /proc/sys/vm/min_free_kbytes.
|
||||
|
||||
|
||||
Multiple Interfaces on Same Ethernet Broadcast Network
|
||||
------------------------------------------------------
|
||||
Due to the default ARP behavior on Linux, it is not possible to have
|
||||
one system on two IP networks in the same Ethernet broadcast domain
|
||||
(non-partitioned switch) behave as expected. All Ethernet interfaces
|
||||
will respond to IP traffic for any IP address assigned to the system.
|
||||
This results in unbalanced receive traffic.
|
||||
|
||||
If you have multiple interfaces in a server, do either of the following:
|
||||
|
||||
- Turn on ARP filtering by entering:
|
||||
echo 1 > /proc/sys/net/ipv4/conf/all/arp_filter
|
||||
|
||||
- Install the interfaces in separate broadcast domains - either in
|
||||
different switches or in a switch partitioned to VLANs.
|
||||
|
||||
|
||||
UDP Stress Test Dropped Packet Issue
|
||||
--------------------------------------
|
||||
Under small packets UDP stress test with 10GbE driver, the Linux system
|
||||
may drop UDP packets due to the fullness of socket buffers. You may want
|
||||
to change the driver's Flow Control variables to the minimum value for
|
||||
controlling packet reception.
|
||||
|
||||
|
||||
Tx Hangs Possible Under Stress
|
||||
------------------------------
|
||||
Under stress conditions, if TX hangs occur, turning off TSO
|
||||
"ethtool -K eth0 tso off" may resolve the problem.
|
||||
|
||||
|
||||
Support
|
||||
=======
|
||||
|
||||
For general information and support, go to the Intel support website at:
|
||||
For general information, go to the Intel support website at:
|
||||
|
||||
http://support.intel.com
|
||||
|
||||
or the Intel Wired Networking project hosted by Sourceforge at:
|
||||
|
||||
http://sourceforge.net/projects/e1000
|
||||
|
||||
If an issue is identified with the released source code on the supported
|
||||
kernel with a supported adapter, email the specific information related to
|
||||
the issue to linux.nics@intel.com.
|
||||
kernel with a supported adapter, email the specific information related
|
||||
to the issue to e1000-devel@lists.sf.net
|
||||
|
@ -1694,26 +1694,6 @@ config VIA_RHINE_MMIO
|
||||
|
||||
If unsure, say Y.
|
||||
|
||||
config VIA_RHINE_NAPI
|
||||
bool "Use Rx Polling (NAPI)"
|
||||
depends on VIA_RHINE
|
||||
help
|
||||
NAPI is a new driver API designed to reduce CPU and interrupt load
|
||||
when the driver is receiving lots of packets from the card.
|
||||
|
||||
If your estimated Rx load is 10kpps or more, or if the card will be
|
||||
deployed on potentially unfriendly networks (e.g. in a firewall),
|
||||
then say Y here.
|
||||
|
||||
config LAN_SAA9730
|
||||
bool "Philips SAA9730 Ethernet support"
|
||||
depends on NET_PCI && PCI && MIPS_ATLAS
|
||||
help
|
||||
The SAA9730 is a combined multimedia and peripheral controller used
|
||||
in thin clients, Internet access terminals, and diskless
|
||||
workstations.
|
||||
See <http://www.semiconductors.philips.com/pip/SAA9730_flyer_1>.
|
||||
|
||||
config SC92031
|
||||
tristate "Silan SC92031 PCI Fast Ethernet Adapter driver (EXPERIMENTAL)"
|
||||
depends on NET_PCI && PCI && EXPERIMENTAL
|
||||
@ -2029,6 +2009,15 @@ config IGB
|
||||
To compile this driver as a module, choose M here. The module
|
||||
will be called igb.
|
||||
|
||||
config IGB_LRO
|
||||
bool "Use software LRO"
|
||||
depends on IGB && INET
|
||||
select INET_LRO
|
||||
---help---
|
||||
Say Y here if you want to use large receive offload.
|
||||
|
||||
If in doubt, say N.
|
||||
|
||||
source "drivers/net/ixp2000/Kconfig"
|
||||
|
||||
config MYRI_SBUS
|
||||
@ -2273,10 +2262,6 @@ config GIANFAR
|
||||
This driver supports the Gigabit TSEC on the MPC83xx, MPC85xx,
|
||||
and MPC86xx family of chips, and the FEC on the 8540.
|
||||
|
||||
config GFAR_NAPI
|
||||
bool "Use Rx Polling (NAPI)"
|
||||
depends on GIANFAR
|
||||
|
||||
config UCC_GETH
|
||||
tristate "Freescale QE Gigabit Ethernet"
|
||||
depends on QUICC_ENGINE
|
||||
@ -2285,10 +2270,6 @@ config UCC_GETH
|
||||
This driver supports the Gigabit Ethernet mode of the QUICC Engine,
|
||||
which is available on some Freescale SOCs.
|
||||
|
||||
config UGETH_NAPI
|
||||
bool "Use Rx Polling (NAPI)"
|
||||
depends on UCC_GETH
|
||||
|
||||
config UGETH_MAGIC_PACKET
|
||||
bool "Magic Packet detection support"
|
||||
depends on UCC_GETH
|
||||
@ -2378,14 +2359,6 @@ config CHELSIO_T1_1G
|
||||
Enables support for Chelsio's gigabit Ethernet PCI cards. If you
|
||||
are using only 10G cards say 'N' here.
|
||||
|
||||
config CHELSIO_T1_NAPI
|
||||
bool "Use Rx Polling (NAPI)"
|
||||
depends on CHELSIO_T1
|
||||
default y
|
||||
help
|
||||
NAPI is a driver API designed to reduce CPU and interrupt load
|
||||
when the driver is receiving lots of packets from the card.
|
||||
|
||||
config CHELSIO_T3
|
||||
tristate "Chelsio Communications T3 10Gb Ethernet support"
|
||||
depends on PCI && INET
|
||||
@ -2457,20 +2430,6 @@ config IXGB
|
||||
To compile this driver as a module, choose M here. The module
|
||||
will be called ixgb.
|
||||
|
||||
config IXGB_NAPI
|
||||
bool "Use Rx Polling (NAPI) (EXPERIMENTAL)"
|
||||
depends on IXGB && EXPERIMENTAL
|
||||
help
|
||||
NAPI is a new driver API designed to reduce CPU and interrupt load
|
||||
when the driver is receiving lots of packets from the card. It is
|
||||
still somewhat experimental and thus not yet enabled by default.
|
||||
|
||||
If your estimated Rx load is 10kpps or more, or if the card will be
|
||||
deployed on potentially unfriendly networks (e.g. in a firewall),
|
||||
then say Y here.
|
||||
|
||||
If in doubt, say N.
|
||||
|
||||
config S2IO
|
||||
tristate "S2IO 10Gbe XFrame NIC"
|
||||
depends on PCI
|
||||
|
@ -166,7 +166,6 @@ obj-$(CONFIG_EEXPRESS_PRO) += eepro.o
|
||||
obj-$(CONFIG_8139CP) += 8139cp.o
|
||||
obj-$(CONFIG_8139TOO) += 8139too.o
|
||||
obj-$(CONFIG_ZNET) += znet.o
|
||||
obj-$(CONFIG_LAN_SAA9730) += saa9730.o
|
||||
obj-$(CONFIG_CPMAC) += cpmac.o
|
||||
obj-$(CONFIG_DEPCA) += depca.o
|
||||
obj-$(CONFIG_EWRK3) += ewrk3.o
|
||||
|
@ -1153,9 +1153,7 @@ static int __devinit init_one(struct pci_dev *pdev,
|
||||
#ifdef CONFIG_NET_POLL_CONTROLLER
|
||||
netdev->poll_controller = t1_netpoll;
|
||||
#endif
|
||||
#ifdef CONFIG_CHELSIO_T1_NAPI
|
||||
netif_napi_add(netdev, &adapter->napi, t1_poll, 64);
|
||||
#endif
|
||||
|
||||
SET_ETHTOOL_OPS(netdev, &t1_ethtool_ops);
|
||||
}
|
||||
|
@ -1396,20 +1396,10 @@ static void sge_rx(struct sge *sge, struct freelQ *fl, unsigned int len)
|
||||
|
||||
if (unlikely(adapter->vlan_grp && p->vlan_valid)) {
|
||||
st->vlan_xtract++;
|
||||
#ifdef CONFIG_CHELSIO_T1_NAPI
|
||||
vlan_hwaccel_receive_skb(skb, adapter->vlan_grp,
|
||||
ntohs(p->vlan));
|
||||
#else
|
||||
vlan_hwaccel_rx(skb, adapter->vlan_grp,
|
||||
ntohs(p->vlan));
|
||||
#endif
|
||||
} else {
|
||||
#ifdef CONFIG_CHELSIO_T1_NAPI
|
||||
} else
|
||||
netif_receive_skb(skb);
|
||||
#else
|
||||
netif_rx(skb);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1568,7 +1558,6 @@ static inline int responses_pending(const struct adapter *adapter)
|
||||
return (e->GenerationBit == Q->genbit);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_CHELSIO_T1_NAPI
|
||||
/*
|
||||
* A simpler version of process_responses() that handles only pure (i.e.,
|
||||
* non data-carrying) responses. Such respones are too light-weight to justify
|
||||
@ -1636,9 +1625,6 @@ int t1_poll(struct napi_struct *napi, int budget)
|
||||
return work_done;
|
||||
}
|
||||
|
||||
/*
|
||||
* NAPI version of the main interrupt handler.
|
||||
*/
|
||||
irqreturn_t t1_interrupt(int irq, void *data)
|
||||
{
|
||||
struct adapter *adapter = data;
|
||||
@ -1656,7 +1642,8 @@ irqreturn_t t1_interrupt(int irq, void *data)
|
||||
else {
|
||||
/* no data, no NAPI needed */
|
||||
writel(sge->respQ.cidx, adapter->regs + A_SG_SLEEPING);
|
||||
napi_enable(&adapter->napi); /* undo schedule_prep */
|
||||
/* undo schedule_prep */
|
||||
napi_enable(&adapter->napi);
|
||||
}
|
||||
}
|
||||
return IRQ_HANDLED;
|
||||
@ -1672,53 +1659,6 @@ irqreturn_t t1_interrupt(int irq, void *data)
|
||||
return IRQ_RETVAL(handled != 0);
|
||||
}
|
||||
|
||||
#else
|
||||
/*
|
||||
* Main interrupt handler, optimized assuming that we took a 'DATA'
|
||||
* interrupt.
|
||||
*
|
||||
* 1. Clear the interrupt
|
||||
* 2. Loop while we find valid descriptors and process them; accumulate
|
||||
* information that can be processed after the loop
|
||||
* 3. Tell the SGE at which index we stopped processing descriptors
|
||||
* 4. Bookkeeping; free TX buffers, ring doorbell if there are any
|
||||
* outstanding TX buffers waiting, replenish RX buffers, potentially
|
||||
* reenable upper layers if they were turned off due to lack of TX
|
||||
* resources which are available again.
|
||||
* 5. If we took an interrupt, but no valid respQ descriptors was found we
|
||||
* let the slow_intr_handler run and do error handling.
|
||||
*/
|
||||
irqreturn_t t1_interrupt(int irq, void *cookie)
|
||||
{
|
||||
int work_done;
|
||||
struct adapter *adapter = cookie;
|
||||
struct respQ *Q = &adapter->sge->respQ;
|
||||
|
||||
spin_lock(&adapter->async_lock);
|
||||
|
||||
writel(F_PL_INTR_SGE_DATA, adapter->regs + A_PL_CAUSE);
|
||||
|
||||
if (likely(responses_pending(adapter)))
|
||||
work_done = process_responses(adapter, -1);
|
||||
else
|
||||
work_done = t1_slow_intr_handler(adapter);
|
||||
|
||||
/*
|
||||
* The unconditional clearing of the PL_CAUSE above may have raced
|
||||
* with DMA completion and the corresponding generation of a response
|
||||
* to cause us to miss the resulting data interrupt. The next write
|
||||
* is also unconditional to recover the missed interrupt and render
|
||||
* this race harmless.
|
||||
*/
|
||||
writel(Q->cidx, adapter->regs + A_SG_SLEEPING);
|
||||
|
||||
if (!work_done)
|
||||
adapter->sge->stats.unhandled_irqs++;
|
||||
spin_unlock(&adapter->async_lock);
|
||||
return IRQ_RETVAL(work_done != 0);
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Enqueues the sk_buff onto the cmdQ[qid] and has hardware fetch it.
|
||||
*
|
||||
|
@ -110,10 +110,7 @@ struct ulp_iscsi_info {
|
||||
unsigned int llimit;
|
||||
unsigned int ulimit;
|
||||
unsigned int tagmask;
|
||||
unsigned int pgsz3;
|
||||
unsigned int pgsz2;
|
||||
unsigned int pgsz1;
|
||||
unsigned int pgsz0;
|
||||
u8 pgsz_factor[4];
|
||||
unsigned int max_rxsz;
|
||||
unsigned int max_txsz;
|
||||
struct pci_dev *pdev;
|
||||
|
@ -207,6 +207,17 @@ static int cxgb_ulp_iscsi_ctl(struct adapter *adapter, unsigned int req,
|
||||
break;
|
||||
case ULP_ISCSI_SET_PARAMS:
|
||||
t3_write_reg(adapter, A_ULPRX_ISCSI_TAGMASK, uiip->tagmask);
|
||||
/* set MaxRxData and MaxCoalesceSize to 16224 */
|
||||
t3_write_reg(adapter, A_TP_PARA_REG2, 0x3f603f60);
|
||||
/* program the ddp page sizes */
|
||||
{
|
||||
int i;
|
||||
unsigned int val = 0;
|
||||
for (i = 0; i < 4; i++)
|
||||
val |= (uiip->pgsz_factor[i] & 0xF) << (8 * i);
|
||||
if (val)
|
||||
t3_write_reg(adapter, A_ULPRX_ISCSI_PSZ, val);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
ret = -EOPNOTSUPP;
|
||||
|
@ -1517,16 +1517,18 @@
|
||||
|
||||
#define A_ULPRX_ISCSI_TAGMASK 0x514
|
||||
|
||||
#define S_HPZ0 0
|
||||
#define M_HPZ0 0xf
|
||||
#define V_HPZ0(x) ((x) << S_HPZ0)
|
||||
#define G_HPZ0(x) (((x) >> S_HPZ0) & M_HPZ0)
|
||||
#define A_ULPRX_ISCSI_PSZ 0x518
|
||||
|
||||
#define A_ULPRX_TDDP_LLIMIT 0x51c
|
||||
|
||||
#define A_ULPRX_TDDP_ULIMIT 0x520
|
||||
#define A_ULPRX_TDDP_PSZ 0x528
|
||||
|
||||
#define S_HPZ0 0
|
||||
#define M_HPZ0 0xf
|
||||
#define V_HPZ0(x) ((x) << S_HPZ0)
|
||||
#define G_HPZ0(x) (((x) >> S_HPZ0) & M_HPZ0)
|
||||
|
||||
#define A_ULPRX_STAG_LLIMIT 0x52c
|
||||
|
||||
#define A_ULPRX_STAG_ULIMIT 0x530
|
||||
|
@ -191,6 +191,9 @@ union opcode_tid {
|
||||
#define G_OPCODE(x) (((x) >> S_OPCODE) & 0xFF)
|
||||
#define G_TID(x) ((x) & 0xFFFFFF)
|
||||
|
||||
#define S_QNUM 0
|
||||
#define G_QNUM(x) (((x) >> S_QNUM) & 0xFFFF)
|
||||
|
||||
#define S_HASHTYPE 22
|
||||
#define M_HASHTYPE 0x3
|
||||
#define G_HASHTYPE(x) (((x) >> S_HASHTYPE) & M_HASHTYPE)
|
||||
@ -779,6 +782,12 @@ struct tx_data_wr {
|
||||
__be32 param;
|
||||
};
|
||||
|
||||
/* tx_data_wr.flags fields */
|
||||
#define S_TX_ACK_PAGES 21
|
||||
#define M_TX_ACK_PAGES 0x7
|
||||
#define V_TX_ACK_PAGES(x) ((x) << S_TX_ACK_PAGES)
|
||||
#define G_TX_ACK_PAGES(x) (((x) >> S_TX_ACK_PAGES) & M_TX_ACK_PAGES)
|
||||
|
||||
/* tx_data_wr.param fields */
|
||||
#define S_TX_PORT 0
|
||||
#define M_TX_PORT 0x7
|
||||
@ -1452,4 +1461,35 @@ struct cpl_rdma_terminate {
|
||||
#define M_TERM_TID 0xFFFFF
|
||||
#define V_TERM_TID(x) ((x) << S_TERM_TID)
|
||||
#define G_TERM_TID(x) (((x) >> S_TERM_TID) & M_TERM_TID)
|
||||
|
||||
/* ULP_TX opcodes */
|
||||
enum { ULP_MEM_READ = 2, ULP_MEM_WRITE = 3, ULP_TXPKT = 4 };
|
||||
|
||||
#define S_ULPTX_CMD 28
|
||||
#define M_ULPTX_CMD 0xF
|
||||
#define V_ULPTX_CMD(x) ((x) << S_ULPTX_CMD)
|
||||
|
||||
#define S_ULPTX_NFLITS 0
|
||||
#define M_ULPTX_NFLITS 0xFF
|
||||
#define V_ULPTX_NFLITS(x) ((x) << S_ULPTX_NFLITS)
|
||||
|
||||
struct ulp_mem_io {
|
||||
WR_HDR;
|
||||
__be32 cmd_lock_addr;
|
||||
__be32 len;
|
||||
};
|
||||
|
||||
/* ulp_mem_io.cmd_lock_addr fields */
|
||||
#define S_ULP_MEMIO_ADDR 0
|
||||
#define M_ULP_MEMIO_ADDR 0x7FFFFFF
|
||||
#define V_ULP_MEMIO_ADDR(x) ((x) << S_ULP_MEMIO_ADDR)
|
||||
#define S_ULP_MEMIO_LOCK 27
|
||||
#define V_ULP_MEMIO_LOCK(x) ((x) << S_ULP_MEMIO_LOCK)
|
||||
#define F_ULP_MEMIO_LOCK V_ULP_MEMIO_LOCK(1U)
|
||||
|
||||
/* ulp_mem_io.len fields */
|
||||
#define S_ULP_MEMIO_DATA_LEN 28
|
||||
#define M_ULP_MEMIO_DATA_LEN 0xF
|
||||
#define V_ULP_MEMIO_DATA_LEN(x) ((x) << S_ULP_MEMIO_DATA_LEN)
|
||||
|
||||
#endif /* T3_CPL_H */
|
||||
|
@ -64,6 +64,7 @@ struct t3cdev {
|
||||
void *l3opt; /* optional layer 3 data */
|
||||
void *l4opt; /* optional layer 4 data */
|
||||
void *ulp; /* ulp stuff */
|
||||
void *ulp_iscsi; /* ulp iscsi */
|
||||
};
|
||||
|
||||
#endif /* _T3CDEV_H_ */
|
||||
|
@ -44,8 +44,7 @@
|
||||
* happen immediately, but will wait until either a set number
|
||||
* of frames or amount of time have passed). In NAPI, the
|
||||
* interrupt handler will signal there is work to be done, and
|
||||
* exit. Without NAPI, the packet(s) will be handled
|
||||
* immediately. Both methods will start at the last known empty
|
||||
* exit. This method will start at the last known empty
|
||||
* descriptor, and process every subsequent descriptor until there
|
||||
* are none left with data (NAPI will stop after a set number of
|
||||
* packets to give time to other tasks, but will eventually
|
||||
@ -101,12 +100,6 @@
|
||||
#undef BRIEF_GFAR_ERRORS
|
||||
#undef VERBOSE_GFAR_ERRORS
|
||||
|
||||
#ifdef CONFIG_GFAR_NAPI
|
||||
#define RECEIVE(x) netif_receive_skb(x)
|
||||
#else
|
||||
#define RECEIVE(x) netif_rx(x)
|
||||
#endif
|
||||
|
||||
const char gfar_driver_name[] = "Gianfar Ethernet";
|
||||
const char gfar_driver_version[] = "1.3";
|
||||
|
||||
@ -131,9 +124,7 @@ static void free_skb_resources(struct gfar_private *priv);
|
||||
static void gfar_set_multi(struct net_device *dev);
|
||||
static void gfar_set_hash_for_addr(struct net_device *dev, u8 *addr);
|
||||
static void gfar_configure_serdes(struct net_device *dev);
|
||||
#ifdef CONFIG_GFAR_NAPI
|
||||
static int gfar_poll(struct napi_struct *napi, int budget);
|
||||
#endif
|
||||
#ifdef CONFIG_NET_POLL_CONTROLLER
|
||||
static void gfar_netpoll(struct net_device *dev);
|
||||
#endif
|
||||
@ -260,9 +251,7 @@ static int gfar_probe(struct platform_device *pdev)
|
||||
dev->hard_start_xmit = gfar_start_xmit;
|
||||
dev->tx_timeout = gfar_timeout;
|
||||
dev->watchdog_timeo = TX_TIMEOUT;
|
||||
#ifdef CONFIG_GFAR_NAPI
|
||||
netif_napi_add(dev, &priv->napi, gfar_poll, GFAR_DEV_WEIGHT);
|
||||
#endif
|
||||
#ifdef CONFIG_NET_POLL_CONTROLLER
|
||||
dev->poll_controller = gfar_netpoll;
|
||||
#endif
|
||||
@ -363,11 +352,7 @@ static int gfar_probe(struct platform_device *pdev)
|
||||
|
||||
/* Even more device info helps when determining which kernel */
|
||||
/* provided which set of benchmarks. */
|
||||
#ifdef CONFIG_GFAR_NAPI
|
||||
printk(KERN_INFO "%s: Running with NAPI enabled\n", dev->name);
|
||||
#else
|
||||
printk(KERN_INFO "%s: Running with NAPI disabled\n", dev->name);
|
||||
#endif
|
||||
printk(KERN_INFO "%s: %d/%d RX/TX BD ring size\n",
|
||||
dev->name, priv->rx_ring_size, priv->tx_ring_size);
|
||||
|
||||
@ -945,14 +930,10 @@ tx_skb_fail:
|
||||
/* Returns 0 for success. */
|
||||
static int gfar_enet_open(struct net_device *dev)
|
||||
{
|
||||
#ifdef CONFIG_GFAR_NAPI
|
||||
struct gfar_private *priv = netdev_priv(dev);
|
||||
#endif
|
||||
int err;
|
||||
|
||||
#ifdef CONFIG_GFAR_NAPI
|
||||
napi_enable(&priv->napi);
|
||||
#endif
|
||||
|
||||
/* Initialize a bunch of registers */
|
||||
init_registers(dev);
|
||||
@ -962,17 +943,13 @@ static int gfar_enet_open(struct net_device *dev)
|
||||
err = init_phy(dev);
|
||||
|
||||
if(err) {
|
||||
#ifdef CONFIG_GFAR_NAPI
|
||||
napi_disable(&priv->napi);
|
||||
#endif
|
||||
return err;
|
||||
}
|
||||
|
||||
err = startup_gfar(dev);
|
||||
if (err) {
|
||||
#ifdef CONFIG_GFAR_NAPI
|
||||
napi_disable(&priv->napi);
|
||||
#endif
|
||||
return err;
|
||||
}
|
||||
|
||||
@ -1128,9 +1105,7 @@ static int gfar_close(struct net_device *dev)
|
||||
{
|
||||
struct gfar_private *priv = netdev_priv(dev);
|
||||
|
||||
#ifdef CONFIG_GFAR_NAPI
|
||||
napi_disable(&priv->napi);
|
||||
#endif
|
||||
|
||||
stop_gfar(dev);
|
||||
|
||||
@ -1427,14 +1402,9 @@ irqreturn_t gfar_receive(int irq, void *dev_id)
|
||||
{
|
||||
struct net_device *dev = (struct net_device *) dev_id;
|
||||
struct gfar_private *priv = netdev_priv(dev);
|
||||
#ifdef CONFIG_GFAR_NAPI
|
||||
u32 tempval;
|
||||
#else
|
||||
unsigned long flags;
|
||||
#endif
|
||||
|
||||
/* support NAPI */
|
||||
#ifdef CONFIG_GFAR_NAPI
|
||||
/* Clear IEVENT, so interrupts aren't called again
|
||||
* because of the packets that have already arrived */
|
||||
gfar_write(&priv->regs->ievent, IEVENT_RTX_MASK);
|
||||
@ -1451,38 +1421,10 @@ irqreturn_t gfar_receive(int irq, void *dev_id)
|
||||
dev->name, gfar_read(&priv->regs->ievent),
|
||||
gfar_read(&priv->regs->imask));
|
||||
}
|
||||
#else
|
||||
/* Clear IEVENT, so rx interrupt isn't called again
|
||||
* because of this interrupt */
|
||||
gfar_write(&priv->regs->ievent, IEVENT_RX_MASK);
|
||||
|
||||
spin_lock_irqsave(&priv->rxlock, flags);
|
||||
gfar_clean_rx_ring(dev, priv->rx_ring_size);
|
||||
|
||||
/* If we are coalescing interrupts, update the timer */
|
||||
/* Otherwise, clear it */
|
||||
if (likely(priv->rxcoalescing)) {
|
||||
gfar_write(&priv->regs->rxic, 0);
|
||||
gfar_write(&priv->regs->rxic,
|
||||
mk_ic_value(priv->rxcount, priv->rxtime));
|
||||
}
|
||||
|
||||
spin_unlock_irqrestore(&priv->rxlock, flags);
|
||||
#endif
|
||||
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
static inline int gfar_rx_vlan(struct sk_buff *skb,
|
||||
struct vlan_group *vlgrp, unsigned short vlctl)
|
||||
{
|
||||
#ifdef CONFIG_GFAR_NAPI
|
||||
return vlan_hwaccel_receive_skb(skb, vlgrp, vlctl);
|
||||
#else
|
||||
return vlan_hwaccel_rx(skb, vlgrp, vlctl);
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline void gfar_rx_checksum(struct sk_buff *skb, struct rxfcb *fcb)
|
||||
{
|
||||
/* If valid headers were found, and valid sums
|
||||
@ -1539,10 +1481,11 @@ static int gfar_process_frame(struct net_device *dev, struct sk_buff *skb,
|
||||
skb->protocol = eth_type_trans(skb, dev);
|
||||
|
||||
/* Send the packet up the stack */
|
||||
if (unlikely(priv->vlgrp && (fcb->flags & RXFCB_VLN)))
|
||||
ret = gfar_rx_vlan(skb, priv->vlgrp, fcb->vlctl);
|
||||
else
|
||||
ret = RECEIVE(skb);
|
||||
if (unlikely(priv->vlgrp && (fcb->flags & RXFCB_VLN))) {
|
||||
ret = vlan_hwaccel_receive_skb(skb, priv->vlgrp,
|
||||
fcb->vlctl);
|
||||
} else
|
||||
ret = netif_receive_skb(skb);
|
||||
|
||||
if (NET_RX_DROP == ret)
|
||||
priv->extra_stats.kernel_dropped++;
|
||||
@ -1629,7 +1572,6 @@ int gfar_clean_rx_ring(struct net_device *dev, int rx_work_limit)
|
||||
return howmany;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_GFAR_NAPI
|
||||
static int gfar_poll(struct napi_struct *napi, int budget)
|
||||
{
|
||||
struct gfar_private *priv = container_of(napi, struct gfar_private, napi);
|
||||
@ -1664,7 +1606,6 @@ static int gfar_poll(struct napi_struct *napi, int budget)
|
||||
|
||||
return howmany;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_NET_POLL_CONTROLLER
|
||||
/*
|
||||
@ -2003,11 +1944,6 @@ static irqreturn_t gfar_error(int irq, void *dev_id)
|
||||
|
||||
gfar_receive(irq, dev_id);
|
||||
|
||||
#ifndef CONFIG_GFAR_NAPI
|
||||
/* Clear the halt bit in RSTAT */
|
||||
gfar_write(&priv->regs->rstat, RSTAT_CLEAR_RHALT);
|
||||
#endif
|
||||
|
||||
if (netif_msg_rx_err(priv))
|
||||
printk(KERN_DEBUG "%s: busy error (rstat: %x)\n",
|
||||
dev->name, gfar_read(&priv->regs->rstat));
|
||||
|
@ -77,13 +77,8 @@ extern const char gfar_driver_name[];
|
||||
extern const char gfar_driver_version[];
|
||||
|
||||
/* These need to be powers of 2 for this driver */
|
||||
#ifdef CONFIG_GFAR_NAPI
|
||||
#define DEFAULT_TX_RING_SIZE 256
|
||||
#define DEFAULT_RX_RING_SIZE 256
|
||||
#else
|
||||
#define DEFAULT_TX_RING_SIZE 64
|
||||
#define DEFAULT_RX_RING_SIZE 64
|
||||
#endif
|
||||
|
||||
#define GFAR_RX_MAX_RING_SIZE 256
|
||||
#define GFAR_TX_MAX_RING_SIZE 256
|
||||
@ -128,14 +123,8 @@ extern const char gfar_driver_version[];
|
||||
|
||||
#define DEFAULT_RXTIME 21
|
||||
|
||||
/* Non NAPI Case */
|
||||
#ifndef CONFIG_GFAR_NAPI
|
||||
#define DEFAULT_RX_COALESCE 1
|
||||
#define DEFAULT_RXCOUNT 16
|
||||
#else
|
||||
#define DEFAULT_RX_COALESCE 0
|
||||
#define DEFAULT_RXCOUNT 0
|
||||
#endif /* CONFIG_GFAR_NAPI */
|
||||
|
||||
#define MIIMCFG_INIT_VALUE 0x00000007
|
||||
#define MIIMCFG_RESET 0x80000000
|
||||
|
@ -31,6 +31,7 @@
|
||||
|
||||
#include <linux/types.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/if_ether.h>
|
||||
|
||||
#include "e1000_mac.h"
|
||||
#include "e1000_82575.h"
|
||||
@ -45,7 +46,6 @@ static s32 igb_get_cfg_done_82575(struct e1000_hw *);
|
||||
static s32 igb_init_hw_82575(struct e1000_hw *);
|
||||
static s32 igb_phy_hw_reset_sgmii_82575(struct e1000_hw *);
|
||||
static s32 igb_read_phy_reg_sgmii_82575(struct e1000_hw *, u32, u16 *);
|
||||
static void igb_rar_set_82575(struct e1000_hw *, u8 *, u32);
|
||||
static s32 igb_reset_hw_82575(struct e1000_hw *);
|
||||
static s32 igb_set_d0_lplu_state_82575(struct e1000_hw *, bool);
|
||||
static s32 igb_setup_copper_link_82575(struct e1000_hw *);
|
||||
@ -84,6 +84,12 @@ static s32 igb_get_invariants_82575(struct e1000_hw *hw)
|
||||
case E1000_DEV_ID_82575GB_QUAD_COPPER:
|
||||
mac->type = e1000_82575;
|
||||
break;
|
||||
case E1000_DEV_ID_82576:
|
||||
case E1000_DEV_ID_82576_FIBER:
|
||||
case E1000_DEV_ID_82576_SERDES:
|
||||
case E1000_DEV_ID_82576_QUAD_COPPER:
|
||||
mac->type = e1000_82576;
|
||||
break;
|
||||
default:
|
||||
return -E1000_ERR_MAC_INIT;
|
||||
break;
|
||||
@ -128,6 +134,8 @@ static s32 igb_get_invariants_82575(struct e1000_hw *hw)
|
||||
mac->mta_reg_count = 128;
|
||||
/* Set rar entry count */
|
||||
mac->rar_entry_count = E1000_RAR_ENTRIES_82575;
|
||||
if (mac->type == e1000_82576)
|
||||
mac->rar_entry_count = E1000_RAR_ENTRIES_82576;
|
||||
/* Set if part includes ASF firmware */
|
||||
mac->asf_firmware_present = true;
|
||||
/* Set if manageability features are enabled. */
|
||||
@ -700,7 +708,6 @@ static s32 igb_check_for_link_82575(struct e1000_hw *hw)
|
||||
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
/**
|
||||
* igb_get_pcs_speed_and_duplex_82575 - Retrieve current speed/duplex
|
||||
* @hw: pointer to the HW structure
|
||||
@ -757,18 +764,129 @@ static s32 igb_get_pcs_speed_and_duplex_82575(struct e1000_hw *hw, u16 *speed,
|
||||
}
|
||||
|
||||
/**
|
||||
* igb_rar_set_82575 - Set receive address register
|
||||
* igb_init_rx_addrs_82575 - Initialize receive address's
|
||||
* @hw: pointer to the HW structure
|
||||
* @addr: pointer to the receive address
|
||||
* @index: receive address array register
|
||||
* @rar_count: receive address registers
|
||||
*
|
||||
* Sets the receive address array register at index to the address passed
|
||||
* in by addr.
|
||||
* Setups the receive address registers by setting the base receive address
|
||||
* register to the devices MAC address and clearing all the other receive
|
||||
* address registers to 0.
|
||||
**/
|
||||
static void igb_rar_set_82575(struct e1000_hw *hw, u8 *addr, u32 index)
|
||||
static void igb_init_rx_addrs_82575(struct e1000_hw *hw, u16 rar_count)
|
||||
{
|
||||
if (index < E1000_RAR_ENTRIES_82575)
|
||||
igb_rar_set(hw, addr, index);
|
||||
u32 i;
|
||||
u8 addr[6] = {0,0,0,0,0,0};
|
||||
/*
|
||||
* This function is essentially the same as that of
|
||||
* e1000_init_rx_addrs_generic. However it also takes care
|
||||
* of the special case where the register offset of the
|
||||
* second set of RARs begins elsewhere. This is implicitly taken care by
|
||||
* function e1000_rar_set_generic.
|
||||
*/
|
||||
|
||||
hw_dbg("e1000_init_rx_addrs_82575");
|
||||
|
||||
/* Setup the receive address */
|
||||
hw_dbg("Programming MAC Address into RAR[0]\n");
|
||||
hw->mac.ops.rar_set(hw, hw->mac.addr, 0);
|
||||
|
||||
/* Zero out the other (rar_entry_count - 1) receive addresses */
|
||||
hw_dbg("Clearing RAR[1-%u]\n", rar_count-1);
|
||||
for (i = 1; i < rar_count; i++)
|
||||
hw->mac.ops.rar_set(hw, addr, i);
|
||||
}
|
||||
|
||||
/**
|
||||
* igb_update_mc_addr_list_82575 - Update Multicast addresses
|
||||
* @hw: pointer to the HW structure
|
||||
* @mc_addr_list: array of multicast addresses to program
|
||||
* @mc_addr_count: number of multicast addresses to program
|
||||
* @rar_used_count: the first RAR register free to program
|
||||
* @rar_count: total number of supported Receive Address Registers
|
||||
*
|
||||
* Updates the Receive Address Registers and Multicast Table Array.
|
||||
* The caller must have a packed mc_addr_list of multicast addresses.
|
||||
* The parameter rar_count will usually be hw->mac.rar_entry_count
|
||||
* unless there are workarounds that change this.
|
||||
**/
|
||||
void igb_update_mc_addr_list_82575(struct e1000_hw *hw,
|
||||
u8 *mc_addr_list, u32 mc_addr_count,
|
||||
u32 rar_used_count, u32 rar_count)
|
||||
{
|
||||
u32 hash_value;
|
||||
u32 i;
|
||||
u8 addr[6] = {0,0,0,0,0,0};
|
||||
/*
|
||||
* This function is essentially the same as that of
|
||||
* igb_update_mc_addr_list_generic. However it also takes care
|
||||
* of the special case where the register offset of the
|
||||
* second set of RARs begins elsewhere. This is implicitly taken care by
|
||||
* function e1000_rar_set_generic.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Load the first set of multicast addresses into the exact
|
||||
* filters (RAR). If there are not enough to fill the RAR
|
||||
* array, clear the filters.
|
||||
*/
|
||||
for (i = rar_used_count; i < rar_count; i++) {
|
||||
if (mc_addr_count) {
|
||||
igb_rar_set(hw, mc_addr_list, i);
|
||||
mc_addr_count--;
|
||||
mc_addr_list += ETH_ALEN;
|
||||
} else {
|
||||
igb_rar_set(hw, addr, i);
|
||||
}
|
||||
}
|
||||
|
||||
/* Clear the old settings from the MTA */
|
||||
hw_dbg("Clearing MTA\n");
|
||||
for (i = 0; i < hw->mac.mta_reg_count; i++) {
|
||||
array_wr32(E1000_MTA, i, 0);
|
||||
wrfl();
|
||||
}
|
||||
|
||||
/* Load any remaining multicast addresses into the hash table. */
|
||||
for (; mc_addr_count > 0; mc_addr_count--) {
|
||||
hash_value = igb_hash_mc_addr(hw, mc_addr_list);
|
||||
hw_dbg("Hash value = 0x%03X\n", hash_value);
|
||||
hw->mac.ops.mta_set(hw, hash_value);
|
||||
mc_addr_list += ETH_ALEN;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* igb_shutdown_fiber_serdes_link_82575 - Remove link during power down
|
||||
* @hw: pointer to the HW structure
|
||||
*
|
||||
* In the case of fiber serdes, shut down optics and PCS on driver unload
|
||||
* when management pass thru is not enabled.
|
||||
**/
|
||||
void igb_shutdown_fiber_serdes_link_82575(struct e1000_hw *hw)
|
||||
{
|
||||
u32 reg;
|
||||
|
||||
if (hw->mac.type != e1000_82576 ||
|
||||
(hw->phy.media_type != e1000_media_type_fiber &&
|
||||
hw->phy.media_type != e1000_media_type_internal_serdes))
|
||||
return;
|
||||
|
||||
/* if the management interface is not enabled, then power down */
|
||||
if (!igb_enable_mng_pass_thru(hw)) {
|
||||
/* Disable PCS to turn off link */
|
||||
reg = rd32(E1000_PCS_CFG0);
|
||||
reg &= ~E1000_PCS_CFG_PCS_EN;
|
||||
wr32(E1000_PCS_CFG0, reg);
|
||||
|
||||
/* shutdown the laser */
|
||||
reg = rd32(E1000_CTRL_EXT);
|
||||
reg |= E1000_CTRL_EXT_SDP7_DATA;
|
||||
wr32(E1000_CTRL_EXT, reg);
|
||||
|
||||
/* flush the write to verify completion */
|
||||
wrfl();
|
||||
msleep(1);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
@ -854,7 +972,7 @@ static s32 igb_init_hw_82575(struct e1000_hw *hw)
|
||||
igb_clear_vfta(hw);
|
||||
|
||||
/* Setup the receive address */
|
||||
igb_init_rx_addrs(hw, rar_count);
|
||||
igb_init_rx_addrs_82575(hw, rar_count);
|
||||
/* Zero out the Multicast HASH table */
|
||||
hw_dbg("Zeroing the MTA\n");
|
||||
for (i = 0; i < mac->mta_reg_count; i++)
|
||||
@ -1113,6 +1231,70 @@ out:
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
/**
|
||||
* igb_translate_register_82576 - Translate the proper register offset
|
||||
* @reg: e1000 register to be read
|
||||
*
|
||||
* Registers in 82576 are located in different offsets than other adapters
|
||||
* even though they function in the same manner. This function takes in
|
||||
* the name of the register to read and returns the correct offset for
|
||||
* 82576 silicon.
|
||||
**/
|
||||
u32 igb_translate_register_82576(u32 reg)
|
||||
{
|
||||
/*
|
||||
* Some of the Kawela registers are located at different
|
||||
* offsets than they are in older adapters.
|
||||
* Despite the difference in location, the registers
|
||||
* function in the same manner.
|
||||
*/
|
||||
switch (reg) {
|
||||
case E1000_TDBAL(0):
|
||||
reg = 0x0E000;
|
||||
break;
|
||||
case E1000_TDBAH(0):
|
||||
reg = 0x0E004;
|
||||
break;
|
||||
case E1000_TDLEN(0):
|
||||
reg = 0x0E008;
|
||||
break;
|
||||
case E1000_TDH(0):
|
||||
reg = 0x0E010;
|
||||
break;
|
||||
case E1000_TDT(0):
|
||||
reg = 0x0E018;
|
||||
break;
|
||||
case E1000_TXDCTL(0):
|
||||
reg = 0x0E028;
|
||||
break;
|
||||
case E1000_RDBAL(0):
|
||||
reg = 0x0C000;
|
||||
break;
|
||||
case E1000_RDBAH(0):
|
||||
reg = 0x0C004;
|
||||
break;
|
||||
case E1000_RDLEN(0):
|
||||
reg = 0x0C008;
|
||||
break;
|
||||
case E1000_RDH(0):
|
||||
reg = 0x0C010;
|
||||
break;
|
||||
case E1000_RDT(0):
|
||||
reg = 0x0C018;
|
||||
break;
|
||||
case E1000_RXDCTL(0):
|
||||
reg = 0x0C028;
|
||||
break;
|
||||
case E1000_SRRCTL(0):
|
||||
reg = 0x0C00C;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return reg;
|
||||
}
|
||||
|
||||
/**
|
||||
* igb_reset_init_script_82575 - Inits HW defaults after reset
|
||||
* @hw: pointer to the HW structure
|
||||
@ -1304,7 +1486,7 @@ static struct e1000_mac_operations e1000_mac_ops_82575 = {
|
||||
.reset_hw = igb_reset_hw_82575,
|
||||
.init_hw = igb_init_hw_82575,
|
||||
.check_for_link = igb_check_for_link_82575,
|
||||
.rar_set = igb_rar_set_82575,
|
||||
.rar_set = igb_rar_set,
|
||||
.read_mac_addr = igb_read_mac_addr_82575,
|
||||
.get_speed_and_duplex = igb_get_speed_and_duplex_copper,
|
||||
};
|
||||
|
@ -28,9 +28,13 @@
|
||||
#ifndef _E1000_82575_H_
|
||||
#define _E1000_82575_H_
|
||||
|
||||
u32 igb_translate_register_82576(u32 reg);
|
||||
void igb_update_mc_addr_list_82575(struct e1000_hw*, u8*, u32, u32, u32);
|
||||
extern void igb_shutdown_fiber_serdes_link_82575(struct e1000_hw *hw);
|
||||
extern void igb_rx_fifo_flush_82575(struct e1000_hw *hw);
|
||||
|
||||
#define E1000_RAR_ENTRIES_82575 16
|
||||
#define E1000_RAR_ENTRIES_82576 24
|
||||
|
||||
/* SRRCTL bit definitions */
|
||||
#define E1000_SRRCTL_BSIZEPKT_SHIFT 10 /* Shift _right_ */
|
||||
@ -95,6 +99,8 @@ union e1000_adv_rx_desc {
|
||||
/* RSS Hash results */
|
||||
|
||||
/* RSS Packet Types as indicated in the receive descriptor */
|
||||
#define E1000_RXDADV_PKTTYPE_IPV4 0x00000010 /* IPV4 hdr present */
|
||||
#define E1000_RXDADV_PKTTYPE_TCP 0x00000100 /* TCP hdr present */
|
||||
|
||||
/* Transmit Descriptor - Advanced */
|
||||
union e1000_adv_tx_desc {
|
||||
@ -144,9 +150,25 @@ struct e1000_adv_tx_context_desc {
|
||||
#define E1000_RXDCTL_QUEUE_ENABLE 0x02000000 /* Enable specific Rx Queue */
|
||||
|
||||
/* Direct Cache Access (DCA) definitions */
|
||||
#define E1000_DCA_CTRL_DCA_ENABLE 0x00000000 /* DCA Enable */
|
||||
#define E1000_DCA_CTRL_DCA_DISABLE 0x00000001 /* DCA Disable */
|
||||
|
||||
#define E1000_DCA_CTRL_DCA_MODE_CB1 0x00 /* DCA Mode CB1 */
|
||||
#define E1000_DCA_CTRL_DCA_MODE_CB2 0x02 /* DCA Mode CB2 */
|
||||
|
||||
#define E1000_DCA_RXCTRL_CPUID_MASK 0x0000001F /* Rx CPUID Mask */
|
||||
#define E1000_DCA_RXCTRL_DESC_DCA_EN (1 << 5) /* DCA Rx Desc enable */
|
||||
#define E1000_DCA_RXCTRL_HEAD_DCA_EN (1 << 6) /* DCA Rx Desc header enable */
|
||||
#define E1000_DCA_RXCTRL_DATA_DCA_EN (1 << 7) /* DCA Rx Desc payload enable */
|
||||
|
||||
#define E1000_DCA_TXCTRL_CPUID_MASK 0x0000001F /* Tx CPUID Mask */
|
||||
#define E1000_DCA_TXCTRL_DESC_DCA_EN (1 << 5) /* DCA Tx Desc enable */
|
||||
#define E1000_DCA_TXCTRL_TX_WB_RO_EN (1 << 11) /* Tx Desc writeback RO bit */
|
||||
|
||||
/* Additional DCA related definitions, note change in position of CPUID */
|
||||
#define E1000_DCA_TXCTRL_CPUID_MASK_82576 0xFF000000 /* Tx CPUID Mask */
|
||||
#define E1000_DCA_RXCTRL_CPUID_MASK_82576 0xFF000000 /* Rx CPUID Mask */
|
||||
#define E1000_DCA_TXCTRL_CPUID_SHIFT 24 /* Tx CPUID now in the last byte */
|
||||
#define E1000_DCA_RXCTRL_CPUID_SHIFT 24 /* Rx CPUID now in the last byte */
|
||||
|
||||
#endif
|
||||
|
@ -90,6 +90,11 @@
|
||||
#define E1000_I2CCMD_ERROR 0x80000000
|
||||
#define E1000_MAX_SGMII_PHY_REG_ADDR 255
|
||||
#define E1000_I2CCMD_PHY_TIMEOUT 200
|
||||
#define E1000_IVAR_VALID 0x80
|
||||
#define E1000_GPIE_NSICR 0x00000001
|
||||
#define E1000_GPIE_MSIX_MODE 0x00000010
|
||||
#define E1000_GPIE_EIAME 0x40000000
|
||||
#define E1000_GPIE_PBA 0x80000000
|
||||
|
||||
/* Receive Descriptor bit definitions */
|
||||
#define E1000_RXD_STAT_DD 0x01 /* Descriptor Done */
|
||||
@ -213,6 +218,7 @@
|
||||
/* Device Control */
|
||||
#define E1000_CTRL_FD 0x00000001 /* Full duplex.0=half; 1=full */
|
||||
#define E1000_CTRL_GIO_MASTER_DISABLE 0x00000004 /*Blocks new Master requests */
|
||||
#define E1000_CTRL_LRST 0x00000008 /* Link reset. 0=normal,1=reset */
|
||||
#define E1000_CTRL_ASDE 0x00000020 /* Auto-speed detect enable */
|
||||
#define E1000_CTRL_SLU 0x00000040 /* Set link up (Force Link) */
|
||||
#define E1000_CTRL_ILOS 0x00000080 /* Invert Loss-Of Signal */
|
||||
@ -244,6 +250,7 @@
|
||||
*/
|
||||
|
||||
#define E1000_CONNSW_ENRGSRC 0x4
|
||||
#define E1000_PCS_CFG_PCS_EN 8
|
||||
#define E1000_PCS_LCTL_FLV_LINK_UP 1
|
||||
#define E1000_PCS_LCTL_FSV_100 2
|
||||
#define E1000_PCS_LCTL_FSV_1000 4
|
||||
@ -253,6 +260,7 @@
|
||||
#define E1000_PCS_LCTL_AN_ENABLE 0x10000
|
||||
#define E1000_PCS_LCTL_AN_RESTART 0x20000
|
||||
#define E1000_PCS_LCTL_AN_TIMEOUT 0x40000
|
||||
#define E1000_ENABLE_SERDES_LOOPBACK 0x0410
|
||||
|
||||
#define E1000_PCS_LSTS_LINK_OK 1
|
||||
#define E1000_PCS_LSTS_SPEED_100 2
|
||||
@ -360,6 +368,7 @@
|
||||
#define E1000_PBA_16K 0x0010 /* 16KB, default TX allocation */
|
||||
#define E1000_PBA_24K 0x0018
|
||||
#define E1000_PBA_34K 0x0022
|
||||
#define E1000_PBA_64K 0x0040 /* 64KB */
|
||||
|
||||
#define IFS_MAX 80
|
||||
#define IFS_MIN 40
|
||||
@ -528,6 +537,7 @@
|
||||
/* PHY Control Register */
|
||||
#define MII_CR_FULL_DUPLEX 0x0100 /* FDX =1, half duplex =0 */
|
||||
#define MII_CR_RESTART_AUTO_NEG 0x0200 /* Restart auto negotiation */
|
||||
#define MII_CR_POWER_DOWN 0x0800 /* Power down */
|
||||
#define MII_CR_AUTO_NEG_EN 0x1000 /* Auto Neg Enable */
|
||||
#define MII_CR_LOOPBACK 0x4000 /* 0 = normal, 1 = loopback */
|
||||
#define MII_CR_RESET 0x8000 /* 0 = normal, 1 = PHY reset */
|
||||
|
@ -38,6 +38,10 @@
|
||||
|
||||
struct e1000_hw;
|
||||
|
||||
#define E1000_DEV_ID_82576 0x10C9
|
||||
#define E1000_DEV_ID_82576_FIBER 0x10E6
|
||||
#define E1000_DEV_ID_82576_SERDES 0x10E7
|
||||
#define E1000_DEV_ID_82576_QUAD_COPPER 0x10E8
|
||||
#define E1000_DEV_ID_82575EB_COPPER 0x10A7
|
||||
#define E1000_DEV_ID_82575EB_FIBER_SERDES 0x10A9
|
||||
#define E1000_DEV_ID_82575GB_QUAD_COPPER 0x10D6
|
||||
@ -50,6 +54,7 @@ struct e1000_hw;
|
||||
enum e1000_mac_type {
|
||||
e1000_undefined = 0,
|
||||
e1000_82575,
|
||||
e1000_82576,
|
||||
e1000_num_macs /* List is 1-based, so subtract 1 for true count. */
|
||||
};
|
||||
|
||||
@ -410,14 +415,17 @@ struct e1000_mac_operations {
|
||||
s32 (*check_for_link)(struct e1000_hw *);
|
||||
s32 (*reset_hw)(struct e1000_hw *);
|
||||
s32 (*init_hw)(struct e1000_hw *);
|
||||
bool (*check_mng_mode)(struct e1000_hw *);
|
||||
s32 (*setup_physical_interface)(struct e1000_hw *);
|
||||
void (*rar_set)(struct e1000_hw *, u8 *, u32);
|
||||
s32 (*read_mac_addr)(struct e1000_hw *);
|
||||
s32 (*get_speed_and_duplex)(struct e1000_hw *, u16 *, u16 *);
|
||||
void (*mta_set)(struct e1000_hw *, u32);
|
||||
};
|
||||
|
||||
struct e1000_phy_operations {
|
||||
s32 (*acquire_phy)(struct e1000_hw *);
|
||||
s32 (*check_reset_block)(struct e1000_hw *);
|
||||
s32 (*force_speed_duplex)(struct e1000_hw *);
|
||||
s32 (*get_cfg_done)(struct e1000_hw *hw);
|
||||
s32 (*get_cable_length)(struct e1000_hw *);
|
||||
|
@ -36,7 +36,6 @@
|
||||
|
||||
static s32 igb_set_default_fc(struct e1000_hw *hw);
|
||||
static s32 igb_set_fc_watermarks(struct e1000_hw *hw);
|
||||
static u32 igb_hash_mc_addr(struct e1000_hw *hw, u8 *mc_addr);
|
||||
|
||||
/**
|
||||
* igb_remove_device - Free device specific structure
|
||||
@ -360,7 +359,7 @@ void igb_update_mc_addr_list(struct e1000_hw *hw,
|
||||
* the multicast filter table array address and new table value. See
|
||||
* igb_mta_set()
|
||||
**/
|
||||
static u32 igb_hash_mc_addr(struct e1000_hw *hw, u8 *mc_addr)
|
||||
u32 igb_hash_mc_addr(struct e1000_hw *hw, u8 *mc_addr)
|
||||
{
|
||||
u32 hash_value, hash_mask;
|
||||
u8 bit_shift = 0;
|
||||
|
@ -94,5 +94,6 @@ enum e1000_mng_mode {
|
||||
#define E1000_HICR_C 0x02
|
||||
|
||||
extern void e1000_init_function_pointers_82575(struct e1000_hw *hw);
|
||||
extern u32 igb_hash_mc_addr(struct e1000_hw *hw, u8 *mc_addr);
|
||||
|
||||
#endif
|
||||
|
@ -56,6 +56,9 @@
|
||||
#define E1000_EIMC 0x01528 /* Ext. Interrupt Mask Clear - WO */
|
||||
#define E1000_EIAC 0x0152C /* Ext. Interrupt Auto Clear - RW */
|
||||
#define E1000_EIAM 0x01530 /* Ext. Interrupt Ack Auto Clear Mask - RW */
|
||||
#define E1000_GPIE 0x01514 /* General Purpose Interrupt Enable - RW */
|
||||
#define E1000_IVAR0 0x01700 /* Interrupt Vector Allocation (array) - RW */
|
||||
#define E1000_IVAR_MISC 0x01740 /* IVAR for "other" causes - RW */
|
||||
#define E1000_TCTL 0x00400 /* TX Control - RW */
|
||||
#define E1000_TCTL_EXT 0x00404 /* Extended TX Control - RW */
|
||||
#define E1000_TIPG 0x00410 /* TX Inter-packet gap -RW */
|
||||
@ -217,6 +220,7 @@
|
||||
#define E1000_RFCTL 0x05008 /* Receive Filter Control*/
|
||||
#define E1000_MTA 0x05200 /* Multicast Table Array - RW Array */
|
||||
#define E1000_RA 0x05400 /* Receive Address - RW Array */
|
||||
#define E1000_RA2 0x054E0 /* 2nd half of receive address array - RW Array */
|
||||
#define E1000_VFTA 0x05600 /* VLAN Filter Table Array - RW Array */
|
||||
#define E1000_VMD_CTL 0x0581C /* VMDq Control - RW */
|
||||
#define E1000_WUC 0x05800 /* Wakeup Control - RW */
|
||||
@ -235,6 +239,8 @@
|
||||
#define E1000_FACTPS 0x05B30 /* Function Active and Power State to MNG */
|
||||
#define E1000_SWSM 0x05B50 /* SW Semaphore */
|
||||
#define E1000_FWSM 0x05B54 /* FW Semaphore */
|
||||
#define E1000_DCA_ID 0x05B70 /* DCA Requester ID Information - RO */
|
||||
#define E1000_DCA_CTRL 0x05B74 /* DCA Control - RW */
|
||||
#define E1000_HICR 0x08F00 /* Host Inteface Control */
|
||||
|
||||
/* RSS registers */
|
||||
@ -256,7 +262,8 @@
|
||||
#define E1000_RETA(_i) (0x05C00 + ((_i) * 4))
|
||||
#define E1000_RSSRK(_i) (0x05C80 + ((_i) * 4)) /* RSS Random Key - RW Array */
|
||||
|
||||
#define E1000_REGISTER(a, reg) reg
|
||||
#define E1000_REGISTER(a, reg) (((a)->mac.type < e1000_82576) \
|
||||
? reg : e1000_translate_register_82576(reg))
|
||||
|
||||
#define wr32(reg, value) (writel(value, hw->hw_addr + reg))
|
||||
#define rd32(reg) (readl(hw->hw_addr + reg))
|
||||
|
@ -36,12 +36,20 @@
|
||||
|
||||
struct igb_adapter;
|
||||
|
||||
#ifdef CONFIG_IGB_LRO
|
||||
#include <linux/inet_lro.h>
|
||||
#define MAX_LRO_AGGR 32
|
||||
#define MAX_LRO_DESCRIPTORS 8
|
||||
#endif
|
||||
|
||||
/* Interrupt defines */
|
||||
#define IGB_MAX_TX_CLEAN 72
|
||||
|
||||
#define IGB_MIN_DYN_ITR 3000
|
||||
#define IGB_MAX_DYN_ITR 96000
|
||||
#define IGB_START_ITR 6000
|
||||
|
||||
/* ((1000000000ns / (6000ints/s * 1024ns)) << 2 = 648 */
|
||||
#define IGB_START_ITR 648
|
||||
|
||||
#define IGB_DYN_ITR_PACKET_THRESHOLD 2
|
||||
#define IGB_DYN_ITR_LENGTH_LOW 200
|
||||
@ -62,6 +70,7 @@ struct igb_adapter;
|
||||
|
||||
/* Transmit and receive queues */
|
||||
#define IGB_MAX_RX_QUEUES 4
|
||||
#define IGB_MAX_TX_QUEUES 4
|
||||
|
||||
/* RX descriptor control thresholds.
|
||||
* PTHRESH - MAC will consider prefetch if it has fewer than this number of
|
||||
@ -124,6 +133,7 @@ struct igb_buffer {
|
||||
struct {
|
||||
struct page *page;
|
||||
u64 page_dma;
|
||||
unsigned int page_offset;
|
||||
};
|
||||
};
|
||||
};
|
||||
@ -157,18 +167,19 @@ struct igb_ring {
|
||||
union {
|
||||
/* TX */
|
||||
struct {
|
||||
spinlock_t tx_clean_lock;
|
||||
spinlock_t tx_lock;
|
||||
struct igb_queue_stats tx_stats;
|
||||
bool detect_tx_hung;
|
||||
};
|
||||
/* RX */
|
||||
struct {
|
||||
/* arrays of page information for packet split */
|
||||
struct sk_buff *pending_skb;
|
||||
int pending_skb_page;
|
||||
int no_itr_adjust;
|
||||
struct igb_queue_stats rx_stats;
|
||||
struct napi_struct napi;
|
||||
int set_itr;
|
||||
struct igb_ring *buddy;
|
||||
#ifdef CONFIG_IGB_LRO
|
||||
struct net_lro_mgr lro_mgr;
|
||||
bool lro_used;
|
||||
#endif
|
||||
};
|
||||
};
|
||||
|
||||
@ -211,7 +222,6 @@ struct igb_adapter {
|
||||
u32 itr_setting;
|
||||
u16 tx_itr;
|
||||
u16 rx_itr;
|
||||
int set_itr;
|
||||
|
||||
struct work_struct reset_task;
|
||||
struct work_struct watchdog_task;
|
||||
@ -270,15 +280,32 @@ struct igb_adapter {
|
||||
|
||||
/* to not mess up cache alignment, always add to the bottom */
|
||||
unsigned long state;
|
||||
unsigned int msi_enabled;
|
||||
|
||||
unsigned int flags;
|
||||
u32 eeprom_wol;
|
||||
|
||||
/* for ioport free */
|
||||
int bars;
|
||||
int need_ioport;
|
||||
|
||||
#ifdef CONFIG_NETDEVICES_MULTIQUEUE
|
||||
struct igb_ring *multi_tx_table[IGB_MAX_TX_QUEUES];
|
||||
#endif /* CONFIG_NETDEVICES_MULTIQUEUE */
|
||||
#ifdef CONFIG_IGB_LRO
|
||||
unsigned int lro_max_aggr;
|
||||
unsigned int lro_aggregated;
|
||||
unsigned int lro_flushed;
|
||||
unsigned int lro_no_desc;
|
||||
#endif
|
||||
};
|
||||
|
||||
#define IGB_FLAG_HAS_MSI (1 << 0)
|
||||
#define IGB_FLAG_MSI_ENABLE (1 << 1)
|
||||
#define IGB_FLAG_HAS_DCA (1 << 2)
|
||||
#define IGB_FLAG_DCA_ENABLED (1 << 3)
|
||||
#define IGB_FLAG_IN_NETPOLL (1 << 5)
|
||||
#define IGB_FLAG_QUAD_PORT_A (1 << 6)
|
||||
#define IGB_FLAG_NEED_CTX_IDX (1 << 7)
|
||||
|
||||
enum e1000_state_t {
|
||||
__IGB_TESTING,
|
||||
__IGB_RESETTING,
|
||||
|
@ -93,13 +93,16 @@ static const struct igb_stats igb_gstrings_stats[] = {
|
||||
{ "tx_smbus", IGB_STAT(stats.mgptc) },
|
||||
{ "rx_smbus", IGB_STAT(stats.mgprc) },
|
||||
{ "dropped_smbus", IGB_STAT(stats.mgpdc) },
|
||||
#ifdef CONFIG_IGB_LRO
|
||||
{ "lro_aggregated", IGB_STAT(lro_aggregated) },
|
||||
{ "lro_flushed", IGB_STAT(lro_flushed) },
|
||||
{ "lro_no_desc", IGB_STAT(lro_no_desc) },
|
||||
#endif
|
||||
};
|
||||
|
||||
#define IGB_QUEUE_STATS_LEN \
|
||||
((((((struct igb_adapter *)netdev->priv)->num_rx_queues > 1) ? \
|
||||
((struct igb_adapter *)netdev->priv)->num_rx_queues : 0) + \
|
||||
(((((struct igb_adapter *)netdev->priv)->num_tx_queues > 1) ? \
|
||||
((struct igb_adapter *)netdev->priv)->num_tx_queues : 0))) * \
|
||||
((((struct igb_adapter *)netdev->priv)->num_rx_queues + \
|
||||
((struct igb_adapter *)netdev->priv)->num_tx_queues) * \
|
||||
(sizeof(struct igb_queue_stats) / sizeof(u64)))
|
||||
#define IGB_GLOBAL_STATS_LEN \
|
||||
sizeof(igb_gstrings_stats) / sizeof(struct igb_stats)
|
||||
@ -829,8 +832,9 @@ err_setup:
|
||||
/* ethtool register test data */
|
||||
struct igb_reg_test {
|
||||
u16 reg;
|
||||
u8 array_len;
|
||||
u8 test_type;
|
||||
u16 reg_offset;
|
||||
u16 array_len;
|
||||
u16 test_type;
|
||||
u32 mask;
|
||||
u32 write;
|
||||
};
|
||||
@ -852,34 +856,72 @@ struct igb_reg_test {
|
||||
#define TABLE64_TEST_LO 5
|
||||
#define TABLE64_TEST_HI 6
|
||||
|
||||
/* default register test */
|
||||
static struct igb_reg_test reg_test_82575[] = {
|
||||
{ E1000_FCAL, 1, PATTERN_TEST, 0xFFFFFFFF, 0xFFFFFFFF },
|
||||
{ E1000_FCAH, 1, PATTERN_TEST, 0x0000FFFF, 0xFFFFFFFF },
|
||||
{ E1000_FCT, 1, PATTERN_TEST, 0x0000FFFF, 0xFFFFFFFF },
|
||||
{ E1000_VET, 1, PATTERN_TEST, 0xFFFFFFFF, 0xFFFFFFFF },
|
||||
{ E1000_RDBAL(0), 4, PATTERN_TEST, 0xFFFFFF80, 0xFFFFFFFF },
|
||||
{ E1000_RDBAH(0), 4, PATTERN_TEST, 0xFFFFFFFF, 0xFFFFFFFF },
|
||||
{ E1000_RDLEN(0), 4, PATTERN_TEST, 0x000FFF80, 0x000FFFFF },
|
||||
/* 82576 reg test */
|
||||
static struct igb_reg_test reg_test_82576[] = {
|
||||
{ E1000_FCAL, 0x100, 1, PATTERN_TEST, 0xFFFFFFFF, 0xFFFFFFFF },
|
||||
{ E1000_FCAH, 0x100, 1, PATTERN_TEST, 0x0000FFFF, 0xFFFFFFFF },
|
||||
{ E1000_FCT, 0x100, 1, PATTERN_TEST, 0x0000FFFF, 0xFFFFFFFF },
|
||||
{ E1000_VET, 0x100, 1, PATTERN_TEST, 0xFFFFFFFF, 0xFFFFFFFF },
|
||||
{ E1000_RDBAL(0), 0x100, 4, PATTERN_TEST, 0xFFFFFF80, 0xFFFFFFFF },
|
||||
{ E1000_RDBAH(0), 0x100, 4, PATTERN_TEST, 0xFFFFFFFF, 0xFFFFFFFF },
|
||||
{ E1000_RDLEN(0), 0x100, 4, PATTERN_TEST, 0x000FFFF0, 0x000FFFFF },
|
||||
{ E1000_RDBAL(4), 0x40, 8, PATTERN_TEST, 0xFFFFFF80, 0xFFFFFFFF },
|
||||
{ E1000_RDBAH(4), 0x40, 8, PATTERN_TEST, 0xFFFFFFFF, 0xFFFFFFFF },
|
||||
{ E1000_RDLEN(4), 0x40, 8, PATTERN_TEST, 0x000FFFF0, 0x000FFFFF },
|
||||
/* Enable all four RX queues before testing. */
|
||||
{ E1000_RXDCTL(0), 4, WRITE_NO_TEST, 0, E1000_RXDCTL_QUEUE_ENABLE },
|
||||
{ E1000_RXDCTL(0), 0x100, 1, WRITE_NO_TEST, 0, E1000_RXDCTL_QUEUE_ENABLE },
|
||||
/* RDH is read-only for 82576, only test RDT. */
|
||||
{ E1000_RDT(0), 0x100, 4, PATTERN_TEST, 0x0000FFFF, 0x0000FFFF },
|
||||
{ E1000_RXDCTL(0), 0x100, 4, WRITE_NO_TEST, 0, 0 },
|
||||
{ E1000_FCRTH, 0x100, 1, PATTERN_TEST, 0x0000FFF0, 0x0000FFF0 },
|
||||
{ E1000_FCTTV, 0x100, 1, PATTERN_TEST, 0x0000FFFF, 0x0000FFFF },
|
||||
{ E1000_TIPG, 0x100, 1, PATTERN_TEST, 0x3FFFFFFF, 0x3FFFFFFF },
|
||||
{ E1000_TDBAL(0), 0x100, 4, PATTERN_TEST, 0xFFFFFF80, 0xFFFFFFFF },
|
||||
{ E1000_TDBAH(0), 0x100, 4, PATTERN_TEST, 0xFFFFFFFF, 0xFFFFFFFF },
|
||||
{ E1000_TDLEN(0), 0x100, 4, PATTERN_TEST, 0x000FFFF0, 0x000FFFFF },
|
||||
{ E1000_TDBAL(4), 0x40, 8, PATTERN_TEST, 0xFFFFFF80, 0xFFFFFFFF },
|
||||
{ E1000_TDBAH(4), 0x40, 8, PATTERN_TEST, 0xFFFFFFFF, 0xFFFFFFFF },
|
||||
{ E1000_TDLEN(4), 0x40, 8, PATTERN_TEST, 0x000FFFF0, 0x000FFFFF },
|
||||
{ E1000_RCTL, 0x100, 1, SET_READ_TEST, 0xFFFFFFFF, 0x00000000 },
|
||||
{ E1000_RCTL, 0x100, 1, SET_READ_TEST, 0x04CFB0FE, 0x003FFFFB },
|
||||
{ E1000_RCTL, 0x100, 1, SET_READ_TEST, 0x04CFB0FE, 0xFFFFFFFF },
|
||||
{ E1000_TCTL, 0x100, 1, SET_READ_TEST, 0xFFFFFFFF, 0x00000000 },
|
||||
{ E1000_RA, 0, 16, TABLE64_TEST_LO, 0xFFFFFFFF, 0xFFFFFFFF },
|
||||
{ E1000_RA, 0, 16, TABLE64_TEST_HI, 0x83FFFFFF, 0xFFFFFFFF },
|
||||
{ E1000_RA2, 0, 8, TABLE64_TEST_LO, 0xFFFFFFFF, 0xFFFFFFFF },
|
||||
{ E1000_RA2, 0, 8, TABLE64_TEST_HI, 0x83FFFFFF, 0xFFFFFFFF },
|
||||
{ E1000_MTA, 0, 128,TABLE32_TEST, 0xFFFFFFFF, 0xFFFFFFFF },
|
||||
{ 0, 0, 0, 0 }
|
||||
};
|
||||
|
||||
/* 82575 register test */
|
||||
static struct igb_reg_test reg_test_82575[] = {
|
||||
{ E1000_FCAL, 0x100, 1, PATTERN_TEST, 0xFFFFFFFF, 0xFFFFFFFF },
|
||||
{ E1000_FCAH, 0x100, 1, PATTERN_TEST, 0x0000FFFF, 0xFFFFFFFF },
|
||||
{ E1000_FCT, 0x100, 1, PATTERN_TEST, 0x0000FFFF, 0xFFFFFFFF },
|
||||
{ E1000_VET, 0x100, 1, PATTERN_TEST, 0xFFFFFFFF, 0xFFFFFFFF },
|
||||
{ E1000_RDBAL(0), 0x100, 4, PATTERN_TEST, 0xFFFFFF80, 0xFFFFFFFF },
|
||||
{ E1000_RDBAH(0), 0x100, 4, PATTERN_TEST, 0xFFFFFFFF, 0xFFFFFFFF },
|
||||
{ E1000_RDLEN(0), 0x100, 4, PATTERN_TEST, 0x000FFF80, 0x000FFFFF },
|
||||
/* Enable all four RX queues before testing. */
|
||||
{ E1000_RXDCTL(0), 0x100, 4, WRITE_NO_TEST, 0, E1000_RXDCTL_QUEUE_ENABLE },
|
||||
/* RDH is read-only for 82575, only test RDT. */
|
||||
{ E1000_RDT(0), 4, PATTERN_TEST, 0x0000FFFF, 0x0000FFFF },
|
||||
{ E1000_RXDCTL(0), 4, WRITE_NO_TEST, 0, 0 },
|
||||
{ E1000_FCRTH, 1, PATTERN_TEST, 0x0000FFF0, 0x0000FFF0 },
|
||||
{ E1000_FCTTV, 1, PATTERN_TEST, 0x0000FFFF, 0x0000FFFF },
|
||||
{ E1000_TIPG, 1, PATTERN_TEST, 0x3FFFFFFF, 0x3FFFFFFF },
|
||||
{ E1000_TDBAL(0), 4, PATTERN_TEST, 0xFFFFFF80, 0xFFFFFFFF },
|
||||
{ E1000_TDBAH(0), 4, PATTERN_TEST, 0xFFFFFFFF, 0xFFFFFFFF },
|
||||
{ E1000_TDLEN(0), 4, PATTERN_TEST, 0x000FFF80, 0x000FFFFF },
|
||||
{ E1000_RCTL, 1, SET_READ_TEST, 0xFFFFFFFF, 0x00000000 },
|
||||
{ E1000_RCTL, 1, SET_READ_TEST, 0x04CFB3FE, 0x003FFFFB },
|
||||
{ E1000_RCTL, 1, SET_READ_TEST, 0x04CFB3FE, 0xFFFFFFFF },
|
||||
{ E1000_TCTL, 1, SET_READ_TEST, 0xFFFFFFFF, 0x00000000 },
|
||||
{ E1000_TXCW, 1, PATTERN_TEST, 0xC000FFFF, 0x0000FFFF },
|
||||
{ E1000_RA, 16, TABLE64_TEST_LO, 0xFFFFFFFF, 0xFFFFFFFF },
|
||||
{ E1000_RA, 16, TABLE64_TEST_HI, 0x800FFFFF, 0xFFFFFFFF },
|
||||
{ E1000_MTA, 128, TABLE32_TEST, 0xFFFFFFFF, 0xFFFFFFFF },
|
||||
{ E1000_RDT(0), 0x100, 4, PATTERN_TEST, 0x0000FFFF, 0x0000FFFF },
|
||||
{ E1000_RXDCTL(0), 0x100, 4, WRITE_NO_TEST, 0, 0 },
|
||||
{ E1000_FCRTH, 0x100, 1, PATTERN_TEST, 0x0000FFF0, 0x0000FFF0 },
|
||||
{ E1000_FCTTV, 0x100, 1, PATTERN_TEST, 0x0000FFFF, 0x0000FFFF },
|
||||
{ E1000_TIPG, 0x100, 1, PATTERN_TEST, 0x3FFFFFFF, 0x3FFFFFFF },
|
||||
{ E1000_TDBAL(0), 0x100, 4, PATTERN_TEST, 0xFFFFFF80, 0xFFFFFFFF },
|
||||
{ E1000_TDBAH(0), 0x100, 4, PATTERN_TEST, 0xFFFFFFFF, 0xFFFFFFFF },
|
||||
{ E1000_TDLEN(0), 0x100, 4, PATTERN_TEST, 0x000FFF80, 0x000FFFFF },
|
||||
{ E1000_RCTL, 0x100, 1, SET_READ_TEST, 0xFFFFFFFF, 0x00000000 },
|
||||
{ E1000_RCTL, 0x100, 1, SET_READ_TEST, 0x04CFB3FE, 0x003FFFFB },
|
||||
{ E1000_RCTL, 0x100, 1, SET_READ_TEST, 0x04CFB3FE, 0xFFFFFFFF },
|
||||
{ E1000_TCTL, 0x100, 1, SET_READ_TEST, 0xFFFFFFFF, 0x00000000 },
|
||||
{ E1000_TXCW, 0x100, 1, PATTERN_TEST, 0xC000FFFF, 0x0000FFFF },
|
||||
{ E1000_RA, 0, 16, TABLE64_TEST_LO, 0xFFFFFFFF, 0xFFFFFFFF },
|
||||
{ E1000_RA, 0, 16, TABLE64_TEST_HI, 0x800FFFFF, 0xFFFFFFFF },
|
||||
{ E1000_MTA, 0, 128, TABLE32_TEST, 0xFFFFFFFF, 0xFFFFFFFF },
|
||||
{ 0, 0, 0, 0 }
|
||||
};
|
||||
|
||||
@ -939,7 +981,15 @@ static int igb_reg_test(struct igb_adapter *adapter, u64 *data)
|
||||
u32 i, toggle;
|
||||
|
||||
toggle = 0x7FFFF3FF;
|
||||
|
||||
switch (adapter->hw.mac.type) {
|
||||
case e1000_82576:
|
||||
test = reg_test_82576;
|
||||
break;
|
||||
default:
|
||||
test = reg_test_82575;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Because the status register is such a special case,
|
||||
* we handle it separately from the rest of the register
|
||||
@ -966,19 +1016,19 @@ static int igb_reg_test(struct igb_adapter *adapter, u64 *data)
|
||||
for (i = 0; i < test->array_len; i++) {
|
||||
switch (test->test_type) {
|
||||
case PATTERN_TEST:
|
||||
REG_PATTERN_TEST(test->reg + (i * 0x100),
|
||||
REG_PATTERN_TEST(test->reg + (i * test->reg_offset),
|
||||
test->mask,
|
||||
test->write);
|
||||
break;
|
||||
case SET_READ_TEST:
|
||||
REG_SET_AND_CHECK(test->reg + (i * 0x100),
|
||||
REG_SET_AND_CHECK(test->reg + (i * test->reg_offset),
|
||||
test->mask,
|
||||
test->write);
|
||||
break;
|
||||
case WRITE_NO_TEST:
|
||||
writel(test->write,
|
||||
(adapter->hw.hw_addr + test->reg)
|
||||
+ (i * 0x100));
|
||||
+ (i * test->reg_offset));
|
||||
break;
|
||||
case TABLE32_TEST:
|
||||
REG_PATTERN_TEST(test->reg + (i * 4),
|
||||
@ -1052,7 +1102,7 @@ static int igb_intr_test(struct igb_adapter *adapter, u64 *data)
|
||||
if (adapter->msix_entries) {
|
||||
/* NOTE: we don't test MSI-X interrupts here, yet */
|
||||
return 0;
|
||||
} else if (adapter->msi_enabled) {
|
||||
} else if (adapter->flags & IGB_FLAG_HAS_MSI) {
|
||||
shared_int = false;
|
||||
if (request_irq(irq, &igb_test_intr, 0, netdev->name, netdev)) {
|
||||
*data = 1;
|
||||
@ -1394,13 +1444,39 @@ static int igb_set_phy_loopback(struct igb_adapter *adapter)
|
||||
static int igb_setup_loopback_test(struct igb_adapter *adapter)
|
||||
{
|
||||
struct e1000_hw *hw = &adapter->hw;
|
||||
u32 rctl;
|
||||
u32 reg;
|
||||
|
||||
if (hw->phy.media_type == e1000_media_type_fiber ||
|
||||
hw->phy.media_type == e1000_media_type_internal_serdes) {
|
||||
rctl = rd32(E1000_RCTL);
|
||||
rctl |= E1000_RCTL_LBM_TCVR;
|
||||
wr32(E1000_RCTL, rctl);
|
||||
reg = rd32(E1000_RCTL);
|
||||
reg |= E1000_RCTL_LBM_TCVR;
|
||||
wr32(E1000_RCTL, reg);
|
||||
|
||||
wr32(E1000_SCTL, E1000_ENABLE_SERDES_LOOPBACK);
|
||||
|
||||
reg = rd32(E1000_CTRL);
|
||||
reg &= ~(E1000_CTRL_RFCE |
|
||||
E1000_CTRL_TFCE |
|
||||
E1000_CTRL_LRST);
|
||||
reg |= E1000_CTRL_SLU |
|
||||
E1000_CTRL_FD;
|
||||
wr32(E1000_CTRL, reg);
|
||||
|
||||
/* Unset switch control to serdes energy detect */
|
||||
reg = rd32(E1000_CONNSW);
|
||||
reg &= ~E1000_CONNSW_ENRGSRC;
|
||||
wr32(E1000_CONNSW, reg);
|
||||
|
||||
/* Set PCS register for forced speed */
|
||||
reg = rd32(E1000_PCS_LCTL);
|
||||
reg &= ~E1000_PCS_LCTL_AN_ENABLE; /* Disable Autoneg*/
|
||||
reg |= E1000_PCS_LCTL_FLV_LINK_UP | /* Force link up */
|
||||
E1000_PCS_LCTL_FSV_1000 | /* Force 1000 */
|
||||
E1000_PCS_LCTL_FDV_FULL | /* SerDes Full duplex */
|
||||
E1000_PCS_LCTL_FSD | /* Force Speed */
|
||||
E1000_PCS_LCTL_FORCE_LINK; /* Force Link */
|
||||
wr32(E1000_PCS_LCTL, reg);
|
||||
|
||||
return 0;
|
||||
} else if (hw->phy.media_type == e1000_media_type_copper) {
|
||||
return igb_set_phy_loopback(adapter);
|
||||
@ -1660,6 +1736,8 @@ static int igb_wol_exclusion(struct igb_adapter *adapter,
|
||||
wol->supported = 0;
|
||||
break;
|
||||
case E1000_DEV_ID_82575EB_FIBER_SERDES:
|
||||
case E1000_DEV_ID_82576_FIBER:
|
||||
case E1000_DEV_ID_82576_SERDES:
|
||||
/* Wake events not supported on port B */
|
||||
if (rd32(E1000_STATUS) & E1000_STATUS_FUNC_1) {
|
||||
wol->supported = 0;
|
||||
@ -1668,6 +1746,15 @@ static int igb_wol_exclusion(struct igb_adapter *adapter,
|
||||
/* return success for non excluded adapter ports */
|
||||
retval = 0;
|
||||
break;
|
||||
case E1000_DEV_ID_82576_QUAD_COPPER:
|
||||
/* quad port adapters only support WoL on port A */
|
||||
if (!(adapter->flags & IGB_FLAG_QUAD_PORT_A)) {
|
||||
wol->supported = 0;
|
||||
break;
|
||||
}
|
||||
/* return success for non excluded adapter ports */
|
||||
retval = 0;
|
||||
break;
|
||||
default:
|
||||
/* dual port cards only support WoL on port A from now on
|
||||
* unless it was enabled in the eeprom for port B
|
||||
@ -1774,6 +1861,8 @@ static int igb_set_coalesce(struct net_device *netdev,
|
||||
struct ethtool_coalesce *ec)
|
||||
{
|
||||
struct igb_adapter *adapter = netdev_priv(netdev);
|
||||
struct e1000_hw *hw = &adapter->hw;
|
||||
int i;
|
||||
|
||||
if ((ec->rx_coalesce_usecs > IGB_MAX_ITR_USECS) ||
|
||||
((ec->rx_coalesce_usecs > 3) &&
|
||||
@ -1782,13 +1871,16 @@ static int igb_set_coalesce(struct net_device *netdev,
|
||||
return -EINVAL;
|
||||
|
||||
/* convert to rate of irq's per second */
|
||||
if (ec->rx_coalesce_usecs <= 3)
|
||||
if (ec->rx_coalesce_usecs && ec->rx_coalesce_usecs <= 3) {
|
||||
adapter->itr_setting = ec->rx_coalesce_usecs;
|
||||
else
|
||||
adapter->itr_setting = (1000000 / ec->rx_coalesce_usecs);
|
||||
adapter->itr = IGB_START_ITR;
|
||||
} else {
|
||||
adapter->itr_setting = ec->rx_coalesce_usecs << 2;
|
||||
adapter->itr = adapter->itr_setting;
|
||||
}
|
||||
|
||||
if (netif_running(netdev))
|
||||
igb_reinit_locked(adapter);
|
||||
for (i = 0; i < adapter->num_rx_queues; i++)
|
||||
wr32(adapter->rx_ring[i].itr_register, adapter->itr);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -1801,7 +1893,7 @@ static int igb_get_coalesce(struct net_device *netdev,
|
||||
if (adapter->itr_setting <= 3)
|
||||
ec->rx_coalesce_usecs = adapter->itr_setting;
|
||||
else
|
||||
ec->rx_coalesce_usecs = 1000000 / adapter->itr_setting;
|
||||
ec->rx_coalesce_usecs = adapter->itr_setting >> 2;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -1835,6 +1927,18 @@ static void igb_get_ethtool_stats(struct net_device *netdev,
|
||||
int stat_count = sizeof(struct igb_queue_stats) / sizeof(u64);
|
||||
int j;
|
||||
int i;
|
||||
#ifdef CONFIG_IGB_LRO
|
||||
int aggregated = 0, flushed = 0, no_desc = 0;
|
||||
|
||||
for (i = 0; i < adapter->num_rx_queues; i++) {
|
||||
aggregated += adapter->rx_ring[i].lro_mgr.stats.aggregated;
|
||||
flushed += adapter->rx_ring[i].lro_mgr.stats.flushed;
|
||||
no_desc += adapter->rx_ring[i].lro_mgr.stats.no_desc;
|
||||
}
|
||||
adapter->lro_aggregated = aggregated;
|
||||
adapter->lro_flushed = flushed;
|
||||
adapter->lro_no_desc = no_desc;
|
||||
#endif
|
||||
|
||||
igb_update_stats(adapter);
|
||||
for (i = 0; i < IGB_GLOBAL_STATS_LEN; i++) {
|
||||
@ -1842,6 +1946,13 @@ static void igb_get_ethtool_stats(struct net_device *netdev,
|
||||
data[i] = (igb_gstrings_stats[i].sizeof_stat ==
|
||||
sizeof(u64)) ? *(u64 *)p : *(u32 *)p;
|
||||
}
|
||||
for (j = 0; j < adapter->num_tx_queues; j++) {
|
||||
int k;
|
||||
queue_stat = (u64 *)&adapter->tx_ring[j].tx_stats;
|
||||
for (k = 0; k < stat_count; k++)
|
||||
data[i + k] = queue_stat[k];
|
||||
i += k;
|
||||
}
|
||||
for (j = 0; j < adapter->num_rx_queues; j++) {
|
||||
int k;
|
||||
queue_stat = (u64 *)&adapter->rx_ring[j].rx_stats;
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,7 +1,7 @@
|
||||
################################################################################
|
||||
#
|
||||
# Intel PRO/10GbE Linux driver
|
||||
# Copyright(c) 1999 - 2006 Intel Corporation.
|
||||
# Copyright(c) 1999 - 2008 Intel Corporation.
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify it
|
||||
# under the terms and conditions of the GNU General Public License,
|
||||
|
@ -1,7 +1,7 @@
|
||||
/*******************************************************************************
|
||||
|
||||
Intel PRO/10GbE Linux driver
|
||||
Copyright(c) 1999 - 2006 Intel Corporation.
|
||||
Copyright(c) 1999 - 2008 Intel Corporation.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it
|
||||
under the terms and conditions of the GNU General Public License,
|
||||
@ -94,10 +94,8 @@ struct ixgb_adapter;
|
||||
#define MIN_TXD 64
|
||||
|
||||
/* hardware cannot reliably support more than 512 descriptors owned by
|
||||
* hardware descrioptor cache otherwise an unreliable ring under heavy
|
||||
* recieve load may result */
|
||||
/* #define DEFAULT_RXD 1024 */
|
||||
/* #define MAX_RXD 4096 */
|
||||
* hardware descriptor cache otherwise an unreliable ring under heavy
|
||||
* receive load may result */
|
||||
#define DEFAULT_RXD 512
|
||||
#define MAX_RXD 512
|
||||
#define MIN_RXD 64
|
||||
@ -157,7 +155,6 @@ struct ixgb_adapter {
|
||||
u32 part_num;
|
||||
u16 link_speed;
|
||||
u16 link_duplex;
|
||||
spinlock_t tx_lock;
|
||||
struct work_struct tx_timeout_task;
|
||||
|
||||
struct timer_list blink_timer;
|
||||
|
@ -1,7 +1,7 @@
|
||||
/*******************************************************************************
|
||||
|
||||
Intel PRO/10GbE Linux driver
|
||||
Copyright(c) 1999 - 2006 Intel Corporation.
|
||||
Copyright(c) 1999 - 2008 Intel Corporation.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it
|
||||
under the terms and conditions of the GNU General Public License,
|
||||
@ -205,7 +205,7 @@ ixgb_standby_eeprom(struct ixgb_hw *hw)
|
||||
|
||||
eecd_reg = IXGB_READ_REG(hw, EECD);
|
||||
|
||||
/* Deselct EEPROM */
|
||||
/* Deselect EEPROM */
|
||||
eecd_reg &= ~(IXGB_EECD_CS | IXGB_EECD_SK);
|
||||
IXGB_WRITE_REG(hw, EECD, eecd_reg);
|
||||
udelay(50);
|
||||
@ -293,7 +293,7 @@ ixgb_wait_eeprom_command(struct ixgb_hw *hw)
|
||||
*/
|
||||
ixgb_standby_eeprom(hw);
|
||||
|
||||
/* Now read DO repeatedly until is high (equal to '1'). The EEEPROM will
|
||||
/* Now read DO repeatedly until is high (equal to '1'). The EEPROM will
|
||||
* signal that the command has been completed by raising the DO signal.
|
||||
* If DO does not go high in 10 milliseconds, then error out.
|
||||
*/
|
||||
@ -365,7 +365,7 @@ ixgb_update_eeprom_checksum(struct ixgb_hw *hw)
|
||||
*
|
||||
* hw - Struct containing variables accessed by shared code
|
||||
* reg - offset within the EEPROM to be written to
|
||||
* data - 16 bit word to be writen to the EEPROM
|
||||
* data - 16 bit word to be written to the EEPROM
|
||||
*
|
||||
* If ixgb_update_eeprom_checksum is not called after this function, the
|
||||
* EEPROM will most likely contain an invalid checksum.
|
||||
|
@ -1,7 +1,7 @@
|
||||
/*******************************************************************************
|
||||
|
||||
Intel PRO/10GbE Linux driver
|
||||
Copyright(c) 1999 - 2006 Intel Corporation.
|
||||
Copyright(c) 1999 - 2008 Intel Corporation.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it
|
||||
under the terms and conditions of the GNU General Public License,
|
||||
@ -34,11 +34,11 @@
|
||||
#define IXGB_ETH_LENGTH_OF_ADDRESS 6
|
||||
|
||||
/* EEPROM Commands */
|
||||
#define EEPROM_READ_OPCODE 0x6 /* EERPOM read opcode */
|
||||
#define EEPROM_WRITE_OPCODE 0x5 /* EERPOM write opcode */
|
||||
#define EEPROM_ERASE_OPCODE 0x7 /* EERPOM erase opcode */
|
||||
#define EEPROM_EWEN_OPCODE 0x13 /* EERPOM erase/write enable */
|
||||
#define EEPROM_EWDS_OPCODE 0x10 /* EERPOM erast/write disable */
|
||||
#define EEPROM_READ_OPCODE 0x6 /* EEPROM read opcode */
|
||||
#define EEPROM_WRITE_OPCODE 0x5 /* EEPROM write opcode */
|
||||
#define EEPROM_ERASE_OPCODE 0x7 /* EEPROM erase opcode */
|
||||
#define EEPROM_EWEN_OPCODE 0x13 /* EEPROM erase/write enable */
|
||||
#define EEPROM_EWDS_OPCODE 0x10 /* EEPROM erase/write disable */
|
||||
|
||||
/* EEPROM MAP (Word Offsets) */
|
||||
#define EEPROM_IA_1_2_REG 0x0000
|
||||
|
@ -1,7 +1,7 @@
|
||||
/*******************************************************************************
|
||||
|
||||
Intel PRO/10GbE Linux driver
|
||||
Copyright(c) 1999 - 2006 Intel Corporation.
|
||||
Copyright(c) 1999 - 2008 Intel Corporation.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it
|
||||
under the terms and conditions of the GNU General Public License,
|
||||
@ -441,12 +441,10 @@ ixgb_get_eeprom(struct net_device *netdev,
|
||||
return -ENOMEM;
|
||||
|
||||
/* note the eeprom was good because the driver loaded */
|
||||
for(i = 0; i <= (last_word - first_word); i++) {
|
||||
for (i = 0; i <= (last_word - first_word); i++)
|
||||
eeprom_buff[i] = ixgb_get_eeprom_word(hw, (first_word + i));
|
||||
}
|
||||
|
||||
memcpy(bytes, (u8 *)eeprom_buff + (eeprom->offset & 1),
|
||||
eeprom->len);
|
||||
memcpy(bytes, (u8 *)eeprom_buff + (eeprom->offset & 1), eeprom->len);
|
||||
kfree(eeprom_buff);
|
||||
|
||||
geeprom_error:
|
||||
|
@ -1,7 +1,7 @@
|
||||
/*******************************************************************************
|
||||
|
||||
Intel PRO/10GbE Linux driver
|
||||
Copyright(c) 1999 - 2006 Intel Corporation.
|
||||
Copyright(c) 1999 - 2008 Intel Corporation.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it
|
||||
under the terms and conditions of the GNU General Public License,
|
||||
@ -371,7 +371,7 @@ ixgb_init_hw(struct ixgb_hw *hw)
|
||||
* hw - Struct containing variables accessed by shared code
|
||||
*
|
||||
* Places the MAC address in receive address register 0 and clears the rest
|
||||
* of the receive addresss registers. Clears the multicast table. Assumes
|
||||
* of the receive address registers. Clears the multicast table. Assumes
|
||||
* the receiver is in reset when the routine is called.
|
||||
*****************************************************************************/
|
||||
static void
|
||||
@ -459,9 +459,8 @@ ixgb_mc_addr_list_update(struct ixgb_hw *hw,
|
||||
|
||||
/* Clear the MTA */
|
||||
DEBUGOUT(" Clearing MTA\n");
|
||||
for(i = 0; i < IXGB_MC_TBL_SIZE; i++) {
|
||||
for (i = 0; i < IXGB_MC_TBL_SIZE; i++)
|
||||
IXGB_WRITE_REG_ARRAY(hw, MTA, i, 0);
|
||||
}
|
||||
|
||||
/* Add the new addresses */
|
||||
for (i = 0; i < mc_addr_count; i++) {
|
||||
@ -719,9 +718,8 @@ ixgb_setup_fc(struct ixgb_hw *hw)
|
||||
/* Write the new settings */
|
||||
IXGB_WRITE_REG(hw, CTRL0, ctrl_reg);
|
||||
|
||||
if (pap_reg != 0) {
|
||||
if (pap_reg != 0)
|
||||
IXGB_WRITE_REG(hw, PAP, pap_reg);
|
||||
}
|
||||
|
||||
/* Set the flow control receive threshold registers. Normally,
|
||||
* these registers will be set to a default threshold that may be
|
||||
@ -965,7 +963,7 @@ ixgb_check_for_link(struct ixgb_hw *hw)
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* Check for a bad link condition that may have occured.
|
||||
* Check for a bad link condition that may have occurred.
|
||||
* The indication is that the RFC / LFC registers may be incrementing
|
||||
* continually. A full adapter reset is required to recover.
|
||||
*
|
||||
|
@ -1,7 +1,7 @@
|
||||
/*******************************************************************************
|
||||
|
||||
Intel PRO/10GbE Linux driver
|
||||
Copyright(c) 1999 - 2006 Intel Corporation.
|
||||
Copyright(c) 1999 - 2008 Intel Corporation.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it
|
||||
under the terms and conditions of the GNU General Public License,
|
||||
|
@ -1,7 +1,7 @@
|
||||
/*******************************************************************************
|
||||
|
||||
Intel PRO/10GbE Linux driver
|
||||
Copyright(c) 1999 - 2006 Intel Corporation.
|
||||
Copyright(c) 1999 - 2008 Intel Corporation.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it
|
||||
under the terms and conditions of the GNU General Public License,
|
||||
|
@ -1,7 +1,7 @@
|
||||
/*******************************************************************************
|
||||
|
||||
Intel PRO/10GbE Linux driver
|
||||
Copyright(c) 1999 - 2006 Intel Corporation.
|
||||
Copyright(c) 1999 - 2008 Intel Corporation.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it
|
||||
under the terms and conditions of the GNU General Public License,
|
||||
@ -31,14 +31,16 @@
|
||||
char ixgb_driver_name[] = "ixgb";
|
||||
static char ixgb_driver_string[] = "Intel(R) PRO/10GbE Network Driver";
|
||||
|
||||
#ifndef CONFIG_IXGB_NAPI
|
||||
#define DRIVERNAPI
|
||||
#else
|
||||
#define DRIVERNAPI "-NAPI"
|
||||
#endif
|
||||
#define DRV_VERSION "1.0.126-k4"DRIVERNAPI
|
||||
#define DRV_VERSION "1.0.135-k2" DRIVERNAPI
|
||||
const char ixgb_driver_version[] = DRV_VERSION;
|
||||
static const char ixgb_copyright[] = "Copyright (c) 1999-2006 Intel Corporation.";
|
||||
static const char ixgb_copyright[] = "Copyright (c) 1999-2008 Intel Corporation.";
|
||||
|
||||
#define IXGB_CB_LENGTH 256
|
||||
static unsigned int copybreak __read_mostly = IXGB_CB_LENGTH;
|
||||
module_param(copybreak, uint, 0644);
|
||||
MODULE_PARM_DESC(copybreak,
|
||||
"Maximum size of packet that is copied to a new buffer on receive");
|
||||
|
||||
/* ixgb_pci_tbl - PCI Device ID Table
|
||||
*
|
||||
@ -65,16 +67,6 @@ static struct pci_device_id ixgb_pci_tbl[] = {
|
||||
MODULE_DEVICE_TABLE(pci, ixgb_pci_tbl);
|
||||
|
||||
/* Local Function Prototypes */
|
||||
|
||||
int ixgb_up(struct ixgb_adapter *adapter);
|
||||
void ixgb_down(struct ixgb_adapter *adapter, bool kill_watchdog);
|
||||
void ixgb_reset(struct ixgb_adapter *adapter);
|
||||
int ixgb_setup_tx_resources(struct ixgb_adapter *adapter);
|
||||
int ixgb_setup_rx_resources(struct ixgb_adapter *adapter);
|
||||
void ixgb_free_tx_resources(struct ixgb_adapter *adapter);
|
||||
void ixgb_free_rx_resources(struct ixgb_adapter *adapter);
|
||||
void ixgb_update_stats(struct ixgb_adapter *adapter);
|
||||
|
||||
static int ixgb_init_module(void);
|
||||
static void ixgb_exit_module(void);
|
||||
static int ixgb_probe(struct pci_dev *pdev, const struct pci_device_id *ent);
|
||||
@ -96,16 +88,13 @@ static int ixgb_set_mac(struct net_device *netdev, void *p);
|
||||
static irqreturn_t ixgb_intr(int irq, void *data);
|
||||
static bool ixgb_clean_tx_irq(struct ixgb_adapter *adapter);
|
||||
|
||||
#ifdef CONFIG_IXGB_NAPI
|
||||
static int ixgb_clean(struct napi_struct *napi, int budget);
|
||||
static bool ixgb_clean_rx_irq(struct ixgb_adapter *adapter,
|
||||
int *work_done, int work_to_do);
|
||||
#else
|
||||
static bool ixgb_clean_rx_irq(struct ixgb_adapter *adapter);
|
||||
#endif
|
||||
static void ixgb_alloc_rx_buffers(struct ixgb_adapter *adapter);
|
||||
static int ixgb_clean(struct napi_struct *, int);
|
||||
static bool ixgb_clean_rx_irq(struct ixgb_adapter *, int *, int);
|
||||
static void ixgb_alloc_rx_buffers(struct ixgb_adapter *, int);
|
||||
|
||||
static void ixgb_tx_timeout(struct net_device *dev);
|
||||
static void ixgb_tx_timeout_task(struct work_struct *work);
|
||||
|
||||
static void ixgb_vlan_rx_register(struct net_device *netdev,
|
||||
struct vlan_group *grp);
|
||||
static void ixgb_vlan_rx_add_vid(struct net_device *netdev, u16 vid);
|
||||
@ -146,14 +135,6 @@ static int debug = DEFAULT_DEBUG_LEVEL_SHIFT;
|
||||
module_param(debug, int, 0);
|
||||
MODULE_PARM_DESC(debug, "Debug level (0=none,...,16=all)");
|
||||
|
||||
/* some defines for controlling descriptor fetches in h/w */
|
||||
#define RXDCTL_WTHRESH_DEFAULT 15 /* chip writes back at this many or RXT0 */
|
||||
#define RXDCTL_PTHRESH_DEFAULT 0 /* chip considers prefech below
|
||||
* this */
|
||||
#define RXDCTL_HTHRESH_DEFAULT 0 /* chip will only prefetch if tail
|
||||
* is pushed this many descriptors
|
||||
* from head */
|
||||
|
||||
/**
|
||||
* ixgb_init_module - Driver Registration Routine
|
||||
*
|
||||
@ -236,7 +217,7 @@ ixgb_up(struct ixgb_adapter *adapter)
|
||||
ixgb_configure_tx(adapter);
|
||||
ixgb_setup_rctl(adapter);
|
||||
ixgb_configure_rx(adapter);
|
||||
ixgb_alloc_rx_buffers(adapter);
|
||||
ixgb_alloc_rx_buffers(adapter, IXGB_DESC_UNUSED(&adapter->rx_ring));
|
||||
|
||||
/* disable interrupts and get the hardware into a known state */
|
||||
IXGB_WRITE_REG(&adapter->hw, IMC, 0xffffffff);
|
||||
@ -282,9 +263,7 @@ ixgb_up(struct ixgb_adapter *adapter)
|
||||
|
||||
clear_bit(__IXGB_DOWN, &adapter->flags);
|
||||
|
||||
#ifdef CONFIG_IXGB_NAPI
|
||||
napi_enable(&adapter->napi);
|
||||
#endif
|
||||
ixgb_irq_enable(adapter);
|
||||
|
||||
mod_timer(&adapter->watchdog_timer, jiffies);
|
||||
@ -300,9 +279,7 @@ ixgb_down(struct ixgb_adapter *adapter, bool kill_watchdog)
|
||||
/* prevent the interrupt handler from restarting watchdog */
|
||||
set_bit(__IXGB_DOWN, &adapter->flags);
|
||||
|
||||
#ifdef CONFIG_IXGB_NAPI
|
||||
napi_disable(&adapter->napi);
|
||||
#endif
|
||||
/* waiting for NAPI to complete can re-enable interrupts */
|
||||
ixgb_irq_disable(adapter);
|
||||
free_irq(adapter->pdev->irq, netdev);
|
||||
@ -357,19 +334,17 @@ ixgb_reset(struct ixgb_adapter *adapter)
|
||||
**/
|
||||
|
||||
static int __devinit
|
||||
ixgb_probe(struct pci_dev *pdev,
|
||||
const struct pci_device_id *ent)
|
||||
ixgb_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
|
||||
{
|
||||
struct net_device *netdev = NULL;
|
||||
struct ixgb_adapter *adapter;
|
||||
static int cards_found = 0;
|
||||
unsigned long mmio_start;
|
||||
int mmio_len;
|
||||
int pci_using_dac;
|
||||
int i;
|
||||
int err;
|
||||
|
||||
if((err = pci_enable_device(pdev)))
|
||||
err = pci_enable_device(pdev);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
if (!(err = pci_set_dma_mask(pdev, DMA_64BIT_MASK)) &&
|
||||
@ -385,7 +360,8 @@ ixgb_probe(struct pci_dev *pdev,
|
||||
pci_using_dac = 0;
|
||||
}
|
||||
|
||||
if((err = pci_request_regions(pdev, ixgb_driver_name)))
|
||||
err = pci_request_regions(pdev, ixgb_driver_name);
|
||||
if (err)
|
||||
goto err_request_regions;
|
||||
|
||||
pci_set_master(pdev);
|
||||
@ -405,10 +381,8 @@ ixgb_probe(struct pci_dev *pdev,
|
||||
adapter->hw.back = adapter;
|
||||
adapter->msg_enable = netif_msg_init(debug, DEFAULT_DEBUG_LEVEL_SHIFT);
|
||||
|
||||
mmio_start = pci_resource_start(pdev, BAR_0);
|
||||
mmio_len = pci_resource_len(pdev, BAR_0);
|
||||
|
||||
adapter->hw.hw_addr = ioremap(mmio_start, mmio_len);
|
||||
adapter->hw.hw_addr = ioremap(pci_resource_start(pdev, BAR_0),
|
||||
pci_resource_len(pdev, BAR_0));
|
||||
if (!adapter->hw.hw_addr) {
|
||||
err = -EIO;
|
||||
goto err_ioremap;
|
||||
@ -433,9 +407,7 @@ ixgb_probe(struct pci_dev *pdev,
|
||||
ixgb_set_ethtool_ops(netdev);
|
||||
netdev->tx_timeout = &ixgb_tx_timeout;
|
||||
netdev->watchdog_timeo = 5 * HZ;
|
||||
#ifdef CONFIG_IXGB_NAPI
|
||||
netif_napi_add(netdev, &adapter->napi, ixgb_clean, 64);
|
||||
#endif
|
||||
netdev->vlan_rx_register = ixgb_vlan_rx_register;
|
||||
netdev->vlan_rx_add_vid = ixgb_vlan_rx_add_vid;
|
||||
netdev->vlan_rx_kill_vid = ixgb_vlan_rx_kill_vid;
|
||||
@ -444,9 +416,6 @@ ixgb_probe(struct pci_dev *pdev,
|
||||
#endif
|
||||
|
||||
strncpy(netdev->name, pci_name(pdev), sizeof(netdev->name) - 1);
|
||||
netdev->mem_start = mmio_start;
|
||||
netdev->mem_end = mmio_start + mmio_len;
|
||||
netdev->base_addr = adapter->hw.io_base;
|
||||
|
||||
adapter->bd_number = cards_found;
|
||||
adapter->link_speed = 0;
|
||||
@ -454,7 +423,8 @@ ixgb_probe(struct pci_dev *pdev,
|
||||
|
||||
/* setup the private structure */
|
||||
|
||||
if((err = ixgb_sw_init(adapter)))
|
||||
err = ixgb_sw_init(adapter);
|
||||
if (err)
|
||||
goto err_sw_init;
|
||||
|
||||
netdev->features = NETIF_F_SG |
|
||||
@ -463,9 +433,6 @@ ixgb_probe(struct pci_dev *pdev,
|
||||
NETIF_F_HW_VLAN_RX |
|
||||
NETIF_F_HW_VLAN_FILTER;
|
||||
netdev->features |= NETIF_F_TSO;
|
||||
#ifdef NETIF_F_LLTX
|
||||
netdev->features |= NETIF_F_LLTX;
|
||||
#endif
|
||||
|
||||
if (pci_using_dac)
|
||||
netdev->features |= NETIF_F_HIGHDMA;
|
||||
@ -496,7 +463,8 @@ ixgb_probe(struct pci_dev *pdev,
|
||||
INIT_WORK(&adapter->tx_timeout_task, ixgb_tx_timeout_task);
|
||||
|
||||
strcpy(netdev->name, "eth%d");
|
||||
if((err = register_netdev(netdev)))
|
||||
err = register_netdev(netdev);
|
||||
if (err)
|
||||
goto err_register;
|
||||
|
||||
/* we're going to reset, so assume we have no link for now */
|
||||
@ -543,6 +511,8 @@ ixgb_remove(struct pci_dev *pdev)
|
||||
struct net_device *netdev = pci_get_drvdata(pdev);
|
||||
struct ixgb_adapter *adapter = netdev_priv(netdev);
|
||||
|
||||
flush_scheduled_work();
|
||||
|
||||
unregister_netdev(netdev);
|
||||
|
||||
iounmap(adapter->hw.hw_addr);
|
||||
@ -575,7 +545,7 @@ ixgb_sw_init(struct ixgb_adapter *adapter)
|
||||
hw->subsystem_id = pdev->subsystem_device;
|
||||
|
||||
hw->max_frame_size = netdev->mtu + ENET_HEADER_SIZE + ENET_FCS_LENGTH;
|
||||
adapter->rx_buffer_len = hw->max_frame_size;
|
||||
adapter->rx_buffer_len = hw->max_frame_size + 8; /* + 8 for errata */
|
||||
|
||||
if ((hw->device_id == IXGB_DEVICE_ID_82597EX)
|
||||
|| (hw->device_id == IXGB_DEVICE_ID_82597EX_CX4)
|
||||
@ -590,8 +560,6 @@ ixgb_sw_init(struct ixgb_adapter *adapter)
|
||||
/* enable flow control to be programmed */
|
||||
hw->fc.send_xon = 1;
|
||||
|
||||
spin_lock_init(&adapter->tx_lock);
|
||||
|
||||
set_bit(__IXGB_DOWN, &adapter->flags);
|
||||
return 0;
|
||||
}
|
||||
@ -616,16 +584,18 @@ ixgb_open(struct net_device *netdev)
|
||||
int err;
|
||||
|
||||
/* allocate transmit descriptors */
|
||||
|
||||
if((err = ixgb_setup_tx_resources(adapter)))
|
||||
err = ixgb_setup_tx_resources(adapter);
|
||||
if (err)
|
||||
goto err_setup_tx;
|
||||
|
||||
/* allocate receive descriptors */
|
||||
|
||||
if((err = ixgb_setup_rx_resources(adapter)))
|
||||
err = ixgb_setup_rx_resources(adapter);
|
||||
if (err)
|
||||
goto err_setup_rx;
|
||||
|
||||
if((err = ixgb_up(adapter)))
|
||||
err = ixgb_up(adapter);
|
||||
if (err)
|
||||
goto err_up;
|
||||
|
||||
return 0;
|
||||
@ -750,8 +720,8 @@ ixgb_configure_tx(struct ixgb_adapter *adapter)
|
||||
|
||||
/* Setup Transmit Descriptor Settings for this adapter */
|
||||
adapter->tx_cmd_type =
|
||||
IXGB_TX_DESC_TYPE
|
||||
| (adapter->tx_int_delay_enable ? IXGB_TX_DESC_CMD_IDE : 0);
|
||||
IXGB_TX_DESC_TYPE |
|
||||
(adapter->tx_int_delay_enable ? IXGB_TX_DESC_CMD_IDE : 0);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -846,7 +816,6 @@ ixgb_configure_rx(struct ixgb_adapter *adapter)
|
||||
struct ixgb_hw *hw = &adapter->hw;
|
||||
u32 rctl;
|
||||
u32 rxcsum;
|
||||
u32 rxdctl;
|
||||
|
||||
/* make sure receives are disabled while setting up the descriptors */
|
||||
|
||||
@ -868,18 +837,12 @@ ixgb_configure_rx(struct ixgb_adapter *adapter)
|
||||
IXGB_WRITE_REG(hw, RDH, 0);
|
||||
IXGB_WRITE_REG(hw, RDT, 0);
|
||||
|
||||
/* set up pre-fetching of receive buffers so we get some before we
|
||||
* run out (default hardware behavior is to run out before fetching
|
||||
* more). This sets up to fetch if HTHRESH rx descriptors are avail
|
||||
* and the descriptors in hw cache are below PTHRESH. This avoids
|
||||
* the hardware behavior of fetching <=512 descriptors in a single
|
||||
* burst that pre-empts all other activity, usually causing fifo
|
||||
* overflows. */
|
||||
/* use WTHRESH to burst write 16 descriptors or burst when RXT0 */
|
||||
rxdctl = RXDCTL_WTHRESH_DEFAULT << IXGB_RXDCTL_WTHRESH_SHIFT |
|
||||
RXDCTL_HTHRESH_DEFAULT << IXGB_RXDCTL_HTHRESH_SHIFT |
|
||||
RXDCTL_PTHRESH_DEFAULT << IXGB_RXDCTL_PTHRESH_SHIFT;
|
||||
IXGB_WRITE_REG(hw, RXDCTL, rxdctl);
|
||||
/* due to the hardware errata with RXDCTL, we are unable to use any of
|
||||
* the performance enhancing features of it without causing other
|
||||
* subtle bugs, some of the bugs could include receive length
|
||||
* corruption at high data rates (WTHRESH > 0) and/or receive
|
||||
* descriptor ring irregularites (particularly in hardware cache) */
|
||||
IXGB_WRITE_REG(hw, RXDCTL, 0);
|
||||
|
||||
/* Enable Receive Checksum Offload for TCP and UDP */
|
||||
if (adapter->rx_csum) {
|
||||
@ -926,8 +889,10 @@ ixgb_unmap_and_free_tx_resource(struct ixgb_adapter *adapter,
|
||||
pci_unmap_page(pdev, buffer_info->dma, buffer_info->length,
|
||||
PCI_DMA_TODEVICE);
|
||||
|
||||
/* okay to call kfree_skb here instead of kfree_skb_any because
|
||||
* this is never called in interrupt context */
|
||||
if (buffer_info->skb)
|
||||
dev_kfree_skb_any(buffer_info->skb);
|
||||
dev_kfree_skb(buffer_info->skb);
|
||||
|
||||
buffer_info->skb = NULL;
|
||||
buffer_info->dma = 0;
|
||||
@ -1104,7 +1069,8 @@ ixgb_set_multi(struct net_device *netdev)
|
||||
|
||||
IXGB_WRITE_REG(hw, RCTL, rctl);
|
||||
|
||||
for(i = 0, mc_ptr = netdev->mc_list; mc_ptr;
|
||||
for (i = 0, mc_ptr = netdev->mc_list;
|
||||
mc_ptr;
|
||||
i++, mc_ptr = mc_ptr->next)
|
||||
memcpy(&mta[i * IXGB_ETH_LENGTH_OF_ADDRESS],
|
||||
mc_ptr->dmi_addr, IXGB_ETH_LENGTH_OF_ADDRESS);
|
||||
@ -1312,12 +1278,12 @@ ixgb_tx_map(struct ixgb_adapter *adapter, struct sk_buff *skb,
|
||||
|
||||
buffer_info->length = size;
|
||||
WARN_ON(buffer_info->dma != 0);
|
||||
buffer_info->time_stamp = jiffies;
|
||||
buffer_info->dma =
|
||||
pci_map_single(adapter->pdev,
|
||||
skb->data + offset,
|
||||
size,
|
||||
PCI_DMA_TODEVICE);
|
||||
buffer_info->time_stamp = jiffies;
|
||||
buffer_info->next_to_watch = 0;
|
||||
|
||||
len -= size;
|
||||
@ -1344,13 +1310,13 @@ ixgb_tx_map(struct ixgb_adapter *adapter, struct sk_buff *skb,
|
||||
size -= 4;
|
||||
|
||||
buffer_info->length = size;
|
||||
buffer_info->time_stamp = jiffies;
|
||||
buffer_info->dma =
|
||||
pci_map_page(adapter->pdev,
|
||||
frag->page,
|
||||
frag->page_offset + offset,
|
||||
size,
|
||||
PCI_DMA_TODEVICE);
|
||||
buffer_info->time_stamp = jiffies;
|
||||
buffer_info->next_to_watch = 0;
|
||||
|
||||
len -= size;
|
||||
@ -1385,9 +1351,8 @@ ixgb_tx_queue(struct ixgb_adapter *adapter, int count, int vlan_id,int tx_flags)
|
||||
if (tx_flags & IXGB_TX_FLAGS_CSUM)
|
||||
popts |= IXGB_TX_DESC_POPTS_TXSM;
|
||||
|
||||
if(tx_flags & IXGB_TX_FLAGS_VLAN) {
|
||||
if (tx_flags & IXGB_TX_FLAGS_VLAN)
|
||||
cmd_type_len |= IXGB_TX_DESC_CMD_VLE;
|
||||
}
|
||||
|
||||
i = tx_ring->next_to_use;
|
||||
|
||||
@ -1404,8 +1369,8 @@ ixgb_tx_queue(struct ixgb_adapter *adapter, int count, int vlan_id,int tx_flags)
|
||||
if (++i == tx_ring->count) i = 0;
|
||||
}
|
||||
|
||||
tx_desc->cmd_type_len |= cpu_to_le32(IXGB_TX_DESC_CMD_EOP
|
||||
| IXGB_TX_DESC_CMD_RS );
|
||||
tx_desc->cmd_type_len |=
|
||||
cpu_to_le32(IXGB_TX_DESC_CMD_EOP | IXGB_TX_DESC_CMD_RS);
|
||||
|
||||
/* Force memory writes to complete before letting h/w
|
||||
* know there are new descriptors to fetch. (Only
|
||||
@ -1461,7 +1426,6 @@ ixgb_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
|
||||
struct ixgb_adapter *adapter = netdev_priv(netdev);
|
||||
unsigned int first;
|
||||
unsigned int tx_flags = 0;
|
||||
unsigned long flags;
|
||||
int vlan_id = 0;
|
||||
int tso;
|
||||
|
||||
@ -1471,30 +1435,13 @@ ixgb_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
|
||||
}
|
||||
|
||||
if (skb->len <= 0) {
|
||||
dev_kfree_skb_any(skb);
|
||||
dev_kfree_skb(skb);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef NETIF_F_LLTX
|
||||
if (!spin_trylock_irqsave(&adapter->tx_lock, flags)) {
|
||||
/* Collision - tell upper layer to requeue */
|
||||
local_irq_restore(flags);
|
||||
return NETDEV_TX_LOCKED;
|
||||
}
|
||||
#else
|
||||
spin_lock_irqsave(&adapter->tx_lock, flags);
|
||||
#endif
|
||||
|
||||
if (unlikely(ixgb_maybe_stop_tx(netdev, &adapter->tx_ring,
|
||||
DESC_NEEDED))) {
|
||||
netif_stop_queue(netdev);
|
||||
spin_unlock_irqrestore(&adapter->tx_lock, flags);
|
||||
DESC_NEEDED)))
|
||||
return NETDEV_TX_BUSY;
|
||||
}
|
||||
|
||||
#ifndef NETIF_F_LLTX
|
||||
spin_unlock_irqrestore(&adapter->tx_lock, flags);
|
||||
#endif
|
||||
|
||||
if (adapter->vlgrp && vlan_tx_tag_present(skb)) {
|
||||
tx_flags |= IXGB_TX_FLAGS_VLAN;
|
||||
@ -1505,10 +1452,7 @@ ixgb_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
|
||||
|
||||
tso = ixgb_tso(adapter, skb);
|
||||
if (tso < 0) {
|
||||
dev_kfree_skb_any(skb);
|
||||
#ifdef NETIF_F_LLTX
|
||||
spin_unlock_irqrestore(&adapter->tx_lock, flags);
|
||||
#endif
|
||||
dev_kfree_skb(skb);
|
||||
return NETDEV_TX_OK;
|
||||
}
|
||||
|
||||
@ -1522,13 +1466,9 @@ ixgb_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
|
||||
|
||||
netdev->trans_start = jiffies;
|
||||
|
||||
#ifdef NETIF_F_LLTX
|
||||
/* Make sure there is space in the ring for the next send. */
|
||||
ixgb_maybe_stop_tx(netdev, &adapter->tx_ring, DESC_NEEDED);
|
||||
|
||||
spin_unlock_irqrestore(&adapter->tx_lock, flags);
|
||||
|
||||
#endif
|
||||
return NETDEV_TX_OK;
|
||||
}
|
||||
|
||||
@ -1588,21 +1528,25 @@ ixgb_change_mtu(struct net_device *netdev, int new_mtu)
|
||||
int max_frame = new_mtu + ENET_HEADER_SIZE + ENET_FCS_LENGTH;
|
||||
int old_max_frame = netdev->mtu + ENET_HEADER_SIZE + ENET_FCS_LENGTH;
|
||||
|
||||
|
||||
if((max_frame < IXGB_MIN_ENET_FRAME_SIZE_WITHOUT_FCS + ENET_FCS_LENGTH)
|
||||
|| (max_frame > IXGB_MAX_JUMBO_FRAME_SIZE + ENET_FCS_LENGTH)) {
|
||||
/* MTU < 68 is an error for IPv4 traffic, just don't allow it */
|
||||
if ((new_mtu < 68) ||
|
||||
(max_frame > IXGB_MAX_JUMBO_FRAME_SIZE + ENET_FCS_LENGTH)) {
|
||||
DPRINTK(PROBE, ERR, "Invalid MTU setting %d\n", new_mtu);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
adapter->rx_buffer_len = max_frame;
|
||||
if (old_max_frame == max_frame)
|
||||
return 0;
|
||||
|
||||
if (netif_running(netdev))
|
||||
ixgb_down(adapter, true);
|
||||
|
||||
adapter->rx_buffer_len = max_frame + 8; /* + 8 for errata */
|
||||
|
||||
netdev->mtu = new_mtu;
|
||||
|
||||
if ((old_max_frame != max_frame) && netif_running(netdev)) {
|
||||
ixgb_down(adapter, true);
|
||||
if (netif_running(netdev))
|
||||
ixgb_up(adapter);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -1751,9 +1695,6 @@ ixgb_intr(int irq, void *data)
|
||||
struct ixgb_adapter *adapter = netdev_priv(netdev);
|
||||
struct ixgb_hw *hw = &adapter->hw;
|
||||
u32 icr = IXGB_READ_REG(hw, ICR);
|
||||
#ifndef CONFIG_IXGB_NAPI
|
||||
unsigned int i;
|
||||
#endif
|
||||
|
||||
if (unlikely(!icr))
|
||||
return IRQ_NONE; /* Not our interrupt */
|
||||
@ -1762,7 +1703,6 @@ ixgb_intr(int irq, void *data)
|
||||
if (!test_bit(__IXGB_DOWN, &adapter->flags))
|
||||
mod_timer(&adapter->watchdog_timer, jiffies);
|
||||
|
||||
#ifdef CONFIG_IXGB_NAPI
|
||||
if (netif_rx_schedule_prep(netdev, &adapter->napi)) {
|
||||
|
||||
/* Disable interrupts and register for poll. The flush
|
||||
@ -1772,20 +1712,9 @@ ixgb_intr(int irq, void *data)
|
||||
IXGB_WRITE_REG(&adapter->hw, IMC, ~0);
|
||||
__netif_rx_schedule(netdev, &adapter->napi);
|
||||
}
|
||||
#else
|
||||
/* yes, that is actually a & and it is meant to make sure that
|
||||
* every pass through this for loop checks both receive and
|
||||
* transmit queues for completed descriptors, intended to
|
||||
* avoid starvation issues and assist tx/rx fairness. */
|
||||
for(i = 0; i < IXGB_MAX_INTR; i++)
|
||||
if(!ixgb_clean_rx_irq(adapter) &
|
||||
!ixgb_clean_tx_irq(adapter))
|
||||
break;
|
||||
#endif
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_IXGB_NAPI
|
||||
/**
|
||||
* ixgb_clean - NAPI Rx polling callback
|
||||
* @adapter: board private structure
|
||||
@ -1804,12 +1733,12 @@ ixgb_clean(struct napi_struct *napi, int budget)
|
||||
/* If budget not fully consumed, exit the polling mode */
|
||||
if (work_done < budget) {
|
||||
netif_rx_complete(netdev, napi);
|
||||
if (!test_bit(__IXGB_DOWN, &adapter->flags))
|
||||
ixgb_irq_enable(adapter);
|
||||
}
|
||||
|
||||
return work_done;
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* ixgb_clean_tx_irq - Reclaim resources after transmit completes
|
||||
@ -1836,8 +1765,8 @@ ixgb_clean_tx_irq(struct ixgb_adapter *adapter)
|
||||
tx_desc = IXGB_TX_DESC(*tx_ring, i);
|
||||
buffer_info = &tx_ring->buffer_info[i];
|
||||
|
||||
if (tx_desc->popts
|
||||
& (IXGB_TX_DESC_POPTS_TXSM |
|
||||
if (tx_desc->popts &
|
||||
(IXGB_TX_DESC_POPTS_TXSM |
|
||||
IXGB_TX_DESC_POPTS_IXSM))
|
||||
adapter->hw_csum_tx_good++;
|
||||
|
||||
@ -1855,12 +1784,17 @@ ixgb_clean_tx_irq(struct ixgb_adapter *adapter)
|
||||
|
||||
tx_ring->next_to_clean = i;
|
||||
|
||||
if (unlikely(netif_queue_stopped(netdev))) {
|
||||
spin_lock(&adapter->tx_lock);
|
||||
if (netif_queue_stopped(netdev) && netif_carrier_ok(netdev) &&
|
||||
(IXGB_DESC_UNUSED(tx_ring) >= DESC_NEEDED))
|
||||
if (unlikely(cleaned && netif_carrier_ok(netdev) &&
|
||||
IXGB_DESC_UNUSED(tx_ring) >= DESC_NEEDED)) {
|
||||
/* Make sure that anybody stopping the queue after this
|
||||
* sees the new next_to_clean. */
|
||||
smp_mb();
|
||||
|
||||
if (netif_queue_stopped(netdev) &&
|
||||
!(test_bit(__IXGB_DOWN, &adapter->flags))) {
|
||||
netif_wake_queue(netdev);
|
||||
spin_unlock(&adapter->tx_lock);
|
||||
++adapter->restart_queue;
|
||||
}
|
||||
}
|
||||
|
||||
if (adapter->detect_tx_hung) {
|
||||
@ -1937,11 +1871,7 @@ ixgb_rx_checksum(struct ixgb_adapter *adapter,
|
||||
**/
|
||||
|
||||
static bool
|
||||
#ifdef CONFIG_IXGB_NAPI
|
||||
ixgb_clean_rx_irq(struct ixgb_adapter *adapter, int *work_done, int work_to_do)
|
||||
#else
|
||||
ixgb_clean_rx_irq(struct ixgb_adapter *adapter)
|
||||
#endif
|
||||
{
|
||||
struct ixgb_desc_ring *rx_ring = &adapter->rx_ring;
|
||||
struct net_device *netdev = adapter->netdev;
|
||||
@ -1950,6 +1880,7 @@ ixgb_clean_rx_irq(struct ixgb_adapter *adapter)
|
||||
struct ixgb_buffer *buffer_info, *next_buffer, *next2_buffer;
|
||||
u32 length;
|
||||
unsigned int i, j;
|
||||
int cleaned_count = 0;
|
||||
bool cleaned = false;
|
||||
|
||||
i = rx_ring->next_to_clean;
|
||||
@ -1957,20 +1888,18 @@ ixgb_clean_rx_irq(struct ixgb_adapter *adapter)
|
||||
buffer_info = &rx_ring->buffer_info[i];
|
||||
|
||||
while (rx_desc->status & IXGB_RX_DESC_STATUS_DD) {
|
||||
struct sk_buff *skb, *next_skb;
|
||||
struct sk_buff *skb;
|
||||
u8 status;
|
||||
|
||||
#ifdef CONFIG_IXGB_NAPI
|
||||
if (*work_done >= work_to_do)
|
||||
break;
|
||||
|
||||
(*work_done)++;
|
||||
#endif
|
||||
status = rx_desc->status;
|
||||
skb = buffer_info->skb;
|
||||
buffer_info->skb = NULL;
|
||||
|
||||
prefetch(skb->data);
|
||||
prefetch(skb->data - NET_IP_ALIGN);
|
||||
|
||||
if (++i == rx_ring->count) i = 0;
|
||||
next_rxd = IXGB_RX_DESC(*rx_ring, i);
|
||||
@ -1981,17 +1910,18 @@ ixgb_clean_rx_irq(struct ixgb_adapter *adapter)
|
||||
prefetch(next2_buffer);
|
||||
|
||||
next_buffer = &rx_ring->buffer_info[i];
|
||||
next_skb = next_buffer->skb;
|
||||
prefetch(next_skb);
|
||||
|
||||
cleaned = true;
|
||||
cleaned_count++;
|
||||
|
||||
pci_unmap_single(pdev,
|
||||
buffer_info->dma,
|
||||
buffer_info->length,
|
||||
PCI_DMA_FROMDEVICE);
|
||||
buffer_info->dma = 0;
|
||||
|
||||
length = le16_to_cpu(rx_desc->length);
|
||||
rx_desc->length = 0;
|
||||
|
||||
if (unlikely(!(status & IXGB_RX_DESC_STATUS_EOP))) {
|
||||
|
||||
@ -2004,11 +1934,9 @@ ixgb_clean_rx_irq(struct ixgb_adapter *adapter)
|
||||
goto rxdesc_done;
|
||||
}
|
||||
|
||||
if (unlikely(rx_desc->errors
|
||||
& (IXGB_RX_DESC_ERRORS_CE | IXGB_RX_DESC_ERRORS_SE
|
||||
| IXGB_RX_DESC_ERRORS_P |
|
||||
IXGB_RX_DESC_ERRORS_RXE))) {
|
||||
|
||||
if (unlikely(rx_desc->errors &
|
||||
(IXGB_RX_DESC_ERRORS_CE | IXGB_RX_DESC_ERRORS_SE |
|
||||
IXGB_RX_DESC_ERRORS_P | IXGB_RX_DESC_ERRORS_RXE))) {
|
||||
dev_kfree_skb_irq(skb);
|
||||
goto rxdesc_done;
|
||||
}
|
||||
@ -2016,8 +1944,7 @@ ixgb_clean_rx_irq(struct ixgb_adapter *adapter)
|
||||
/* code added for copybreak, this should improve
|
||||
* performance for small packets with large amounts
|
||||
* of reassembly being done in the stack */
|
||||
#define IXGB_CB_LENGTH 256
|
||||
if (length < IXGB_CB_LENGTH) {
|
||||
if (length < copybreak) {
|
||||
struct sk_buff *new_skb =
|
||||
netdev_alloc_skb(netdev, length + NET_IP_ALIGN);
|
||||
if (new_skb) {
|
||||
@ -2042,27 +1969,24 @@ ixgb_clean_rx_irq(struct ixgb_adapter *adapter)
|
||||
ixgb_rx_checksum(adapter, rx_desc, skb);
|
||||
|
||||
skb->protocol = eth_type_trans(skb, netdev);
|
||||
#ifdef CONFIG_IXGB_NAPI
|
||||
if (adapter->vlgrp && (status & IXGB_RX_DESC_STATUS_VP)) {
|
||||
vlan_hwaccel_receive_skb(skb, adapter->vlgrp,
|
||||
le16_to_cpu(rx_desc->special));
|
||||
} else {
|
||||
netif_receive_skb(skb);
|
||||
}
|
||||
#else /* CONFIG_IXGB_NAPI */
|
||||
if(adapter->vlgrp && (status & IXGB_RX_DESC_STATUS_VP)) {
|
||||
vlan_hwaccel_rx(skb, adapter->vlgrp,
|
||||
le16_to_cpu(rx_desc->special));
|
||||
} else {
|
||||
netif_rx(skb);
|
||||
}
|
||||
#endif /* CONFIG_IXGB_NAPI */
|
||||
netdev->last_rx = jiffies;
|
||||
|
||||
rxdesc_done:
|
||||
/* clean up descriptor, might be written over by hw */
|
||||
rx_desc->status = 0;
|
||||
|
||||
/* return some buffers to hardware, one at a time is too slow */
|
||||
if (unlikely(cleaned_count >= IXGB_RX_BUFFER_WRITE)) {
|
||||
ixgb_alloc_rx_buffers(adapter, cleaned_count);
|
||||
cleaned_count = 0;
|
||||
}
|
||||
|
||||
/* use prefetched values */
|
||||
rx_desc = next_rxd;
|
||||
buffer_info = next_buffer;
|
||||
@ -2070,7 +1994,9 @@ rxdesc_done:
|
||||
|
||||
rx_ring->next_to_clean = i;
|
||||
|
||||
ixgb_alloc_rx_buffers(adapter);
|
||||
cleaned_count = IXGB_DESC_UNUSED(rx_ring);
|
||||
if (cleaned_count)
|
||||
ixgb_alloc_rx_buffers(adapter, cleaned_count);
|
||||
|
||||
return cleaned;
|
||||
}
|
||||
@ -2081,7 +2007,7 @@ rxdesc_done:
|
||||
**/
|
||||
|
||||
static void
|
||||
ixgb_alloc_rx_buffers(struct ixgb_adapter *adapter)
|
||||
ixgb_alloc_rx_buffers(struct ixgb_adapter *adapter, int cleaned_count)
|
||||
{
|
||||
struct ixgb_desc_ring *rx_ring = &adapter->rx_ring;
|
||||
struct net_device *netdev = adapter->netdev;
|
||||
@ -2098,7 +2024,7 @@ ixgb_alloc_rx_buffers(struct ixgb_adapter *adapter)
|
||||
|
||||
|
||||
/* leave three descriptors unused */
|
||||
while(--cleancount > 2) {
|
||||
while (--cleancount > 2 && cleaned_count--) {
|
||||
/* recycle! its good for you */
|
||||
skb = buffer_info->skb;
|
||||
if (skb) {
|
||||
@ -2295,7 +2221,7 @@ static pci_ers_result_t ixgb_io_error_detected (struct pci_dev *pdev,
|
||||
* ixgb_io_slot_reset - called after the pci bus has been reset.
|
||||
* @pdev pointer to pci device with error
|
||||
*
|
||||
* This callback is called after the PCI buss has been reset.
|
||||
* This callback is called after the PCI bus has been reset.
|
||||
* Basically, this tries to restart the card from scratch.
|
||||
* This is a shortened version of the device probe/discovery code,
|
||||
* it resembles the first-half of the ixgb_probe() routine.
|
||||
|
@ -1,7 +1,7 @@
|
||||
/*******************************************************************************
|
||||
|
||||
Intel PRO/10GbE Linux driver
|
||||
Copyright(c) 1999 - 2006 Intel Corporation.
|
||||
Copyright(c) 1999 - 2008 Intel Corporation.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it
|
||||
under the terms and conditions of the GNU General Public License,
|
||||
|
@ -1,7 +1,7 @@
|
||||
/*******************************************************************************
|
||||
|
||||
Intel PRO/10GbE Linux driver
|
||||
Copyright(c) 1999 - 2006 Intel Corporation.
|
||||
Copyright(c) 1999 - 2008 Intel Corporation.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it
|
||||
under the terms and conditions of the GNU General Public License,
|
||||
|
@ -177,6 +177,7 @@ struct mii_bus *alloc_mdio_bitbang(struct mdiobb_ctrl *ctrl)
|
||||
|
||||
return bus;
|
||||
}
|
||||
EXPORT_SYMBOL(alloc_mdio_bitbang);
|
||||
|
||||
void free_mdio_bitbang(struct mii_bus *bus)
|
||||
{
|
||||
@ -185,5 +186,6 @@ void free_mdio_bitbang(struct mii_bus *bus)
|
||||
module_put(ctrl->ops->owner);
|
||||
kfree(bus);
|
||||
}
|
||||
EXPORT_SYMBOL(free_mdio_bitbang);
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
|
@ -86,7 +86,7 @@
|
||||
#include "s2io.h"
|
||||
#include "s2io-regs.h"
|
||||
|
||||
#define DRV_VERSION "2.0.26.24"
|
||||
#define DRV_VERSION "2.0.26.25"
|
||||
|
||||
/* S2io Driver name & version. */
|
||||
static char s2io_driver_name[] = "Neterion";
|
||||
@ -1891,8 +1891,6 @@ static int init_nic(struct s2io_nic *nic)
|
||||
|
||||
static int s2io_link_fault_indication(struct s2io_nic *nic)
|
||||
{
|
||||
if (nic->config.intr_type != INTA)
|
||||
return MAC_RMAC_ERR_TIMER;
|
||||
if (nic->device_type == XFRAME_II_DEVICE)
|
||||
return LINK_UP_DOWN_INTERRUPT;
|
||||
else
|
||||
@ -1925,7 +1923,9 @@ 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;
|
||||
@ -2015,10 +2015,12 @@ static void en_dis_err_alarms(struct s2io_nic *nic, u16 mask, int flag)
|
||||
gen_int_mask |= RXMAC_INT_M;
|
||||
do_s2io_write_bits(MAC_INT_STATUS_RMAC_INT, flag,
|
||||
&bar0->mac_int_mask);
|
||||
do_s2io_write_bits(RMAC_RX_BUFF_OVRN | RMAC_RX_SM_ERR |
|
||||
interruptible = RMAC_RX_BUFF_OVRN | RMAC_RX_SM_ERR |
|
||||
RMAC_UNUSED_INT | RMAC_SINGLE_ECC_ERR |
|
||||
RMAC_DOUBLE_ECC_ERR |
|
||||
RMAC_LINK_STATE_CHANGE_INT,
|
||||
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);
|
||||
}
|
||||
|
||||
@ -2501,6 +2503,9 @@ static void stop_nic(struct s2io_nic *nic)
|
||||
/**
|
||||
* fill_rx_buffers - Allocates the Rx side skbs
|
||||
* @ring_info: 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
|
||||
@ -2518,7 +2523,7 @@ static void stop_nic(struct s2io_nic *nic)
|
||||
* SUCCESS on success or an appropriate -ve value on failure.
|
||||
*/
|
||||
|
||||
static int fill_rx_buffers(struct ring_info *ring)
|
||||
static int fill_rx_buffers(struct ring_info *ring, int from_card_up)
|
||||
{
|
||||
struct sk_buff *skb;
|
||||
struct RxD_t *rxdp;
|
||||
@ -2637,17 +2642,16 @@ static int fill_rx_buffers(struct ring_info *ring)
|
||||
skb->data = (void *) (unsigned long)tmp;
|
||||
skb_reset_tail_pointer(skb);
|
||||
|
||||
/* AK: check is wrong. 0 can be valid dma address */
|
||||
if (!(rxdp3->Buffer0_ptr))
|
||||
if (from_card_up) {
|
||||
rxdp3->Buffer0_ptr =
|
||||
pci_map_single(ring->pdev, ba->ba_0,
|
||||
BUF0_LEN, PCI_DMA_FROMDEVICE);
|
||||
else
|
||||
if (pci_dma_mapping_error(rxdp3->Buffer0_ptr))
|
||||
goto pci_map_failed;
|
||||
} else
|
||||
pci_dma_sync_single_for_device(ring->pdev,
|
||||
(dma_addr_t) rxdp3->Buffer0_ptr,
|
||||
BUF0_LEN, PCI_DMA_FROMDEVICE);
|
||||
if (pci_dma_mapping_error(rxdp3->Buffer0_ptr))
|
||||
goto pci_map_failed;
|
||||
|
||||
rxdp->Control_2 = SET_BUFFER0_SIZE_3(BUF0_LEN);
|
||||
if (ring->rxd_mode == RXD_MODE_3B) {
|
||||
@ -2664,14 +2668,14 @@ static int fill_rx_buffers(struct ring_info *ring)
|
||||
if (pci_dma_mapping_error(rxdp3->Buffer2_ptr))
|
||||
goto pci_map_failed;
|
||||
|
||||
/* AK: check is wrong */
|
||||
if (!rxdp3->Buffer1_ptr)
|
||||
if (from_card_up) {
|
||||
rxdp3->Buffer1_ptr =
|
||||
pci_map_single(ring->pdev,
|
||||
ba->ba_1, BUF1_LEN,
|
||||
PCI_DMA_FROMDEVICE);
|
||||
|
||||
if (pci_dma_mapping_error(rxdp3->Buffer1_ptr)) {
|
||||
if (pci_dma_mapping_error
|
||||
(rxdp3->Buffer1_ptr)) {
|
||||
pci_unmap_single
|
||||
(ring->pdev,
|
||||
(dma_addr_t)(unsigned long)
|
||||
@ -2680,6 +2684,7 @@ static int fill_rx_buffers(struct ring_info *ring)
|
||||
PCI_DMA_FROMDEVICE);
|
||||
goto pci_map_failed;
|
||||
}
|
||||
}
|
||||
rxdp->Control_2 |= SET_BUFFER1_SIZE_3(1);
|
||||
rxdp->Control_2 |= SET_BUFFER2_SIZE_3
|
||||
(ring->mtu + 4);
|
||||
@ -2813,7 +2818,7 @@ static void free_rx_buffers(struct s2io_nic *sp)
|
||||
|
||||
static int s2io_chk_rx_buffers(struct ring_info *ring)
|
||||
{
|
||||
if (fill_rx_buffers(ring) == -ENOMEM) {
|
||||
if (fill_rx_buffers(ring, 0) == -ENOMEM) {
|
||||
DBG_PRINT(INFO_DBG, "%s:Out of memory", ring->dev->name);
|
||||
DBG_PRINT(INFO_DBG, " in Rx Intr!!\n");
|
||||
}
|
||||
@ -2944,7 +2949,7 @@ static void s2io_netpoll(struct net_device *dev)
|
||||
rx_intr_handler(&mac_control->rings[i], 0);
|
||||
|
||||
for (i = 0; i < config->rx_ring_num; i++) {
|
||||
if (fill_rx_buffers(&mac_control->rings[i]) == -ENOMEM) {
|
||||
if (fill_rx_buffers(&mac_control->rings[i], 0) == -ENOMEM) {
|
||||
DBG_PRINT(INFO_DBG, "%s:Out of memory", dev->name);
|
||||
DBG_PRINT(INFO_DBG, " in Rx Netpoll!!\n");
|
||||
break;
|
||||
@ -4373,8 +4378,12 @@ static irqreturn_t s2io_msix_fifo_handle(int irq, void *dev_id)
|
||||
/* 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);
|
||||
|
||||
@ -4383,9 +4392,11 @@ static irqreturn_t s2io_msix_fifo_handle(int irq, void *dev_id)
|
||||
|
||||
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)
|
||||
{
|
||||
@ -7112,6 +7123,9 @@ static void do_s2io_card_down(struct s2io_nic * sp, int do_io)
|
||||
|
||||
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
|
||||
@ -7183,7 +7197,7 @@ static int s2io_card_up(struct s2io_nic * sp)
|
||||
|
||||
for (i = 0; i < config->rx_ring_num; i++) {
|
||||
mac_control->rings[i].mtu = dev->mtu;
|
||||
ret = fill_rx_buffers(&mac_control->rings[i]);
|
||||
ret = fill_rx_buffers(&mac_control->rings[i], 1);
|
||||
if (ret) {
|
||||
DBG_PRINT(ERR_DBG, "%s: Out of memory in Open\n",
|
||||
dev->name);
|
||||
@ -7244,17 +7258,19 @@ static int s2io_card_up(struct s2io_nic * sp)
|
||||
|
||||
S2IO_TIMER_CONF(sp->alarm_timer, s2io_alarm_handle, sp, (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)
|
||||
en_dis_able_nic_intrs(sp, TX_TRAFFIC_INTR, ENABLE_INTRS);
|
||||
else {
|
||||
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);
|
||||
}
|
||||
|
||||
set_bit(__S2IO_STATE_CARD_UP, &sp->state);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1107,6 +1107,7 @@ 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);
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,384 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2000, 2005 MIPS Technologies, Inc. All rights reserved.
|
||||
* Authors: Carsten Langgaard <carstenl@mips.com>
|
||||
* Maciej W. Rozycki <macro@mips.com>
|
||||
*
|
||||
* ########################################################################
|
||||
*
|
||||
* This program is free software; you can distribute it and/or modify it
|
||||
* under the terms of the GNU General Public License (Version 2) as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
|
||||
*
|
||||
* ########################################################################
|
||||
*
|
||||
* SAA9730 ethernet driver description.
|
||||
*
|
||||
*/
|
||||
#ifndef _SAA9730_H
|
||||
#define _SAA9730_H
|
||||
|
||||
|
||||
/* Number of 6-byte entries in the CAM. */
|
||||
#define LAN_SAA9730_CAM_ENTRIES 10
|
||||
#define LAN_SAA9730_CAM_DWORDS ((LAN_SAA9730_CAM_ENTRIES*6)/4)
|
||||
|
||||
/* TX and RX packet size: fixed to 2048 bytes, according to HW requirements. */
|
||||
#define LAN_SAA9730_PACKET_SIZE 2048
|
||||
|
||||
/*
|
||||
* Number of TX buffers = number of RX buffers = 2, which is fixed according
|
||||
* to HW requirements.
|
||||
*/
|
||||
#define LAN_SAA9730_BUFFERS 2
|
||||
|
||||
/* Number of RX packets per RX buffer. */
|
||||
#define LAN_SAA9730_RCV_Q_SIZE 15
|
||||
|
||||
/* Number of TX packets per TX buffer. */
|
||||
#define LAN_SAA9730_TXM_Q_SIZE 15
|
||||
|
||||
/*
|
||||
* We get an interrupt for each LAN_SAA9730_DEFAULT_RCV_Q_INT_THRESHOLD
|
||||
* packets received.
|
||||
* If however we receive less than LAN_SAA9730_DEFAULT_RCV_Q_INT_THRESHOLD
|
||||
* packets, the hardware can timeout after a certain time and still tell
|
||||
* us packets have arrived.
|
||||
* The timeout value in unit of 32 PCI clocks (33Mhz).
|
||||
* The value 200 approximates 0.0002 seconds.
|
||||
*/
|
||||
#define LAN_SAA9730_RCV_Q_INT_THRESHOLD 1
|
||||
#define LAN_SAA9730_DEFAULT_TIME_OUT_CNT 10
|
||||
|
||||
#define RXSF_NDIS 0
|
||||
#define RXSF_READY 2
|
||||
#define RXSF_HWDONE 3
|
||||
|
||||
#define TXSF_EMPTY 0
|
||||
#define TXSF_READY 2
|
||||
#define TXSF_HWDONE 3
|
||||
|
||||
#define LANEND_LITTLE 0
|
||||
#define LANEND_BIG_2143 1
|
||||
#define LANEND_BIG_4321 2
|
||||
|
||||
#define LANMB_ANY 0
|
||||
#define LANMB_8 1
|
||||
#define LANMB_32 2
|
||||
#define LANMB_64 3
|
||||
|
||||
#define MACCM_AUTOMATIC 0
|
||||
#define MACCM_10MB 1
|
||||
#define MACCM_MII 2
|
||||
|
||||
/*
|
||||
* PHY definitions for Basic registers of QS6612 (used on MIPS ATLAS board)
|
||||
*/
|
||||
#define PHY_CONTROL 0x0
|
||||
#define PHY_STATUS 0x1
|
||||
#define PHY_STATUS_LINK_UP 0x4
|
||||
#define PHY_CONTROL_RESET 0x8000
|
||||
#define PHY_CONTROL_AUTO_NEG 0x1000
|
||||
#define PHY_CONTROL_RESTART_AUTO_NEG 0x0200
|
||||
#define PHY_ADDRESS 0x0
|
||||
|
||||
/* PK_COUNT register. */
|
||||
#define PK_COUNT_TX_A_SHF 24
|
||||
#define PK_COUNT_TX_A_MSK (0xff << PK_COUNT_TX_A_SHF)
|
||||
#define PK_COUNT_TX_B_SHF 16
|
||||
#define PK_COUNT_TX_B_MSK (0xff << PK_COUNT_TX_B_SHF)
|
||||
#define PK_COUNT_RX_A_SHF 8
|
||||
#define PK_COUNT_RX_A_MSK (0xff << PK_COUNT_RX_A_SHF)
|
||||
#define PK_COUNT_RX_B_SHF 0
|
||||
#define PK_COUNT_RX_B_MSK (0xff << PK_COUNT_RX_B_SHF)
|
||||
|
||||
/* OK2USE register. */
|
||||
#define OK2USE_TX_A 0x8
|
||||
#define OK2USE_TX_B 0x4
|
||||
#define OK2USE_RX_A 0x2
|
||||
#define OK2USE_RX_B 0x1
|
||||
|
||||
/* LAN DMA CONTROL register. */
|
||||
#define DMA_CTL_BLK_INT 0x80000000
|
||||
#define DMA_CTL_MAX_XFER_SHF 18
|
||||
#define DMA_CTL_MAX_XFER_MSK (0x3 << LAN_DMA_CTL_MAX_XFER_SHF)
|
||||
#define DMA_CTL_ENDIAN_SHF 16
|
||||
#define DMA_CTL_ENDIAN_MSK (0x3 << LAN_DMA_CTL_ENDIAN_SHF)
|
||||
#define DMA_CTL_RX_INT_COUNT_SHF 8
|
||||
#define DMA_CTL_RX_INT_COUNT_MSK (0xff << LAN_DMA_CTL_RX_INT_COUNT_SHF)
|
||||
#define DMA_CTL_EN_TX_DMA 0x00000080
|
||||
#define DMA_CTL_EN_RX_DMA 0x00000040
|
||||
#define DMA_CTL_RX_INT_BUFFUL_EN 0x00000020
|
||||
#define DMA_CTL_RX_INT_TO_EN 0x00000010
|
||||
#define DMA_CTL_RX_INT_EN 0x00000008
|
||||
#define DMA_CTL_TX_INT_EN 0x00000004
|
||||
#define DMA_CTL_MAC_TX_INT_EN 0x00000002
|
||||
#define DMA_CTL_MAC_RX_INT_EN 0x00000001
|
||||
|
||||
/* DMA STATUS register. */
|
||||
#define DMA_STATUS_BAD_ADDR_SHF 16
|
||||
#define DMA_STATUS_BAD_ADDR_MSK (0xf << DMA_STATUS_BAD_ADDR_SHF)
|
||||
#define DMA_STATUS_RX_PKTS_RECEIVED_SHF 8
|
||||
#define DMA_STATUS_RX_PKTS_RECEIVED_MSK (0xff << DMA_STATUS_RX_PKTS_RECEIVED_SHF)
|
||||
#define DMA_STATUS_TX_EN_SYNC 0x00000080
|
||||
#define DMA_STATUS_RX_BUF_A_FUL 0x00000040
|
||||
#define DMA_STATUS_RX_BUF_B_FUL 0x00000020
|
||||
#define DMA_STATUS_RX_TO_INT 0x00000010
|
||||
#define DMA_STATUS_RX_INT 0x00000008
|
||||
#define DMA_STATUS_TX_INT 0x00000004
|
||||
#define DMA_STATUS_MAC_TX_INT 0x00000002
|
||||
#define DMA_STATUS_MAC_RX_INT 0x00000001
|
||||
|
||||
/* DMA TEST/PANIC SWITHES register. */
|
||||
#define DMA_TEST_LOOPBACK 0x01000000
|
||||
#define DMA_TEST_SW_RESET 0x00000001
|
||||
|
||||
/* MAC CONTROL register. */
|
||||
#define MAC_CONTROL_EN_MISS_ROLL 0x00002000
|
||||
#define MAC_CONTROL_MISS_ROLL 0x00000400
|
||||
#define MAC_CONTROL_LOOP10 0x00000080
|
||||
#define MAC_CONTROL_CONN_SHF 5
|
||||
#define MAC_CONTROL_CONN_MSK (0x3 << MAC_CONTROL_CONN_SHF)
|
||||
#define MAC_CONTROL_MAC_LOOP 0x00000010
|
||||
#define MAC_CONTROL_FULL_DUP 0x00000008
|
||||
#define MAC_CONTROL_RESET 0x00000004
|
||||
#define MAC_CONTROL_HALT_IMM 0x00000002
|
||||
#define MAC_CONTROL_HALT_REQ 0x00000001
|
||||
|
||||
/* CAM CONTROL register. */
|
||||
#define CAM_CONTROL_COMP_EN 0x00000010
|
||||
#define CAM_CONTROL_NEG_CAM 0x00000008
|
||||
#define CAM_CONTROL_BROAD_ACC 0x00000004
|
||||
#define CAM_CONTROL_GROUP_ACC 0x00000002
|
||||
#define CAM_CONTROL_STATION_ACC 0x00000001
|
||||
|
||||
/* TRANSMIT CONTROL register. */
|
||||
#define TX_CTL_EN_COMP 0x00004000
|
||||
#define TX_CTL_EN_TX_PAR 0x00002000
|
||||
#define TX_CTL_EN_LATE_COLL 0x00001000
|
||||
#define TX_CTL_EN_EX_COLL 0x00000800
|
||||
#define TX_CTL_EN_L_CARR 0x00000400
|
||||
#define TX_CTL_EN_EX_DEFER 0x00000200
|
||||
#define TX_CTL_EN_UNDER 0x00000100
|
||||
#define TX_CTL_MII10 0x00000080
|
||||
#define TX_CTL_SD_PAUSE 0x00000040
|
||||
#define TX_CTL_NO_EX_DEF0 0x00000020
|
||||
#define TX_CTL_F_BACK 0x00000010
|
||||
#define TX_CTL_NO_CRC 0x00000008
|
||||
#define TX_CTL_NO_PAD 0x00000004
|
||||
#define TX_CTL_TX_HALT 0x00000002
|
||||
#define TX_CTL_TX_EN 0x00000001
|
||||
|
||||
/* TRANSMIT STATUS register. */
|
||||
#define TX_STATUS_SQ_ERR 0x00010000
|
||||
#define TX_STATUS_TX_HALTED 0x00008000
|
||||
#define TX_STATUS_COMP 0x00004000
|
||||
#define TX_STATUS_TX_PAR 0x00002000
|
||||
#define TX_STATUS_LATE_COLL 0x00001000
|
||||
#define TX_STATUS_TX10_STAT 0x00000800
|
||||
#define TX_STATUS_L_CARR 0x00000400
|
||||
#define TX_STATUS_EX_DEFER 0x00000200
|
||||
#define TX_STATUS_UNDER 0x00000100
|
||||
#define TX_STATUS_IN_TX 0x00000080
|
||||
#define TX_STATUS_PAUSED 0x00000040
|
||||
#define TX_STATUS_TX_DEFERRED 0x00000020
|
||||
#define TX_STATUS_EX_COLL 0x00000010
|
||||
#define TX_STATUS_TX_COLL_SHF 0
|
||||
#define TX_STATUS_TX_COLL_MSK (0xf << TX_STATUS_TX_COLL_SHF)
|
||||
|
||||
/* RECEIVE CONTROL register. */
|
||||
#define RX_CTL_EN_GOOD 0x00004000
|
||||
#define RX_CTL_EN_RX_PAR 0x00002000
|
||||
#define RX_CTL_EN_LONG_ERR 0x00000800
|
||||
#define RX_CTL_EN_OVER 0x00000400
|
||||
#define RX_CTL_EN_CRC_ERR 0x00000200
|
||||
#define RX_CTL_EN_ALIGN 0x00000100
|
||||
#define RX_CTL_IGNORE_CRC 0x00000040
|
||||
#define RX_CTL_PASS_CTL 0x00000020
|
||||
#define RX_CTL_STRIP_CRC 0x00000010
|
||||
#define RX_CTL_SHORT_EN 0x00000008
|
||||
#define RX_CTL_LONG_EN 0x00000004
|
||||
#define RX_CTL_RX_HALT 0x00000002
|
||||
#define RX_CTL_RX_EN 0x00000001
|
||||
|
||||
/* RECEIVE STATUS register. */
|
||||
#define RX_STATUS_RX_HALTED 0x00008000
|
||||
#define RX_STATUS_GOOD 0x00004000
|
||||
#define RX_STATUS_RX_PAR 0x00002000
|
||||
#define RX_STATUS_LONG_ERR 0x00000800
|
||||
#define RX_STATUS_OVERFLOW 0x00000400
|
||||
#define RX_STATUS_CRC_ERR 0x00000200
|
||||
#define RX_STATUS_ALIGN_ERR 0x00000100
|
||||
#define RX_STATUS_RX10_STAT 0x00000080
|
||||
#define RX_STATUS_INT_RX 0x00000040
|
||||
#define RX_STATUS_CTL_RECD 0x00000020
|
||||
|
||||
/* MD_CA register. */
|
||||
#define MD_CA_PRE_SUP 0x00001000
|
||||
#define MD_CA_BUSY 0x00000800
|
||||
#define MD_CA_WR 0x00000400
|
||||
#define MD_CA_PHY_SHF 5
|
||||
#define MD_CA_PHY_MSK (0x1f << MD_CA_PHY_SHF)
|
||||
#define MD_CA_ADDR_SHF 0
|
||||
#define MD_CA_ADDR_MSK (0x1f << MD_CA_ADDR_SHF)
|
||||
|
||||
/* Tx Status/Control. */
|
||||
#define TX_STAT_CTL_OWNER_SHF 30
|
||||
#define TX_STAT_CTL_OWNER_MSK (0x3 << TX_STAT_CTL_OWNER_SHF)
|
||||
#define TX_STAT_CTL_FRAME_SHF 27
|
||||
#define TX_STAT_CTL_FRAME_MSK (0x7 << TX_STAT_CTL_FRAME_SHF)
|
||||
#define TX_STAT_CTL_STATUS_SHF 11
|
||||
#define TX_STAT_CTL_STATUS_MSK (0x1ffff << TX_STAT_CTL_STATUS_SHF)
|
||||
#define TX_STAT_CTL_LENGTH_SHF 0
|
||||
#define TX_STAT_CTL_LENGTH_MSK (0x7ff << TX_STAT_CTL_LENGTH_SHF)
|
||||
|
||||
#define TX_STAT_CTL_ERROR_MSK ((TX_STATUS_SQ_ERR | \
|
||||
TX_STATUS_TX_HALTED | \
|
||||
TX_STATUS_TX_PAR | \
|
||||
TX_STATUS_LATE_COLL | \
|
||||
TX_STATUS_L_CARR | \
|
||||
TX_STATUS_EX_DEFER | \
|
||||
TX_STATUS_UNDER | \
|
||||
TX_STATUS_PAUSED | \
|
||||
TX_STATUS_TX_DEFERRED | \
|
||||
TX_STATUS_EX_COLL | \
|
||||
TX_STATUS_TX_COLL_MSK) \
|
||||
<< TX_STAT_CTL_STATUS_SHF)
|
||||
#define TX_STAT_CTL_INT_AFTER_TX 0x4
|
||||
|
||||
/* Rx Status/Control. */
|
||||
#define RX_STAT_CTL_OWNER_SHF 30
|
||||
#define RX_STAT_CTL_OWNER_MSK (0x3 << RX_STAT_CTL_OWNER_SHF)
|
||||
#define RX_STAT_CTL_STATUS_SHF 11
|
||||
#define RX_STAT_CTL_STATUS_MSK (0xffff << RX_STAT_CTL_STATUS_SHF)
|
||||
#define RX_STAT_CTL_LENGTH_SHF 0
|
||||
#define RX_STAT_CTL_LENGTH_MSK (0x7ff << RX_STAT_CTL_LENGTH_SHF)
|
||||
|
||||
|
||||
|
||||
/* The SAA9730 (LAN) controller register map, as seen via the PCI-bus. */
|
||||
#define SAA9730_LAN_REGS_ADDR 0x20400
|
||||
#define SAA9730_LAN_REGS_SIZE 0x00400
|
||||
|
||||
struct lan_saa9730_regmap {
|
||||
volatile unsigned int TxBuffA; /* 0x20400 */
|
||||
volatile unsigned int TxBuffB; /* 0x20404 */
|
||||
volatile unsigned int RxBuffA; /* 0x20408 */
|
||||
volatile unsigned int RxBuffB; /* 0x2040c */
|
||||
volatile unsigned int PacketCount; /* 0x20410 */
|
||||
volatile unsigned int Ok2Use; /* 0x20414 */
|
||||
volatile unsigned int LanDmaCtl; /* 0x20418 */
|
||||
volatile unsigned int Timeout; /* 0x2041c */
|
||||
volatile unsigned int DmaStatus; /* 0x20420 */
|
||||
volatile unsigned int DmaTest; /* 0x20424 */
|
||||
volatile unsigned char filler20428[0x20430 - 0x20428];
|
||||
volatile unsigned int PauseCount; /* 0x20430 */
|
||||
volatile unsigned int RemotePauseCount; /* 0x20434 */
|
||||
volatile unsigned char filler20438[0x20440 - 0x20438];
|
||||
volatile unsigned int MacCtl; /* 0x20440 */
|
||||
volatile unsigned int CamCtl; /* 0x20444 */
|
||||
volatile unsigned int TxCtl; /* 0x20448 */
|
||||
volatile unsigned int TxStatus; /* 0x2044c */
|
||||
volatile unsigned int RxCtl; /* 0x20450 */
|
||||
volatile unsigned int RxStatus; /* 0x20454 */
|
||||
volatile unsigned int StationMgmtData; /* 0x20458 */
|
||||
volatile unsigned int StationMgmtCtl; /* 0x2045c */
|
||||
volatile unsigned int CamAddress; /* 0x20460 */
|
||||
volatile unsigned int CamData; /* 0x20464 */
|
||||
volatile unsigned int CamEnable; /* 0x20468 */
|
||||
volatile unsigned char filler2046c[0x20500 - 0x2046c];
|
||||
volatile unsigned int DebugPCIMasterAddr; /* 0x20500 */
|
||||
volatile unsigned int DebugLanTxStateMachine; /* 0x20504 */
|
||||
volatile unsigned int DebugLanRxStateMachine; /* 0x20508 */
|
||||
volatile unsigned int DebugLanTxFifoPointers; /* 0x2050c */
|
||||
volatile unsigned int DebugLanRxFifoPointers; /* 0x20510 */
|
||||
volatile unsigned int DebugLanCtlStateMachine; /* 0x20514 */
|
||||
};
|
||||
typedef volatile struct lan_saa9730_regmap t_lan_saa9730_regmap;
|
||||
|
||||
|
||||
/* EVM interrupt control registers. */
|
||||
#define EVM_LAN_INT 0x00010000
|
||||
#define EVM_MASTER_EN 0x00000001
|
||||
|
||||
/* The SAA9730 (EVM) controller register map, as seen via the PCI-bus. */
|
||||
#define SAA9730_EVM_REGS_ADDR 0x02000
|
||||
#define SAA9730_EVM_REGS_SIZE 0x00400
|
||||
|
||||
struct evm_saa9730_regmap {
|
||||
volatile unsigned int InterruptStatus1; /* 0x2000 */
|
||||
volatile unsigned int InterruptEnable1; /* 0x2004 */
|
||||
volatile unsigned int InterruptMonitor1; /* 0x2008 */
|
||||
volatile unsigned int Counter; /* 0x200c */
|
||||
volatile unsigned int CounterThreshold; /* 0x2010 */
|
||||
volatile unsigned int CounterControl; /* 0x2014 */
|
||||
volatile unsigned int GpioControl1; /* 0x2018 */
|
||||
volatile unsigned int InterruptStatus2; /* 0x201c */
|
||||
volatile unsigned int InterruptEnable2; /* 0x2020 */
|
||||
volatile unsigned int InterruptMonitor2; /* 0x2024 */
|
||||
volatile unsigned int GpioControl2; /* 0x2028 */
|
||||
volatile unsigned int InterruptBlock1; /* 0x202c */
|
||||
volatile unsigned int InterruptBlock2; /* 0x2030 */
|
||||
};
|
||||
typedef volatile struct evm_saa9730_regmap t_evm_saa9730_regmap;
|
||||
|
||||
|
||||
struct lan_saa9730_private {
|
||||
/*
|
||||
* Rx/Tx packet buffers.
|
||||
* The Rx and Tx packets must be PACKET_SIZE aligned.
|
||||
*/
|
||||
void *buffer_start;
|
||||
unsigned int buffer_size;
|
||||
|
||||
/*
|
||||
* DMA address of beginning of this object, returned
|
||||
* by pci_alloc_consistent().
|
||||
*/
|
||||
dma_addr_t dma_addr;
|
||||
|
||||
/* Pointer to the associated pci device structure */
|
||||
struct pci_dev *pci_dev;
|
||||
|
||||
/* Pointer for the SAA9730 LAN controller register set. */
|
||||
t_lan_saa9730_regmap *lan_saa9730_regs;
|
||||
|
||||
/* Pointer to the SAA9730 EVM register. */
|
||||
t_evm_saa9730_regmap *evm_saa9730_regs;
|
||||
|
||||
/* Rcv buffer Index. */
|
||||
unsigned char NextRcvPacketIndex;
|
||||
/* Next buffer index. */
|
||||
unsigned char NextRcvBufferIndex;
|
||||
|
||||
/* Index of next packet to use in that buffer. */
|
||||
unsigned char NextTxmPacketIndex;
|
||||
/* Next buffer index. */
|
||||
unsigned char NextTxmBufferIndex;
|
||||
|
||||
/* Index of first pending packet ready to send. */
|
||||
unsigned char PendingTxmPacketIndex;
|
||||
/* Pending buffer index. */
|
||||
unsigned char PendingTxmBufferIndex;
|
||||
|
||||
unsigned char DmaRcvPackets;
|
||||
unsigned char DmaTxmPackets;
|
||||
|
||||
void *TxmBuffer[LAN_SAA9730_BUFFERS][LAN_SAA9730_TXM_Q_SIZE];
|
||||
void *RcvBuffer[LAN_SAA9730_BUFFERS][LAN_SAA9730_RCV_Q_SIZE];
|
||||
unsigned int TxBufferFree[LAN_SAA9730_BUFFERS];
|
||||
|
||||
unsigned char PhysicalAddress[LAN_SAA9730_CAM_ENTRIES][6];
|
||||
|
||||
spinlock_t lock;
|
||||
};
|
||||
|
||||
#endif /* _SAA9730_H */
|
@ -3500,11 +3500,7 @@ static int ucc_geth_rx(struct ucc_geth_private *ugeth, u8 rxQ, int rx_work_limit
|
||||
|
||||
dev->stats.rx_bytes += length;
|
||||
/* Send the packet up the stack */
|
||||
#ifdef CONFIG_UGETH_NAPI
|
||||
netif_receive_skb(skb);
|
||||
#else
|
||||
netif_rx(skb);
|
||||
#endif /* CONFIG_UGETH_NAPI */
|
||||
}
|
||||
|
||||
ugeth->dev->last_rx = jiffies;
|
||||
@ -3580,7 +3576,6 @@ static int ucc_geth_tx(struct net_device *dev, u8 txQ)
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_UGETH_NAPI
|
||||
static int ucc_geth_poll(struct napi_struct *napi, int budget)
|
||||
{
|
||||
struct ucc_geth_private *ugeth = container_of(napi, struct ucc_geth_private, napi);
|
||||
@ -3607,7 +3602,6 @@ static int ucc_geth_poll(struct napi_struct *napi, int budget)
|
||||
|
||||
return howmany;
|
||||
}
|
||||
#endif /* CONFIG_UGETH_NAPI */
|
||||
|
||||
static irqreturn_t ucc_geth_irq_handler(int irq, void *info)
|
||||
{
|
||||
@ -3617,9 +3611,6 @@ static irqreturn_t ucc_geth_irq_handler(int irq, void *info)
|
||||
struct ucc_geth_info *ug_info;
|
||||
register u32 ucce;
|
||||
register u32 uccm;
|
||||
#ifndef CONFIG_UGETH_NAPI
|
||||
register u32 rx_mask;
|
||||
#endif
|
||||
register u32 tx_mask;
|
||||
u8 i;
|
||||
|
||||
@ -3636,21 +3627,11 @@ static irqreturn_t ucc_geth_irq_handler(int irq, void *info)
|
||||
|
||||
/* check for receive events that require processing */
|
||||
if (ucce & UCCE_RX_EVENTS) {
|
||||
#ifdef CONFIG_UGETH_NAPI
|
||||
if (netif_rx_schedule_prep(dev, &ugeth->napi)) {
|
||||
uccm &= ~UCCE_RX_EVENTS;
|
||||
out_be32(uccf->p_uccm, uccm);
|
||||
__netif_rx_schedule(dev, &ugeth->napi);
|
||||
}
|
||||
#else
|
||||
rx_mask = UCCE_RXBF_SINGLE_MASK;
|
||||
for (i = 0; i < ug_info->numQueuesRx; i++) {
|
||||
if (ucce & rx_mask)
|
||||
ucc_geth_rx(ugeth, i, (int)ugeth->ug_info->bdRingLenRx[i]);
|
||||
ucce &= ~rx_mask;
|
||||
rx_mask <<= 1;
|
||||
}
|
||||
#endif /* CONFIG_UGETH_NAPI */
|
||||
}
|
||||
|
||||
/* Tx event processing */
|
||||
@ -3720,9 +3701,8 @@ static int ucc_geth_open(struct net_device *dev)
|
||||
return err;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_UGETH_NAPI
|
||||
napi_enable(&ugeth->napi);
|
||||
#endif
|
||||
|
||||
err = ucc_geth_startup(ugeth);
|
||||
if (err) {
|
||||
if (netif_msg_ifup(ugeth))
|
||||
@ -3783,9 +3763,8 @@ static int ucc_geth_open(struct net_device *dev)
|
||||
return err;
|
||||
|
||||
out_err:
|
||||
#ifdef CONFIG_UGETH_NAPI
|
||||
napi_disable(&ugeth->napi);
|
||||
#endif
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
@ -3796,9 +3775,7 @@ static int ucc_geth_close(struct net_device *dev)
|
||||
|
||||
ugeth_vdbg("%s: IN", __FUNCTION__);
|
||||
|
||||
#ifdef CONFIG_UGETH_NAPI
|
||||
napi_disable(&ugeth->napi);
|
||||
#endif
|
||||
|
||||
ucc_geth_stop(ugeth);
|
||||
|
||||
@ -4050,9 +4027,7 @@ static int ucc_geth_probe(struct of_device* ofdev, const struct of_device_id *ma
|
||||
dev->hard_start_xmit = ucc_geth_start_xmit;
|
||||
dev->tx_timeout = ucc_geth_timeout;
|
||||
dev->watchdog_timeo = TX_TIMEOUT;
|
||||
#ifdef CONFIG_UGETH_NAPI
|
||||
netif_napi_add(dev, &ugeth->napi, ucc_geth_poll, UCC_GETH_DEV_WEIGHT);
|
||||
#endif /* CONFIG_UGETH_NAPI */
|
||||
#ifdef CONFIG_NET_POLL_CONTROLLER
|
||||
dev->poll_controller = ucc_netpoll;
|
||||
#endif
|
||||
|
@ -73,12 +73,7 @@ static const int multicast_filter_limit = 32;
|
||||
There are no ill effects from too-large receive rings. */
|
||||
#define TX_RING_SIZE 16
|
||||
#define TX_QUEUE_LEN 10 /* Limit ring entries actually used. */
|
||||
#ifdef CONFIG_VIA_RHINE_NAPI
|
||||
#define RX_RING_SIZE 64
|
||||
#else
|
||||
#define RX_RING_SIZE 16
|
||||
#endif
|
||||
|
||||
|
||||
/* Operational parameters that usually are not changed. */
|
||||
|
||||
@ -583,7 +578,6 @@ static void rhine_poll(struct net_device *dev)
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_VIA_RHINE_NAPI
|
||||
static int rhine_napipoll(struct napi_struct *napi, int budget)
|
||||
{
|
||||
struct rhine_private *rp = container_of(napi, struct rhine_private, napi);
|
||||
@ -604,7 +598,6 @@ static int rhine_napipoll(struct napi_struct *napi, int budget)
|
||||
}
|
||||
return work_done;
|
||||
}
|
||||
#endif
|
||||
|
||||
static void __devinit rhine_hw_init(struct net_device *dev, long pioaddr)
|
||||
{
|
||||
@ -784,9 +777,8 @@ static int __devinit rhine_init_one(struct pci_dev *pdev,
|
||||
#ifdef CONFIG_NET_POLL_CONTROLLER
|
||||
dev->poll_controller = rhine_poll;
|
||||
#endif
|
||||
#ifdef CONFIG_VIA_RHINE_NAPI
|
||||
netif_napi_add(dev, &rp->napi, rhine_napipoll, 64);
|
||||
#endif
|
||||
|
||||
if (rp->quirks & rqRhineI)
|
||||
dev->features |= NETIF_F_SG|NETIF_F_HW_CSUM;
|
||||
|
||||
@ -1056,9 +1048,7 @@ static void init_registers(struct net_device *dev)
|
||||
|
||||
rhine_set_rx_mode(dev);
|
||||
|
||||
#ifdef CONFIG_VIA_RHINE_NAPI
|
||||
napi_enable(&rp->napi);
|
||||
#endif
|
||||
|
||||
/* Enable interrupts by setting the interrupt mask. */
|
||||
iowrite16(IntrRxDone | IntrRxErr | IntrRxEmpty| IntrRxOverflow |
|
||||
@ -1193,9 +1183,7 @@ static void rhine_tx_timeout(struct net_device *dev)
|
||||
/* protect against concurrent rx interrupts */
|
||||
disable_irq(rp->pdev->irq);
|
||||
|
||||
#ifdef CONFIG_VIA_RHINE_NAPI
|
||||
napi_disable(&rp->napi);
|
||||
#endif
|
||||
|
||||
spin_lock(&rp->lock);
|
||||
|
||||
@ -1319,16 +1307,12 @@ static irqreturn_t rhine_interrupt(int irq, void *dev_instance)
|
||||
|
||||
if (intr_status & (IntrRxDone | IntrRxErr | IntrRxDropped |
|
||||
IntrRxWakeUp | IntrRxEmpty | IntrRxNoBuf)) {
|
||||
#ifdef CONFIG_VIA_RHINE_NAPI
|
||||
iowrite16(IntrTxAborted |
|
||||
IntrTxDone | IntrTxError | IntrTxUnderrun |
|
||||
IntrPCIErr | IntrStatsMax | IntrLinkChange,
|
||||
ioaddr + IntrEnable);
|
||||
|
||||
netif_rx_schedule(dev, &rp->napi);
|
||||
#else
|
||||
rhine_rx(dev, RX_RING_SIZE);
|
||||
#endif
|
||||
}
|
||||
|
||||
if (intr_status & (IntrTxErrSummary | IntrTxDone)) {
|
||||
@ -1520,11 +1504,7 @@ static int rhine_rx(struct net_device *dev, int limit)
|
||||
PCI_DMA_FROMDEVICE);
|
||||
}
|
||||
skb->protocol = eth_type_trans(skb, dev);
|
||||
#ifdef CONFIG_VIA_RHINE_NAPI
|
||||
netif_receive_skb(skb);
|
||||
#else
|
||||
netif_rx(skb);
|
||||
#endif
|
||||
dev->last_rx = jiffies;
|
||||
rp->stats.rx_bytes += pkt_len;
|
||||
rp->stats.rx_packets++;
|
||||
@ -1836,9 +1816,7 @@ static int rhine_close(struct net_device *dev)
|
||||
spin_lock_irq(&rp->lock);
|
||||
|
||||
netif_stop_queue(dev);
|
||||
#ifdef CONFIG_VIA_RHINE_NAPI
|
||||
napi_disable(&rp->napi);
|
||||
#endif
|
||||
|
||||
if (debug > 1)
|
||||
printk(KERN_DEBUG "%s: Shutting down ethercard, "
|
||||
@ -1937,9 +1915,8 @@ static int rhine_suspend(struct pci_dev *pdev, pm_message_t state)
|
||||
if (!netif_running(dev))
|
||||
return 0;
|
||||
|
||||
#ifdef CONFIG_VIA_RHINE_NAPI
|
||||
napi_disable(&rp->napi);
|
||||
#endif
|
||||
|
||||
netif_device_detach(dev);
|
||||
pci_save_state(pdev);
|
||||
|
||||
|
@ -1102,61 +1102,41 @@ static int __devinit velocity_get_pci_info(struct velocity_info *vptr, struct pc
|
||||
|
||||
static int velocity_init_rings(struct velocity_info *vptr)
|
||||
{
|
||||
int i;
|
||||
unsigned int psize;
|
||||
unsigned int tsize;
|
||||
struct velocity_opt *opt = &vptr->options;
|
||||
const unsigned int rx_ring_size = opt->numrx * sizeof(struct rx_desc);
|
||||
const unsigned int tx_ring_size = opt->numtx * sizeof(struct tx_desc);
|
||||
struct pci_dev *pdev = vptr->pdev;
|
||||
dma_addr_t pool_dma;
|
||||
u8 *pool;
|
||||
|
||||
/*
|
||||
* Allocate all RD/TD rings a single pool
|
||||
*/
|
||||
|
||||
psize = vptr->options.numrx * sizeof(struct rx_desc) +
|
||||
vptr->options.numtx * sizeof(struct tx_desc) * vptr->num_txq;
|
||||
void *pool;
|
||||
unsigned int i;
|
||||
|
||||
/*
|
||||
* Allocate all RD/TD rings a single pool.
|
||||
*
|
||||
* pci_alloc_consistent() fulfills the requirement for 64 bytes
|
||||
* alignment
|
||||
*/
|
||||
pool = pci_alloc_consistent(vptr->pdev, psize, &pool_dma);
|
||||
|
||||
if (pool == NULL) {
|
||||
printk(KERN_ERR "%s : DMA memory allocation failed.\n",
|
||||
pool = pci_alloc_consistent(pdev, tx_ring_size * vptr->num_txq +
|
||||
rx_ring_size, &pool_dma);
|
||||
if (!pool) {
|
||||
dev_err(&pdev->dev, "%s : DMA memory allocation failed.\n",
|
||||
vptr->dev->name);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
memset(pool, 0, psize);
|
||||
|
||||
vptr->rd_ring = (struct rx_desc *) pool;
|
||||
|
||||
vptr->rd_ring = pool;
|
||||
vptr->rd_pool_dma = pool_dma;
|
||||
|
||||
tsize = vptr->options.numtx * PKT_BUF_SZ * vptr->num_txq;
|
||||
vptr->tx_bufs = pci_alloc_consistent(vptr->pdev, tsize,
|
||||
&vptr->tx_bufs_dma);
|
||||
pool += rx_ring_size;
|
||||
pool_dma += rx_ring_size;
|
||||
|
||||
if (vptr->tx_bufs == NULL) {
|
||||
printk(KERN_ERR "%s: DMA memory allocation failed.\n",
|
||||
vptr->dev->name);
|
||||
pci_free_consistent(vptr->pdev, psize, pool, pool_dma);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
memset(vptr->tx_bufs, 0, vptr->options.numtx * PKT_BUF_SZ * vptr->num_txq);
|
||||
|
||||
i = vptr->options.numrx * sizeof(struct rx_desc);
|
||||
pool += i;
|
||||
pool_dma += i;
|
||||
for (i = 0; i < vptr->num_txq; i++) {
|
||||
int offset = vptr->options.numtx * sizeof(struct tx_desc);
|
||||
|
||||
vptr->td_rings[i] = pool;
|
||||
vptr->td_pool_dma[i] = pool_dma;
|
||||
vptr->td_rings[i] = (struct tx_desc *) pool;
|
||||
pool += offset;
|
||||
pool_dma += offset;
|
||||
pool += tx_ring_size;
|
||||
pool_dma += tx_ring_size;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1169,19 +1149,13 @@ static int velocity_init_rings(struct velocity_info *vptr)
|
||||
|
||||
static void velocity_free_rings(struct velocity_info *vptr)
|
||||
{
|
||||
int size;
|
||||
|
||||
size = vptr->options.numrx * sizeof(struct rx_desc) +
|
||||
const int size = vptr->options.numrx * sizeof(struct rx_desc) +
|
||||
vptr->options.numtx * sizeof(struct tx_desc) * vptr->num_txq;
|
||||
|
||||
pci_free_consistent(vptr->pdev, size, vptr->rd_ring, vptr->rd_pool_dma);
|
||||
|
||||
size = vptr->options.numtx * PKT_BUF_SZ * vptr->num_txq;
|
||||
|
||||
pci_free_consistent(vptr->pdev, size, vptr->tx_bufs, vptr->tx_bufs_dma);
|
||||
}
|
||||
|
||||
static inline void velocity_give_many_rx_descs(struct velocity_info *vptr)
|
||||
static void velocity_give_many_rx_descs(struct velocity_info *vptr)
|
||||
{
|
||||
struct mac_regs __iomem *regs = vptr->mac_regs;
|
||||
int avail, dirty, unusable;
|
||||
@ -1208,7 +1182,7 @@ static inline void velocity_give_many_rx_descs(struct velocity_info *vptr)
|
||||
|
||||
static int velocity_rx_refill(struct velocity_info *vptr)
|
||||
{
|
||||
int dirty = vptr->rd_dirty, done = 0, ret = 0;
|
||||
int dirty = vptr->rd_dirty, done = 0;
|
||||
|
||||
do {
|
||||
struct rx_desc *rd = vptr->rd_ring + dirty;
|
||||
@ -1218,8 +1192,7 @@ static int velocity_rx_refill(struct velocity_info *vptr)
|
||||
break;
|
||||
|
||||
if (!vptr->rd_info[dirty].skb) {
|
||||
ret = velocity_alloc_rx_buf(vptr, dirty);
|
||||
if (ret < 0)
|
||||
if (velocity_alloc_rx_buf(vptr, dirty) < 0)
|
||||
break;
|
||||
}
|
||||
done++;
|
||||
@ -1229,10 +1202,14 @@ static int velocity_rx_refill(struct velocity_info *vptr)
|
||||
if (done) {
|
||||
vptr->rd_dirty = dirty;
|
||||
vptr->rd_filled += done;
|
||||
velocity_give_many_rx_descs(vptr);
|
||||
}
|
||||
|
||||
return ret;
|
||||
return done;
|
||||
}
|
||||
|
||||
static void velocity_set_rxbufsize(struct velocity_info *vptr, int mtu)
|
||||
{
|
||||
vptr->rx_buf_sz = (mtu <= ETH_DATA_LEN) ? PKT_BUF_SZ : mtu + 32;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1245,25 +1222,24 @@ static int velocity_rx_refill(struct velocity_info *vptr)
|
||||
|
||||
static int velocity_init_rd_ring(struct velocity_info *vptr)
|
||||
{
|
||||
int ret;
|
||||
int mtu = vptr->dev->mtu;
|
||||
|
||||
vptr->rx_buf_sz = (mtu <= ETH_DATA_LEN) ? PKT_BUF_SZ : mtu + 32;
|
||||
int ret = -ENOMEM;
|
||||
|
||||
vptr->rd_info = kcalloc(vptr->options.numrx,
|
||||
sizeof(struct velocity_rd_info), GFP_KERNEL);
|
||||
if (!vptr->rd_info)
|
||||
return -ENOMEM;
|
||||
goto out;
|
||||
|
||||
vptr->rd_filled = vptr->rd_dirty = vptr->rd_curr = 0;
|
||||
|
||||
ret = velocity_rx_refill(vptr);
|
||||
if (ret < 0) {
|
||||
if (velocity_rx_refill(vptr) != vptr->options.numrx) {
|
||||
VELOCITY_PRT(MSG_LEVEL_ERR, KERN_ERR
|
||||
"%s: failed to allocate RX buffer.\n", vptr->dev->name);
|
||||
velocity_free_rd_ring(vptr);
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = 0;
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -1313,10 +1289,8 @@ static void velocity_free_rd_ring(struct velocity_info *vptr)
|
||||
|
||||
static int velocity_init_td_ring(struct velocity_info *vptr)
|
||||
{
|
||||
int i, j;
|
||||
dma_addr_t curr;
|
||||
struct tx_desc *td;
|
||||
struct velocity_td_info *td_info;
|
||||
unsigned int j;
|
||||
|
||||
/* Init the TD ring entries */
|
||||
for (j = 0; j < vptr->num_txq; j++) {
|
||||
@ -1331,14 +1305,6 @@ static int velocity_init_td_ring(struct velocity_info *vptr)
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
for (i = 0; i < vptr->options.numtx; i++, curr += sizeof(struct tx_desc)) {
|
||||
td = &(vptr->td_rings[j][i]);
|
||||
td_info = &(vptr->td_infos[j][i]);
|
||||
td_info->buf = vptr->tx_bufs +
|
||||
(j * vptr->options.numtx + i) * PKT_BUF_SZ;
|
||||
td_info->buf_dma = vptr->tx_bufs_dma +
|
||||
(j * vptr->options.numtx + i) * PKT_BUF_SZ;
|
||||
}
|
||||
vptr->td_tail[j] = vptr->td_curr[j] = vptr->td_used[j] = 0;
|
||||
}
|
||||
return 0;
|
||||
@ -1448,10 +1414,8 @@ static int velocity_rx_srv(struct velocity_info *vptr, int status)
|
||||
|
||||
vptr->rd_curr = rd_curr;
|
||||
|
||||
if (works > 0 && velocity_rx_refill(vptr) < 0) {
|
||||
VELOCITY_PRT(MSG_LEVEL_ERR, KERN_ERR
|
||||
"%s: rx buf allocation failure\n", vptr->dev->name);
|
||||
}
|
||||
if ((works > 0) && (velocity_rx_refill(vptr) > 0))
|
||||
velocity_give_many_rx_descs(vptr);
|
||||
|
||||
VAR_USED(stats);
|
||||
return works;
|
||||
@ -1867,7 +1831,7 @@ static void velocity_free_tx_buf(struct velocity_info *vptr, struct velocity_td_
|
||||
/*
|
||||
* Don't unmap the pre-allocated tx_bufs
|
||||
*/
|
||||
if (tdinfo->skb_dma && (tdinfo->skb_dma[0] != tdinfo->buf_dma)) {
|
||||
if (tdinfo->skb_dma) {
|
||||
|
||||
for (i = 0; i < tdinfo->nskb_dma; i++) {
|
||||
#ifdef VELOCITY_ZERO_COPY_SUPPORT
|
||||
@ -1898,6 +1862,8 @@ static int velocity_open(struct net_device *dev)
|
||||
struct velocity_info *vptr = netdev_priv(dev);
|
||||
int ret;
|
||||
|
||||
velocity_set_rxbufsize(vptr, dev->mtu);
|
||||
|
||||
ret = velocity_init_rings(vptr);
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
@ -1913,6 +1879,8 @@ static int velocity_open(struct net_device *dev)
|
||||
/* Ensure chip is running */
|
||||
pci_set_power_state(vptr->pdev, PCI_D0);
|
||||
|
||||
velocity_give_many_rx_descs(vptr);
|
||||
|
||||
velocity_init_registers(vptr, VELOCITY_INIT_COLD);
|
||||
|
||||
ret = request_irq(vptr->pdev->irq, &velocity_intr, IRQF_SHARED,
|
||||
@ -1977,6 +1945,8 @@ static int velocity_change_mtu(struct net_device *dev, int new_mtu)
|
||||
|
||||
dev->mtu = new_mtu;
|
||||
|
||||
velocity_set_rxbufsize(vptr, new_mtu);
|
||||
|
||||
ret = velocity_init_rd_ring(vptr);
|
||||
if (ret < 0)
|
||||
goto out_unlock;
|
||||
@ -2063,9 +2033,19 @@ static int velocity_xmit(struct sk_buff *skb, struct net_device *dev)
|
||||
struct tx_desc *td_ptr;
|
||||
struct velocity_td_info *tdinfo;
|
||||
unsigned long flags;
|
||||
int index;
|
||||
int pktlen = skb->len;
|
||||
__le16 len = cpu_to_le16(pktlen);
|
||||
__le16 len;
|
||||
int index;
|
||||
|
||||
|
||||
|
||||
if (skb->len < ETH_ZLEN) {
|
||||
if (skb_padto(skb, ETH_ZLEN))
|
||||
goto out;
|
||||
pktlen = ETH_ZLEN;
|
||||
}
|
||||
|
||||
len = cpu_to_le16(pktlen);
|
||||
|
||||
#ifdef VELOCITY_ZERO_COPY_SUPPORT
|
||||
if (skb_shinfo(skb)->nr_frags > 6 && __skb_linearize(skb)) {
|
||||
@ -2083,23 +2063,6 @@ static int velocity_xmit(struct sk_buff *skb, struct net_device *dev)
|
||||
td_ptr->tdesc1.TCR = TCR0_TIC;
|
||||
td_ptr->td_buf[0].size &= ~TD_QUEUE;
|
||||
|
||||
/*
|
||||
* Pad short frames.
|
||||
*/
|
||||
if (pktlen < ETH_ZLEN) {
|
||||
/* Cannot occur until ZC support */
|
||||
pktlen = ETH_ZLEN;
|
||||
len = cpu_to_le16(ETH_ZLEN);
|
||||
skb_copy_from_linear_data(skb, tdinfo->buf, skb->len);
|
||||
memset(tdinfo->buf + skb->len, 0, ETH_ZLEN - skb->len);
|
||||
tdinfo->skb = skb;
|
||||
tdinfo->skb_dma[0] = tdinfo->buf_dma;
|
||||
td_ptr->tdesc0.len = len;
|
||||
td_ptr->td_buf[0].pa_low = cpu_to_le32(tdinfo->skb_dma[0]);
|
||||
td_ptr->td_buf[0].pa_high = 0;
|
||||
td_ptr->td_buf[0].size = len; /* queue is 0 anyway */
|
||||
tdinfo->nskb_dma = 1;
|
||||
} else
|
||||
#ifdef VELOCITY_ZERO_COPY_SUPPORT
|
||||
if (skb_shinfo(skb)->nr_frags > 0) {
|
||||
int nfrags = skb_shinfo(skb)->nr_frags;
|
||||
@ -2191,7 +2154,8 @@ static int velocity_xmit(struct sk_buff *skb, struct net_device *dev)
|
||||
}
|
||||
dev->trans_start = jiffies;
|
||||
spin_unlock_irqrestore(&vptr->lock, flags);
|
||||
return 0;
|
||||
out:
|
||||
return NETDEV_TX_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -236,10 +236,8 @@ struct velocity_rd_info {
|
||||
|
||||
struct velocity_td_info {
|
||||
struct sk_buff *skb;
|
||||
u8 *buf;
|
||||
int nskb_dma;
|
||||
dma_addr_t skb_dma[7];
|
||||
dma_addr_t buf_dma;
|
||||
};
|
||||
|
||||
enum velocity_owner {
|
||||
@ -1506,9 +1504,6 @@ struct velocity_info {
|
||||
dma_addr_t rd_pool_dma;
|
||||
dma_addr_t td_pool_dma[TX_QUEUE_NO];
|
||||
|
||||
dma_addr_t tx_bufs_dma;
|
||||
u8 *tx_bufs;
|
||||
|
||||
struct vlan_group *vlgrp;
|
||||
u8 ip_addr[4];
|
||||
enum chip_type chip_id;
|
||||
|
@ -550,7 +550,8 @@ static struct virtio_device_id id_table[] = {
|
||||
};
|
||||
|
||||
static unsigned int features[] = {
|
||||
VIRTIO_NET_F_CSUM, VIRTIO_NET_F_GSO, VIRTIO_NET_F_MAC,
|
||||
VIRTIO_NET_F_CSUM, VIRTIO_NET_F_GUEST_CSUM,
|
||||
VIRTIO_NET_F_GSO, VIRTIO_NET_F_MAC,
|
||||
VIRTIO_NET_F_HOST_TSO4, VIRTIO_NET_F_HOST_UFO, VIRTIO_NET_F_HOST_TSO6,
|
||||
VIRTIO_NET_F_HOST_ECN, VIRTIO_F_NOTIFY_ON_EMPTY,
|
||||
};
|
||||
|
@ -828,6 +828,19 @@ static inline void netif_napi_add(struct net_device *dev,
|
||||
set_bit(NAPI_STATE_SCHED, &napi->state);
|
||||
}
|
||||
|
||||
/**
|
||||
* netif_napi_del - remove a napi context
|
||||
* @napi: napi context
|
||||
*
|
||||
* netif_napi_del() removes a napi context from the network device napi list
|
||||
*/
|
||||
static inline void netif_napi_del(struct napi_struct *napi)
|
||||
{
|
||||
#ifdef CONFIG_NETPOLL
|
||||
list_del(&napi->dev_list);
|
||||
#endif
|
||||
}
|
||||
|
||||
struct packet_type {
|
||||
__be16 type; /* This is really htons(ether_type). */
|
||||
struct net_device *dev; /* NULL is wildcarded here */
|
||||
|
Loading…
Reference in New Issue
Block a user