mirror of
https://github.com/adulau/aha.git
synced 2024-12-28 03:36:19 +00:00
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-2.6
Conflicts: drivers/net/s2io.c
This commit is contained in:
commit
e1ec1b8ccd
55 changed files with 286 additions and 687 deletions
|
@ -84,9 +84,6 @@ policy-routing.txt
|
||||||
- IP policy-based routing
|
- IP policy-based routing
|
||||||
ray_cs.txt
|
ray_cs.txt
|
||||||
- Raylink Wireless LAN card driver info.
|
- Raylink Wireless LAN card driver info.
|
||||||
sk98lin.txt
|
|
||||||
- Marvell Yukon Chipset / SysKonnect SK-98xx compliant Gigabit
|
|
||||||
Ethernet Adapter family driver info
|
|
||||||
skfp.txt
|
skfp.txt
|
||||||
- SysKonnect FDDI (SK-5xxx, Compaq Netelligent) driver info.
|
- SysKonnect FDDI (SK-5xxx, Compaq Netelligent) driver info.
|
||||||
smc9.txt
|
smc9.txt
|
||||||
|
|
|
@ -1,568 +0,0 @@
|
||||||
(C)Copyright 1999-2004 Marvell(R).
|
|
||||||
All rights reserved
|
|
||||||
===========================================================================
|
|
||||||
|
|
||||||
sk98lin.txt created 13-Feb-2004
|
|
||||||
|
|
||||||
Readme File for sk98lin v6.23
|
|
||||||
Marvell Yukon/SysKonnect SK-98xx Gigabit Ethernet Adapter family driver for LINUX
|
|
||||||
|
|
||||||
This file contains
|
|
||||||
1 Overview
|
|
||||||
2 Required Files
|
|
||||||
3 Installation
|
|
||||||
3.1 Driver Installation
|
|
||||||
3.2 Inclusion of adapter at system start
|
|
||||||
4 Driver Parameters
|
|
||||||
4.1 Per-Port Parameters
|
|
||||||
4.2 Adapter Parameters
|
|
||||||
5 Large Frame Support
|
|
||||||
6 VLAN and Link Aggregation Support (IEEE 802.1, 802.1q, 802.3ad)
|
|
||||||
7 Troubleshooting
|
|
||||||
|
|
||||||
===========================================================================
|
|
||||||
|
|
||||||
|
|
||||||
1 Overview
|
|
||||||
===========
|
|
||||||
|
|
||||||
The sk98lin driver supports the Marvell Yukon and SysKonnect
|
|
||||||
SK-98xx/SK-95xx compliant Gigabit Ethernet Adapter on Linux. It has
|
|
||||||
been tested with Linux on Intel/x86 machines.
|
|
||||||
***
|
|
||||||
|
|
||||||
|
|
||||||
2 Required Files
|
|
||||||
=================
|
|
||||||
|
|
||||||
The linux kernel source.
|
|
||||||
No additional files required.
|
|
||||||
***
|
|
||||||
|
|
||||||
|
|
||||||
3 Installation
|
|
||||||
===============
|
|
||||||
|
|
||||||
It is recommended to download the latest version of the driver from the
|
|
||||||
SysKonnect web site www.syskonnect.com. If you have downloaded the latest
|
|
||||||
driver, the Linux kernel has to be patched before the driver can be
|
|
||||||
installed. For details on how to patch a Linux kernel, refer to the
|
|
||||||
patch.txt file.
|
|
||||||
|
|
||||||
3.1 Driver Installation
|
|
||||||
------------------------
|
|
||||||
|
|
||||||
The following steps describe the actions that are required to install
|
|
||||||
the driver and to start it manually. These steps should be carried
|
|
||||||
out for the initial driver setup. Once confirmed to be ok, they can
|
|
||||||
be included in the system start.
|
|
||||||
|
|
||||||
NOTE 1: To perform the following tasks you need 'root' access.
|
|
||||||
|
|
||||||
NOTE 2: In case of problems, please read the section "Troubleshooting"
|
|
||||||
below.
|
|
||||||
|
|
||||||
The driver can either be integrated into the kernel or it can be compiled
|
|
||||||
as a module. Select the appropriate option during the kernel
|
|
||||||
configuration.
|
|
||||||
|
|
||||||
Compile/use the driver as a module
|
|
||||||
----------------------------------
|
|
||||||
To compile the driver, go to the directory /usr/src/linux and
|
|
||||||
execute the command "make menuconfig" or "make xconfig" and proceed as
|
|
||||||
follows:
|
|
||||||
|
|
||||||
To integrate the driver permanently into the kernel, proceed as follows:
|
|
||||||
|
|
||||||
1. Select the menu "Network device support" and then "Ethernet(1000Mbit)"
|
|
||||||
2. Mark "Marvell Yukon Chipset / SysKonnect SK-98xx family support"
|
|
||||||
with (*)
|
|
||||||
3. Build a new kernel when the configuration of the above options is
|
|
||||||
finished.
|
|
||||||
4. Install the new kernel.
|
|
||||||
5. Reboot your system.
|
|
||||||
|
|
||||||
To use the driver as a module, proceed as follows:
|
|
||||||
|
|
||||||
1. Enable 'loadable module support' in the kernel.
|
|
||||||
2. For automatic driver start, enable the 'Kernel module loader'.
|
|
||||||
3. Select the menu "Network device support" and then "Ethernet(1000Mbit)"
|
|
||||||
4. Mark "Marvell Yukon Chipset / SysKonnect SK-98xx family support"
|
|
||||||
with (M)
|
|
||||||
5. Execute the command "make modules".
|
|
||||||
6. Execute the command "make modules_install".
|
|
||||||
The appropriate modules will be installed.
|
|
||||||
7. Reboot your system.
|
|
||||||
|
|
||||||
|
|
||||||
Load the module manually
|
|
||||||
------------------------
|
|
||||||
To load the module manually, proceed as follows:
|
|
||||||
|
|
||||||
1. Enter "modprobe sk98lin".
|
|
||||||
2. If a Marvell Yukon or SysKonnect SK-98xx adapter is installed in
|
|
||||||
your computer and you have a /proc file system, execute the command:
|
|
||||||
"ls /proc/net/sk98lin/"
|
|
||||||
This should produce an output containing a line with the following
|
|
||||||
format:
|
|
||||||
eth0 eth1 ...
|
|
||||||
which indicates that your adapter has been found and initialized.
|
|
||||||
|
|
||||||
NOTE 1: If you have more than one Marvell Yukon or SysKonnect SK-98xx
|
|
||||||
adapter installed, the adapters will be listed as 'eth0',
|
|
||||||
'eth1', 'eth2', etc.
|
|
||||||
For each adapter, repeat steps 3 and 4 below.
|
|
||||||
|
|
||||||
NOTE 2: If you have other Ethernet adapters installed, your Marvell
|
|
||||||
Yukon or SysKonnect SK-98xx adapter will be mapped to the
|
|
||||||
next available number, e.g. 'eth1'. The mapping is executed
|
|
||||||
automatically.
|
|
||||||
The module installation message (displayed either in a system
|
|
||||||
log file or on the console) prints a line for each adapter
|
|
||||||
found containing the corresponding 'ethX'.
|
|
||||||
|
|
||||||
3. Select an IP address and assign it to the respective adapter by
|
|
||||||
entering:
|
|
||||||
ifconfig eth0 <ip-address>
|
|
||||||
With this command, the adapter is connected to the Ethernet.
|
|
||||||
|
|
||||||
SK-98xx Gigabit Ethernet Server Adapters: The yellow LED on the adapter
|
|
||||||
is now active, the link status LED of the primary port is active and
|
|
||||||
the link status LED of the secondary port (on dual port adapters) is
|
|
||||||
blinking (if the ports are connected to a switch or hub).
|
|
||||||
SK-98xx V2.0 Gigabit Ethernet Adapters: The link status LED is active.
|
|
||||||
In addition, you will receive a status message on the console stating
|
|
||||||
"ethX: network connection up using port Y" and showing the selected
|
|
||||||
connection parameters (x stands for the ethernet device number
|
|
||||||
(0,1,2, etc), y stands for the port name (A or B)).
|
|
||||||
|
|
||||||
NOTE: If you are in doubt about IP addresses, ask your network
|
|
||||||
administrator for assistance.
|
|
||||||
|
|
||||||
4. Your adapter should now be fully operational.
|
|
||||||
Use 'ping <otherstation>' to verify the connection to other computers
|
|
||||||
on your network.
|
|
||||||
5. To check the adapter configuration view /proc/net/sk98lin/[devicename].
|
|
||||||
For example by executing:
|
|
||||||
"cat /proc/net/sk98lin/eth0"
|
|
||||||
|
|
||||||
Unload the module
|
|
||||||
-----------------
|
|
||||||
To stop and unload the driver modules, proceed as follows:
|
|
||||||
|
|
||||||
1. Execute the command "ifconfig eth0 down".
|
|
||||||
2. Execute the command "rmmod sk98lin".
|
|
||||||
|
|
||||||
3.2 Inclusion of adapter at system start
|
|
||||||
-----------------------------------------
|
|
||||||
|
|
||||||
Since a large number of different Linux distributions are
|
|
||||||
available, we are unable to describe a general installation procedure
|
|
||||||
for the driver module.
|
|
||||||
Because the driver is now integrated in the kernel, installation should
|
|
||||||
be easy, using the standard mechanism of your distribution.
|
|
||||||
Refer to the distribution's manual for installation of ethernet adapters.
|
|
||||||
|
|
||||||
***
|
|
||||||
|
|
||||||
4 Driver Parameters
|
|
||||||
====================
|
|
||||||
|
|
||||||
Parameters can be set at the command line after the module has been
|
|
||||||
loaded with the command 'modprobe'.
|
|
||||||
In some distributions, the configuration tools are able to pass parameters
|
|
||||||
to the driver module.
|
|
||||||
|
|
||||||
If you use the kernel module loader, you can set driver parameters
|
|
||||||
in the file /etc/modprobe.conf (or /etc/modules.conf in 2.4 or earlier).
|
|
||||||
To set the driver parameters in this file, proceed as follows:
|
|
||||||
|
|
||||||
1. Insert a line of the form :
|
|
||||||
options sk98lin ...
|
|
||||||
For "...", the same syntax is required as described for the command
|
|
||||||
line parameters of modprobe below.
|
|
||||||
2. To activate the new parameters, either reboot your computer
|
|
||||||
or
|
|
||||||
unload and reload the driver.
|
|
||||||
The syntax of the driver parameters is:
|
|
||||||
|
|
||||||
modprobe sk98lin parameter=value1[,value2[,value3...]]
|
|
||||||
|
|
||||||
where value1 refers to the first adapter, value2 to the second etc.
|
|
||||||
|
|
||||||
NOTE: All parameters are case sensitive. Write them exactly as shown
|
|
||||||
below.
|
|
||||||
|
|
||||||
Example:
|
|
||||||
Suppose you have two adapters. You want to set auto-negotiation
|
|
||||||
on the first adapter to ON and on the second adapter to OFF.
|
|
||||||
You also want to set DuplexCapabilities on the first adapter
|
|
||||||
to FULL, and on the second adapter to HALF.
|
|
||||||
Then, you must enter:
|
|
||||||
|
|
||||||
modprobe sk98lin AutoNeg_A=On,Off DupCap_A=Full,Half
|
|
||||||
|
|
||||||
NOTE: The number of adapters that can be configured this way is
|
|
||||||
limited in the driver (file skge.c, constant SK_MAX_CARD_PARAM).
|
|
||||||
The current limit is 16. If you happen to install
|
|
||||||
more adapters, adjust this and recompile.
|
|
||||||
|
|
||||||
|
|
||||||
4.1 Per-Port Parameters
|
|
||||||
------------------------
|
|
||||||
|
|
||||||
These settings are available for each port on the adapter.
|
|
||||||
In the following description, '?' stands for the port for
|
|
||||||
which you set the parameter (A or B).
|
|
||||||
|
|
||||||
Speed
|
|
||||||
-----
|
|
||||||
Parameter: Speed_?
|
|
||||||
Values: 10, 100, 1000, Auto
|
|
||||||
Default: Auto
|
|
||||||
|
|
||||||
This parameter is used to set the speed capabilities. It is only valid
|
|
||||||
for the SK-98xx V2.0 copper adapters.
|
|
||||||
Usually, the speed is negotiated between the two ports during link
|
|
||||||
establishment. If this fails, a port can be forced to a specific setting
|
|
||||||
with this parameter.
|
|
||||||
|
|
||||||
Auto-Negotiation
|
|
||||||
----------------
|
|
||||||
Parameter: AutoNeg_?
|
|
||||||
Values: On, Off, Sense
|
|
||||||
Default: On
|
|
||||||
|
|
||||||
The "Sense"-mode automatically detects whether the link partner supports
|
|
||||||
auto-negotiation or not.
|
|
||||||
|
|
||||||
Duplex Capabilities
|
|
||||||
-------------------
|
|
||||||
Parameter: DupCap_?
|
|
||||||
Values: Half, Full, Both
|
|
||||||
Default: Both
|
|
||||||
|
|
||||||
This parameters is only relevant if auto-negotiation for this port is
|
|
||||||
not set to "Sense". If auto-negotiation is set to "On", all three values
|
|
||||||
are possible. If it is set to "Off", only "Full" and "Half" are allowed.
|
|
||||||
This parameter is useful if your link partner does not support all
|
|
||||||
possible combinations.
|
|
||||||
|
|
||||||
Flow Control
|
|
||||||
------------
|
|
||||||
Parameter: FlowCtrl_?
|
|
||||||
Values: Sym, SymOrRem, LocSend, None
|
|
||||||
Default: SymOrRem
|
|
||||||
|
|
||||||
This parameter can be used to set the flow control capabilities the
|
|
||||||
port reports during auto-negotiation. It can be set for each port
|
|
||||||
individually.
|
|
||||||
Possible modes:
|
|
||||||
-- Sym = Symmetric: both link partners are allowed to send
|
|
||||||
PAUSE frames
|
|
||||||
-- SymOrRem = SymmetricOrRemote: both or only remote partner
|
|
||||||
are allowed to send PAUSE frames
|
|
||||||
-- LocSend = LocalSend: only local link partner is allowed
|
|
||||||
to send PAUSE frames
|
|
||||||
-- None = no link partner is allowed to send PAUSE frames
|
|
||||||
|
|
||||||
NOTE: This parameter is ignored if auto-negotiation is set to "Off".
|
|
||||||
|
|
||||||
Role in Master-Slave-Negotiation (1000Base-T only)
|
|
||||||
--------------------------------------------------
|
|
||||||
Parameter: Role_?
|
|
||||||
Values: Auto, Master, Slave
|
|
||||||
Default: Auto
|
|
||||||
|
|
||||||
This parameter is only valid for the SK-9821 and SK-9822 adapters.
|
|
||||||
For two 1000Base-T ports to communicate, one must take the role of the
|
|
||||||
master (providing timing information), while the other must be the
|
|
||||||
slave. Usually, this is negotiated between the two ports during link
|
|
||||||
establishment. If this fails, a port can be forced to a specific setting
|
|
||||||
with this parameter.
|
|
||||||
|
|
||||||
|
|
||||||
4.2 Adapter Parameters
|
|
||||||
-----------------------
|
|
||||||
|
|
||||||
Connection Type (SK-98xx V2.0 copper adapters only)
|
|
||||||
---------------
|
|
||||||
Parameter: ConType
|
|
||||||
Values: Auto, 100FD, 100HD, 10FD, 10HD
|
|
||||||
Default: Auto
|
|
||||||
|
|
||||||
The parameter 'ConType' is a combination of all five per-port parameters
|
|
||||||
within one single parameter. This simplifies the configuration of both ports
|
|
||||||
of an adapter card! The different values of this variable reflect the most
|
|
||||||
meaningful combinations of port parameters.
|
|
||||||
|
|
||||||
The following table shows the values of 'ConType' and the corresponding
|
|
||||||
combinations of the per-port parameters:
|
|
||||||
|
|
||||||
ConType | DupCap AutoNeg FlowCtrl Role Speed
|
|
||||||
----------+------------------------------------------------------
|
|
||||||
Auto | Both On SymOrRem Auto Auto
|
|
||||||
100FD | Full Off None Auto (ignored) 100
|
|
||||||
100HD | Half Off None Auto (ignored) 100
|
|
||||||
10FD | Full Off None Auto (ignored) 10
|
|
||||||
10HD | Half Off None Auto (ignored) 10
|
|
||||||
|
|
||||||
Stating any other port parameter together with this 'ConType' variable
|
|
||||||
will result in a merged configuration of those settings. This due to
|
|
||||||
the fact, that the per-port parameters (e.g. Speed_? ) have a higher
|
|
||||||
priority than the combined variable 'ConType'.
|
|
||||||
|
|
||||||
NOTE: This parameter is always used on both ports of the adapter card.
|
|
||||||
|
|
||||||
Interrupt Moderation
|
|
||||||
--------------------
|
|
||||||
Parameter: Moderation
|
|
||||||
Values: None, Static, Dynamic
|
|
||||||
Default: None
|
|
||||||
|
|
||||||
Interrupt moderation is employed to limit the maximum number of interrupts
|
|
||||||
the driver has to serve. That is, one or more interrupts (which indicate any
|
|
||||||
transmit or receive packet to be processed) are queued until the driver
|
|
||||||
processes them. When queued interrupts are to be served, is determined by the
|
|
||||||
'IntsPerSec' parameter, which is explained later below.
|
|
||||||
|
|
||||||
Possible modes:
|
|
||||||
|
|
||||||
-- None - No interrupt moderation is applied on the adapter card.
|
|
||||||
Therefore, each transmit or receive interrupt is served immediately
|
|
||||||
as soon as it appears on the interrupt line of the adapter card.
|
|
||||||
|
|
||||||
-- Static - Interrupt moderation is applied on the adapter card.
|
|
||||||
All transmit and receive interrupts are queued until a complete
|
|
||||||
moderation interval ends. If such a moderation interval ends, all
|
|
||||||
queued interrupts are processed in one big bunch without any delay.
|
|
||||||
The term 'static' reflects the fact, that interrupt moderation is
|
|
||||||
always enabled, regardless how much network load is currently
|
|
||||||
passing via a particular interface. In addition, the duration of
|
|
||||||
the moderation interval has a fixed length that never changes while
|
|
||||||
the driver is operational.
|
|
||||||
|
|
||||||
-- Dynamic - Interrupt moderation might be applied on the adapter card,
|
|
||||||
depending on the load of the system. If the driver detects that the
|
|
||||||
system load is too high, the driver tries to shield the system against
|
|
||||||
too much network load by enabling interrupt moderation. If - at a later
|
|
||||||
time - the CPU utilization decreases again (or if the network load is
|
|
||||||
negligible) the interrupt moderation will automatically be disabled.
|
|
||||||
|
|
||||||
Interrupt moderation should be used when the driver has to handle one or more
|
|
||||||
interfaces with a high network load, which - as a consequence - leads also to a
|
|
||||||
high CPU utilization. When moderation is applied in such high network load
|
|
||||||
situations, CPU load might be reduced by 20-30%.
|
|
||||||
|
|
||||||
NOTE: The drawback of using interrupt moderation is an increase of the round-
|
|
||||||
trip-time (RTT), due to the queueing and serving of interrupts at dedicated
|
|
||||||
moderation times.
|
|
||||||
|
|
||||||
Interrupts per second
|
|
||||||
---------------------
|
|
||||||
Parameter: IntsPerSec
|
|
||||||
Values: 30...40000 (interrupts per second)
|
|
||||||
Default: 2000
|
|
||||||
|
|
||||||
This parameter is only used if either static or dynamic interrupt moderation
|
|
||||||
is used on a network adapter card. Using this parameter if no moderation is
|
|
||||||
applied will lead to no action performed.
|
|
||||||
|
|
||||||
This parameter determines the length of any interrupt moderation interval.
|
|
||||||
Assuming that static interrupt moderation is to be used, an 'IntsPerSec'
|
|
||||||
parameter value of 2000 will lead to an interrupt moderation interval of
|
|
||||||
500 microseconds.
|
|
||||||
|
|
||||||
NOTE: The duration of the moderation interval is to be chosen with care.
|
|
||||||
At first glance, selecting a very long duration (e.g. only 100 interrupts per
|
|
||||||
second) seems to be meaningful, but the increase of packet-processing delay
|
|
||||||
is tremendous. On the other hand, selecting a very short moderation time might
|
|
||||||
compensate the use of any moderation being applied.
|
|
||||||
|
|
||||||
|
|
||||||
Preferred Port
|
|
||||||
--------------
|
|
||||||
Parameter: PrefPort
|
|
||||||
Values: A, B
|
|
||||||
Default: A
|
|
||||||
|
|
||||||
This is used to force the preferred port to A or B (on dual-port network
|
|
||||||
adapters). The preferred port is the one that is used if both are detected
|
|
||||||
as fully functional.
|
|
||||||
|
|
||||||
RLMT Mode (Redundant Link Management Technology)
|
|
||||||
------------------------------------------------
|
|
||||||
Parameter: RlmtMode
|
|
||||||
Values: CheckLinkState,CheckLocalPort, CheckSeg, DualNet
|
|
||||||
Default: CheckLinkState
|
|
||||||
|
|
||||||
RLMT monitors the status of the port. If the link of the active port
|
|
||||||
fails, RLMT switches immediately to the standby link. The virtual link is
|
|
||||||
maintained as long as at least one 'physical' link is up.
|
|
||||||
|
|
||||||
Possible modes:
|
|
||||||
|
|
||||||
-- CheckLinkState - Check link state only: RLMT uses the link state
|
|
||||||
reported by the adapter hardware for each individual port to
|
|
||||||
determine whether a port can be used for all network traffic or
|
|
||||||
not.
|
|
||||||
|
|
||||||
-- CheckLocalPort - In this mode, RLMT monitors the network path
|
|
||||||
between the two ports of an adapter by regularly exchanging packets
|
|
||||||
between them. This mode requires a network configuration in which
|
|
||||||
the two ports are able to "see" each other (i.e. there must not be
|
|
||||||
any router between the ports).
|
|
||||||
|
|
||||||
-- CheckSeg - Check local port and segmentation: This mode supports the
|
|
||||||
same functions as the CheckLocalPort mode and additionally checks
|
|
||||||
network segmentation between the ports. Therefore, this mode is only
|
|
||||||
to be used if Gigabit Ethernet switches are installed on the network
|
|
||||||
that have been configured to use the Spanning Tree protocol.
|
|
||||||
|
|
||||||
-- DualNet - In this mode, ports A and B are used as separate devices.
|
|
||||||
If you have a dual port adapter, port A will be configured as eth0
|
|
||||||
and port B as eth1. Both ports can be used independently with
|
|
||||||
distinct IP addresses. The preferred port setting is not used.
|
|
||||||
RLMT is turned off.
|
|
||||||
|
|
||||||
NOTE: RLMT modes CLP and CLPSS are designed to operate in configurations
|
|
||||||
where a network path between the ports on one adapter exists.
|
|
||||||
Moreover, they are not designed to work where adapters are connected
|
|
||||||
back-to-back.
|
|
||||||
***
|
|
||||||
|
|
||||||
|
|
||||||
5 Large Frame Support
|
|
||||||
======================
|
|
||||||
|
|
||||||
The driver supports large frames (also called jumbo frames). Using large
|
|
||||||
frames can result in an improved throughput if transferring large amounts
|
|
||||||
of data.
|
|
||||||
To enable large frames, set the MTU (maximum transfer unit) of the
|
|
||||||
interface to the desired value (up to 9000), execute the following
|
|
||||||
command:
|
|
||||||
ifconfig eth0 mtu 9000
|
|
||||||
This will only work if you have two adapters connected back-to-back
|
|
||||||
or if you use a switch that supports large frames. When using a switch,
|
|
||||||
it should be configured to allow large frames and auto-negotiation should
|
|
||||||
be set to OFF. The setting must be configured on all adapters that can be
|
|
||||||
reached by the large frames. If one adapter is not set to receive large
|
|
||||||
frames, it will simply drop them.
|
|
||||||
|
|
||||||
You can switch back to the standard ethernet frame size by executing the
|
|
||||||
following command:
|
|
||||||
ifconfig eth0 mtu 1500
|
|
||||||
|
|
||||||
To permanently configure this setting, add a script with the 'ifconfig'
|
|
||||||
line to the system startup sequence (named something like "S99sk98lin"
|
|
||||||
in /etc/rc.d/rc2.d).
|
|
||||||
***
|
|
||||||
|
|
||||||
|
|
||||||
6 VLAN and Link Aggregation Support (IEEE 802.1, 802.1q, 802.3ad)
|
|
||||||
==================================================================
|
|
||||||
|
|
||||||
The Marvell Yukon/SysKonnect Linux drivers are able to support VLAN and
|
|
||||||
Link Aggregation according to IEEE standards 802.1, 802.1q, and 802.3ad.
|
|
||||||
These features are only available after installation of open source
|
|
||||||
modules available on the Internet:
|
|
||||||
For VLAN go to: http://www.candelatech.com/~greear/vlan.html
|
|
||||||
For Link Aggregation go to: http://www.st.rim.or.jp/~yumo
|
|
||||||
|
|
||||||
NOTE: SysKonnect GmbH does not offer any support for these open source
|
|
||||||
modules and does not take the responsibility for any kind of
|
|
||||||
failures or problems arising in connection with these modules.
|
|
||||||
|
|
||||||
NOTE: Configuring Link Aggregation on a SysKonnect dual link adapter may
|
|
||||||
cause problems when unloading the driver.
|
|
||||||
|
|
||||||
|
|
||||||
7 Troubleshooting
|
|
||||||
==================
|
|
||||||
|
|
||||||
If any problems occur during the installation process, check the
|
|
||||||
following list:
|
|
||||||
|
|
||||||
|
|
||||||
Problem: The SK-98xx adapter cannot be found by the driver.
|
|
||||||
Solution: In /proc/pci search for the following entry:
|
|
||||||
'Ethernet controller: SysKonnect SK-98xx ...'
|
|
||||||
If this entry exists, the SK-98xx or SK-98xx V2.0 adapter has
|
|
||||||
been found by the system and should be operational.
|
|
||||||
If this entry does not exist or if the file '/proc/pci' is not
|
|
||||||
found, there may be a hardware problem or the PCI support may
|
|
||||||
not be enabled in your kernel.
|
|
||||||
The adapter can be checked using the diagnostics program which
|
|
||||||
is available on the SysKonnect web site:
|
|
||||||
www.syskonnect.com
|
|
||||||
|
|
||||||
Some COMPAQ machines have problems dealing with PCI under Linux.
|
|
||||||
This problem is described in the 'PCI howto' document
|
|
||||||
(included in some distributions or available from the
|
|
||||||
web, e.g. at 'www.linux.org').
|
|
||||||
|
|
||||||
|
|
||||||
Problem: Programs such as 'ifconfig' or 'route' cannot be found or the
|
|
||||||
error message 'Operation not permitted' is displayed.
|
|
||||||
Reason: You are not logged in as user 'root'.
|
|
||||||
Solution: Logout and login as 'root' or change to 'root' via 'su'.
|
|
||||||
|
|
||||||
|
|
||||||
Problem: Upon use of the command 'ping <address>' the message
|
|
||||||
"ping: sendto: Network is unreachable" is displayed.
|
|
||||||
Reason: Your route is not set correctly.
|
|
||||||
Solution: If you are using RedHat, you probably forgot to set up the
|
|
||||||
route in the 'network configuration'.
|
|
||||||
Check the existing routes with the 'route' command and check
|
|
||||||
if an entry for 'eth0' exists, and if so, if it is set correctly.
|
|
||||||
|
|
||||||
|
|
||||||
Problem: The driver can be started, the adapter is connected to the
|
|
||||||
network, but you cannot receive or transmit any packets;
|
|
||||||
e.g. 'ping' does not work.
|
|
||||||
Reason: There is an incorrect route in your routing table.
|
|
||||||
Solution: Check the routing table with the command 'route' and read the
|
|
||||||
manual help pages dealing with routes (enter 'man route').
|
|
||||||
|
|
||||||
NOTE: Although the 2.2.x kernel versions generate the routing entry
|
|
||||||
automatically, problems of this kind may occur here as well. We've
|
|
||||||
come across a situation in which the driver started correctly at
|
|
||||||
system start, but after the driver has been removed and reloaded,
|
|
||||||
the route of the adapter's network pointed to the 'dummy0'device
|
|
||||||
and had to be corrected manually.
|
|
||||||
|
|
||||||
|
|
||||||
Problem: Your computer should act as a router between multiple
|
|
||||||
IP subnetworks (using multiple adapters), but computers in
|
|
||||||
other subnetworks cannot be reached.
|
|
||||||
Reason: Either the router's kernel is not configured for IP forwarding
|
|
||||||
or the routing table and gateway configuration of at least one
|
|
||||||
computer is not working.
|
|
||||||
|
|
||||||
Problem: Upon driver start, the following error message is displayed:
|
|
||||||
"eth0: -- ERROR --
|
|
||||||
Class: internal Software error
|
|
||||||
Nr: 0xcc
|
|
||||||
Msg: SkGeInitPort() cannot init running ports"
|
|
||||||
Reason: You are using a driver compiled for single processor machines
|
|
||||||
on a multiprocessor machine with SMP (Symmetric MultiProcessor)
|
|
||||||
kernel.
|
|
||||||
Solution: Configure your kernel appropriately and recompile the kernel or
|
|
||||||
the modules.
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
If your problem is not listed here, please contact SysKonnect's technical
|
|
||||||
support for help (linux@syskonnect.de).
|
|
||||||
When contacting our technical support, please ensure that the following
|
|
||||||
information is available:
|
|
||||||
- System Manufacturer and HW Informations (CPU, Memory... )
|
|
||||||
- PCI-Boards in your system
|
|
||||||
- Distribution
|
|
||||||
- Kernel version
|
|
||||||
- Driver version
|
|
||||||
***
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
***End of Readme File***
|
|
|
@ -978,6 +978,7 @@ static int fs_open(struct atm_vcc *atm_vcc)
|
||||||
/* Docs are vague about this atm_hdr field. By the way, the FS
|
/* Docs are vague about this atm_hdr field. By the way, the FS
|
||||||
* chip makes odd errors if lower bits are set.... -- REW */
|
* chip makes odd errors if lower bits are set.... -- REW */
|
||||||
tc->atm_hdr = (vpi << 20) | (vci << 4);
|
tc->atm_hdr = (vpi << 20) | (vci << 4);
|
||||||
|
tmc0 = 0;
|
||||||
{
|
{
|
||||||
int pcr = atm_pcr_goal (txtp);
|
int pcr = atm_pcr_goal (txtp);
|
||||||
|
|
||||||
|
|
|
@ -3000,8 +3000,7 @@ he_proc_read(struct atm_dev *dev, loff_t *pos, char *page)
|
||||||
|
|
||||||
/* eeprom routines -- see 4.7 */
|
/* eeprom routines -- see 4.7 */
|
||||||
|
|
||||||
u8
|
static u8 read_prom_byte(struct he_dev *he_dev, int addr)
|
||||||
read_prom_byte(struct he_dev *he_dev, int addr)
|
|
||||||
{
|
{
|
||||||
u32 val = 0, tmp_read = 0;
|
u32 val = 0, tmp_read = 0;
|
||||||
int i, j = 0;
|
int i, j = 0;
|
||||||
|
|
|
@ -2016,8 +2016,7 @@ idt77252_send_skb(struct atm_vcc *vcc, struct sk_buff *skb, int oam)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
static int idt77252_send(struct atm_vcc *vcc, struct sk_buff *skb)
|
||||||
idt77252_send(struct atm_vcc *vcc, struct sk_buff *skb)
|
|
||||||
{
|
{
|
||||||
return idt77252_send_skb(vcc, skb, 0);
|
return idt77252_send_skb(vcc, skb, 0);
|
||||||
}
|
}
|
||||||
|
@ -3072,8 +3071,7 @@ idt77252_dev_open(struct idt77252_dev *card)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
static void idt77252_dev_close(struct atm_dev *dev)
|
||||||
idt77252_dev_close(struct atm_dev *dev)
|
|
||||||
{
|
{
|
||||||
struct idt77252_dev *card = dev->dev_data;
|
struct idt77252_dev *card = dev->dev_data;
|
||||||
u32 conf;
|
u32 conf;
|
||||||
|
|
|
@ -958,6 +958,7 @@ static void ia_suni_pm7345_init (IADEV *iadev)
|
||||||
|
|
||||||
/***************************** IA_LIB END *****************************/
|
/***************************** IA_LIB END *****************************/
|
||||||
|
|
||||||
|
#ifdef CONFIG_ATM_IA_DEBUG
|
||||||
static int tcnter = 0;
|
static int tcnter = 0;
|
||||||
static void xdump( u_char* cp, int length, char* prefix )
|
static void xdump( u_char* cp, int length, char* prefix )
|
||||||
{
|
{
|
||||||
|
@ -992,6 +993,7 @@ static void xdump( u_char* cp, int length, char* prefix )
|
||||||
}
|
}
|
||||||
|
|
||||||
} /* close xdump(... */
|
} /* close xdump(... */
|
||||||
|
#endif /* CONFIG_ATM_IA_DEBUG */
|
||||||
|
|
||||||
|
|
||||||
static struct atm_dev *ia_boards = NULL;
|
static struct atm_dev *ia_boards = NULL;
|
||||||
|
|
|
@ -2555,7 +2555,7 @@ config NIU
|
||||||
|
|
||||||
config PASEMI_MAC
|
config PASEMI_MAC
|
||||||
tristate "PA Semi 1/10Gbit MAC"
|
tristate "PA Semi 1/10Gbit MAC"
|
||||||
depends on PPC64 && PCI
|
depends on PPC_PASEMI && PCI
|
||||||
select PHYLIB
|
select PHYLIB
|
||||||
select INET_LRO
|
select INET_LRO
|
||||||
help
|
help
|
||||||
|
|
|
@ -575,7 +575,6 @@ adjust_head:
|
||||||
static int bf537mac_hard_start_xmit(struct sk_buff *skb,
|
static int bf537mac_hard_start_xmit(struct sk_buff *skb,
|
||||||
struct net_device *dev)
|
struct net_device *dev)
|
||||||
{
|
{
|
||||||
struct bf537mac_local *lp = netdev_priv(dev);
|
|
||||||
unsigned int data;
|
unsigned int data;
|
||||||
|
|
||||||
current_tx_ptr->skb = skb;
|
current_tx_ptr->skb = skb;
|
||||||
|
@ -634,7 +633,6 @@ out:
|
||||||
static void bf537mac_rx(struct net_device *dev)
|
static void bf537mac_rx(struct net_device *dev)
|
||||||
{
|
{
|
||||||
struct sk_buff *skb, *new_skb;
|
struct sk_buff *skb, *new_skb;
|
||||||
struct bf537mac_local *lp = netdev_priv(dev);
|
|
||||||
unsigned short len;
|
unsigned short len;
|
||||||
|
|
||||||
/* allocate a new skb for next time receive */
|
/* allocate a new skb for next time receive */
|
||||||
|
|
|
@ -341,6 +341,7 @@ static ssize_t bonding_store_slaves(struct device *d,
|
||||||
|
|
||||||
if (command[0] == '-') {
|
if (command[0] == '-') {
|
||||||
dev = NULL;
|
dev = NULL;
|
||||||
|
original_mtu = 0;
|
||||||
bond_for_each_slave(bond, slave, i)
|
bond_for_each_slave(bond, slave, i)
|
||||||
if (strnicmp(slave->dev->name, ifname, IFNAMSIZ) == 0) {
|
if (strnicmp(slave->dev->name, ifname, IFNAMSIZ) == 0) {
|
||||||
dev = slave->dev;
|
dev = slave->dev;
|
||||||
|
|
|
@ -1854,6 +1854,7 @@ static int nv_start_xmit(struct sk_buff *skb, struct net_device *dev)
|
||||||
struct ring_desc* start_tx;
|
struct ring_desc* start_tx;
|
||||||
struct ring_desc* prev_tx;
|
struct ring_desc* prev_tx;
|
||||||
struct nv_skb_map* prev_tx_ctx;
|
struct nv_skb_map* prev_tx_ctx;
|
||||||
|
unsigned long flags;
|
||||||
|
|
||||||
/* add fragments to entries count */
|
/* add fragments to entries count */
|
||||||
for (i = 0; i < fragments; i++) {
|
for (i = 0; i < fragments; i++) {
|
||||||
|
@ -1863,10 +1864,10 @@ static int nv_start_xmit(struct sk_buff *skb, struct net_device *dev)
|
||||||
|
|
||||||
empty_slots = nv_get_empty_tx_slots(np);
|
empty_slots = nv_get_empty_tx_slots(np);
|
||||||
if (unlikely(empty_slots <= entries)) {
|
if (unlikely(empty_slots <= entries)) {
|
||||||
spin_lock_irq(&np->lock);
|
spin_lock_irqsave(&np->lock, flags);
|
||||||
netif_stop_queue(dev);
|
netif_stop_queue(dev);
|
||||||
np->tx_stop = 1;
|
np->tx_stop = 1;
|
||||||
spin_unlock_irq(&np->lock);
|
spin_unlock_irqrestore(&np->lock, flags);
|
||||||
return NETDEV_TX_BUSY;
|
return NETDEV_TX_BUSY;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1929,13 +1930,13 @@ static int nv_start_xmit(struct sk_buff *skb, struct net_device *dev)
|
||||||
tx_flags_extra = skb->ip_summed == CHECKSUM_PARTIAL ?
|
tx_flags_extra = skb->ip_summed == CHECKSUM_PARTIAL ?
|
||||||
NV_TX2_CHECKSUM_L3 | NV_TX2_CHECKSUM_L4 : 0;
|
NV_TX2_CHECKSUM_L3 | NV_TX2_CHECKSUM_L4 : 0;
|
||||||
|
|
||||||
spin_lock_irq(&np->lock);
|
spin_lock_irqsave(&np->lock, flags);
|
||||||
|
|
||||||
/* set tx flags */
|
/* set tx flags */
|
||||||
start_tx->flaglen |= cpu_to_le32(tx_flags | tx_flags_extra);
|
start_tx->flaglen |= cpu_to_le32(tx_flags | tx_flags_extra);
|
||||||
np->put_tx.orig = put_tx;
|
np->put_tx.orig = put_tx;
|
||||||
|
|
||||||
spin_unlock_irq(&np->lock);
|
spin_unlock_irqrestore(&np->lock, flags);
|
||||||
|
|
||||||
dprintk(KERN_DEBUG "%s: nv_start_xmit: entries %d queued for transmission. tx_flags_extra: %x\n",
|
dprintk(KERN_DEBUG "%s: nv_start_xmit: entries %d queued for transmission. tx_flags_extra: %x\n",
|
||||||
dev->name, entries, tx_flags_extra);
|
dev->name, entries, tx_flags_extra);
|
||||||
|
@ -1971,6 +1972,7 @@ static int nv_start_xmit_optimized(struct sk_buff *skb, struct net_device *dev)
|
||||||
struct ring_desc_ex* prev_tx;
|
struct ring_desc_ex* prev_tx;
|
||||||
struct nv_skb_map* prev_tx_ctx;
|
struct nv_skb_map* prev_tx_ctx;
|
||||||
struct nv_skb_map* start_tx_ctx;
|
struct nv_skb_map* start_tx_ctx;
|
||||||
|
unsigned long flags;
|
||||||
|
|
||||||
/* add fragments to entries count */
|
/* add fragments to entries count */
|
||||||
for (i = 0; i < fragments; i++) {
|
for (i = 0; i < fragments; i++) {
|
||||||
|
@ -1980,10 +1982,10 @@ static int nv_start_xmit_optimized(struct sk_buff *skb, struct net_device *dev)
|
||||||
|
|
||||||
empty_slots = nv_get_empty_tx_slots(np);
|
empty_slots = nv_get_empty_tx_slots(np);
|
||||||
if (unlikely(empty_slots <= entries)) {
|
if (unlikely(empty_slots <= entries)) {
|
||||||
spin_lock_irq(&np->lock);
|
spin_lock_irqsave(&np->lock, flags);
|
||||||
netif_stop_queue(dev);
|
netif_stop_queue(dev);
|
||||||
np->tx_stop = 1;
|
np->tx_stop = 1;
|
||||||
spin_unlock_irq(&np->lock);
|
spin_unlock_irqrestore(&np->lock, flags);
|
||||||
return NETDEV_TX_BUSY;
|
return NETDEV_TX_BUSY;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2059,7 +2061,7 @@ static int nv_start_xmit_optimized(struct sk_buff *skb, struct net_device *dev)
|
||||||
start_tx->txvlan = 0;
|
start_tx->txvlan = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
spin_lock_irq(&np->lock);
|
spin_lock_irqsave(&np->lock, flags);
|
||||||
|
|
||||||
if (np->tx_limit) {
|
if (np->tx_limit) {
|
||||||
/* Limit the number of outstanding tx. Setup all fragments, but
|
/* Limit the number of outstanding tx. Setup all fragments, but
|
||||||
|
@ -2085,7 +2087,7 @@ static int nv_start_xmit_optimized(struct sk_buff *skb, struct net_device *dev)
|
||||||
start_tx->flaglen |= cpu_to_le32(tx_flags | tx_flags_extra);
|
start_tx->flaglen |= cpu_to_le32(tx_flags | tx_flags_extra);
|
||||||
np->put_tx.ex = put_tx;
|
np->put_tx.ex = put_tx;
|
||||||
|
|
||||||
spin_unlock_irq(&np->lock);
|
spin_unlock_irqrestore(&np->lock, flags);
|
||||||
|
|
||||||
dprintk(KERN_DEBUG "%s: nv_start_xmit_optimized: entries %d queued for transmission. tx_flags_extra: %x\n",
|
dprintk(KERN_DEBUG "%s: nv_start_xmit_optimized: entries %d queued for transmission. tx_flags_extra: %x\n",
|
||||||
dev->name, entries, tx_flags_extra);
|
dev->name, entries, tx_flags_extra);
|
||||||
|
|
|
@ -1242,8 +1242,8 @@ static int emac_close(struct net_device *ndev)
|
||||||
static inline u16 emac_tx_csum(struct emac_instance *dev,
|
static inline u16 emac_tx_csum(struct emac_instance *dev,
|
||||||
struct sk_buff *skb)
|
struct sk_buff *skb)
|
||||||
{
|
{
|
||||||
if (emac_has_feature(dev, EMAC_FTR_HAS_TAH &&
|
if (emac_has_feature(dev, EMAC_FTR_HAS_TAH) &&
|
||||||
skb->ip_summed == CHECKSUM_PARTIAL)) {
|
(skb->ip_summed == CHECKSUM_PARTIAL)) {
|
||||||
++dev->stats.tx_packets_csum;
|
++dev->stats.tx_packets_csum;
|
||||||
return EMAC_TX_CTRL_TAH_CSUM;
|
return EMAC_TX_CTRL_TAH_CSUM;
|
||||||
}
|
}
|
||||||
|
|
|
@ -86,7 +86,7 @@
|
||||||
#include "s2io.h"
|
#include "s2io.h"
|
||||||
#include "s2io-regs.h"
|
#include "s2io-regs.h"
|
||||||
|
|
||||||
#define DRV_VERSION "2.0.26.19"
|
#define DRV_VERSION "2.0.26.20"
|
||||||
|
|
||||||
/* S2io Driver name & version. */
|
/* S2io Driver name & version. */
|
||||||
static char s2io_driver_name[] = "Neterion";
|
static char s2io_driver_name[] = "Neterion";
|
||||||
|
|
|
@ -343,6 +343,12 @@ int __devinit tulip_read_eeprom(struct net_device *dev, int location, int addr_l
|
||||||
void __iomem *ee_addr = tp->base_addr + CSR9;
|
void __iomem *ee_addr = tp->base_addr + CSR9;
|
||||||
int read_cmd = location | (EE_READ_CMD << addr_len);
|
int read_cmd = location | (EE_READ_CMD << addr_len);
|
||||||
|
|
||||||
|
/* If location is past the end of what we can address, don't
|
||||||
|
* read some other location (ie truncate). Just return zero.
|
||||||
|
*/
|
||||||
|
if (location > (1 << addr_len) - 1)
|
||||||
|
return 0;
|
||||||
|
|
||||||
iowrite32(EE_ENB & ~EE_CS, ee_addr);
|
iowrite32(EE_ENB & ~EE_CS, ee_addr);
|
||||||
iowrite32(EE_ENB, ee_addr);
|
iowrite32(EE_ENB, ee_addr);
|
||||||
|
|
||||||
|
|
|
@ -1437,6 +1437,7 @@ static int __devinit tulip_init_one (struct pci_dev *pdev,
|
||||||
EEPROM.
|
EEPROM.
|
||||||
*/
|
*/
|
||||||
ee_data = tp->eeprom;
|
ee_data = tp->eeprom;
|
||||||
|
memset(ee_data, 0, sizeof(tp->eeprom));
|
||||||
sum = 0;
|
sum = 0;
|
||||||
if (chip_idx == LC82C168) {
|
if (chip_idx == LC82C168) {
|
||||||
for (i = 0; i < 3; i++) {
|
for (i = 0; i < 3; i++) {
|
||||||
|
@ -1458,8 +1459,12 @@ static int __devinit tulip_init_one (struct pci_dev *pdev,
|
||||||
/* A serial EEPROM interface, we read now and sort it out later. */
|
/* A serial EEPROM interface, we read now and sort it out later. */
|
||||||
int sa_offset = 0;
|
int sa_offset = 0;
|
||||||
int ee_addr_size = tulip_read_eeprom(dev, 0xff, 8) & 0x40000 ? 8 : 6;
|
int ee_addr_size = tulip_read_eeprom(dev, 0xff, 8) & 0x40000 ? 8 : 6;
|
||||||
|
int ee_max_addr = ((1 << ee_addr_size) - 1) * sizeof(u16);
|
||||||
|
|
||||||
for (i = 0; i < sizeof(tp->eeprom); i+=2) {
|
if (ee_max_addr > sizeof(tp->eeprom))
|
||||||
|
ee_max_addr = sizeof(tp->eeprom);
|
||||||
|
|
||||||
|
for (i = 0; i < ee_max_addr ; i += sizeof(u16)) {
|
||||||
u16 data = tulip_read_eeprom(dev, i/2, ee_addr_size);
|
u16 data = tulip_read_eeprom(dev, i/2, ee_addr_size);
|
||||||
ee_data[i] = data & 0xff;
|
ee_data[i] = data & 0xff;
|
||||||
ee_data[i + 1] = data >> 8;
|
ee_data[i + 1] = data >> 8;
|
||||||
|
|
|
@ -129,7 +129,7 @@ config USB_USBNET
|
||||||
|
|
||||||
config USB_NET_AX8817X
|
config USB_NET_AX8817X
|
||||||
tristate "ASIX AX88xxx Based USB 2.0 Ethernet Adapters"
|
tristate "ASIX AX88xxx Based USB 2.0 Ethernet Adapters"
|
||||||
depends on USB_USBNET && NET_ETHERNET
|
depends on USB_USBNET
|
||||||
select CRC32
|
select CRC32
|
||||||
default y
|
default y
|
||||||
help
|
help
|
||||||
|
|
|
@ -354,7 +354,7 @@ static void dm9601_set_multicast(struct net_device *net)
|
||||||
struct dev_mc_list *mc_list = net->mc_list;
|
struct dev_mc_list *mc_list = net->mc_list;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for (i = 0; i < net->mc_count; i++) {
|
for (i = 0; i < net->mc_count; i++, mc_list = mc_list->next) {
|
||||||
u32 crc = ether_crc(ETH_ALEN, mc_list->dmi_addr) >> 26;
|
u32 crc = ether_crc(ETH_ALEN, mc_list->dmi_addr) >> 26;
|
||||||
hashes[crc >> 3] |= 1 << (crc & 0x7);
|
hashes[crc >> 3] |= 1 << (crc & 0x7);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1128,12 +1128,8 @@ pegasus_get_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
|
||||||
{
|
{
|
||||||
pegasus_t *pegasus;
|
pegasus_t *pegasus;
|
||||||
|
|
||||||
if (in_atomic())
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
pegasus = netdev_priv(dev);
|
pegasus = netdev_priv(dev);
|
||||||
mii_ethtool_gset(&pegasus->mii, ecmd);
|
mii_ethtool_gset(&pegasus->mii, ecmd);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -58,7 +58,7 @@ struct lapbethdev {
|
||||||
struct net_device_stats stats; /* some statistics */
|
struct net_device_stats stats; /* some statistics */
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct list_head lapbeth_devices = LIST_HEAD_INIT(lapbeth_devices);
|
static LIST_HEAD(lapbeth_devices);
|
||||||
|
|
||||||
/* ------------------------------------------------------------------------ */
|
/* ------------------------------------------------------------------------ */
|
||||||
|
|
||||||
|
|
|
@ -574,6 +574,7 @@ static int setup_rx_descbuffer(struct b43_dmaring *ring,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (b43_dma_mapping_error(ring, dmaaddr, ring->rx_buffersize, 0)) {
|
if (b43_dma_mapping_error(ring, dmaaddr, ring->rx_buffersize, 0)) {
|
||||||
|
b43err(ring->dev->wl, "RX DMA buffer allocation failed\n");
|
||||||
dev_kfree_skb_any(skb);
|
dev_kfree_skb_any(skb);
|
||||||
return -EIO;
|
return -EIO;
|
||||||
}
|
}
|
||||||
|
@ -829,8 +830,12 @@ struct b43_dmaring *b43_setup_dmaring(struct b43_wldev *dev,
|
||||||
DMA_TO_DEVICE);
|
DMA_TO_DEVICE);
|
||||||
|
|
||||||
if (b43_dma_mapping_error(ring, dma_test,
|
if (b43_dma_mapping_error(ring, dma_test,
|
||||||
b43_txhdr_size(dev), 1))
|
b43_txhdr_size(dev), 1)) {
|
||||||
|
|
||||||
|
b43err(dev->wl,
|
||||||
|
"TXHDR DMA allocation failed\n");
|
||||||
goto err_kfree_txhdr_cache;
|
goto err_kfree_txhdr_cache;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
dma_unmap_single(dev->dev->dev,
|
dma_unmap_single(dev->dev->dev,
|
||||||
|
|
|
@ -91,6 +91,8 @@ static int __devinit b43_pcmcia_probe(struct pcmcia_device *dev)
|
||||||
|
|
||||||
dev->conf.ConfigBase = parse.config.base;
|
dev->conf.ConfigBase = parse.config.base;
|
||||||
dev->conf.Present = parse.config.rmask[0];
|
dev->conf.Present = parse.config.rmask[0];
|
||||||
|
dev->conf.Attributes = CONF_ENABLE_IRQ;
|
||||||
|
dev->conf.IntType = INT_MEMORY_AND_IO;
|
||||||
|
|
||||||
dev->io.BasePort2 = 0;
|
dev->io.BasePort2 = 0;
|
||||||
dev->io.NumPorts2 = 0;
|
dev->io.NumPorts2 = 0;
|
||||||
|
@ -112,8 +114,8 @@ static int __devinit b43_pcmcia_probe(struct pcmcia_device *dev)
|
||||||
if (res != CS_SUCCESS)
|
if (res != CS_SUCCESS)
|
||||||
goto err_disable;
|
goto err_disable;
|
||||||
|
|
||||||
dev->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING | IRQ_FIRST_SHARED;
|
dev->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
|
||||||
dev->irq.IRQInfo1 = IRQ_LEVEL_ID | IRQ_SHARE_ID;
|
dev->irq.IRQInfo1 = IRQ_LEVEL_ID;
|
||||||
dev->irq.Handler = NULL; /* The handler is registered later. */
|
dev->irq.Handler = NULL; /* The handler is registered later. */
|
||||||
dev->irq.Instance = NULL;
|
dev->irq.Instance = NULL;
|
||||||
res = pcmcia_request_irq(dev, &dev->irq);
|
res = pcmcia_request_irq(dev, &dev->irq);
|
||||||
|
|
|
@ -677,9 +677,7 @@ sbi_get_int_status_exit:
|
||||||
|
|
||||||
/* Card has a command result for us */
|
/* Card has a command result for us */
|
||||||
if (*ireg & IF_CS_C_S_CMD_UPLD_RDY) {
|
if (*ireg & IF_CS_C_S_CMD_UPLD_RDY) {
|
||||||
spin_lock(&priv->driver_lock);
|
|
||||||
ret = if_cs_receive_cmdres(priv, priv->upld_buf, &priv->upld_len);
|
ret = if_cs_receive_cmdres(priv, priv->upld_buf, &priv->upld_len);
|
||||||
spin_unlock(&priv->driver_lock);
|
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
lbs_pr_err("could not receive cmd from card\n");
|
lbs_pr_err("could not receive cmd from card\n");
|
||||||
}
|
}
|
||||||
|
|
|
@ -1252,11 +1252,20 @@ int rt2x00lib_suspend(struct rt2x00_dev *rt2x00dev, pm_message_t state)
|
||||||
|
|
||||||
exit:
|
exit:
|
||||||
/*
|
/*
|
||||||
* Set device mode to sleep for power management.
|
* Set device mode to sleep for power management,
|
||||||
|
* on some hardware this call seems to consistently fail.
|
||||||
|
* From the specifications it is hard to tell why it fails,
|
||||||
|
* and if this is a "bad thing".
|
||||||
|
* Overall it is safe to just ignore the failure and
|
||||||
|
* continue suspending. The only downside is that the
|
||||||
|
* device will not be in optimal power save mode, but with
|
||||||
|
* the radio and the other components already disabled the
|
||||||
|
* device is as good as disabled.
|
||||||
*/
|
*/
|
||||||
retval = rt2x00dev->ops->lib->set_device_state(rt2x00dev, STATE_SLEEP);
|
retval = rt2x00dev->ops->lib->set_device_state(rt2x00dev, STATE_SLEEP);
|
||||||
if (retval)
|
if (retval)
|
||||||
return retval;
|
WARNING(rt2x00dev, "Device failed to enter sleep state, "
|
||||||
|
"continue suspending.\n");
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1105,12 +1105,14 @@ static inline int netif_is_multiqueue(const struct net_device *dev)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Use this variant when it is known for sure that it
|
/* Use this variant when it is known for sure that it
|
||||||
* is executing from interrupt context.
|
* is executing from hardware interrupt context or with hardware interrupts
|
||||||
|
* disabled.
|
||||||
*/
|
*/
|
||||||
extern void dev_kfree_skb_irq(struct sk_buff *skb);
|
extern void dev_kfree_skb_irq(struct sk_buff *skb);
|
||||||
|
|
||||||
/* Use this variant in places where it could be invoked
|
/* Use this variant in places where it could be invoked
|
||||||
* either from interrupt or non-interrupt context.
|
* from either hardware interrupt or other context, with hardware interrupts
|
||||||
|
* either disabled or enabled.
|
||||||
*/
|
*/
|
||||||
extern void dev_kfree_skb_any(struct sk_buff *skb);
|
extern void dev_kfree_skb_any(struct sk_buff *skb);
|
||||||
|
|
||||||
|
|
|
@ -65,7 +65,6 @@ struct llc_sap {
|
||||||
|
|
||||||
extern struct list_head llc_sap_list;
|
extern struct list_head llc_sap_list;
|
||||||
extern rwlock_t llc_sap_list_lock;
|
extern rwlock_t llc_sap_list_lock;
|
||||||
extern unsigned char llc_station_mac_sa[ETH_ALEN];
|
|
||||||
|
|
||||||
extern int llc_rcv(struct sk_buff *skb, struct net_device *dev,
|
extern int llc_rcv(struct sk_buff *skb, struct net_device *dev,
|
||||||
struct packet_type *pt, struct net_device *orig_dev);
|
struct packet_type *pt, struct net_device *orig_dev);
|
||||||
|
|
|
@ -381,7 +381,7 @@ static inline void llc_pdu_init_as_xid_cmd(struct sk_buff *skb,
|
||||||
xid_info->fmt_id = LLC_XID_FMT_ID; /* 0x81 */
|
xid_info->fmt_id = LLC_XID_FMT_ID; /* 0x81 */
|
||||||
xid_info->type = svcs_supported;
|
xid_info->type = svcs_supported;
|
||||||
xid_info->rw = rx_window << 1; /* size of receive window */
|
xid_info->rw = rx_window << 1; /* size of receive window */
|
||||||
skb_put(skb, 3);
|
skb_put(skb, sizeof(struct llc_xid_info));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -406,7 +406,7 @@ static inline void llc_pdu_init_as_xid_rsp(struct sk_buff *skb,
|
||||||
xid_info->fmt_id = LLC_XID_FMT_ID;
|
xid_info->fmt_id = LLC_XID_FMT_ID;
|
||||||
xid_info->type = svcs_supported;
|
xid_info->type = svcs_supported;
|
||||||
xid_info->rw = rx_window << 1;
|
xid_info->rw = rx_window << 1;
|
||||||
skb_put(skb, 3);
|
skb_put(skb, sizeof(struct llc_xid_info));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* LLC Type 2 FRMR response information field format */
|
/* LLC Type 2 FRMR response information field format */
|
||||||
|
|
|
@ -1,5 +1,8 @@
|
||||||
#ifndef LLC_SAP_H
|
#ifndef LLC_SAP_H
|
||||||
#define LLC_SAP_H
|
#define LLC_SAP_H
|
||||||
|
|
||||||
|
#include <asm/types.h>
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 1997 by Procom Technology,Inc.
|
* Copyright (c) 1997 by Procom Technology,Inc.
|
||||||
* 2001-2003 by Arnaldo Carvalho de Melo <acme@conectiva.com.br>
|
* 2001-2003 by Arnaldo Carvalho de Melo <acme@conectiva.com.br>
|
||||||
|
@ -19,8 +22,8 @@ struct sock;
|
||||||
extern void llc_sap_rtn_pdu(struct llc_sap *sap, struct sk_buff *skb);
|
extern void llc_sap_rtn_pdu(struct llc_sap *sap, struct sk_buff *skb);
|
||||||
extern void llc_save_primitive(struct sock *sk, struct sk_buff* skb,
|
extern void llc_save_primitive(struct sock *sk, struct sk_buff* skb,
|
||||||
unsigned char prim);
|
unsigned char prim);
|
||||||
extern struct sk_buff *llc_alloc_frame(struct sock *sk,
|
extern struct sk_buff *llc_alloc_frame(struct sock *sk, struct net_device *dev,
|
||||||
struct net_device *dev);
|
u8 type, u32 data_size);
|
||||||
|
|
||||||
extern void llc_build_and_send_test_pkt(struct llc_sap *sap,
|
extern void llc_build_and_send_test_pkt(struct llc_sap *sap,
|
||||||
struct sk_buff *skb,
|
struct sk_buff *skb,
|
||||||
|
|
|
@ -384,17 +384,35 @@ static void vlan_sync_address(struct net_device *dev,
|
||||||
memcpy(vlan->real_dev_addr, dev->dev_addr, ETH_ALEN);
|
memcpy(vlan->real_dev_addr, dev->dev_addr, ETH_ALEN);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void __vlan_device_event(struct net_device *dev, unsigned long event)
|
||||||
|
{
|
||||||
|
switch (event) {
|
||||||
|
case NETDEV_CHANGENAME:
|
||||||
|
vlan_proc_rem_dev(dev);
|
||||||
|
if (vlan_proc_add_dev(dev) < 0)
|
||||||
|
pr_warning("8021q: failed to change proc name for %s\n",
|
||||||
|
dev->name);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static int vlan_device_event(struct notifier_block *unused, unsigned long event,
|
static int vlan_device_event(struct notifier_block *unused, unsigned long event,
|
||||||
void *ptr)
|
void *ptr)
|
||||||
{
|
{
|
||||||
struct net_device *dev = ptr;
|
struct net_device *dev = ptr;
|
||||||
struct vlan_group *grp = __vlan_find_group(dev->ifindex);
|
struct vlan_group *grp;
|
||||||
int i, flgs;
|
int i, flgs;
|
||||||
struct net_device *vlandev;
|
struct net_device *vlandev;
|
||||||
|
|
||||||
if (dev_net(dev) != &init_net)
|
if (dev_net(dev) != &init_net)
|
||||||
return NOTIFY_DONE;
|
return NOTIFY_DONE;
|
||||||
|
|
||||||
|
if (is_vlan_dev(dev)) {
|
||||||
|
__vlan_device_event(dev, event);
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
grp = __vlan_find_group(dev->ifindex);
|
||||||
if (!grp)
|
if (!grp)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
|
|
|
@ -45,4 +45,9 @@ void vlan_netlink_fini(void);
|
||||||
|
|
||||||
extern struct rtnl_link_ops vlan_link_ops;
|
extern struct rtnl_link_ops vlan_link_ops;
|
||||||
|
|
||||||
|
static inline int is_vlan_dev(struct net_device *dev)
|
||||||
|
{
|
||||||
|
return dev->priv_flags & IFF_802_1Q_VLAN;
|
||||||
|
}
|
||||||
|
|
||||||
#endif /* !(__BEN_VLAN_802_1Q_INC__) */
|
#endif /* !(__BEN_VLAN_802_1Q_INC__) */
|
||||||
|
|
|
@ -210,11 +210,6 @@ int vlan_proc_rem_dev(struct net_device *vlandev)
|
||||||
* The following few functions build the content of /proc/net/vlan/config
|
* The following few functions build the content of /proc/net/vlan/config
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static inline int is_vlan_dev(struct net_device *dev)
|
|
||||||
{
|
|
||||||
return dev->priv_flags & IFF_802_1Q_VLAN;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* start read of /proc/net/vlan/config */
|
/* start read of /proc/net/vlan/config */
|
||||||
static void *vlan_seq_start(struct seq_file *seq, loff_t *pos)
|
static void *vlan_seq_start(struct seq_file *seq, loff_t *pos)
|
||||||
__acquires(dev_base_lock)
|
__acquires(dev_base_lock)
|
||||||
|
|
|
@ -53,6 +53,30 @@
|
||||||
/* Bluetooth sockets */
|
/* Bluetooth sockets */
|
||||||
#define BT_MAX_PROTO 8
|
#define BT_MAX_PROTO 8
|
||||||
static struct net_proto_family *bt_proto[BT_MAX_PROTO];
|
static struct net_proto_family *bt_proto[BT_MAX_PROTO];
|
||||||
|
|
||||||
|
static struct lock_class_key bt_slock_key[BT_MAX_PROTO];
|
||||||
|
static struct lock_class_key bt_lock_key[BT_MAX_PROTO];
|
||||||
|
static const char *bt_key_strings[BT_MAX_PROTO] = {
|
||||||
|
"sk_lock-AF_BLUETOOTH-BTPROTO_L2CAP",
|
||||||
|
"sk_lock-AF_BLUETOOTH-BTPROTO_HCI",
|
||||||
|
"sk_lock-AF_BLUETOOTH-BTPROTO_SCO",
|
||||||
|
"sk_lock-AF_BLUETOOTH-BTPROTO_RFCOMM",
|
||||||
|
"sk_lock-AF_BLUETOOTH-BTPROTO_BNEP",
|
||||||
|
"sk_lock-AF_BLUETOOTH-BTPROTO_CMTP",
|
||||||
|
"sk_lock-AF_BLUETOOTH-BTPROTO_HIDP",
|
||||||
|
"sk_lock-AF_BLUETOOTH-BTPROTO_AVDTP",
|
||||||
|
};
|
||||||
|
|
||||||
|
static const char *bt_slock_key_strings[BT_MAX_PROTO] = {
|
||||||
|
"slock-AF_BLUETOOTH-BTPROTO_L2CAP",
|
||||||
|
"slock-AF_BLUETOOTH-BTPROTO_HCI",
|
||||||
|
"slock-AF_BLUETOOTH-BTPROTO_SCO",
|
||||||
|
"slock-AF_BLUETOOTH-BTPROTO_RFCOMM",
|
||||||
|
"slock-AF_BLUETOOTH-BTPROTO_BNEP",
|
||||||
|
"slock-AF_BLUETOOTH-BTPROTO_CMTP",
|
||||||
|
"slock-AF_BLUETOOTH-BTPROTO_HIDP",
|
||||||
|
"slock-AF_BLUETOOTH-BTPROTO_AVDTP",
|
||||||
|
};
|
||||||
static DEFINE_RWLOCK(bt_proto_lock);
|
static DEFINE_RWLOCK(bt_proto_lock);
|
||||||
|
|
||||||
int bt_sock_register(int proto, struct net_proto_family *ops)
|
int bt_sock_register(int proto, struct net_proto_family *ops)
|
||||||
|
@ -95,6 +119,21 @@ int bt_sock_unregister(int proto)
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(bt_sock_unregister);
|
EXPORT_SYMBOL(bt_sock_unregister);
|
||||||
|
|
||||||
|
static void bt_reclassify_sock_lock(struct socket *sock, int proto)
|
||||||
|
{
|
||||||
|
struct sock *sk = sock->sk;
|
||||||
|
|
||||||
|
if (!sk)
|
||||||
|
return;
|
||||||
|
BUG_ON(sock_owned_by_user(sk));
|
||||||
|
|
||||||
|
sock_lock_init_class_and_name(sk,
|
||||||
|
bt_slock_key_strings[proto],
|
||||||
|
&bt_slock_key[proto],
|
||||||
|
bt_key_strings[proto],
|
||||||
|
&bt_lock_key[proto]);
|
||||||
|
}
|
||||||
|
|
||||||
static int bt_sock_create(struct net *net, struct socket *sock, int proto)
|
static int bt_sock_create(struct net *net, struct socket *sock, int proto)
|
||||||
{
|
{
|
||||||
int err;
|
int err;
|
||||||
|
@ -117,6 +156,7 @@ static int bt_sock_create(struct net *net, struct socket *sock, int proto)
|
||||||
|
|
||||||
if (bt_proto[proto] && try_module_get(bt_proto[proto]->owner)) {
|
if (bt_proto[proto] && try_module_get(bt_proto[proto]->owner)) {
|
||||||
err = bt_proto[proto]->create(net, sock, proto);
|
err = bt_proto[proto]->create(net, sock, proto);
|
||||||
|
bt_reclassify_sock_lock(sock, proto);
|
||||||
module_put(bt_proto[proto]->owner);
|
module_put(bt_proto[proto]->owner);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -84,7 +84,7 @@ static struct hci_sec_filter hci_sec_filter = {
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct bt_sock_list hci_sk_list = {
|
static struct bt_sock_list hci_sk_list = {
|
||||||
.lock = RW_LOCK_UNLOCKED
|
.lock = __RW_LOCK_UNLOCKED(hci_sk_list.lock)
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Send frame to RAW socket */
|
/* Send frame to RAW socket */
|
||||||
|
|
|
@ -62,7 +62,7 @@ static u32 l2cap_feat_mask = 0x0000;
|
||||||
static const struct proto_ops l2cap_sock_ops;
|
static const struct proto_ops l2cap_sock_ops;
|
||||||
|
|
||||||
static struct bt_sock_list l2cap_sk_list = {
|
static struct bt_sock_list l2cap_sk_list = {
|
||||||
.lock = RW_LOCK_UNLOCKED
|
.lock = __RW_LOCK_UNLOCKED(l2cap_sk_list.lock)
|
||||||
};
|
};
|
||||||
|
|
||||||
static void __l2cap_sock_close(struct sock *sk, int reason);
|
static void __l2cap_sock_close(struct sock *sk, int reason);
|
||||||
|
|
|
@ -423,8 +423,8 @@ static int __rfcomm_dlc_close(struct rfcomm_dlc *d, int err)
|
||||||
|
|
||||||
rfcomm_dlc_lock(d);
|
rfcomm_dlc_lock(d);
|
||||||
d->state = BT_CLOSED;
|
d->state = BT_CLOSED;
|
||||||
d->state_change(d, err);
|
|
||||||
rfcomm_dlc_unlock(d);
|
rfcomm_dlc_unlock(d);
|
||||||
|
d->state_change(d, err);
|
||||||
|
|
||||||
skb_queue_purge(&d->tx_queue);
|
skb_queue_purge(&d->tx_queue);
|
||||||
rfcomm_dlc_unlink(d);
|
rfcomm_dlc_unlink(d);
|
||||||
|
|
|
@ -60,7 +60,7 @@
|
||||||
static const struct proto_ops rfcomm_sock_ops;
|
static const struct proto_ops rfcomm_sock_ops;
|
||||||
|
|
||||||
static struct bt_sock_list rfcomm_sk_list = {
|
static struct bt_sock_list rfcomm_sk_list = {
|
||||||
.lock = RW_LOCK_UNLOCKED
|
.lock = __RW_LOCK_UNLOCKED(rfcomm_sk_list.lock)
|
||||||
};
|
};
|
||||||
|
|
||||||
static void rfcomm_sock_close(struct sock *sk);
|
static void rfcomm_sock_close(struct sock *sk);
|
||||||
|
|
|
@ -570,12 +570,7 @@ static void rfcomm_dev_state_change(struct rfcomm_dlc *dlc, int err)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
rfcomm_dev_del(dev);
|
rfcomm_dev_del(dev);
|
||||||
/* We have to drop DLC lock here, otherwise
|
|
||||||
rfcomm_dev_put() will dead lock if it's
|
|
||||||
the last reference. */
|
|
||||||
rfcomm_dlc_unlock(dlc);
|
|
||||||
rfcomm_dev_put(dev);
|
rfcomm_dev_put(dev);
|
||||||
rfcomm_dlc_lock(dlc);
|
|
||||||
}
|
}
|
||||||
} else
|
} else
|
||||||
tty_hangup(dev->tty);
|
tty_hangup(dev->tty);
|
||||||
|
|
|
@ -58,7 +58,7 @@
|
||||||
static const struct proto_ops sco_sock_ops;
|
static const struct proto_ops sco_sock_ops;
|
||||||
|
|
||||||
static struct bt_sock_list sco_sk_list = {
|
static struct bt_sock_list sco_sk_list = {
|
||||||
.lock = RW_LOCK_UNLOCKED
|
.lock = __RW_LOCK_UNLOCKED(sco_sk_list.lock)
|
||||||
};
|
};
|
||||||
|
|
||||||
static void __sco_chan_add(struct sco_conn *conn, struct sock *sk, struct sock *parent);
|
static void __sco_chan_add(struct sco_conn *conn, struct sock *sk, struct sock *parent);
|
||||||
|
|
|
@ -86,7 +86,10 @@ EXPORT_SYMBOL(inet_frags_fini);
|
||||||
void inet_frags_exit_net(struct netns_frags *nf, struct inet_frags *f)
|
void inet_frags_exit_net(struct netns_frags *nf, struct inet_frags *f)
|
||||||
{
|
{
|
||||||
nf->low_thresh = 0;
|
nf->low_thresh = 0;
|
||||||
|
|
||||||
|
local_bh_disable();
|
||||||
inet_frag_evictor(nf, f);
|
inet_frag_evictor(nf, f);
|
||||||
|
local_bh_enable();
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(inet_frags_exit_net);
|
EXPORT_SYMBOL(inet_frags_exit_net);
|
||||||
|
|
||||||
|
|
|
@ -85,7 +85,7 @@ int ip_forward(struct sk_buff *skb)
|
||||||
if (opt->is_strictroute && rt->rt_dst != rt->rt_gateway)
|
if (opt->is_strictroute && rt->rt_dst != rt->rt_gateway)
|
||||||
goto sr_failed;
|
goto sr_failed;
|
||||||
|
|
||||||
if (unlikely(skb->len > dst_mtu(&rt->u.dst) &&
|
if (unlikely(skb->len > dst_mtu(&rt->u.dst) && !skb_is_gso(skb) &&
|
||||||
(ip_hdr(skb)->frag_off & htons(IP_DF))) && !skb->local_df) {
|
(ip_hdr(skb)->frag_off & htons(IP_DF))) && !skb->local_df) {
|
||||||
IP_INC_STATS(IPSTATS_MIB_FRAGFAILS);
|
IP_INC_STATS(IPSTATS_MIB_FRAGFAILS);
|
||||||
icmp_send(skb, ICMP_DEST_UNREACH, ICMP_FRAG_NEEDED,
|
icmp_send(skb, ICMP_DEST_UNREACH, ICMP_FRAG_NEEDED,
|
||||||
|
|
|
@ -1551,14 +1551,14 @@ static void *udp_seq_start(struct seq_file *seq, loff_t *pos)
|
||||||
__acquires(udp_hash_lock)
|
__acquires(udp_hash_lock)
|
||||||
{
|
{
|
||||||
read_lock(&udp_hash_lock);
|
read_lock(&udp_hash_lock);
|
||||||
return *pos ? udp_get_idx(seq, *pos-1) : (void *)1;
|
return *pos ? udp_get_idx(seq, *pos-1) : SEQ_START_TOKEN;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void *udp_seq_next(struct seq_file *seq, void *v, loff_t *pos)
|
static void *udp_seq_next(struct seq_file *seq, void *v, loff_t *pos)
|
||||||
{
|
{
|
||||||
struct sock *sk;
|
struct sock *sk;
|
||||||
|
|
||||||
if (v == (void *)1)
|
if (v == SEQ_START_TOKEN)
|
||||||
sk = udp_get_idx(seq, 0);
|
sk = udp_get_idx(seq, 0);
|
||||||
else
|
else
|
||||||
sk = udp_get_next(seq, v);
|
sk = udp_get_next(seq, v);
|
||||||
|
|
|
@ -776,6 +776,7 @@ static int ipv6_create_tempaddr(struct inet6_ifaddr *ifp, struct inet6_ifaddr *i
|
||||||
struct inet6_dev *idev = ifp->idev;
|
struct inet6_dev *idev = ifp->idev;
|
||||||
struct in6_addr addr, *tmpaddr;
|
struct in6_addr addr, *tmpaddr;
|
||||||
unsigned long tmp_prefered_lft, tmp_valid_lft, tmp_cstamp, tmp_tstamp;
|
unsigned long tmp_prefered_lft, tmp_valid_lft, tmp_cstamp, tmp_tstamp;
|
||||||
|
unsigned long regen_advance;
|
||||||
int tmp_plen;
|
int tmp_plen;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
int max_addresses;
|
int max_addresses;
|
||||||
|
@ -836,8 +837,23 @@ retry:
|
||||||
tmp_tstamp = ifp->tstamp;
|
tmp_tstamp = ifp->tstamp;
|
||||||
spin_unlock_bh(&ifp->lock);
|
spin_unlock_bh(&ifp->lock);
|
||||||
|
|
||||||
|
regen_advance = idev->cnf.regen_max_retry *
|
||||||
|
idev->cnf.dad_transmits *
|
||||||
|
idev->nd_parms->retrans_time / HZ;
|
||||||
write_unlock(&idev->lock);
|
write_unlock(&idev->lock);
|
||||||
|
|
||||||
|
/* A temporary address is created only if this calculated Preferred
|
||||||
|
* Lifetime is greater than REGEN_ADVANCE time units. In particular,
|
||||||
|
* an implementation must not create a temporary address with a zero
|
||||||
|
* Preferred Lifetime.
|
||||||
|
*/
|
||||||
|
if (tmp_prefered_lft <= regen_advance) {
|
||||||
|
in6_ifa_put(ifp);
|
||||||
|
in6_dev_put(idev);
|
||||||
|
ret = -1;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
addr_flags = IFA_F_TEMPORARY;
|
addr_flags = IFA_F_TEMPORARY;
|
||||||
/* set in addrconf_prefix_rcv() */
|
/* set in addrconf_prefix_rcv() */
|
||||||
if (ifp->flags & IFA_F_OPTIMISTIC)
|
if (ifp->flags & IFA_F_OPTIMISTIC)
|
||||||
|
@ -1834,6 +1850,9 @@ ok:
|
||||||
* lifetimes of an existing temporary address
|
* lifetimes of an existing temporary address
|
||||||
* when processing a Prefix Information Option.
|
* when processing a Prefix Information Option.
|
||||||
*/
|
*/
|
||||||
|
if (ifp != ift->ifpub)
|
||||||
|
continue;
|
||||||
|
|
||||||
spin_lock(&ift->lock);
|
spin_lock(&ift->lock);
|
||||||
flags = ift->flags;
|
flags = ift->flags;
|
||||||
if (ift->valid_lft > valid_lft &&
|
if (ift->valid_lft > valid_lft &&
|
||||||
|
|
|
@ -440,10 +440,10 @@ void icmpv6_send(struct sk_buff *skb, int type, int code, __u32 info,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (xfrm_decode_session_reverse(skb, &fl2, AF_INET6))
|
if (xfrm_decode_session_reverse(skb, &fl2, AF_INET6))
|
||||||
goto out;
|
goto out_dst_release;
|
||||||
|
|
||||||
if (ip6_dst_lookup(sk, &dst2, &fl))
|
if (ip6_dst_lookup(sk, &dst2, &fl))
|
||||||
goto out;
|
goto out_dst_release;
|
||||||
|
|
||||||
err = xfrm_lookup(&dst2, &fl, sk, XFRM_LOOKUP_ICMP);
|
err = xfrm_lookup(&dst2, &fl, sk, XFRM_LOOKUP_ICMP);
|
||||||
if (err == -ENOENT) {
|
if (err == -ENOENT) {
|
||||||
|
|
|
@ -234,8 +234,7 @@ int ip6_mc_input(struct sk_buff *skb)
|
||||||
IP6_INC_STATS_BH(ip6_dst_idev(skb->dst), IPSTATS_MIB_INMCASTPKTS);
|
IP6_INC_STATS_BH(ip6_dst_idev(skb->dst), IPSTATS_MIB_INMCASTPKTS);
|
||||||
|
|
||||||
hdr = ipv6_hdr(skb);
|
hdr = ipv6_hdr(skb);
|
||||||
deliver = unlikely(skb->dev->flags & (IFF_PROMISC|IFF_ALLMULTI)) ||
|
deliver = ipv6_chk_mcast_addr(skb->dev, &hdr->daddr, NULL);
|
||||||
ipv6_chk_mcast_addr(skb->dev, &hdr->daddr, NULL);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* IPv6 multicast router mode isnt currently supported.
|
* IPv6 multicast router mode isnt currently supported.
|
||||||
|
|
|
@ -171,7 +171,9 @@ static __inline__ void fq_kill(struct nf_ct_frag6_queue *fq)
|
||||||
|
|
||||||
static void nf_ct_frag6_evictor(void)
|
static void nf_ct_frag6_evictor(void)
|
||||||
{
|
{
|
||||||
|
local_bh_disable();
|
||||||
inet_frag_evictor(&nf_init_frags, &nf_frags);
|
inet_frag_evictor(&nf_init_frags, &nf_frags);
|
||||||
|
local_bh_enable();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void nf_ct_frag6_expire(unsigned long data)
|
static void nf_ct_frag6_expire(unsigned long data)
|
||||||
|
|
|
@ -155,6 +155,9 @@ static int llc_ui_create(struct net *net, struct socket *sock, int protocol)
|
||||||
struct sock *sk;
|
struct sock *sk;
|
||||||
int rc = -ESOCKTNOSUPPORT;
|
int rc = -ESOCKTNOSUPPORT;
|
||||||
|
|
||||||
|
if (!capable(CAP_NET_RAW))
|
||||||
|
return -EPERM;
|
||||||
|
|
||||||
if (net != &init_net)
|
if (net != &init_net)
|
||||||
return -EAFNOSUPPORT;
|
return -EAFNOSUPPORT;
|
||||||
|
|
||||||
|
|
|
@ -198,7 +198,7 @@ int llc_conn_ac_send_disc_cmd_p_set_x(struct sock *sk, struct sk_buff *skb)
|
||||||
{
|
{
|
||||||
int rc = -ENOBUFS;
|
int rc = -ENOBUFS;
|
||||||
struct llc_sock *llc = llc_sk(sk);
|
struct llc_sock *llc = llc_sk(sk);
|
||||||
struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev);
|
struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev, LLC_PDU_TYPE_U, 0);
|
||||||
|
|
||||||
if (nskb) {
|
if (nskb) {
|
||||||
struct llc_sap *sap = llc->sap;
|
struct llc_sap *sap = llc->sap;
|
||||||
|
@ -223,7 +223,7 @@ int llc_conn_ac_send_dm_rsp_f_set_p(struct sock *sk, struct sk_buff *skb)
|
||||||
{
|
{
|
||||||
int rc = -ENOBUFS;
|
int rc = -ENOBUFS;
|
||||||
struct llc_sock *llc = llc_sk(sk);
|
struct llc_sock *llc = llc_sk(sk);
|
||||||
struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev);
|
struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev, LLC_PDU_TYPE_U, 0);
|
||||||
|
|
||||||
if (nskb) {
|
if (nskb) {
|
||||||
struct llc_sap *sap = llc->sap;
|
struct llc_sap *sap = llc->sap;
|
||||||
|
@ -249,7 +249,7 @@ int llc_conn_ac_send_dm_rsp_f_set_1(struct sock *sk, struct sk_buff *skb)
|
||||||
{
|
{
|
||||||
int rc = -ENOBUFS;
|
int rc = -ENOBUFS;
|
||||||
struct llc_sock *llc = llc_sk(sk);
|
struct llc_sock *llc = llc_sk(sk);
|
||||||
struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev);
|
struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev, LLC_PDU_TYPE_U, 0);
|
||||||
|
|
||||||
if (nskb) {
|
if (nskb) {
|
||||||
struct llc_sap *sap = llc->sap;
|
struct llc_sap *sap = llc->sap;
|
||||||
|
@ -282,7 +282,8 @@ int llc_conn_ac_send_frmr_rsp_f_set_x(struct sock *sk, struct sk_buff *skb)
|
||||||
llc_pdu_decode_pf_bit(skb, &f_bit);
|
llc_pdu_decode_pf_bit(skb, &f_bit);
|
||||||
else
|
else
|
||||||
f_bit = 0;
|
f_bit = 0;
|
||||||
nskb = llc_alloc_frame(sk, llc->dev);
|
nskb = llc_alloc_frame(sk, llc->dev, LLC_PDU_TYPE_U,
|
||||||
|
sizeof(struct llc_frmr_info));
|
||||||
if (nskb) {
|
if (nskb) {
|
||||||
struct llc_sap *sap = llc->sap;
|
struct llc_sap *sap = llc->sap;
|
||||||
|
|
||||||
|
@ -306,7 +307,8 @@ int llc_conn_ac_resend_frmr_rsp_f_set_0(struct sock *sk, struct sk_buff *skb)
|
||||||
{
|
{
|
||||||
int rc = -ENOBUFS;
|
int rc = -ENOBUFS;
|
||||||
struct llc_sock *llc = llc_sk(sk);
|
struct llc_sock *llc = llc_sk(sk);
|
||||||
struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev);
|
struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev, LLC_PDU_TYPE_U,
|
||||||
|
sizeof(struct llc_frmr_info));
|
||||||
|
|
||||||
if (nskb) {
|
if (nskb) {
|
||||||
struct llc_sap *sap = llc->sap;
|
struct llc_sap *sap = llc->sap;
|
||||||
|
@ -336,7 +338,8 @@ int llc_conn_ac_resend_frmr_rsp_f_set_p(struct sock *sk, struct sk_buff *skb)
|
||||||
struct llc_sock *llc = llc_sk(sk);
|
struct llc_sock *llc = llc_sk(sk);
|
||||||
|
|
||||||
llc_pdu_decode_pf_bit(skb, &f_bit);
|
llc_pdu_decode_pf_bit(skb, &f_bit);
|
||||||
nskb = llc_alloc_frame(sk, llc->dev);
|
nskb = llc_alloc_frame(sk, llc->dev, LLC_PDU_TYPE_U,
|
||||||
|
sizeof(struct llc_frmr_info));
|
||||||
if (nskb) {
|
if (nskb) {
|
||||||
struct llc_sap *sap = llc->sap;
|
struct llc_sap *sap = llc->sap;
|
||||||
struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
|
struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
|
||||||
|
@ -424,7 +427,7 @@ int llc_conn_ac_resend_i_xxx_x_set_0_or_send_rr(struct sock *sk,
|
||||||
struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
|
struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
|
||||||
int rc = -ENOBUFS;
|
int rc = -ENOBUFS;
|
||||||
struct llc_sock *llc = llc_sk(sk);
|
struct llc_sock *llc = llc_sk(sk);
|
||||||
struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev);
|
struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev, LLC_PDU_TYPE_U, 0);
|
||||||
|
|
||||||
if (nskb) {
|
if (nskb) {
|
||||||
struct llc_sap *sap = llc->sap;
|
struct llc_sap *sap = llc->sap;
|
||||||
|
@ -459,7 +462,7 @@ int llc_conn_ac_send_rej_cmd_p_set_1(struct sock *sk, struct sk_buff *skb)
|
||||||
{
|
{
|
||||||
int rc = -ENOBUFS;
|
int rc = -ENOBUFS;
|
||||||
struct llc_sock *llc = llc_sk(sk);
|
struct llc_sock *llc = llc_sk(sk);
|
||||||
struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev);
|
struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev, LLC_PDU_TYPE_S, 0);
|
||||||
|
|
||||||
if (nskb) {
|
if (nskb) {
|
||||||
struct llc_sap *sap = llc->sap;
|
struct llc_sap *sap = llc->sap;
|
||||||
|
@ -483,7 +486,7 @@ int llc_conn_ac_send_rej_rsp_f_set_1(struct sock *sk, struct sk_buff *skb)
|
||||||
{
|
{
|
||||||
int rc = -ENOBUFS;
|
int rc = -ENOBUFS;
|
||||||
struct llc_sock *llc = llc_sk(sk);
|
struct llc_sock *llc = llc_sk(sk);
|
||||||
struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev);
|
struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev, LLC_PDU_TYPE_S, 0);
|
||||||
|
|
||||||
if (nskb) {
|
if (nskb) {
|
||||||
struct llc_sap *sap = llc->sap;
|
struct llc_sap *sap = llc->sap;
|
||||||
|
@ -507,7 +510,7 @@ int llc_conn_ac_send_rej_xxx_x_set_0(struct sock *sk, struct sk_buff *skb)
|
||||||
{
|
{
|
||||||
int rc = -ENOBUFS;
|
int rc = -ENOBUFS;
|
||||||
struct llc_sock *llc = llc_sk(sk);
|
struct llc_sock *llc = llc_sk(sk);
|
||||||
struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev);
|
struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev, LLC_PDU_TYPE_S, 0);
|
||||||
|
|
||||||
if (nskb) {
|
if (nskb) {
|
||||||
struct llc_sap *sap = llc->sap;
|
struct llc_sap *sap = llc->sap;
|
||||||
|
@ -531,7 +534,7 @@ int llc_conn_ac_send_rnr_cmd_p_set_1(struct sock *sk, struct sk_buff *skb)
|
||||||
{
|
{
|
||||||
int rc = -ENOBUFS;
|
int rc = -ENOBUFS;
|
||||||
struct llc_sock *llc = llc_sk(sk);
|
struct llc_sock *llc = llc_sk(sk);
|
||||||
struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev);
|
struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev, LLC_PDU_TYPE_S, 0);
|
||||||
|
|
||||||
if (nskb) {
|
if (nskb) {
|
||||||
struct llc_sap *sap = llc->sap;
|
struct llc_sap *sap = llc->sap;
|
||||||
|
@ -555,7 +558,7 @@ int llc_conn_ac_send_rnr_rsp_f_set_1(struct sock *sk, struct sk_buff *skb)
|
||||||
{
|
{
|
||||||
int rc = -ENOBUFS;
|
int rc = -ENOBUFS;
|
||||||
struct llc_sock *llc = llc_sk(sk);
|
struct llc_sock *llc = llc_sk(sk);
|
||||||
struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev);
|
struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev, LLC_PDU_TYPE_S, 0);
|
||||||
|
|
||||||
if (nskb) {
|
if (nskb) {
|
||||||
struct llc_sap *sap = llc->sap;
|
struct llc_sap *sap = llc->sap;
|
||||||
|
@ -579,7 +582,7 @@ int llc_conn_ac_send_rnr_xxx_x_set_0(struct sock *sk, struct sk_buff *skb)
|
||||||
{
|
{
|
||||||
int rc = -ENOBUFS;
|
int rc = -ENOBUFS;
|
||||||
struct llc_sock *llc = llc_sk(sk);
|
struct llc_sock *llc = llc_sk(sk);
|
||||||
struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev);
|
struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev, LLC_PDU_TYPE_S, 0);
|
||||||
|
|
||||||
if (nskb) {
|
if (nskb) {
|
||||||
struct llc_sap *sap = llc->sap;
|
struct llc_sap *sap = llc->sap;
|
||||||
|
@ -615,7 +618,7 @@ int llc_conn_ac_opt_send_rnr_xxx_x_set_0(struct sock *sk, struct sk_buff *skb)
|
||||||
{
|
{
|
||||||
int rc = -ENOBUFS;
|
int rc = -ENOBUFS;
|
||||||
struct llc_sock *llc = llc_sk(sk);
|
struct llc_sock *llc = llc_sk(sk);
|
||||||
struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev);
|
struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev, LLC_PDU_TYPE_S, 0);
|
||||||
|
|
||||||
if (nskb) {
|
if (nskb) {
|
||||||
struct llc_sap *sap = llc->sap;
|
struct llc_sap *sap = llc->sap;
|
||||||
|
@ -639,7 +642,7 @@ int llc_conn_ac_send_rr_cmd_p_set_1(struct sock *sk, struct sk_buff *skb)
|
||||||
{
|
{
|
||||||
int rc = -ENOBUFS;
|
int rc = -ENOBUFS;
|
||||||
struct llc_sock *llc = llc_sk(sk);
|
struct llc_sock *llc = llc_sk(sk);
|
||||||
struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev);
|
struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev, LLC_PDU_TYPE_S, 0);
|
||||||
|
|
||||||
if (nskb) {
|
if (nskb) {
|
||||||
struct llc_sap *sap = llc->sap;
|
struct llc_sap *sap = llc->sap;
|
||||||
|
@ -663,7 +666,7 @@ int llc_conn_ac_send_rr_rsp_f_set_1(struct sock *sk, struct sk_buff *skb)
|
||||||
{
|
{
|
||||||
int rc = -ENOBUFS;
|
int rc = -ENOBUFS;
|
||||||
struct llc_sock *llc = llc_sk(sk);
|
struct llc_sock *llc = llc_sk(sk);
|
||||||
struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev);
|
struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev, LLC_PDU_TYPE_S, 0);
|
||||||
|
|
||||||
if (nskb) {
|
if (nskb) {
|
||||||
struct llc_sap *sap = llc->sap;
|
struct llc_sap *sap = llc->sap;
|
||||||
|
@ -688,7 +691,7 @@ int llc_conn_ac_send_ack_rsp_f_set_1(struct sock *sk, struct sk_buff *skb)
|
||||||
{
|
{
|
||||||
int rc = -ENOBUFS;
|
int rc = -ENOBUFS;
|
||||||
struct llc_sock *llc = llc_sk(sk);
|
struct llc_sock *llc = llc_sk(sk);
|
||||||
struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev);
|
struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev, LLC_PDU_TYPE_S, 0);
|
||||||
|
|
||||||
if (nskb) {
|
if (nskb) {
|
||||||
struct llc_sap *sap = llc->sap;
|
struct llc_sap *sap = llc->sap;
|
||||||
|
@ -712,7 +715,7 @@ int llc_conn_ac_send_rr_xxx_x_set_0(struct sock *sk, struct sk_buff *skb)
|
||||||
{
|
{
|
||||||
int rc = -ENOBUFS;
|
int rc = -ENOBUFS;
|
||||||
struct llc_sock *llc = llc_sk(sk);
|
struct llc_sock *llc = llc_sk(sk);
|
||||||
struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev);
|
struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev, LLC_PDU_TYPE_S, 0);
|
||||||
|
|
||||||
if (nskb) {
|
if (nskb) {
|
||||||
struct llc_sap *sap = llc->sap;
|
struct llc_sap *sap = llc->sap;
|
||||||
|
@ -736,7 +739,7 @@ int llc_conn_ac_send_ack_xxx_x_set_0(struct sock *sk, struct sk_buff *skb)
|
||||||
{
|
{
|
||||||
int rc = -ENOBUFS;
|
int rc = -ENOBUFS;
|
||||||
struct llc_sock *llc = llc_sk(sk);
|
struct llc_sock *llc = llc_sk(sk);
|
||||||
struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev);
|
struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev, LLC_PDU_TYPE_S, 0);
|
||||||
|
|
||||||
if (nskb) {
|
if (nskb) {
|
||||||
struct llc_sap *sap = llc->sap;
|
struct llc_sap *sap = llc->sap;
|
||||||
|
@ -770,7 +773,7 @@ int llc_conn_ac_send_sabme_cmd_p_set_x(struct sock *sk, struct sk_buff *skb)
|
||||||
{
|
{
|
||||||
int rc = -ENOBUFS;
|
int rc = -ENOBUFS;
|
||||||
struct llc_sock *llc = llc_sk(sk);
|
struct llc_sock *llc = llc_sk(sk);
|
||||||
struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev);
|
struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev, LLC_PDU_TYPE_U, 0);
|
||||||
|
|
||||||
if (nskb) {
|
if (nskb) {
|
||||||
struct llc_sap *sap = llc->sap;
|
struct llc_sap *sap = llc->sap;
|
||||||
|
@ -799,7 +802,7 @@ int llc_conn_ac_send_ua_rsp_f_set_p(struct sock *sk, struct sk_buff *skb)
|
||||||
u8 f_bit;
|
u8 f_bit;
|
||||||
int rc = -ENOBUFS;
|
int rc = -ENOBUFS;
|
||||||
struct llc_sock *llc = llc_sk(sk);
|
struct llc_sock *llc = llc_sk(sk);
|
||||||
struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev);
|
struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev, LLC_PDU_TYPE_U, 0);
|
||||||
|
|
||||||
llc_pdu_decode_pf_bit(skb, &f_bit);
|
llc_pdu_decode_pf_bit(skb, &f_bit);
|
||||||
if (nskb) {
|
if (nskb) {
|
||||||
|
@ -956,7 +959,7 @@ static int llc_conn_ac_send_rr_rsp_f_set_ackpf(struct sock *sk,
|
||||||
{
|
{
|
||||||
int rc = -ENOBUFS;
|
int rc = -ENOBUFS;
|
||||||
struct llc_sock *llc = llc_sk(sk);
|
struct llc_sock *llc = llc_sk(sk);
|
||||||
struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev);
|
struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev, LLC_PDU_TYPE_S, 0);
|
||||||
|
|
||||||
if (nskb) {
|
if (nskb) {
|
||||||
struct llc_sap *sap = llc->sap;
|
struct llc_sap *sap = llc->sap;
|
||||||
|
|
|
@ -25,8 +25,6 @@
|
||||||
LIST_HEAD(llc_sap_list);
|
LIST_HEAD(llc_sap_list);
|
||||||
DEFINE_RWLOCK(llc_sap_list_lock);
|
DEFINE_RWLOCK(llc_sap_list_lock);
|
||||||
|
|
||||||
unsigned char llc_station_mac_sa[ETH_ALEN];
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* llc_sap_alloc - allocates and initializes sap.
|
* llc_sap_alloc - allocates and initializes sap.
|
||||||
*
|
*
|
||||||
|
@ -37,8 +35,8 @@ static struct llc_sap *llc_sap_alloc(void)
|
||||||
struct llc_sap *sap = kzalloc(sizeof(*sap), GFP_ATOMIC);
|
struct llc_sap *sap = kzalloc(sizeof(*sap), GFP_ATOMIC);
|
||||||
|
|
||||||
if (sap) {
|
if (sap) {
|
||||||
|
/* sap->laddr.mac - leave as a null, it's filled by bind */
|
||||||
sap->state = LLC_SAP_STATE_ACTIVE;
|
sap->state = LLC_SAP_STATE_ACTIVE;
|
||||||
memcpy(sap->laddr.mac, llc_station_mac_sa, ETH_ALEN);
|
|
||||||
rwlock_init(&sap->sk_list.lock);
|
rwlock_init(&sap->sk_list.lock);
|
||||||
atomic_set(&sap->refcnt, 1);
|
atomic_set(&sap->refcnt, 1);
|
||||||
}
|
}
|
||||||
|
@ -167,10 +165,6 @@ static int __init llc_init(void)
|
||||||
if (dev != NULL)
|
if (dev != NULL)
|
||||||
dev = next_net_device(dev);
|
dev = next_net_device(dev);
|
||||||
|
|
||||||
if (dev != NULL)
|
|
||||||
memcpy(llc_station_mac_sa, dev->dev_addr, ETH_ALEN);
|
|
||||||
else
|
|
||||||
memset(llc_station_mac_sa, 0, ETH_ALEN);
|
|
||||||
dev_add_pack(&llc_packet_type);
|
dev_add_pack(&llc_packet_type);
|
||||||
dev_add_pack(&llc_tr_packet_type);
|
dev_add_pack(&llc_tr_packet_type);
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -185,7 +179,6 @@ static void __exit llc_exit(void)
|
||||||
module_init(llc_init);
|
module_init(llc_init);
|
||||||
module_exit(llc_exit);
|
module_exit(llc_exit);
|
||||||
|
|
||||||
EXPORT_SYMBOL(llc_station_mac_sa);
|
|
||||||
EXPORT_SYMBOL(llc_sap_list);
|
EXPORT_SYMBOL(llc_sap_list);
|
||||||
EXPORT_SYMBOL(llc_sap_list_lock);
|
EXPORT_SYMBOL(llc_sap_list_lock);
|
||||||
EXPORT_SYMBOL(llc_sap_find);
|
EXPORT_SYMBOL(llc_sap_find);
|
||||||
|
|
|
@ -117,8 +117,12 @@ static inline int llc_fixup_skb(struct sk_buff *skb)
|
||||||
skb_pull(skb, llc_len);
|
skb_pull(skb, llc_len);
|
||||||
if (skb->protocol == htons(ETH_P_802_2)) {
|
if (skb->protocol == htons(ETH_P_802_2)) {
|
||||||
__be16 pdulen = eth_hdr(skb)->h_proto;
|
__be16 pdulen = eth_hdr(skb)->h_proto;
|
||||||
u16 data_size = ntohs(pdulen) - llc_len;
|
s32 data_size = ntohs(pdulen) - llc_len;
|
||||||
|
|
||||||
|
if (data_size < 0 ||
|
||||||
|
((skb_tail_pointer(skb) -
|
||||||
|
(u8 *)pdu) - llc_len) < data_size)
|
||||||
|
return 0;
|
||||||
if (unlikely(pskb_trim_rcsum(skb, data_size)))
|
if (unlikely(pskb_trim_rcsum(skb, data_size)))
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -241,7 +241,7 @@ void llc_pdu_init_as_frmr_rsp(struct sk_buff *skb, struct llc_pdu_sn *prev_pdu,
|
||||||
FRMR_INFO_SET_PDU_INFO_2LONG_IND(frmr_info, vzyxw);
|
FRMR_INFO_SET_PDU_INFO_2LONG_IND(frmr_info, vzyxw);
|
||||||
FRMR_INFO_SET_PDU_INVALID_Nr_IND(frmr_info, vzyxw);
|
FRMR_INFO_SET_PDU_INVALID_Nr_IND(frmr_info, vzyxw);
|
||||||
FRMR_INFO_SET_PDU_INVALID_Ns_IND(frmr_info, vzyxw);
|
FRMR_INFO_SET_PDU_INVALID_Ns_IND(frmr_info, vzyxw);
|
||||||
skb_put(skb, 5);
|
skb_put(skb, sizeof(struct llc_frmr_info));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -103,7 +103,8 @@ int llc_sap_action_send_xid_r(struct llc_sap *sap, struct sk_buff *skb)
|
||||||
llc_pdu_decode_sa(skb, mac_da);
|
llc_pdu_decode_sa(skb, mac_da);
|
||||||
llc_pdu_decode_da(skb, mac_sa);
|
llc_pdu_decode_da(skb, mac_sa);
|
||||||
llc_pdu_decode_ssap(skb, &dsap);
|
llc_pdu_decode_ssap(skb, &dsap);
|
||||||
nskb = llc_alloc_frame(NULL, skb->dev);
|
nskb = llc_alloc_frame(NULL, skb->dev, LLC_PDU_TYPE_U,
|
||||||
|
sizeof(struct llc_xid_info));
|
||||||
if (!nskb)
|
if (!nskb)
|
||||||
goto out;
|
goto out;
|
||||||
llc_pdu_header_init(nskb, LLC_PDU_TYPE_U, sap->laddr.lsap, dsap,
|
llc_pdu_header_init(nskb, LLC_PDU_TYPE_U, sap->laddr.lsap, dsap,
|
||||||
|
@ -144,11 +145,15 @@ int llc_sap_action_send_test_r(struct llc_sap *sap, struct sk_buff *skb)
|
||||||
u8 mac_da[ETH_ALEN], mac_sa[ETH_ALEN], dsap;
|
u8 mac_da[ETH_ALEN], mac_sa[ETH_ALEN], dsap;
|
||||||
struct sk_buff *nskb;
|
struct sk_buff *nskb;
|
||||||
int rc = 1;
|
int rc = 1;
|
||||||
|
u32 data_size;
|
||||||
|
|
||||||
llc_pdu_decode_sa(skb, mac_da);
|
llc_pdu_decode_sa(skb, mac_da);
|
||||||
llc_pdu_decode_da(skb, mac_sa);
|
llc_pdu_decode_da(skb, mac_sa);
|
||||||
llc_pdu_decode_ssap(skb, &dsap);
|
llc_pdu_decode_ssap(skb, &dsap);
|
||||||
nskb = llc_alloc_frame(NULL, skb->dev);
|
|
||||||
|
/* The test request command is type U (llc_len = 3) */
|
||||||
|
data_size = ntohs(eth_hdr(skb)->h_proto) - 3;
|
||||||
|
nskb = llc_alloc_frame(NULL, skb->dev, LLC_PDU_TYPE_U, data_size);
|
||||||
if (!nskb)
|
if (!nskb)
|
||||||
goto out;
|
goto out;
|
||||||
llc_pdu_header_init(nskb, LLC_PDU_TYPE_U, sap->laddr.lsap, dsap,
|
llc_pdu_header_init(nskb, LLC_PDU_TYPE_U, sap->laddr.lsap, dsap,
|
||||||
|
|
|
@ -24,20 +24,41 @@
|
||||||
#include <net/tcp_states.h>
|
#include <net/tcp_states.h>
|
||||||
#include <linux/llc.h>
|
#include <linux/llc.h>
|
||||||
|
|
||||||
|
static int llc_mac_header_len(unsigned short devtype)
|
||||||
|
{
|
||||||
|
switch (devtype) {
|
||||||
|
case ARPHRD_ETHER:
|
||||||
|
case ARPHRD_LOOPBACK:
|
||||||
|
return sizeof(struct ethhdr);
|
||||||
|
#ifdef CONFIG_TR
|
||||||
|
case ARPHRD_IEEE802_TR:
|
||||||
|
return sizeof(struct trh_hdr);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* llc_alloc_frame - allocates sk_buff for frame
|
* llc_alloc_frame - allocates sk_buff for frame
|
||||||
* @dev: network device this skb will be sent over
|
* @dev: network device this skb will be sent over
|
||||||
|
* @type: pdu type to allocate
|
||||||
|
* @data_size: data size to allocate
|
||||||
*
|
*
|
||||||
* Allocates an sk_buff for frame and initializes sk_buff fields.
|
* Allocates an sk_buff for frame and initializes sk_buff fields.
|
||||||
* Returns allocated skb or %NULL when out of memory.
|
* Returns allocated skb or %NULL when out of memory.
|
||||||
*/
|
*/
|
||||||
struct sk_buff *llc_alloc_frame(struct sock *sk, struct net_device *dev)
|
struct sk_buff *llc_alloc_frame(struct sock *sk, struct net_device *dev,
|
||||||
|
u8 type, u32 data_size)
|
||||||
{
|
{
|
||||||
struct sk_buff *skb = alloc_skb(128, GFP_ATOMIC);
|
int hlen = type == LLC_PDU_TYPE_U ? 3 : 4;
|
||||||
|
struct sk_buff *skb;
|
||||||
|
|
||||||
|
hlen += llc_mac_header_len(dev->type);
|
||||||
|
skb = alloc_skb(hlen + data_size, GFP_ATOMIC);
|
||||||
|
|
||||||
if (skb) {
|
if (skb) {
|
||||||
skb_reset_mac_header(skb);
|
skb_reset_mac_header(skb);
|
||||||
skb_reserve(skb, 50);
|
skb_reserve(skb, hlen);
|
||||||
skb_reset_network_header(skb);
|
skb_reset_network_header(skb);
|
||||||
skb_reset_transport_header(skb);
|
skb_reset_transport_header(skb);
|
||||||
skb->protocol = htons(ETH_P_802_2);
|
skb->protocol = htons(ETH_P_802_2);
|
||||||
|
|
|
@ -253,13 +253,14 @@ static int llc_station_ac_inc_xid_r_cnt_by_1(struct sk_buff *skb)
|
||||||
static int llc_station_ac_send_null_dsap_xid_c(struct sk_buff *skb)
|
static int llc_station_ac_send_null_dsap_xid_c(struct sk_buff *skb)
|
||||||
{
|
{
|
||||||
int rc = 1;
|
int rc = 1;
|
||||||
struct sk_buff *nskb = llc_alloc_frame(NULL, skb->dev);
|
struct sk_buff *nskb = llc_alloc_frame(NULL, skb->dev, LLC_PDU_TYPE_U,
|
||||||
|
sizeof(struct llc_xid_info));
|
||||||
|
|
||||||
if (!nskb)
|
if (!nskb)
|
||||||
goto out;
|
goto out;
|
||||||
llc_pdu_header_init(nskb, LLC_PDU_TYPE_U, 0, 0, LLC_PDU_CMD);
|
llc_pdu_header_init(nskb, LLC_PDU_TYPE_U, 0, 0, LLC_PDU_CMD);
|
||||||
llc_pdu_init_as_xid_cmd(nskb, LLC_XID_NULL_CLASS_2, 127);
|
llc_pdu_init_as_xid_cmd(nskb, LLC_XID_NULL_CLASS_2, 127);
|
||||||
rc = llc_mac_hdr_init(nskb, llc_station_mac_sa, llc_station_mac_sa);
|
rc = llc_mac_hdr_init(nskb, skb->dev->dev_addr, skb->dev->dev_addr);
|
||||||
if (unlikely(rc))
|
if (unlikely(rc))
|
||||||
goto free;
|
goto free;
|
||||||
llc_station_send_pdu(nskb);
|
llc_station_send_pdu(nskb);
|
||||||
|
@ -274,7 +275,8 @@ static int llc_station_ac_send_xid_r(struct sk_buff *skb)
|
||||||
{
|
{
|
||||||
u8 mac_da[ETH_ALEN], dsap;
|
u8 mac_da[ETH_ALEN], dsap;
|
||||||
int rc = 1;
|
int rc = 1;
|
||||||
struct sk_buff* nskb = llc_alloc_frame(NULL, skb->dev);
|
struct sk_buff *nskb = llc_alloc_frame(NULL, skb->dev, LLC_PDU_TYPE_U,
|
||||||
|
sizeof(struct llc_xid_info));
|
||||||
|
|
||||||
if (!nskb)
|
if (!nskb)
|
||||||
goto out;
|
goto out;
|
||||||
|
@ -283,7 +285,7 @@ static int llc_station_ac_send_xid_r(struct sk_buff *skb)
|
||||||
llc_pdu_decode_ssap(skb, &dsap);
|
llc_pdu_decode_ssap(skb, &dsap);
|
||||||
llc_pdu_header_init(nskb, LLC_PDU_TYPE_U, 0, dsap, LLC_PDU_RSP);
|
llc_pdu_header_init(nskb, LLC_PDU_TYPE_U, 0, dsap, LLC_PDU_RSP);
|
||||||
llc_pdu_init_as_xid_rsp(nskb, LLC_XID_NULL_CLASS_2, 127);
|
llc_pdu_init_as_xid_rsp(nskb, LLC_XID_NULL_CLASS_2, 127);
|
||||||
rc = llc_mac_hdr_init(nskb, llc_station_mac_sa, mac_da);
|
rc = llc_mac_hdr_init(nskb, skb->dev->dev_addr, mac_da);
|
||||||
if (unlikely(rc))
|
if (unlikely(rc))
|
||||||
goto free;
|
goto free;
|
||||||
llc_station_send_pdu(nskb);
|
llc_station_send_pdu(nskb);
|
||||||
|
@ -298,7 +300,12 @@ static int llc_station_ac_send_test_r(struct sk_buff *skb)
|
||||||
{
|
{
|
||||||
u8 mac_da[ETH_ALEN], dsap;
|
u8 mac_da[ETH_ALEN], dsap;
|
||||||
int rc = 1;
|
int rc = 1;
|
||||||
struct sk_buff *nskb = llc_alloc_frame(NULL, skb->dev);
|
u32 data_size;
|
||||||
|
struct sk_buff *nskb;
|
||||||
|
|
||||||
|
/* The test request command is type U (llc_len = 3) */
|
||||||
|
data_size = ntohs(eth_hdr(skb)->h_proto) - 3;
|
||||||
|
nskb = llc_alloc_frame(NULL, skb->dev, LLC_PDU_TYPE_U, data_size);
|
||||||
|
|
||||||
if (!nskb)
|
if (!nskb)
|
||||||
goto out;
|
goto out;
|
||||||
|
@ -307,7 +314,7 @@ static int llc_station_ac_send_test_r(struct sk_buff *skb)
|
||||||
llc_pdu_decode_ssap(skb, &dsap);
|
llc_pdu_decode_ssap(skb, &dsap);
|
||||||
llc_pdu_header_init(nskb, LLC_PDU_TYPE_U, 0, dsap, LLC_PDU_RSP);
|
llc_pdu_header_init(nskb, LLC_PDU_TYPE_U, 0, dsap, LLC_PDU_RSP);
|
||||||
llc_pdu_init_as_test_rsp(nskb, skb);
|
llc_pdu_init_as_test_rsp(nskb, skb);
|
||||||
rc = llc_mac_hdr_init(nskb, llc_station_mac_sa, mac_da);
|
rc = llc_mac_hdr_init(nskb, skb->dev->dev_addr, mac_da);
|
||||||
if (unlikely(rc))
|
if (unlikely(rc))
|
||||||
goto free;
|
goto free;
|
||||||
llc_station_send_pdu(nskb);
|
llc_station_send_pdu(nskb);
|
||||||
|
|
|
@ -375,6 +375,18 @@ static int ieee80211_open(struct net_device *dev)
|
||||||
if (need_hw_reconfig)
|
if (need_hw_reconfig)
|
||||||
ieee80211_hw_config(local);
|
ieee80211_hw_config(local);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* ieee80211_sta_work is disabled while network interface
|
||||||
|
* is down. Therefore, some configuration changes may not
|
||||||
|
* yet be effective. Trigger execution of ieee80211_sta_work
|
||||||
|
* to fix this.
|
||||||
|
*/
|
||||||
|
if(sdata->vif.type == IEEE80211_IF_TYPE_STA ||
|
||||||
|
sdata->vif.type == IEEE80211_IF_TYPE_IBSS) {
|
||||||
|
struct ieee80211_if_sta *ifsta = &sdata->u.sta;
|
||||||
|
queue_work(local->hw.workqueue, &ifsta->work);
|
||||||
|
}
|
||||||
|
|
||||||
netif_start_queue(dev);
|
netif_start_queue(dev);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -360,7 +360,7 @@ static u32 ieee80211_handle_erp_ie(struct ieee80211_sub_if_data *sdata,
|
||||||
struct ieee80211_bss_conf *bss_conf = &sdata->bss_conf;
|
struct ieee80211_bss_conf *bss_conf = &sdata->bss_conf;
|
||||||
struct ieee80211_if_sta *ifsta = &sdata->u.sta;
|
struct ieee80211_if_sta *ifsta = &sdata->u.sta;
|
||||||
bool use_protection = (erp_value & WLAN_ERP_USE_PROTECTION) != 0;
|
bool use_protection = (erp_value & WLAN_ERP_USE_PROTECTION) != 0;
|
||||||
bool preamble_mode = (erp_value & WLAN_ERP_BARKER_PREAMBLE) != 0;
|
bool use_short_preamble = (erp_value & WLAN_ERP_BARKER_PREAMBLE) == 0;
|
||||||
DECLARE_MAC_BUF(mac);
|
DECLARE_MAC_BUF(mac);
|
||||||
u32 changed = 0;
|
u32 changed = 0;
|
||||||
|
|
||||||
|
@ -376,16 +376,15 @@ static u32 ieee80211_handle_erp_ie(struct ieee80211_sub_if_data *sdata,
|
||||||
changed |= BSS_CHANGED_ERP_CTS_PROT;
|
changed |= BSS_CHANGED_ERP_CTS_PROT;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (preamble_mode != bss_conf->use_short_preamble) {
|
if (use_short_preamble != bss_conf->use_short_preamble) {
|
||||||
if (net_ratelimit()) {
|
if (net_ratelimit()) {
|
||||||
printk(KERN_DEBUG "%s: switched to %s barker preamble"
|
printk(KERN_DEBUG "%s: switched to %s barker preamble"
|
||||||
" (BSSID=%s)\n",
|
" (BSSID=%s)\n",
|
||||||
sdata->dev->name,
|
sdata->dev->name,
|
||||||
(preamble_mode == WLAN_ERP_PREAMBLE_SHORT) ?
|
use_short_preamble ? "short" : "long",
|
||||||
"short" : "long",
|
|
||||||
print_mac(mac, ifsta->bssid));
|
print_mac(mac, ifsta->bssid));
|
||||||
}
|
}
|
||||||
bss_conf->use_short_preamble = preamble_mode;
|
bss_conf->use_short_preamble = use_short_preamble;
|
||||||
changed |= BSS_CHANGED_ERP_PREAMBLE;
|
changed |= BSS_CHANGED_ERP_PREAMBLE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -598,17 +598,24 @@ static int rose_release(struct socket *sock)
|
||||||
|
|
||||||
if (sk == NULL) return 0;
|
if (sk == NULL) return 0;
|
||||||
|
|
||||||
|
sock_hold(sk);
|
||||||
|
sock_orphan(sk);
|
||||||
|
lock_sock(sk);
|
||||||
rose = rose_sk(sk);
|
rose = rose_sk(sk);
|
||||||
|
|
||||||
switch (rose->state) {
|
switch (rose->state) {
|
||||||
case ROSE_STATE_0:
|
case ROSE_STATE_0:
|
||||||
|
release_sock(sk);
|
||||||
rose_disconnect(sk, 0, -1, -1);
|
rose_disconnect(sk, 0, -1, -1);
|
||||||
|
lock_sock(sk);
|
||||||
rose_destroy_socket(sk);
|
rose_destroy_socket(sk);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ROSE_STATE_2:
|
case ROSE_STATE_2:
|
||||||
rose->neighbour->use--;
|
rose->neighbour->use--;
|
||||||
|
release_sock(sk);
|
||||||
rose_disconnect(sk, 0, -1, -1);
|
rose_disconnect(sk, 0, -1, -1);
|
||||||
|
lock_sock(sk);
|
||||||
rose_destroy_socket(sk);
|
rose_destroy_socket(sk);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -633,6 +640,8 @@ static int rose_release(struct socket *sock)
|
||||||
}
|
}
|
||||||
|
|
||||||
sock->sk = NULL;
|
sock->sk = NULL;
|
||||||
|
release_sock(sk);
|
||||||
|
sock_put(sk);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -184,10 +184,22 @@ static inline int qdisc_restart(struct net_device *dev)
|
||||||
|
|
||||||
void __qdisc_run(struct net_device *dev)
|
void __qdisc_run(struct net_device *dev)
|
||||||
{
|
{
|
||||||
do {
|
unsigned long start_time = jiffies;
|
||||||
if (!qdisc_restart(dev))
|
|
||||||
|
while (qdisc_restart(dev)) {
|
||||||
|
if (netif_queue_stopped(dev))
|
||||||
break;
|
break;
|
||||||
} while (!netif_queue_stopped(dev));
|
|
||||||
|
/*
|
||||||
|
* Postpone processing if
|
||||||
|
* 1. another process needs the CPU;
|
||||||
|
* 2. we've been doing it for too long.
|
||||||
|
*/
|
||||||
|
if (need_resched() || jiffies != start_time) {
|
||||||
|
netif_schedule(dev);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
clear_bit(__LINK_STATE_QDISC_RUNNING, &dev->state);
|
clear_bit(__LINK_STATE_QDISC_RUNNING, &dev->state);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue