Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next-2.6: (1750 commits) ixgbe: Allow Priority Flow Control settings to survive a device reset net: core: remove unneeded include in net/core/utils.c. e1000e: update version number e1000e: fix close interrupt race e1000e: fix loss of multicast packets e1000e: commonize tx cleanup routine to match e1000 & igb netfilter: fix nf_logger name in ebt_ulog. netfilter: fix warning in ebt_ulog init function. netfilter: fix warning about invalid const usage e1000: fix close race with interrupt e1000: cleanup clean_tx_irq routine so that it completely cleans ring e1000: fix tx hang detect logic and address dma mapping issues bridge: bad error handling when adding invalid ether address bonding: select current active slave when enslaving device for mode tlb and alb gianfar: reallocate skb when headroom is not enough for fcb Bump release date to 25Mar2009 and version to 0.22 r6040: Fix second PHY address qeth: fix wait_event_timeout handling qeth: check for completion of a running recovery qeth: unregister MAC addresses during recovery. ... Manually fixed up conflicts in: drivers/infiniband/hw/cxgb3/cxio_hal.h drivers/infiniband/hw/nes/nes_nic.c
This commit is contained in:
Коммит
13220a94d3
|
@ -17,8 +17,7 @@
|
||||||
</authorgroup>
|
</authorgroup>
|
||||||
|
|
||||||
<copyright>
|
<copyright>
|
||||||
<year>2007</year>
|
<year>2007-2009</year>
|
||||||
<year>2008</year>
|
|
||||||
<holder>Johannes Berg</holder>
|
<holder>Johannes Berg</holder>
|
||||||
</copyright>
|
</copyright>
|
||||||
|
|
||||||
|
@ -165,8 +164,8 @@ usage should require reading the full document.
|
||||||
!Pinclude/net/mac80211.h Frame format
|
!Pinclude/net/mac80211.h Frame format
|
||||||
</sect1>
|
</sect1>
|
||||||
<sect1>
|
<sect1>
|
||||||
<title>Alignment issues</title>
|
<title>Packet alignment</title>
|
||||||
<para>TBD</para>
|
!Pnet/mac80211/rx.c Packet alignment
|
||||||
</sect1>
|
</sect1>
|
||||||
<sect1>
|
<sect1>
|
||||||
<title>Calling into mac80211 from interrupts</title>
|
<title>Calling into mac80211 from interrupts</title>
|
||||||
|
@ -223,6 +222,11 @@ usage should require reading the full document.
|
||||||
!Finclude/net/mac80211.h ieee80211_key_flags
|
!Finclude/net/mac80211.h ieee80211_key_flags
|
||||||
</chapter>
|
</chapter>
|
||||||
|
|
||||||
|
<chapter id="powersave">
|
||||||
|
<title>Powersave support</title>
|
||||||
|
!Pinclude/net/mac80211.h Powersave support
|
||||||
|
</chapter>
|
||||||
|
|
||||||
<chapter id="qos">
|
<chapter id="qos">
|
||||||
<title>Multiple queues and QoS support</title>
|
<title>Multiple queues and QoS support</title>
|
||||||
<para>TBD</para>
|
<para>TBD</para>
|
||||||
|
|
|
@ -229,7 +229,9 @@ Who: Jan Engelhardt <jengelh@computergmbh.de>
|
||||||
---------------------------
|
---------------------------
|
||||||
|
|
||||||
What: b43 support for firmware revision < 410
|
What: b43 support for firmware revision < 410
|
||||||
When: July 2008
|
When: The schedule was July 2008, but it was decided that we are going to keep the
|
||||||
|
code as long as there are no major maintanance headaches.
|
||||||
|
So it _could_ be removed _any_ time now, if it conflicts with something new.
|
||||||
Why: The support code for the old firmware hurts code readability/maintainability
|
Why: The support code for the old firmware hurts code readability/maintainability
|
||||||
and slightly hurts runtime performance. Bugfixes for the old firmware
|
and slightly hurts runtime performance. Bugfixes for the old firmware
|
||||||
are not provided by Broadcom anymore.
|
are not provided by Broadcom anymore.
|
||||||
|
|
|
@ -141,7 +141,8 @@ rx_ccid = 2
|
||||||
Default CCID for the receiver-sender half-connection; see tx_ccid.
|
Default CCID for the receiver-sender half-connection; see tx_ccid.
|
||||||
|
|
||||||
seq_window = 100
|
seq_window = 100
|
||||||
The initial sequence window (sec. 7.5.2).
|
The initial sequence window (sec. 7.5.2) of the sender. This influences
|
||||||
|
the local ackno validity and the remote seqno validity windows (7.5.1).
|
||||||
|
|
||||||
tx_qlen = 5
|
tx_qlen = 5
|
||||||
The size of the transmit buffer in packets. A value of 0 corresponds
|
The size of the transmit buffer in packets. A value of 0 corresponds
|
||||||
|
|
|
@ -625,11 +625,11 @@ log_martians - BOOLEAN
|
||||||
accept_redirects - BOOLEAN
|
accept_redirects - BOOLEAN
|
||||||
Accept ICMP redirect messages.
|
Accept ICMP redirect messages.
|
||||||
accept_redirects for the interface will be enabled if:
|
accept_redirects for the interface will be enabled if:
|
||||||
- both conf/{all,interface}/accept_redirects are TRUE in the case forwarding
|
- both conf/{all,interface}/accept_redirects are TRUE in the case
|
||||||
for the interface is enabled
|
forwarding for the interface is enabled
|
||||||
or
|
or
|
||||||
- at least one of conf/{all,interface}/accept_redirects is TRUE in the case
|
- at least one of conf/{all,interface}/accept_redirects is TRUE in the
|
||||||
forwarding for the interface is disabled
|
case forwarding for the interface is disabled
|
||||||
accept_redirects for the interface will be disabled otherwise
|
accept_redirects for the interface will be disabled otherwise
|
||||||
default TRUE (host)
|
default TRUE (host)
|
||||||
FALSE (router)
|
FALSE (router)
|
||||||
|
@ -640,8 +640,8 @@ forwarding - BOOLEAN
|
||||||
mc_forwarding - BOOLEAN
|
mc_forwarding - BOOLEAN
|
||||||
Do multicast routing. The kernel needs to be compiled with CONFIG_MROUTE
|
Do multicast routing. The kernel needs to be compiled with CONFIG_MROUTE
|
||||||
and a multicast routing daemon is required.
|
and a multicast routing daemon is required.
|
||||||
conf/all/mc_forwarding must also be set to TRUE to enable multicast routing
|
conf/all/mc_forwarding must also be set to TRUE to enable multicast
|
||||||
for the interface
|
routing for the interface
|
||||||
|
|
||||||
medium_id - INTEGER
|
medium_id - INTEGER
|
||||||
Integer value used to differentiate the devices by the medium they
|
Integer value used to differentiate the devices by the medium they
|
||||||
|
@ -699,16 +699,22 @@ accept_source_route - BOOLEAN
|
||||||
default TRUE (router)
|
default TRUE (router)
|
||||||
FALSE (host)
|
FALSE (host)
|
||||||
|
|
||||||
rp_filter - BOOLEAN
|
rp_filter - INTEGER
|
||||||
1 - do source validation by reversed path, as specified in RFC1812
|
|
||||||
Recommended option for single homed hosts and stub network
|
|
||||||
routers. Could cause troubles for complicated (not loop free)
|
|
||||||
networks running a slow unreliable protocol (sort of RIP),
|
|
||||||
or using static routes.
|
|
||||||
|
|
||||||
0 - No source validation.
|
0 - No source validation.
|
||||||
|
1 - Strict mode as defined in RFC3704 Strict Reverse Path
|
||||||
|
Each incoming packet is tested against the FIB and if the interface
|
||||||
|
is not the best reverse path the packet check will fail.
|
||||||
|
By default failed packets are discarded.
|
||||||
|
2 - Loose mode as defined in RFC3704 Loose Reverse Path
|
||||||
|
Each incoming packet's source address is also tested against the FIB
|
||||||
|
and if the source address is not reachable via any interface
|
||||||
|
the packet check will fail.
|
||||||
|
|
||||||
conf/all/rp_filter must also be set to TRUE to do source validation
|
Current recommended practice in RFC3704 is to enable strict mode
|
||||||
|
to prevent IP spoofing from DDos attacks. If using asymmetric routing
|
||||||
|
or other complicated routing, then loose mode is recommended.
|
||||||
|
|
||||||
|
conf/all/rp_filter must also be set to non-zero to do source validation
|
||||||
on the interface
|
on the interface
|
||||||
|
|
||||||
Default value is 0. Note that some distributions enable it
|
Default value is 0. Note that some distributions enable it
|
||||||
|
@ -782,6 +788,12 @@ arp_ignore - INTEGER
|
||||||
The max value from conf/{all,interface}/arp_ignore is used
|
The max value from conf/{all,interface}/arp_ignore is used
|
||||||
when ARP request is received on the {interface}
|
when ARP request is received on the {interface}
|
||||||
|
|
||||||
|
arp_notify - BOOLEAN
|
||||||
|
Define mode for notification of address and device changes.
|
||||||
|
0 - (default): do nothing
|
||||||
|
1 - Generate gratuitous arp replies when device is brought up
|
||||||
|
or hardware address changes.
|
||||||
|
|
||||||
arp_accept - BOOLEAN
|
arp_accept - BOOLEAN
|
||||||
Define behavior when gratuitous arp replies are received:
|
Define behavior when gratuitous arp replies are received:
|
||||||
0 - drop gratuitous arp frames
|
0 - drop gratuitous arp frames
|
||||||
|
@ -1031,7 +1043,9 @@ max_addresses - INTEGER
|
||||||
Default: 16
|
Default: 16
|
||||||
|
|
||||||
disable_ipv6 - BOOLEAN
|
disable_ipv6 - BOOLEAN
|
||||||
Disable IPv6 operation.
|
Disable IPv6 operation. If accept_dad is set to 2, this value
|
||||||
|
will be dynamically set to TRUE if DAD fails for the link-local
|
||||||
|
address.
|
||||||
Default: FALSE (enable IPv6 operation)
|
Default: FALSE (enable IPv6 operation)
|
||||||
|
|
||||||
accept_dad - INTEGER
|
accept_dad - INTEGER
|
||||||
|
|
|
@ -0,0 +1,199 @@
|
||||||
|
Linux Base Driver for 10 Gigabit PCI Express Intel(R) Network Connection
|
||||||
|
========================================================================
|
||||||
|
|
||||||
|
March 10, 2009
|
||||||
|
|
||||||
|
|
||||||
|
Contents
|
||||||
|
========
|
||||||
|
|
||||||
|
- In This Release
|
||||||
|
- Identifying Your Adapter
|
||||||
|
- Building and Installation
|
||||||
|
- Additional Configurations
|
||||||
|
- Support
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
In This Release
|
||||||
|
===============
|
||||||
|
|
||||||
|
This file describes the ixgbe Linux Base Driver for the 10 Gigabit PCI
|
||||||
|
Express 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 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
|
||||||
|
- Generic Receive Offload
|
||||||
|
- Data Center Bridging
|
||||||
|
|
||||||
|
Channel Bonding documentation can be found in the Linux kernel source:
|
||||||
|
/Documentation/networking/bonding.txt
|
||||||
|
|
||||||
|
Ethtool, lspci, and ifconfig can be used to display device and driver
|
||||||
|
specific information.
|
||||||
|
|
||||||
|
|
||||||
|
Identifying Your Adapter
|
||||||
|
========================
|
||||||
|
|
||||||
|
This driver supports devices based on the 82598 controller and the 82599
|
||||||
|
controller.
|
||||||
|
|
||||||
|
For specific information on identifying which adapter you have, please visit:
|
||||||
|
|
||||||
|
http://support.intel.com/support/network/sb/CS-008441.htm
|
||||||
|
|
||||||
|
|
||||||
|
Building and Installation
|
||||||
|
=========================
|
||||||
|
|
||||||
|
select m for "Intel(R) 10GbE PCI Express adapters 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 ixgbe
|
||||||
|
|
||||||
|
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/ixgbe/ixgbe.ko
|
||||||
|
|
||||||
|
With 2.6 based kernels also make sure that older ixgbe drivers are
|
||||||
|
removed from the kernel, before loading the new module:
|
||||||
|
|
||||||
|
rmmod ixgbe; modprobe ixgbe
|
||||||
|
|
||||||
|
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>
|
||||||
|
|
||||||
|
|
||||||
|
Additional Configurations
|
||||||
|
=========================
|
||||||
|
|
||||||
|
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 16110. Use the ifconfig command to
|
||||||
|
increase the MTU size. For example:
|
||||||
|
|
||||||
|
ifconfig ethx mtu 9000 up
|
||||||
|
|
||||||
|
The maximum MTU setting for Jumbo Frames is 16110. This value coincides
|
||||||
|
with the maximum Jumbo Frames size of 16128.
|
||||||
|
|
||||||
|
Generic Receive Offload, aka GRO
|
||||||
|
--------------------------------
|
||||||
|
The driver supports the in-kernel software implementation of GRO. GRO has
|
||||||
|
shown that by coalescing Rx traffic into larger chunks of data, CPU
|
||||||
|
utilization can be significantly reduced when under large Rx load. GRO is an
|
||||||
|
evolution of the previously-used LRO interface. GRO is able to coalesce
|
||||||
|
other protocols besides TCP. It's also safe to use with configurations that
|
||||||
|
are problematic for LRO, namely bridging and iSCSI.
|
||||||
|
|
||||||
|
GRO is enabled by default in the driver. Future versions of ethtool will
|
||||||
|
support disabling and re-enabling GRO on the fly.
|
||||||
|
|
||||||
|
|
||||||
|
Data Center Bridging, aka DCB
|
||||||
|
-----------------------------
|
||||||
|
|
||||||
|
DCB is a configuration Quality of Service implementation in hardware.
|
||||||
|
It uses the VLAN priority tag (802.1p) to filter traffic. That means
|
||||||
|
that there are 8 different priorities that traffic can be filtered into.
|
||||||
|
It also enables priority flow control which can limit or eliminate the
|
||||||
|
number of dropped packets during network stress. Bandwidth can be
|
||||||
|
allocated to each of these priorities, which is enforced at the hardware
|
||||||
|
level.
|
||||||
|
|
||||||
|
To enable DCB support in ixgbe, you must enable the DCB netlink layer to
|
||||||
|
allow the userspace tools (see below) to communicate with the driver.
|
||||||
|
This can be found in the kernel configuration here:
|
||||||
|
|
||||||
|
-> Networking support
|
||||||
|
-> Networking options
|
||||||
|
-> Data Center Bridging support
|
||||||
|
|
||||||
|
Once this is selected, DCB support must be selected for ixgbe. This can
|
||||||
|
be found here:
|
||||||
|
|
||||||
|
-> Device Drivers
|
||||||
|
-> Network device support (NETDEVICES [=y])
|
||||||
|
-> Ethernet (10000 Mbit) (NETDEV_10000 [=y])
|
||||||
|
-> Intel(R) 10GbE PCI Express adapters support
|
||||||
|
-> Data Center Bridging (DCB) Support
|
||||||
|
|
||||||
|
After these options are selected, you must rebuild your kernel and your
|
||||||
|
modules.
|
||||||
|
|
||||||
|
In order to use DCB, userspace tools must be downloaded and installed.
|
||||||
|
The dcbd tools can be found at:
|
||||||
|
|
||||||
|
http://e1000.sf.net
|
||||||
|
|
||||||
|
|
||||||
|
Ethtool
|
||||||
|
-------
|
||||||
|
The driver utilizes the ethtool interface for driver configuration and
|
||||||
|
diagnostics, as well as displaying statistical information. Ethtool
|
||||||
|
version 3.0 or later is required for this functionality.
|
||||||
|
|
||||||
|
The latest release of ethtool can be found from
|
||||||
|
http://sourceforge.net/projects/gkernel.
|
||||||
|
|
||||||
|
|
||||||
|
NAPI
|
||||||
|
----
|
||||||
|
|
||||||
|
NAPI (Rx polling mode) is supported in the ixgbe driver. NAPI is enabled
|
||||||
|
by default in the driver.
|
||||||
|
|
||||||
|
See www.cyberus.ca/~hadi/usenix-paper.tgz for more information on NAPI.
|
||||||
|
|
||||||
|
|
||||||
|
Support
|
||||||
|
=======
|
||||||
|
|
||||||
|
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://e1000.sourceforge.net
|
||||||
|
|
||||||
|
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 e1000-devel@lists.sf.net
|
|
@ -0,0 +1,356 @@
|
||||||
|
|
||||||
|
Overview
|
||||||
|
========
|
||||||
|
|
||||||
|
This readme tries to provide some background on the hows and whys of RDS,
|
||||||
|
and will hopefully help you find your way around the code.
|
||||||
|
|
||||||
|
In addition, please see this email about RDS origins:
|
||||||
|
http://oss.oracle.com/pipermail/rds-devel/2007-November/000228.html
|
||||||
|
|
||||||
|
RDS Architecture
|
||||||
|
================
|
||||||
|
|
||||||
|
RDS provides reliable, ordered datagram delivery by using a single
|
||||||
|
reliable connection between any two nodes in the cluster. This allows
|
||||||
|
applications to use a single socket to talk to any other process in the
|
||||||
|
cluster - so in a cluster with N processes you need N sockets, in contrast
|
||||||
|
to N*N if you use a connection-oriented socket transport like TCP.
|
||||||
|
|
||||||
|
RDS is not Infiniband-specific; it was designed to support different
|
||||||
|
transports. The current implementation used to support RDS over TCP as well
|
||||||
|
as IB. Work is in progress to support RDS over iWARP, and using DCE to
|
||||||
|
guarantee no dropped packets on Ethernet, it may be possible to use RDS over
|
||||||
|
UDP in the future.
|
||||||
|
|
||||||
|
The high-level semantics of RDS from the application's point of view are
|
||||||
|
|
||||||
|
* Addressing
|
||||||
|
RDS uses IPv4 addresses and 16bit port numbers to identify
|
||||||
|
the end point of a connection. All socket operations that involve
|
||||||
|
passing addresses between kernel and user space generally
|
||||||
|
use a struct sockaddr_in.
|
||||||
|
|
||||||
|
The fact that IPv4 addresses are used does not mean the underlying
|
||||||
|
transport has to be IP-based. In fact, RDS over IB uses a
|
||||||
|
reliable IB connection; the IP address is used exclusively to
|
||||||
|
locate the remote node's GID (by ARPing for the given IP).
|
||||||
|
|
||||||
|
The port space is entirely independent of UDP, TCP or any other
|
||||||
|
protocol.
|
||||||
|
|
||||||
|
* Socket interface
|
||||||
|
RDS sockets work *mostly* as you would expect from a BSD
|
||||||
|
socket. The next section will cover the details. At any rate,
|
||||||
|
all I/O is performed through the standard BSD socket API.
|
||||||
|
Some additions like zerocopy support are implemented through
|
||||||
|
control messages, while other extensions use the getsockopt/
|
||||||
|
setsockopt calls.
|
||||||
|
|
||||||
|
Sockets must be bound before you can send or receive data.
|
||||||
|
This is needed because binding also selects a transport and
|
||||||
|
attaches it to the socket. Once bound, the transport assignment
|
||||||
|
does not change. RDS will tolerate IPs moving around (eg in
|
||||||
|
a active-active HA scenario), but only as long as the address
|
||||||
|
doesn't move to a different transport.
|
||||||
|
|
||||||
|
* sysctls
|
||||||
|
RDS supports a number of sysctls in /proc/sys/net/rds
|
||||||
|
|
||||||
|
|
||||||
|
Socket Interface
|
||||||
|
================
|
||||||
|
|
||||||
|
AF_RDS, PF_RDS, SOL_RDS
|
||||||
|
These constants haven't been assigned yet, because RDS isn't in
|
||||||
|
mainline yet. Currently, the kernel module assigns some constant
|
||||||
|
and publishes it to user space through two sysctl files
|
||||||
|
/proc/sys/net/rds/pf_rds
|
||||||
|
/proc/sys/net/rds/sol_rds
|
||||||
|
|
||||||
|
fd = socket(PF_RDS, SOCK_SEQPACKET, 0);
|
||||||
|
This creates a new, unbound RDS socket.
|
||||||
|
|
||||||
|
setsockopt(SOL_SOCKET): send and receive buffer size
|
||||||
|
RDS honors the send and receive buffer size socket options.
|
||||||
|
You are not allowed to queue more than SO_SNDSIZE bytes to
|
||||||
|
a socket. A message is queued when sendmsg is called, and
|
||||||
|
it leaves the queue when the remote system acknowledges
|
||||||
|
its arrival.
|
||||||
|
|
||||||
|
The SO_RCVSIZE option controls the maximum receive queue length.
|
||||||
|
This is a soft limit rather than a hard limit - RDS will
|
||||||
|
continue to accept and queue incoming messages, even if that
|
||||||
|
takes the queue length over the limit. However, it will also
|
||||||
|
mark the port as "congested" and send a congestion update to
|
||||||
|
the source node. The source node is supposed to throttle any
|
||||||
|
processes sending to this congested port.
|
||||||
|
|
||||||
|
bind(fd, &sockaddr_in, ...)
|
||||||
|
This binds the socket to a local IP address and port, and a
|
||||||
|
transport.
|
||||||
|
|
||||||
|
sendmsg(fd, ...)
|
||||||
|
Sends a message to the indicated recipient. The kernel will
|
||||||
|
transparently establish the underlying reliable connection
|
||||||
|
if it isn't up yet.
|
||||||
|
|
||||||
|
An attempt to send a message that exceeds SO_SNDSIZE will
|
||||||
|
return with -EMSGSIZE
|
||||||
|
|
||||||
|
An attempt to send a message that would take the total number
|
||||||
|
of queued bytes over the SO_SNDSIZE threshold will return
|
||||||
|
EAGAIN.
|
||||||
|
|
||||||
|
An attempt to send a message to a destination that is marked
|
||||||
|
as "congested" will return ENOBUFS.
|
||||||
|
|
||||||
|
recvmsg(fd, ...)
|
||||||
|
Receives a message that was queued to this socket. The sockets
|
||||||
|
recv queue accounting is adjusted, and if the queue length
|
||||||
|
drops below SO_SNDSIZE, the port is marked uncongested, and
|
||||||
|
a congestion update is sent to all peers.
|
||||||
|
|
||||||
|
Applications can ask the RDS kernel module to receive
|
||||||
|
notifications via control messages (for instance, there is a
|
||||||
|
notification when a congestion update arrived, or when a RDMA
|
||||||
|
operation completes). These notifications are received through
|
||||||
|
the msg.msg_control buffer of struct msghdr. The format of the
|
||||||
|
messages is described in manpages.
|
||||||
|
|
||||||
|
poll(fd)
|
||||||
|
RDS supports the poll interface to allow the application
|
||||||
|
to implement async I/O.
|
||||||
|
|
||||||
|
POLLIN handling is pretty straightforward. When there's an
|
||||||
|
incoming message queued to the socket, or a pending notification,
|
||||||
|
we signal POLLIN.
|
||||||
|
|
||||||
|
POLLOUT is a little harder. Since you can essentially send
|
||||||
|
to any destination, RDS will always signal POLLOUT as long as
|
||||||
|
there's room on the send queue (ie the number of bytes queued
|
||||||
|
is less than the sendbuf size).
|
||||||
|
|
||||||
|
However, the kernel will refuse to accept messages to
|
||||||
|
a destination marked congested - in this case you will loop
|
||||||
|
forever if you rely on poll to tell you what to do.
|
||||||
|
This isn't a trivial problem, but applications can deal with
|
||||||
|
this - by using congestion notifications, and by checking for
|
||||||
|
ENOBUFS errors returned by sendmsg.
|
||||||
|
|
||||||
|
setsockopt(SOL_RDS, RDS_CANCEL_SENT_TO, &sockaddr_in)
|
||||||
|
This allows the application to discard all messages queued to a
|
||||||
|
specific destination on this particular socket.
|
||||||
|
|
||||||
|
This allows the application to cancel outstanding messages if
|
||||||
|
it detects a timeout. For instance, if it tried to send a message,
|
||||||
|
and the remote host is unreachable, RDS will keep trying forever.
|
||||||
|
The application may decide it's not worth it, and cancel the
|
||||||
|
operation. In this case, it would use RDS_CANCEL_SENT_TO to
|
||||||
|
nuke any pending messages.
|
||||||
|
|
||||||
|
|
||||||
|
RDMA for RDS
|
||||||
|
============
|
||||||
|
|
||||||
|
see rds-rdma(7) manpage (available in rds-tools)
|
||||||
|
|
||||||
|
|
||||||
|
Congestion Notifications
|
||||||
|
========================
|
||||||
|
|
||||||
|
see rds(7) manpage
|
||||||
|
|
||||||
|
|
||||||
|
RDS Protocol
|
||||||
|
============
|
||||||
|
|
||||||
|
Message header
|
||||||
|
|
||||||
|
The message header is a 'struct rds_header' (see rds.h):
|
||||||
|
Fields:
|
||||||
|
h_sequence:
|
||||||
|
per-packet sequence number
|
||||||
|
h_ack:
|
||||||
|
piggybacked acknowledgment of last packet received
|
||||||
|
h_len:
|
||||||
|
length of data, not including header
|
||||||
|
h_sport:
|
||||||
|
source port
|
||||||
|
h_dport:
|
||||||
|
destination port
|
||||||
|
h_flags:
|
||||||
|
CONG_BITMAP - this is a congestion update bitmap
|
||||||
|
ACK_REQUIRED - receiver must ack this packet
|
||||||
|
RETRANSMITTED - packet has previously been sent
|
||||||
|
h_credit:
|
||||||
|
indicate to other end of connection that
|
||||||
|
it has more credits available (i.e. there is
|
||||||
|
more send room)
|
||||||
|
h_padding[4]:
|
||||||
|
unused, for future use
|
||||||
|
h_csum:
|
||||||
|
header checksum
|
||||||
|
h_exthdr:
|
||||||
|
optional data can be passed here. This is currently used for
|
||||||
|
passing RDMA-related information.
|
||||||
|
|
||||||
|
ACK and retransmit handling
|
||||||
|
|
||||||
|
One might think that with reliable IB connections you wouldn't need
|
||||||
|
to ack messages that have been received. The problem is that IB
|
||||||
|
hardware generates an ack message before it has DMAed the message
|
||||||
|
into memory. This creates a potential message loss if the HCA is
|
||||||
|
disabled for any reason between when it sends the ack and before
|
||||||
|
the message is DMAed and processed. This is only a potential issue
|
||||||
|
if another HCA is available for fail-over.
|
||||||
|
|
||||||
|
Sending an ack immediately would allow the sender to free the sent
|
||||||
|
message from their send queue quickly, but could cause excessive
|
||||||
|
traffic to be used for acks. RDS piggybacks acks on sent data
|
||||||
|
packets. Ack-only packets are reduced by only allowing one to be
|
||||||
|
in flight at a time, and by the sender only asking for acks when
|
||||||
|
its send buffers start to fill up. All retransmissions are also
|
||||||
|
acked.
|
||||||
|
|
||||||
|
Flow Control
|
||||||
|
|
||||||
|
RDS's IB transport uses a credit-based mechanism to verify that
|
||||||
|
there is space in the peer's receive buffers for more data. This
|
||||||
|
eliminates the need for hardware retries on the connection.
|
||||||
|
|
||||||
|
Congestion
|
||||||
|
|
||||||
|
Messages waiting in the receive queue on the receiving socket
|
||||||
|
are accounted against the sockets SO_RCVBUF option value. Only
|
||||||
|
the payload bytes in the message are accounted for. If the
|
||||||
|
number of bytes queued equals or exceeds rcvbuf then the socket
|
||||||
|
is congested. All sends attempted to this socket's address
|
||||||
|
should return block or return -EWOULDBLOCK.
|
||||||
|
|
||||||
|
Applications are expected to be reasonably tuned such that this
|
||||||
|
situation very rarely occurs. An application encountering this
|
||||||
|
"back-pressure" is considered a bug.
|
||||||
|
|
||||||
|
This is implemented by having each node maintain bitmaps which
|
||||||
|
indicate which ports on bound addresses are congested. As the
|
||||||
|
bitmap changes it is sent through all the connections which
|
||||||
|
terminate in the local address of the bitmap which changed.
|
||||||
|
|
||||||
|
The bitmaps are allocated as connections are brought up. This
|
||||||
|
avoids allocation in the interrupt handling path which queues
|
||||||
|
sages on sockets. The dense bitmaps let transports send the
|
||||||
|
entire bitmap on any bitmap change reasonably efficiently. This
|
||||||
|
is much easier to implement than some finer-grained
|
||||||
|
communication of per-port congestion. The sender does a very
|
||||||
|
inexpensive bit test to test if the port it's about to send to
|
||||||
|
is congested or not.
|
||||||
|
|
||||||
|
|
||||||
|
RDS Transport Layer
|
||||||
|
==================
|
||||||
|
|
||||||
|
As mentioned above, RDS is not IB-specific. Its code is divided
|
||||||
|
into a general RDS layer and a transport layer.
|
||||||
|
|
||||||
|
The general layer handles the socket API, congestion handling,
|
||||||
|
loopback, stats, usermem pinning, and the connection state machine.
|
||||||
|
|
||||||
|
The transport layer handles the details of the transport. The IB
|
||||||
|
transport, for example, handles all the queue pairs, work requests,
|
||||||
|
CM event handlers, and other Infiniband details.
|
||||||
|
|
||||||
|
|
||||||
|
RDS Kernel Structures
|
||||||
|
=====================
|
||||||
|
|
||||||
|
struct rds_message
|
||||||
|
aka possibly "rds_outgoing", the generic RDS layer copies data to
|
||||||
|
be sent and sets header fields as needed, based on the socket API.
|
||||||
|
This is then queued for the individual connection and sent by the
|
||||||
|
connection's transport.
|
||||||
|
struct rds_incoming
|
||||||
|
a generic struct referring to incoming data that can be handed from
|
||||||
|
the transport to the general code and queued by the general code
|
||||||
|
while the socket is awoken. It is then passed back to the transport
|
||||||
|
code to handle the actual copy-to-user.
|
||||||
|
struct rds_socket
|
||||||
|
per-socket information
|
||||||
|
struct rds_connection
|
||||||
|
per-connection information
|
||||||
|
struct rds_transport
|
||||||
|
pointers to transport-specific functions
|
||||||
|
struct rds_statistics
|
||||||
|
non-transport-specific statistics
|
||||||
|
struct rds_cong_map
|
||||||
|
wraps the raw congestion bitmap, contains rbnode, waitq, etc.
|
||||||
|
|
||||||
|
Connection management
|
||||||
|
=====================
|
||||||
|
|
||||||
|
Connections may be in UP, DOWN, CONNECTING, DISCONNECTING, and
|
||||||
|
ERROR states.
|
||||||
|
|
||||||
|
The first time an attempt is made by an RDS socket to send data to
|
||||||
|
a node, a connection is allocated and connected. That connection is
|
||||||
|
then maintained forever -- if there are transport errors, the
|
||||||
|
connection will be dropped and re-established.
|
||||||
|
|
||||||
|
Dropping a connection while packets are queued will cause queued or
|
||||||
|
partially-sent datagrams to be retransmitted when the connection is
|
||||||
|
re-established.
|
||||||
|
|
||||||
|
|
||||||
|
The send path
|
||||||
|
=============
|
||||||
|
|
||||||
|
rds_sendmsg()
|
||||||
|
struct rds_message built from incoming data
|
||||||
|
CMSGs parsed (e.g. RDMA ops)
|
||||||
|
transport connection alloced and connected if not already
|
||||||
|
rds_message placed on send queue
|
||||||
|
send worker awoken
|
||||||
|
rds_send_worker()
|
||||||
|
calls rds_send_xmit() until queue is empty
|
||||||
|
rds_send_xmit()
|
||||||
|
transmits congestion map if one is pending
|
||||||
|
may set ACK_REQUIRED
|
||||||
|
calls transport to send either non-RDMA or RDMA message
|
||||||
|
(RDMA ops never retransmitted)
|
||||||
|
rds_ib_xmit()
|
||||||
|
allocs work requests from send ring
|
||||||
|
adds any new send credits available to peer (h_credits)
|
||||||
|
maps the rds_message's sg list
|
||||||
|
piggybacks ack
|
||||||
|
populates work requests
|
||||||
|
post send to connection's queue pair
|
||||||
|
|
||||||
|
The recv path
|
||||||
|
=============
|
||||||
|
|
||||||
|
rds_ib_recv_cq_comp_handler()
|
||||||
|
looks at write completions
|
||||||
|
unmaps recv buffer from device
|
||||||
|
no errors, call rds_ib_process_recv()
|
||||||
|
refill recv ring
|
||||||
|
rds_ib_process_recv()
|
||||||
|
validate header checksum
|
||||||
|
copy header to rds_ib_incoming struct if start of a new datagram
|
||||||
|
add to ibinc's fraglist
|
||||||
|
if competed datagram:
|
||||||
|
update cong map if datagram was cong update
|
||||||
|
call rds_recv_incoming() otherwise
|
||||||
|
note if ack is required
|
||||||
|
rds_recv_incoming()
|
||||||
|
drop duplicate packets
|
||||||
|
respond to pings
|
||||||
|
find the sock associated with this datagram
|
||||||
|
add to sock queue
|
||||||
|
wake up sock
|
||||||
|
do some congestion calculations
|
||||||
|
rds_recvmsg
|
||||||
|
copy data into user iovec
|
||||||
|
handle CMSGs
|
||||||
|
return to application
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,180 @@
|
||||||
|
The existing interfaces for getting network packages time stamped are:
|
||||||
|
|
||||||
|
* SO_TIMESTAMP
|
||||||
|
Generate time stamp for each incoming packet using the (not necessarily
|
||||||
|
monotonous!) system time. Result is returned via recv_msg() in a
|
||||||
|
control message as timeval (usec resolution).
|
||||||
|
|
||||||
|
* SO_TIMESTAMPNS
|
||||||
|
Same time stamping mechanism as SO_TIMESTAMP, but returns result as
|
||||||
|
timespec (nsec resolution).
|
||||||
|
|
||||||
|
* IP_MULTICAST_LOOP + SO_TIMESTAMP[NS]
|
||||||
|
Only for multicasts: approximate send time stamp by receiving the looped
|
||||||
|
packet and using its receive time stamp.
|
||||||
|
|
||||||
|
The following interface complements the existing ones: receive time
|
||||||
|
stamps can be generated and returned for arbitrary packets and much
|
||||||
|
closer to the point where the packet is really sent. Time stamps can
|
||||||
|
be generated in software (as before) or in hardware (if the hardware
|
||||||
|
has such a feature).
|
||||||
|
|
||||||
|
SO_TIMESTAMPING:
|
||||||
|
|
||||||
|
Instructs the socket layer which kind of information is wanted. The
|
||||||
|
parameter is an integer with some of the following bits set. Setting
|
||||||
|
other bits is an error and doesn't change the current state.
|
||||||
|
|
||||||
|
SOF_TIMESTAMPING_TX_HARDWARE: try to obtain send time stamp in hardware
|
||||||
|
SOF_TIMESTAMPING_TX_SOFTWARE: if SOF_TIMESTAMPING_TX_HARDWARE is off or
|
||||||
|
fails, then do it in software
|
||||||
|
SOF_TIMESTAMPING_RX_HARDWARE: return the original, unmodified time stamp
|
||||||
|
as generated by the hardware
|
||||||
|
SOF_TIMESTAMPING_RX_SOFTWARE: if SOF_TIMESTAMPING_RX_HARDWARE is off or
|
||||||
|
fails, then do it in software
|
||||||
|
SOF_TIMESTAMPING_RAW_HARDWARE: return original raw hardware time stamp
|
||||||
|
SOF_TIMESTAMPING_SYS_HARDWARE: return hardware time stamp transformed to
|
||||||
|
the system time base
|
||||||
|
SOF_TIMESTAMPING_SOFTWARE: return system time stamp generated in
|
||||||
|
software
|
||||||
|
|
||||||
|
SOF_TIMESTAMPING_TX/RX determine how time stamps are generated.
|
||||||
|
SOF_TIMESTAMPING_RAW/SYS determine how they are reported in the
|
||||||
|
following control message:
|
||||||
|
struct scm_timestamping {
|
||||||
|
struct timespec systime;
|
||||||
|
struct timespec hwtimetrans;
|
||||||
|
struct timespec hwtimeraw;
|
||||||
|
};
|
||||||
|
|
||||||
|
recvmsg() can be used to get this control message for regular incoming
|
||||||
|
packets. For send time stamps the outgoing packet is looped back to
|
||||||
|
the socket's error queue with the send time stamp(s) attached. It can
|
||||||
|
be received with recvmsg(flags=MSG_ERRQUEUE). The call returns the
|
||||||
|
original outgoing packet data including all headers preprended down to
|
||||||
|
and including the link layer, the scm_timestamping control message and
|
||||||
|
a sock_extended_err control message with ee_errno==ENOMSG and
|
||||||
|
ee_origin==SO_EE_ORIGIN_TIMESTAMPING. A socket with such a pending
|
||||||
|
bounced packet is ready for reading as far as select() is concerned.
|
||||||
|
If the outgoing packet has to be fragmented, then only the first
|
||||||
|
fragment is time stamped and returned to the sending socket.
|
||||||
|
|
||||||
|
All three values correspond to the same event in time, but were
|
||||||
|
generated in different ways. Each of these values may be empty (= all
|
||||||
|
zero), in which case no such value was available. If the application
|
||||||
|
is not interested in some of these values, they can be left blank to
|
||||||
|
avoid the potential overhead of calculating them.
|
||||||
|
|
||||||
|
systime is the value of the system time at that moment. This
|
||||||
|
corresponds to the value also returned via SO_TIMESTAMP[NS]. If the
|
||||||
|
time stamp was generated by hardware, then this field is
|
||||||
|
empty. Otherwise it is filled in if SOF_TIMESTAMPING_SOFTWARE is
|
||||||
|
set.
|
||||||
|
|
||||||
|
hwtimeraw is the original hardware time stamp. Filled in if
|
||||||
|
SOF_TIMESTAMPING_RAW_HARDWARE is set. No assumptions about its
|
||||||
|
relation to system time should be made.
|
||||||
|
|
||||||
|
hwtimetrans is the hardware time stamp transformed so that it
|
||||||
|
corresponds as good as possible to system time. This correlation is
|
||||||
|
not perfect; as a consequence, sorting packets received via different
|
||||||
|
NICs by their hwtimetrans may differ from the order in which they were
|
||||||
|
received. hwtimetrans may be non-monotonic even for the same NIC.
|
||||||
|
Filled in if SOF_TIMESTAMPING_SYS_HARDWARE is set. Requires support
|
||||||
|
by the network device and will be empty without that support.
|
||||||
|
|
||||||
|
|
||||||
|
SIOCSHWTSTAMP:
|
||||||
|
|
||||||
|
Hardware time stamping must also be initialized for each device driver
|
||||||
|
that is expected to do hardware time stamping. The parameter is:
|
||||||
|
|
||||||
|
struct hwtstamp_config {
|
||||||
|
int flags; /* no flags defined right now, must be zero */
|
||||||
|
int tx_type; /* HWTSTAMP_TX_* */
|
||||||
|
int rx_filter; /* HWTSTAMP_FILTER_* */
|
||||||
|
};
|
||||||
|
|
||||||
|
Desired behavior is passed into the kernel and to a specific device by
|
||||||
|
calling ioctl(SIOCSHWTSTAMP) with a pointer to a struct ifreq whose
|
||||||
|
ifr_data points to a struct hwtstamp_config. The tx_type and
|
||||||
|
rx_filter are hints to the driver what it is expected to do. If
|
||||||
|
the requested fine-grained filtering for incoming packets is not
|
||||||
|
supported, the driver may time stamp more than just the requested types
|
||||||
|
of packets.
|
||||||
|
|
||||||
|
A driver which supports hardware time stamping shall update the struct
|
||||||
|
with the actual, possibly more permissive configuration. If the
|
||||||
|
requested packets cannot be time stamped, then nothing should be
|
||||||
|
changed and ERANGE shall be returned (in contrast to EINVAL, which
|
||||||
|
indicates that SIOCSHWTSTAMP is not supported at all).
|
||||||
|
|
||||||
|
Only a processes with admin rights may change the configuration. User
|
||||||
|
space is responsible to ensure that multiple processes don't interfere
|
||||||
|
with each other and that the settings are reset.
|
||||||
|
|
||||||
|
/* possible values for hwtstamp_config->tx_type */
|
||||||
|
enum {
|
||||||
|
/*
|
||||||
|
* no outgoing packet will need hardware time stamping;
|
||||||
|
* should a packet arrive which asks for it, no hardware
|
||||||
|
* time stamping will be done
|
||||||
|
*/
|
||||||
|
HWTSTAMP_TX_OFF,
|
||||||
|
|
||||||
|
/*
|
||||||
|
* enables hardware time stamping for outgoing packets;
|
||||||
|
* the sender of the packet decides which are to be
|
||||||
|
* time stamped by setting SOF_TIMESTAMPING_TX_SOFTWARE
|
||||||
|
* before sending the packet
|
||||||
|
*/
|
||||||
|
HWTSTAMP_TX_ON,
|
||||||
|
};
|
||||||
|
|
||||||
|
/* possible values for hwtstamp_config->rx_filter */
|
||||||
|
enum {
|
||||||
|
/* time stamp no incoming packet at all */
|
||||||
|
HWTSTAMP_FILTER_NONE,
|
||||||
|
|
||||||
|
/* time stamp any incoming packet */
|
||||||
|
HWTSTAMP_FILTER_ALL,
|
||||||
|
|
||||||
|
/* return value: time stamp all packets requested plus some others */
|
||||||
|
HWTSTAMP_FILTER_SOME,
|
||||||
|
|
||||||
|
/* PTP v1, UDP, any kind of event packet */
|
||||||
|
HWTSTAMP_FILTER_PTP_V1_L4_EVENT,
|
||||||
|
|
||||||
|
...
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
DEVICE IMPLEMENTATION
|
||||||
|
|
||||||
|
A driver which supports hardware time stamping must support the
|
||||||
|
SIOCSHWTSTAMP ioctl. Time stamps for received packets must be stored
|
||||||
|
in the skb with skb_hwtstamp_set().
|
||||||
|
|
||||||
|
Time stamps for outgoing packets are to be generated as follows:
|
||||||
|
- In hard_start_xmit(), check if skb_hwtstamp_check_tx_hardware()
|
||||||
|
returns non-zero. If yes, then the driver is expected
|
||||||
|
to do hardware time stamping.
|
||||||
|
- If this is possible for the skb and requested, then declare
|
||||||
|
that the driver is doing the time stamping by calling
|
||||||
|
skb_hwtstamp_tx_in_progress(). A driver not supporting
|
||||||
|
hardware time stamping doesn't do that. A driver must never
|
||||||
|
touch sk_buff::tstamp! It is used to store how time stamping
|
||||||
|
for an outgoing packets is to be done.
|
||||||
|
- As soon as the driver has sent the packet and/or obtained a
|
||||||
|
hardware time stamp for it, it passes the time stamp back by
|
||||||
|
calling skb_hwtstamp_tx() with the original skb, the raw
|
||||||
|
hardware time stamp and a handle to the device (necessary
|
||||||
|
to convert the hardware time stamp to system time). If obtaining
|
||||||
|
the hardware time stamp somehow fails, then the driver should
|
||||||
|
not fall back to software time stamping. The rationale is that
|
||||||
|
this would occur at a later time in the processing pipeline
|
||||||
|
than other software time stamping and therefore could lead
|
||||||
|
to unexpected deltas between time stamps.
|
||||||
|
- If the driver did not call skb_hwtstamp_tx_in_progress(), then
|
||||||
|
dev_hard_start_xmit() checks whether software time stamping
|
||||||
|
is wanted as fallback and potentially generates the time stamp.
|
|
@ -0,0 +1 @@
|
||||||
|
timestamping
|
|
@ -0,0 +1,6 @@
|
||||||
|
CPPFLAGS = -I../../../include
|
||||||
|
|
||||||
|
timestamping: timestamping.c
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -f timestamping
|
|
@ -0,0 +1,533 @@
|
||||||
|
/*
|
||||||
|
* This program demonstrates how the various time stamping features in
|
||||||
|
* the Linux kernel work. It emulates the behavior of a PTP
|
||||||
|
* implementation in stand-alone master mode by sending PTPv1 Sync
|
||||||
|
* multicasts once every second. It looks for similar packets, but
|
||||||
|
* beyond that doesn't actually implement PTP.
|
||||||
|
*
|
||||||
|
* Outgoing packets are time stamped with SO_TIMESTAMPING with or
|
||||||
|
* without hardware support.
|
||||||
|
*
|
||||||
|
* Incoming packets are time stamped with SO_TIMESTAMPING with or
|
||||||
|
* without hardware support, SIOCGSTAMP[NS] (per-socket time stamp) and
|
||||||
|
* SO_TIMESTAMP[NS].
|
||||||
|
*
|
||||||
|
* Copyright (C) 2009 Intel Corporation.
|
||||||
|
* Author: Patrick Ohly <patrick.ohly@intel.com>
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms and conditions 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.,
|
||||||
|
* 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include <sys/time.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <sys/select.h>
|
||||||
|
#include <sys/ioctl.h>
|
||||||
|
#include <arpa/inet.h>
|
||||||
|
#include <net/if.h>
|
||||||
|
|
||||||
|
#include "asm/types.h"
|
||||||
|
#include "linux/net_tstamp.h"
|
||||||
|
#include "linux/errqueue.h"
|
||||||
|
|
||||||
|
#ifndef SO_TIMESTAMPING
|
||||||
|
# define SO_TIMESTAMPING 37
|
||||||
|
# define SCM_TIMESTAMPING SO_TIMESTAMPING
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef SO_TIMESTAMPNS
|
||||||
|
# define SO_TIMESTAMPNS 35
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef SIOCGSTAMPNS
|
||||||
|
# define SIOCGSTAMPNS 0x8907
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef SIOCSHWTSTAMP
|
||||||
|
# define SIOCSHWTSTAMP 0x89b0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static void usage(const char *error)
|
||||||
|
{
|
||||||
|
if (error)
|
||||||
|
printf("invalid option: %s\n", error);
|
||||||
|
printf("timestamping interface option*\n\n"
|
||||||
|
"Options:\n"
|
||||||
|
" IP_MULTICAST_LOOP - looping outgoing multicasts\n"
|
||||||
|
" SO_TIMESTAMP - normal software time stamping, ms resolution\n"
|
||||||
|
" SO_TIMESTAMPNS - more accurate software time stamping\n"
|
||||||
|
" SOF_TIMESTAMPING_TX_HARDWARE - hardware time stamping of outgoing packets\n"
|
||||||
|
" SOF_TIMESTAMPING_TX_SOFTWARE - software fallback for outgoing packets\n"
|
||||||
|
" SOF_TIMESTAMPING_RX_HARDWARE - hardware time stamping of incoming packets\n"
|
||||||
|
" SOF_TIMESTAMPING_RX_SOFTWARE - software fallback for incoming packets\n"
|
||||||
|
" SOF_TIMESTAMPING_SOFTWARE - request reporting of software time stamps\n"
|
||||||
|
" SOF_TIMESTAMPING_SYS_HARDWARE - request reporting of transformed HW time stamps\n"
|
||||||
|
" SOF_TIMESTAMPING_RAW_HARDWARE - request reporting of raw HW time stamps\n"
|
||||||
|
" SIOCGSTAMP - check last socket time stamp\n"
|
||||||
|
" SIOCGSTAMPNS - more accurate socket time stamp\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void bail(const char *error)
|
||||||
|
{
|
||||||
|
printf("%s: %s\n", error, strerror(errno));
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
static const unsigned char sync[] = {
|
||||||
|
0x00, 0x01, 0x00, 0x01,
|
||||||
|
0x5f, 0x44, 0x46, 0x4c,
|
||||||
|
0x54, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x01, 0x01,
|
||||||
|
|
||||||
|
/* fake uuid */
|
||||||
|
0x00, 0x01,
|
||||||
|
0x02, 0x03, 0x04, 0x05,
|
||||||
|
|
||||||
|
0x00, 0x01, 0x00, 0x37,
|
||||||
|
0x00, 0x00, 0x00, 0x08,
|
||||||
|
0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x49, 0x05, 0xcd, 0x01,
|
||||||
|
0x29, 0xb1, 0x8d, 0xb0,
|
||||||
|
0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x01,
|
||||||
|
|
||||||
|
/* fake uuid */
|
||||||
|
0x00, 0x01,
|
||||||
|
0x02, 0x03, 0x04, 0x05,
|
||||||
|
|
||||||
|
0x00, 0x00, 0x00, 0x37,
|
||||||
|
0x00, 0x00, 0x00, 0x04,
|
||||||
|
0x44, 0x46, 0x4c, 0x54,
|
||||||
|
0x00, 0x00, 0xf0, 0x60,
|
||||||
|
0x00, 0x01, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x01,
|
||||||
|
0x00, 0x00, 0xf0, 0x60,
|
||||||
|
0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x04,
|
||||||
|
0x44, 0x46, 0x4c, 0x54,
|
||||||
|
0x00, 0x01,
|
||||||
|
|
||||||
|
/* fake uuid */
|
||||||
|
0x00, 0x01,
|
||||||
|
0x02, 0x03, 0x04, 0x05,
|
||||||
|
|
||||||
|
0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00
|
||||||
|
};
|
||||||
|
|
||||||
|
static void sendpacket(int sock, struct sockaddr *addr, socklen_t addr_len)
|
||||||
|
{
|
||||||
|
struct timeval now;
|
||||||
|
int res;
|
||||||
|
|
||||||
|
res = sendto(sock, sync, sizeof(sync), 0,
|
||||||
|
addr, addr_len);
|
||||||
|
gettimeofday(&now, 0);
|
||||||
|
if (res < 0)
|
||||||
|
printf("%s: %s\n", "send", strerror(errno));
|
||||||
|
else
|
||||||
|
printf("%ld.%06ld: sent %d bytes\n",
|
||||||
|
(long)now.tv_sec, (long)now.tv_usec,
|
||||||
|
res);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void printpacket(struct msghdr *msg, int res,
|
||||||
|
char *data,
|
||||||
|
int sock, int recvmsg_flags,
|
||||||
|
int siocgstamp, int siocgstampns)
|
||||||
|
{
|
||||||
|
struct sockaddr_in *from_addr = (struct sockaddr_in *)msg->msg_name;
|
||||||
|
struct cmsghdr *cmsg;
|
||||||
|
struct timeval tv;
|
||||||
|
struct timespec ts;
|
||||||
|
struct timeval now;
|
||||||
|
|
||||||
|
gettimeofday(&now, 0);
|
||||||
|
|
||||||
|
printf("%ld.%06ld: received %s data, %d bytes from %s, %d bytes control messages\n",
|
||||||
|
(long)now.tv_sec, (long)now.tv_usec,
|
||||||
|
(recvmsg_flags & MSG_ERRQUEUE) ? "error" : "regular",
|
||||||
|
res,
|
||||||
|
inet_ntoa(from_addr->sin_addr),
|
||||||
|
msg->msg_controllen);
|
||||||
|
for (cmsg = CMSG_FIRSTHDR(msg);
|
||||||
|
cmsg;
|
||||||
|
cmsg = CMSG_NXTHDR(msg, cmsg)) {
|
||||||
|
printf(" cmsg len %d: ", cmsg->cmsg_len);
|
||||||
|
switch (cmsg->cmsg_level) {
|
||||||
|
case SOL_SOCKET:
|
||||||
|
printf("SOL_SOCKET ");
|
||||||
|
switch (cmsg->cmsg_type) {
|
||||||
|
case SO_TIMESTAMP: {
|
||||||
|
struct timeval *stamp =
|
||||||
|
(struct timeval *)CMSG_DATA(cmsg);
|
||||||
|
printf("SO_TIMESTAMP %ld.%06ld",
|
||||||
|
(long)stamp->tv_sec,
|
||||||
|
(long)stamp->tv_usec);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case SO_TIMESTAMPNS: {
|
||||||
|
struct timespec *stamp =
|
||||||
|
(struct timespec *)CMSG_DATA(cmsg);
|
||||||
|
printf("SO_TIMESTAMPNS %ld.%09ld",
|
||||||
|
(long)stamp->tv_sec,
|
||||||
|
(long)stamp->tv_nsec);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case SO_TIMESTAMPING: {
|
||||||
|
struct timespec *stamp =
|
||||||
|
(struct timespec *)CMSG_DATA(cmsg);
|
||||||
|
printf("SO_TIMESTAMPING ");
|
||||||
|
printf("SW %ld.%09ld ",
|
||||||
|
(long)stamp->tv_sec,
|
||||||
|
(long)stamp->tv_nsec);
|
||||||
|
stamp++;
|
||||||
|
printf("HW transformed %ld.%09ld ",
|
||||||
|
(long)stamp->tv_sec,
|
||||||
|
(long)stamp->tv_nsec);
|
||||||
|
stamp++;
|
||||||
|
printf("HW raw %ld.%09ld",
|
||||||
|
(long)stamp->tv_sec,
|
||||||
|
(long)stamp->tv_nsec);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
printf("type %d", cmsg->cmsg_type);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case IPPROTO_IP:
|
||||||
|
printf("IPPROTO_IP ");
|
||||||
|
switch (cmsg->cmsg_type) {
|
||||||
|
case IP_RECVERR: {
|
||||||
|
struct sock_extended_err *err =
|
||||||
|
(struct sock_extended_err *)CMSG_DATA(cmsg);
|
||||||
|
printf("IP_RECVERR ee_errno '%s' ee_origin %d => %s",
|
||||||
|
strerror(err->ee_errno),
|
||||||
|
err->ee_origin,
|
||||||
|
#ifdef SO_EE_ORIGIN_TIMESTAMPING
|
||||||
|
err->ee_origin == SO_EE_ORIGIN_TIMESTAMPING ?
|
||||||
|
"bounced packet" : "unexpected origin"
|
||||||
|
#else
|
||||||
|
"probably SO_EE_ORIGIN_TIMESTAMPING"
|
||||||
|
#endif
|
||||||
|
);
|
||||||
|
if (res < sizeof(sync))
|
||||||
|
printf(" => truncated data?!");
|
||||||
|
else if (!memcmp(sync, data + res - sizeof(sync),
|
||||||
|
sizeof(sync)))
|
||||||
|
printf(" => GOT OUR DATA BACK (HURRAY!)");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case IP_PKTINFO: {
|
||||||
|
struct in_pktinfo *pktinfo =
|
||||||
|
(struct in_pktinfo *)CMSG_DATA(cmsg);
|
||||||
|
printf("IP_PKTINFO interface index %u",
|
||||||
|
pktinfo->ipi_ifindex);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
printf("type %d", cmsg->cmsg_type);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
printf("level %d type %d",
|
||||||
|
cmsg->cmsg_level,
|
||||||
|
cmsg->cmsg_type);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
printf("\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (siocgstamp) {
|
||||||
|
if (ioctl(sock, SIOCGSTAMP, &tv))
|
||||||
|
printf(" %s: %s\n", "SIOCGSTAMP", strerror(errno));
|
||||||
|
else
|
||||||
|
printf("SIOCGSTAMP %ld.%06ld\n",
|
||||||
|
(long)tv.tv_sec,
|
||||||
|
(long)tv.tv_usec);
|
||||||
|
}
|
||||||
|
if (siocgstampns) {
|
||||||
|
if (ioctl(sock, SIOCGSTAMPNS, &ts))
|
||||||
|
printf(" %s: %s\n", "SIOCGSTAMPNS", strerror(errno));
|
||||||
|
else
|
||||||
|
printf("SIOCGSTAMPNS %ld.%09ld\n",
|
||||||
|
(long)ts.tv_sec,
|
||||||
|
(long)ts.tv_nsec);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void recvpacket(int sock, int recvmsg_flags,
|
||||||
|
int siocgstamp, int siocgstampns)
|
||||||
|
{
|
||||||
|
char data[256];
|
||||||
|
struct msghdr msg;
|
||||||
|
struct iovec entry;
|
||||||
|
struct sockaddr_in from_addr;
|
||||||
|
struct {
|
||||||
|
struct cmsghdr cm;
|
||||||
|
char control[512];
|
||||||
|
} control;
|
||||||
|
int res;
|
||||||
|
|
||||||
|
memset(&msg, 0, sizeof(msg));
|
||||||
|
msg.msg_iov = &entry;
|
||||||
|
msg.msg_iovlen = 1;
|
||||||
|
entry.iov_base = data;
|
||||||
|
entry.iov_len = sizeof(data);
|
||||||
|
msg.msg_name = (caddr_t)&from_addr;
|
||||||
|
msg.msg_namelen = sizeof(from_addr);
|
||||||
|
msg.msg_control = &control;
|
||||||
|
msg.msg_controllen = sizeof(control);
|
||||||
|
|
||||||
|
res = recvmsg(sock, &msg, recvmsg_flags|MSG_DONTWAIT);
|
||||||
|
if (res < 0) {
|
||||||
|
printf("%s %s: %s\n",
|
||||||
|
"recvmsg",
|
||||||
|
(recvmsg_flags & MSG_ERRQUEUE) ? "error" : "regular",
|
||||||
|
strerror(errno));
|
||||||
|
} else {
|
||||||
|
printpacket(&msg, res, data,
|
||||||
|
sock, recvmsg_flags,
|
||||||
|
siocgstamp, siocgstampns);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char **argv)
|
||||||
|
{
|
||||||
|
int so_timestamping_flags = 0;
|
||||||
|
int so_timestamp = 0;
|
||||||
|
int so_timestampns = 0;
|
||||||
|
int siocgstamp = 0;
|
||||||
|
int siocgstampns = 0;
|
||||||
|
int ip_multicast_loop = 0;
|
||||||
|
char *interface;
|
||||||
|
int i;
|
||||||
|
int enabled = 1;
|
||||||
|
int sock;
|
||||||
|
struct ifreq device;
|
||||||
|
struct ifreq hwtstamp;
|
||||||
|
struct hwtstamp_config hwconfig, hwconfig_requested;
|
||||||
|
struct sockaddr_in addr;
|
||||||
|
struct ip_mreq imr;
|
||||||
|
struct in_addr iaddr;
|
||||||
|
int val;
|
||||||
|
socklen_t len;
|
||||||
|
struct timeval next;
|
||||||
|
|
||||||
|
if (argc < 2)
|
||||||
|
usage(0);
|
||||||
|
interface = argv[1];
|
||||||
|
|
||||||
|
for (i = 2; i < argc; i++) {
|
||||||
|
if (!strcasecmp(argv[i], "SO_TIMESTAMP"))
|
||||||
|
so_timestamp = 1;
|
||||||
|
else if (!strcasecmp(argv[i], "SO_TIMESTAMPNS"))
|
||||||
|
so_timestampns = 1;
|
||||||
|
else if (!strcasecmp(argv[i], "SIOCGSTAMP"))
|
||||||
|
siocgstamp = 1;
|
||||||
|
else if (!strcasecmp(argv[i], "SIOCGSTAMPNS"))
|
||||||
|
siocgstampns = 1;
|
||||||
|
else if (!strcasecmp(argv[i], "IP_MULTICAST_LOOP"))
|
||||||
|
ip_multicast_loop = 1;
|
||||||
|
else if (!strcasecmp(argv[i], "SOF_TIMESTAMPING_TX_HARDWARE"))
|
||||||
|
so_timestamping_flags |= SOF_TIMESTAMPING_TX_HARDWARE;
|
||||||
|
else if (!strcasecmp(argv[i], "SOF_TIMESTAMPING_TX_SOFTWARE"))
|
||||||
|
so_timestamping_flags |= SOF_TIMESTAMPING_TX_SOFTWARE;
|
||||||
|
else if (!strcasecmp(argv[i], "SOF_TIMESTAMPING_RX_HARDWARE"))
|
||||||
|
so_timestamping_flags |= SOF_TIMESTAMPING_RX_HARDWARE;
|
||||||
|
else if (!strcasecmp(argv[i], "SOF_TIMESTAMPING_RX_SOFTWARE"))
|
||||||
|
so_timestamping_flags |= SOF_TIMESTAMPING_RX_SOFTWARE;
|
||||||
|
else if (!strcasecmp(argv[i], "SOF_TIMESTAMPING_SOFTWARE"))
|
||||||
|
so_timestamping_flags |= SOF_TIMESTAMPING_SOFTWARE;
|
||||||
|
else if (!strcasecmp(argv[i], "SOF_TIMESTAMPING_SYS_HARDWARE"))
|
||||||
|
so_timestamping_flags |= SOF_TIMESTAMPING_SYS_HARDWARE;
|
||||||
|
else if (!strcasecmp(argv[i], "SOF_TIMESTAMPING_RAW_HARDWARE"))
|
||||||
|
so_timestamping_flags |= SOF_TIMESTAMPING_RAW_HARDWARE;
|
||||||
|
else
|
||||||
|
usage(argv[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);
|
||||||
|
if (socket < 0)
|
||||||
|
bail("socket");
|
||||||
|
|
||||||
|
memset(&device, 0, sizeof(device));
|
||||||
|
strncpy(device.ifr_name, interface, sizeof(device.ifr_name));
|
||||||
|
if (ioctl(sock, SIOCGIFADDR, &device) < 0)
|
||||||
|
bail("getting interface IP address");
|
||||||
|
|
||||||
|
memset(&hwtstamp, 0, sizeof(hwtstamp));
|
||||||
|
strncpy(hwtstamp.ifr_name, interface, sizeof(hwtstamp.ifr_name));
|
||||||
|
hwtstamp.ifr_data = (void *)&hwconfig;
|
||||||
|
memset(&hwconfig, 0, sizeof(&hwconfig));
|
||||||
|
hwconfig.tx_type =
|
||||||
|
(so_timestamping_flags & SOF_TIMESTAMPING_TX_HARDWARE) ?
|
||||||
|
HWTSTAMP_TX_ON : HWTSTAMP_TX_OFF;
|
||||||
|
hwconfig.rx_filter =
|
||||||
|
(so_timestamping_flags & SOF_TIMESTAMPING_RX_HARDWARE) ?
|
||||||
|
HWTSTAMP_FILTER_PTP_V1_L4_SYNC : HWTSTAMP_FILTER_NONE;
|
||||||
|
hwconfig_requested = hwconfig;
|
||||||
|
if (ioctl(sock, SIOCSHWTSTAMP, &hwtstamp) < 0) {
|
||||||
|
if ((errno == EINVAL || errno == ENOTSUP) &&
|
||||||
|
hwconfig_requested.tx_type == HWTSTAMP_TX_OFF &&
|
||||||
|
hwconfig_requested.rx_filter == HWTSTAMP_FILTER_NONE)
|
||||||
|
printf("SIOCSHWTSTAMP: disabling hardware time stamping not possible\n");
|
||||||
|
else
|
||||||
|
bail("SIOCSHWTSTAMP");
|
||||||
|
}
|
||||||
|
printf("SIOCSHWTSTAMP: tx_type %d requested, got %d; rx_filter %d requested, got %d\n",
|
||||||
|
hwconfig_requested.tx_type, hwconfig.tx_type,
|
||||||
|
hwconfig_requested.rx_filter, hwconfig.rx_filter);
|
||||||
|
|
||||||
|
/* bind to PTP port */
|
||||||
|
addr.sin_family = AF_INET;
|
||||||
|
addr.sin_addr.s_addr = htonl(INADDR_ANY);
|
||||||
|
addr.sin_port = htons(319 /* PTP event port */);
|
||||||
|
if (bind(sock,
|
||||||
|
(struct sockaddr *)&addr,
|
||||||
|
sizeof(struct sockaddr_in)) < 0)
|
||||||
|
bail("bind");
|
||||||
|
|
||||||
|
/* set multicast group for outgoing packets */
|
||||||
|
inet_aton("224.0.1.130", &iaddr); /* alternate PTP domain 1 */
|
||||||
|
addr.sin_addr = iaddr;
|
||||||
|
imr.imr_multiaddr.s_addr = iaddr.s_addr;
|
||||||
|
imr.imr_interface.s_addr =
|
||||||
|
((struct sockaddr_in *)&device.ifr_addr)->sin_addr.s_addr;
|
||||||
|
if (setsockopt(sock, IPPROTO_IP, IP_MULTICAST_IF,
|
||||||
|
&imr.imr_interface.s_addr, sizeof(struct in_addr)) < 0)
|
||||||
|
bail("set multicast");
|
||||||
|
|
||||||
|
/* join multicast group, loop our own packet */
|
||||||
|
if (setsockopt(sock, IPPROTO_IP, IP_ADD_MEMBERSHIP,
|
||||||
|
&imr, sizeof(struct ip_mreq)) < 0)
|
||||||
|
bail("join multicast group");
|
||||||
|
|
||||||
|
if (setsockopt(sock, IPPROTO_IP, IP_MULTICAST_LOOP,
|
||||||
|
&ip_multicast_loop, sizeof(enabled)) < 0) {
|
||||||
|
bail("loop multicast");
|
||||||
|
}
|
||||||
|
|
||||||
|
/* set socket options for time stamping */
|
||||||
|
if (so_timestamp &&
|
||||||
|
setsockopt(sock, SOL_SOCKET, SO_TIMESTAMP,
|
||||||
|
&enabled, sizeof(enabled)) < 0)
|
||||||
|
bail("setsockopt SO_TIMESTAMP");
|
||||||
|
|
||||||
|
if (so_timestampns &&
|
||||||
|
setsockopt(sock, SOL_SOCKET, SO_TIMESTAMPNS,
|
||||||
|
&enabled, sizeof(enabled)) < 0)
|
||||||
|
bail("setsockopt SO_TIMESTAMPNS");
|
||||||
|
|
||||||
|
if (so_timestamping_flags &&
|
||||||
|
setsockopt(sock, SOL_SOCKET, SO_TIMESTAMPING,
|
||||||
|
&so_timestamping_flags,
|
||||||
|
sizeof(so_timestamping_flags)) < 0)
|
||||||
|
bail("setsockopt SO_TIMESTAMPING");
|
||||||
|
|
||||||
|
/* request IP_PKTINFO for debugging purposes */
|
||||||
|
if (setsockopt(sock, SOL_IP, IP_PKTINFO,
|
||||||
|
&enabled, sizeof(enabled)) < 0)
|
||||||
|
printf("%s: %s\n", "setsockopt IP_PKTINFO", strerror(errno));
|
||||||
|
|
||||||
|
/* verify socket options */
|
||||||
|
len = sizeof(val);
|
||||||
|
if (getsockopt(sock, SOL_SOCKET, SO_TIMESTAMP, &val, &len) < 0)
|
||||||
|
printf("%s: %s\n", "getsockopt SO_TIMESTAMP", strerror(errno));
|
||||||
|
else
|
||||||
|
printf("SO_TIMESTAMP %d\n", val);
|
||||||
|
|
||||||
|
if (getsockopt(sock, SOL_SOCKET, SO_TIMESTAMPNS, &val, &len) < 0)
|
||||||
|
printf("%s: %s\n", "getsockopt SO_TIMESTAMPNS",
|
||||||
|
strerror(errno));
|
||||||
|
else
|
||||||
|
printf("SO_TIMESTAMPNS %d\n", val);
|
||||||
|
|
||||||
|
if (getsockopt(sock, SOL_SOCKET, SO_TIMESTAMPING, &val, &len) < 0) {
|
||||||
|
printf("%s: %s\n", "getsockopt SO_TIMESTAMPING",
|
||||||
|
strerror(errno));
|
||||||
|
} else {
|
||||||
|
printf("SO_TIMESTAMPING %d\n", val);
|
||||||
|
if (val != so_timestamping_flags)
|
||||||
|
printf(" not the expected value %d\n",
|
||||||
|
so_timestamping_flags);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* send packets forever every five seconds */
|
||||||
|
gettimeofday(&next, 0);
|
||||||
|
next.tv_sec = (next.tv_sec + 1) / 5 * 5;
|
||||||
|
next.tv_usec = 0;
|
||||||
|
while (1) {
|
||||||
|
struct timeval now;
|
||||||
|
struct timeval delta;
|
||||||
|
long delta_us;
|
||||||
|
int res;
|
||||||
|
fd_set readfs, errorfs;
|
||||||
|
|
||||||
|
gettimeofday(&now, 0);
|
||||||
|
delta_us = (long)(next.tv_sec - now.tv_sec) * 1000000 +
|
||||||
|
(long)(next.tv_usec - now.tv_usec);
|
||||||
|
if (delta_us > 0) {
|
||||||
|
/* continue waiting for timeout or data */
|
||||||
|
delta.tv_sec = delta_us / 1000000;
|
||||||
|
delta.tv_usec = delta_us % 1000000;
|
||||||
|
|
||||||
|
FD_ZERO(&readfs);
|
||||||
|
FD_ZERO(&errorfs);
|
||||||
|
FD_SET(sock, &readfs);
|
||||||
|
FD_SET(sock, &errorfs);
|
||||||
|
printf("%ld.%06ld: select %ldus\n",
|
||||||
|
(long)now.tv_sec, (long)now.tv_usec,
|
||||||
|
delta_us);
|
||||||
|
res = select(sock + 1, &readfs, 0, &errorfs, &delta);
|
||||||
|
gettimeofday(&now, 0);
|
||||||
|
printf("%ld.%06ld: select returned: %d, %s\n",
|
||||||
|
(long)now.tv_sec, (long)now.tv_usec,
|
||||||
|
res,
|
||||||
|
res < 0 ? strerror(errno) : "success");
|
||||||
|
if (res > 0) {
|
||||||
|
if (FD_ISSET(sock, &readfs))
|
||||||
|
printf("ready for reading\n");
|
||||||
|
if (FD_ISSET(sock, &errorfs))
|
||||||
|
printf("has error\n");
|
||||||
|
recvpacket(sock, 0,
|
||||||
|
siocgstamp,
|
||||||
|
siocgstampns);
|
||||||
|
recvpacket(sock, MSG_ERRQUEUE,
|
||||||
|
siocgstamp,
|
||||||
|
siocgstampns);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
/* write one packet */
|
||||||
|
sendpacket(sock,
|
||||||
|
(struct sockaddr *)&addr,
|
||||||
|
sizeof(addr));
|
||||||
|
next.tv_sec += 5;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
|
@ -56,6 +56,12 @@ Properties:
|
||||||
hardware.
|
hardware.
|
||||||
- fsl,magic-packet : If present, indicates that the hardware supports
|
- fsl,magic-packet : If present, indicates that the hardware supports
|
||||||
waking up via magic packet.
|
waking up via magic packet.
|
||||||
|
- bd-stash : If present, indicates that the hardware supports stashing
|
||||||
|
buffer descriptors in the L2.
|
||||||
|
- rx-stash-len : Denotes the number of bytes of a received buffer to stash
|
||||||
|
in the L2.
|
||||||
|
- rx-stash-idx : Denotes the index of the first byte from the received
|
||||||
|
buffer to stash in the L2.
|
||||||
|
|
||||||
Example:
|
Example:
|
||||||
ethernet@24000 {
|
ethernet@24000 {
|
||||||
|
|
|
@ -1011,6 +1011,8 @@ L: netdev@vger.kernel.org
|
||||||
S: Supported
|
S: Supported
|
||||||
|
|
||||||
BROADCOM TG3 GIGABIT ETHERNET DRIVER
|
BROADCOM TG3 GIGABIT ETHERNET DRIVER
|
||||||
|
P: Matt Carlson
|
||||||
|
M: mcarlson@broadcom.com
|
||||||
P: Michael Chan
|
P: Michael Chan
|
||||||
M: mchan@broadcom.com
|
M: mchan@broadcom.com
|
||||||
L: netdev@vger.kernel.org
|
L: netdev@vger.kernel.org
|
||||||
|
@ -3646,6 +3648,12 @@ M: florian.fainelli@telecomint.eu
|
||||||
L: netdev@vger.kernel.org
|
L: netdev@vger.kernel.org
|
||||||
S: Maintained
|
S: Maintained
|
||||||
|
|
||||||
|
RDS - RELIABLE DATAGRAM SOCKETS
|
||||||
|
P: Andy Grover
|
||||||
|
M: andy.grover@oracle.com
|
||||||
|
L: rds-devel@oss.oracle.com
|
||||||
|
S: Supported
|
||||||
|
|
||||||
READ-COPY UPDATE (RCU)
|
READ-COPY UPDATE (RCU)
|
||||||
P: Dipankar Sarma
|
P: Dipankar Sarma
|
||||||
M: dipankar@in.ibm.com
|
M: dipankar@in.ibm.com
|
||||||
|
|
|
@ -62,6 +62,9 @@
|
||||||
|
|
||||||
#define SO_MARK 36
|
#define SO_MARK 36
|
||||||
|
|
||||||
|
#define SO_TIMESTAMPING 37
|
||||||
|
#define SCM_TIMESTAMPING SO_TIMESTAMPING
|
||||||
|
|
||||||
/* O_NONBLOCK clashes with the bits used for socket types. Therefore we
|
/* O_NONBLOCK clashes with the bits used for socket types. Therefore we
|
||||||
* have to define SOCK_NONBLOCK to a different value here.
|
* have to define SOCK_NONBLOCK to a different value here.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -54,4 +54,7 @@
|
||||||
|
|
||||||
#define SO_MARK 36
|
#define SO_MARK 36
|
||||||
|
|
||||||
|
#define SO_TIMESTAMPING 37
|
||||||
|
#define SCM_TIMESTAMPING SO_TIMESTAMPING
|
||||||
|
|
||||||
#endif /* _ASM_SOCKET_H */
|
#endif /* _ASM_SOCKET_H */
|
||||||
|
|
|
@ -231,14 +231,17 @@ static struct platform_device kirkwood_switch_device = {
|
||||||
|
|
||||||
void __init kirkwood_ge00_switch_init(struct dsa_platform_data *d, int irq)
|
void __init kirkwood_ge00_switch_init(struct dsa_platform_data *d, int irq)
|
||||||
{
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
if (irq != NO_IRQ) {
|
if (irq != NO_IRQ) {
|
||||||
kirkwood_switch_resources[0].start = irq;
|
kirkwood_switch_resources[0].start = irq;
|
||||||
kirkwood_switch_resources[0].end = irq;
|
kirkwood_switch_resources[0].end = irq;
|
||||||
kirkwood_switch_device.num_resources = 1;
|
kirkwood_switch_device.num_resources = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
d->mii_bus = &kirkwood_ge00_shared.dev;
|
|
||||||
d->netdev = &kirkwood_ge00.dev;
|
d->netdev = &kirkwood_ge00.dev;
|
||||||
|
for (i = 0; i < d->nr_chips; i++)
|
||||||
|
d->chip[i].mii_bus = &kirkwood_ge00_shared.dev;
|
||||||
kirkwood_switch_device.dev.platform_data = d;
|
kirkwood_switch_device.dev.platform_data = d;
|
||||||
|
|
||||||
platform_device_register(&kirkwood_switch_device);
|
platform_device_register(&kirkwood_switch_device);
|
||||||
|
|
|
@ -75,7 +75,7 @@ static struct mv643xx_eth_platform_data rd88f6281_ge00_data = {
|
||||||
.duplex = DUPLEX_FULL,
|
.duplex = DUPLEX_FULL,
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct dsa_platform_data rd88f6281_switch_data = {
|
static struct dsa_chip_data rd88f6281_switch_chip_data = {
|
||||||
.port_names[0] = "lan1",
|
.port_names[0] = "lan1",
|
||||||
.port_names[1] = "lan2",
|
.port_names[1] = "lan2",
|
||||||
.port_names[2] = "lan3",
|
.port_names[2] = "lan3",
|
||||||
|
@ -83,6 +83,11 @@ static struct dsa_platform_data rd88f6281_switch_data = {
|
||||||
.port_names[5] = "cpu",
|
.port_names[5] = "cpu",
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static struct dsa_platform_data rd88f6281_switch_plat_data = {
|
||||||
|
.nr_chips = 1,
|
||||||
|
.chip = &rd88f6281_switch_chip_data,
|
||||||
|
};
|
||||||
|
|
||||||
static struct mv643xx_eth_platform_data rd88f6281_ge01_data = {
|
static struct mv643xx_eth_platform_data rd88f6281_ge01_data = {
|
||||||
.phy_addr = MV643XX_ETH_PHY_ADDR(11),
|
.phy_addr = MV643XX_ETH_PHY_ADDR(11),
|
||||||
};
|
};
|
||||||
|
@ -105,12 +110,12 @@ static void __init rd88f6281_init(void)
|
||||||
kirkwood_ge00_init(&rd88f6281_ge00_data);
|
kirkwood_ge00_init(&rd88f6281_ge00_data);
|
||||||
kirkwood_pcie_id(&dev, &rev);
|
kirkwood_pcie_id(&dev, &rev);
|
||||||
if (rev == MV88F6281_REV_A0) {
|
if (rev == MV88F6281_REV_A0) {
|
||||||
rd88f6281_switch_data.sw_addr = 10;
|
rd88f6281_switch_chip_data.sw_addr = 10;
|
||||||
kirkwood_ge01_init(&rd88f6281_ge01_data);
|
kirkwood_ge01_init(&rd88f6281_ge01_data);
|
||||||
} else {
|
} else {
|
||||||
rd88f6281_switch_data.port_names[4] = "wan";
|
rd88f6281_switch_chip_data.port_names[4] = "wan";
|
||||||
}
|
}
|
||||||
kirkwood_ge00_switch_init(&rd88f6281_switch_data, NO_IRQ);
|
kirkwood_ge00_switch_init(&rd88f6281_switch_plat_data, NO_IRQ);
|
||||||
|
|
||||||
kirkwood_rtc_init();
|
kirkwood_rtc_init();
|
||||||
kirkwood_sata_init(&rd88f6281_sata_data);
|
kirkwood_sata_init(&rd88f6281_sata_data);
|
||||||
|
|
|
@ -220,14 +220,17 @@ static struct platform_device orion5x_switch_device = {
|
||||||
|
|
||||||
void __init orion5x_eth_switch_init(struct dsa_platform_data *d, int irq)
|
void __init orion5x_eth_switch_init(struct dsa_platform_data *d, int irq)
|
||||||
{
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
if (irq != NO_IRQ) {
|
if (irq != NO_IRQ) {
|
||||||
orion5x_switch_resources[0].start = irq;
|
orion5x_switch_resources[0].start = irq;
|
||||||
orion5x_switch_resources[0].end = irq;
|
orion5x_switch_resources[0].end = irq;
|
||||||
orion5x_switch_device.num_resources = 1;
|
orion5x_switch_device.num_resources = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
d->mii_bus = &orion5x_eth_shared.dev;
|
|
||||||
d->netdev = &orion5x_eth.dev;
|
d->netdev = &orion5x_eth.dev;
|
||||||
|
for (i = 0; i < d->nr_chips; i++)
|
||||||
|
d->chip[i].mii_bus = &orion5x_eth_shared.dev;
|
||||||
orion5x_switch_device.dev.platform_data = d;
|
orion5x_switch_device.dev.platform_data = d;
|
||||||
|
|
||||||
platform_device_register(&orion5x_switch_device);
|
platform_device_register(&orion5x_switch_device);
|
||||||
|
|
|
@ -94,7 +94,7 @@ static struct mv643xx_eth_platform_data rd88f5181l_fxo_eth_data = {
|
||||||
.duplex = DUPLEX_FULL,
|
.duplex = DUPLEX_FULL,
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct dsa_platform_data rd88f5181l_fxo_switch_data = {
|
static struct dsa_chip_data rd88f5181l_fxo_switch_chip_data = {
|
||||||
.port_names[0] = "lan2",
|
.port_names[0] = "lan2",
|
||||||
.port_names[1] = "lan1",
|
.port_names[1] = "lan1",
|
||||||
.port_names[2] = "wan",
|
.port_names[2] = "wan",
|
||||||
|
@ -103,6 +103,11 @@ static struct dsa_platform_data rd88f5181l_fxo_switch_data = {
|
||||||
.port_names[7] = "lan3",
|
.port_names[7] = "lan3",
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static struct dsa_platform_data rd88f5181l_fxo_switch_plat_data = {
|
||||||
|
.nr_chips = 1,
|
||||||
|
.chip = &rd88f5181l_fxo_switch_chip_data,
|
||||||
|
};
|
||||||
|
|
||||||
static void __init rd88f5181l_fxo_init(void)
|
static void __init rd88f5181l_fxo_init(void)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
|
@ -117,7 +122,7 @@ static void __init rd88f5181l_fxo_init(void)
|
||||||
*/
|
*/
|
||||||
orion5x_ehci0_init();
|
orion5x_ehci0_init();
|
||||||
orion5x_eth_init(&rd88f5181l_fxo_eth_data);
|
orion5x_eth_init(&rd88f5181l_fxo_eth_data);
|
||||||
orion5x_eth_switch_init(&rd88f5181l_fxo_switch_data, NO_IRQ);
|
orion5x_eth_switch_init(&rd88f5181l_fxo_switch_plat_data, NO_IRQ);
|
||||||
orion5x_uart0_init();
|
orion5x_uart0_init();
|
||||||
|
|
||||||
orion5x_setup_dev_boot_win(RD88F5181L_FXO_NOR_BOOT_BASE,
|
orion5x_setup_dev_boot_win(RD88F5181L_FXO_NOR_BOOT_BASE,
|
||||||
|
|
|
@ -95,7 +95,7 @@ static struct mv643xx_eth_platform_data rd88f5181l_ge_eth_data = {
|
||||||
.duplex = DUPLEX_FULL,
|
.duplex = DUPLEX_FULL,
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct dsa_platform_data rd88f5181l_ge_switch_data = {
|
static struct dsa_chip_data rd88f5181l_ge_switch_chip_data = {
|
||||||
.port_names[0] = "lan2",
|
.port_names[0] = "lan2",
|
||||||
.port_names[1] = "lan1",
|
.port_names[1] = "lan1",
|
||||||
.port_names[2] = "wan",
|
.port_names[2] = "wan",
|
||||||
|
@ -104,6 +104,11 @@ static struct dsa_platform_data rd88f5181l_ge_switch_data = {
|
||||||
.port_names[7] = "lan3",
|
.port_names[7] = "lan3",
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static struct dsa_platform_data rd88f5181l_ge_switch_plat_data = {
|
||||||
|
.nr_chips = 1,
|
||||||
|
.chip = &rd88f5181l_ge_switch_chip_data,
|
||||||
|
};
|
||||||
|
|
||||||
static struct i2c_board_info __initdata rd88f5181l_ge_i2c_rtc = {
|
static struct i2c_board_info __initdata rd88f5181l_ge_i2c_rtc = {
|
||||||
I2C_BOARD_INFO("ds1338", 0x68),
|
I2C_BOARD_INFO("ds1338", 0x68),
|
||||||
};
|
};
|
||||||
|
@ -122,7 +127,8 @@ static void __init rd88f5181l_ge_init(void)
|
||||||
*/
|
*/
|
||||||
orion5x_ehci0_init();
|
orion5x_ehci0_init();
|
||||||
orion5x_eth_init(&rd88f5181l_ge_eth_data);
|
orion5x_eth_init(&rd88f5181l_ge_eth_data);
|
||||||
orion5x_eth_switch_init(&rd88f5181l_ge_switch_data, gpio_to_irq(8));
|
orion5x_eth_switch_init(&rd88f5181l_ge_switch_plat_data,
|
||||||
|
gpio_to_irq(8));
|
||||||
orion5x_i2c_init();
|
orion5x_i2c_init();
|
||||||
orion5x_uart0_init();
|
orion5x_uart0_init();
|
||||||
|
|
||||||
|
|
|
@ -35,7 +35,7 @@ static struct mv643xx_eth_platform_data rd88f6183ap_ge_eth_data = {
|
||||||
.duplex = DUPLEX_FULL,
|
.duplex = DUPLEX_FULL,
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct dsa_platform_data rd88f6183ap_ge_switch_data = {
|
static struct dsa_chip_data rd88f6183ap_ge_switch_chip_data = {
|
||||||
.port_names[0] = "lan1",
|
.port_names[0] = "lan1",
|
||||||
.port_names[1] = "lan2",
|
.port_names[1] = "lan2",
|
||||||
.port_names[2] = "lan3",
|
.port_names[2] = "lan3",
|
||||||
|
@ -44,6 +44,11 @@ static struct dsa_platform_data rd88f6183ap_ge_switch_data = {
|
||||||
.port_names[5] = "cpu",
|
.port_names[5] = "cpu",
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static struct dsa_platform_data rd88f6183ap_ge_switch_plat_data = {
|
||||||
|
.nr_chips = 1,
|
||||||
|
.chip = &rd88f6183ap_ge_switch_chip_data,
|
||||||
|
};
|
||||||
|
|
||||||
static struct mtd_partition rd88f6183ap_ge_partitions[] = {
|
static struct mtd_partition rd88f6183ap_ge_partitions[] = {
|
||||||
{
|
{
|
||||||
.name = "kernel",
|
.name = "kernel",
|
||||||
|
@ -89,7 +94,8 @@ static void __init rd88f6183ap_ge_init(void)
|
||||||
*/
|
*/
|
||||||
orion5x_ehci0_init();
|
orion5x_ehci0_init();
|
||||||
orion5x_eth_init(&rd88f6183ap_ge_eth_data);
|
orion5x_eth_init(&rd88f6183ap_ge_eth_data);
|
||||||
orion5x_eth_switch_init(&rd88f6183ap_ge_switch_data, gpio_to_irq(3));
|
orion5x_eth_switch_init(&rd88f6183ap_ge_switch_plat_data,
|
||||||
|
gpio_to_irq(3));
|
||||||
spi_register_board_info(rd88f6183ap_ge_spi_slave_info,
|
spi_register_board_info(rd88f6183ap_ge_spi_slave_info,
|
||||||
ARRAY_SIZE(rd88f6183ap_ge_spi_slave_info));
|
ARRAY_SIZE(rd88f6183ap_ge_spi_slave_info));
|
||||||
orion5x_spi_init();
|
orion5x_spi_init();
|
||||||
|
|
|
@ -106,7 +106,7 @@ static struct mv643xx_eth_platform_data wrt350n_v2_eth_data = {
|
||||||
.duplex = DUPLEX_FULL,
|
.duplex = DUPLEX_FULL,
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct dsa_platform_data wrt350n_v2_switch_data = {
|
static struct dsa_chip_data wrt350n_v2_switch_chip_data = {
|
||||||
.port_names[0] = "lan2",
|
.port_names[0] = "lan2",
|
||||||
.port_names[1] = "lan1",
|
.port_names[1] = "lan1",
|
||||||
.port_names[2] = "wan",
|
.port_names[2] = "wan",
|
||||||
|
@ -115,6 +115,11 @@ static struct dsa_platform_data wrt350n_v2_switch_data = {
|
||||||
.port_names[7] = "lan4",
|
.port_names[7] = "lan4",
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static struct dsa_platform_data wrt350n_v2_switch_plat_data = {
|
||||||
|
.nr_chips = 1,
|
||||||
|
.chip = &wrt350n_v2_switch_chip_data,
|
||||||
|
};
|
||||||
|
|
||||||
static void __init wrt350n_v2_init(void)
|
static void __init wrt350n_v2_init(void)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
|
@ -129,7 +134,7 @@ static void __init wrt350n_v2_init(void)
|
||||||
*/
|
*/
|
||||||
orion5x_ehci0_init();
|
orion5x_ehci0_init();
|
||||||
orion5x_eth_init(&wrt350n_v2_eth_data);
|
orion5x_eth_init(&wrt350n_v2_eth_data);
|
||||||
orion5x_eth_switch_init(&wrt350n_v2_switch_data, NO_IRQ);
|
orion5x_eth_switch_init(&wrt350n_v2_switch_plat_data, NO_IRQ);
|
||||||
orion5x_uart0_init();
|
orion5x_uart0_init();
|
||||||
|
|
||||||
orion5x_setup_dev_boot_win(WRT350N_V2_NOR_BOOT_BASE,
|
orion5x_setup_dev_boot_win(WRT350N_V2_NOR_BOOT_BASE,
|
||||||
|
|
|
@ -54,4 +54,7 @@
|
||||||
|
|
||||||
#define SO_MARK 36
|
#define SO_MARK 36
|
||||||
|
|
||||||
|
#define SO_TIMESTAMPING 37
|
||||||
|
#define SCM_TIMESTAMPING SO_TIMESTAMPING
|
||||||
|
|
||||||
#endif /* __ASM_AVR32_SOCKET_H */
|
#endif /* __ASM_AVR32_SOCKET_H */
|
||||||
|
|
|
@ -53,4 +53,7 @@
|
||||||
|
|
||||||
#define SO_MARK 36
|
#define SO_MARK 36
|
||||||
|
|
||||||
|
#define SO_TIMESTAMPING 37
|
||||||
|
#define SCM_TIMESTAMPING SO_TIMESTAMPING
|
||||||
|
|
||||||
#endif /* _ASM_SOCKET_H */
|
#endif /* _ASM_SOCKET_H */
|
||||||
|
|
|
@ -56,6 +56,9 @@
|
||||||
|
|
||||||
#define SO_MARK 36
|
#define SO_MARK 36
|
||||||
|
|
||||||
|
#define SO_TIMESTAMPING 37
|
||||||
|
#define SCM_TIMESTAMPING SO_TIMESTAMPING
|
||||||
|
|
||||||
#endif /* _ASM_SOCKET_H */
|
#endif /* _ASM_SOCKET_H */
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -54,4 +54,7 @@
|
||||||
|
|
||||||
#define SO_MARK 36
|
#define SO_MARK 36
|
||||||
|
|
||||||
|
#define SO_TIMESTAMPING 37
|
||||||
|
#define SCM_TIMESTAMPING SO_TIMESTAMPING
|
||||||
|
|
||||||
#endif /* _ASM_SOCKET_H */
|
#endif /* _ASM_SOCKET_H */
|
||||||
|
|
|
@ -63,4 +63,7 @@
|
||||||
|
|
||||||
#define SO_MARK 36
|
#define SO_MARK 36
|
||||||
|
|
||||||
|
#define SO_TIMESTAMPING 37
|
||||||
|
#define SCM_TIMESTAMPING SO_TIMESTAMPING
|
||||||
|
|
||||||
#endif /* _ASM_IA64_SOCKET_H */
|
#endif /* _ASM_IA64_SOCKET_H */
|
||||||
|
|
|
@ -54,4 +54,7 @@
|
||||||
|
|
||||||
#define SO_MARK 36
|
#define SO_MARK 36
|
||||||
|
|
||||||
|
#define SO_TIMESTAMPING 37
|
||||||
|
#define SCM_TIMESTAMPING SO_TIMESTAMPING
|
||||||
|
|
||||||
#endif /* _ASM_SOCKET_H */
|
#endif /* _ASM_SOCKET_H */
|
||||||
|
|
|
@ -49,8 +49,39 @@ static struct platform_device m520x_uart = {
|
||||||
.dev.platform_data = m520x_uart_platform,
|
.dev.platform_data = m520x_uart_platform,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static struct resource m520x_fec_resources[] = {
|
||||||
|
{
|
||||||
|
.start = MCF_MBAR + 0x30000,
|
||||||
|
.end = MCF_MBAR + 0x30000 + 0x7ff,
|
||||||
|
.flags = IORESOURCE_MEM,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.start = 64 + 36,
|
||||||
|
.end = 64 + 36,
|
||||||
|
.flags = IORESOURCE_IRQ,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.start = 64 + 40,
|
||||||
|
.end = 64 + 40,
|
||||||
|
.flags = IORESOURCE_IRQ,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.start = 64 + 42,
|
||||||
|
.end = 64 + 42,
|
||||||
|
.flags = IORESOURCE_IRQ,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct platform_device m520x_fec = {
|
||||||
|
.name = "fec",
|
||||||
|
.id = 0,
|
||||||
|
.num_resources = ARRAY_SIZE(m520x_fec_resources),
|
||||||
|
.resource = m520x_fec_resources,
|
||||||
|
};
|
||||||
|
|
||||||
static struct platform_device *m520x_devices[] __initdata = {
|
static struct platform_device *m520x_devices[] __initdata = {
|
||||||
&m520x_uart,
|
&m520x_uart,
|
||||||
|
&m520x_fec,
|
||||||
};
|
};
|
||||||
|
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
|
@ -103,6 +134,30 @@ static void __init m520x_uarts_init(void)
|
||||||
|
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
|
|
||||||
|
static void __init m520x_fec_init(void)
|
||||||
|
{
|
||||||
|
u32 imr;
|
||||||
|
u8 v;
|
||||||
|
|
||||||
|
/* Unmask FEC interrupts at ColdFire interrupt controller */
|
||||||
|
writeb(0x4, MCF_IPSBAR + MCFICM_INTC0 + MCFINTC_ICR0 + 36);
|
||||||
|
writeb(0x4, MCF_IPSBAR + MCFICM_INTC0 + MCFINTC_ICR0 + 40);
|
||||||
|
writeb(0x4, MCF_IPSBAR + MCFICM_INTC0 + MCFINTC_ICR0 + 42);
|
||||||
|
|
||||||
|
imr = readl(MCF_IPSBAR + MCFICM_INTC0 + MCFINTC_IMRH);
|
||||||
|
imr &= ~0x0001FFF0;
|
||||||
|
writel(imr, MCF_IPSBAR + MCFICM_INTC0 + MCFINTC_IMRH);
|
||||||
|
|
||||||
|
/* Set multi-function pins to ethernet mode */
|
||||||
|
v = readb(MCF_IPSBAR + MCF_GPIO_PAR_FEC);
|
||||||
|
writeb(v | 0xf0, MCF_IPSBAR + MCF_GPIO_PAR_FEC);
|
||||||
|
|
||||||
|
v = readb(MCF_IPSBAR + MCF_GPIO_PAR_FECI2C);
|
||||||
|
writeb(v | 0x0f, MCF_IPSBAR + MCF_GPIO_PAR_FECI2C);
|
||||||
|
}
|
||||||
|
|
||||||
|
/***************************************************************************/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Program the vector to be an auto-vectored.
|
* Program the vector to be an auto-vectored.
|
||||||
*/
|
*/
|
||||||
|
@ -118,6 +173,7 @@ void __init config_BSP(char *commandp, int size)
|
||||||
{
|
{
|
||||||
mach_reset = coldfire_reset;
|
mach_reset = coldfire_reset;
|
||||||
m520x_uarts_init();
|
m520x_uarts_init();
|
||||||
|
m520x_fec_init();
|
||||||
}
|
}
|
||||||
|
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
|
|
|
@ -50,8 +50,39 @@ static struct platform_device m523x_uart = {
|
||||||
.dev.platform_data = m523x_uart_platform,
|
.dev.platform_data = m523x_uart_platform,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static struct resource m523x_fec_resources[] = {
|
||||||
|
{
|
||||||
|
.start = MCF_MBAR + 0x1000,
|
||||||
|
.end = MCF_MBAR + 0x1000 + 0x7ff,
|
||||||
|
.flags = IORESOURCE_MEM,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.start = 64 + 23,
|
||||||
|
.end = 64 + 23,
|
||||||
|
.flags = IORESOURCE_IRQ,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.start = 64 + 27,
|
||||||
|
.end = 64 + 27,
|
||||||
|
.flags = IORESOURCE_IRQ,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.start = 64 + 29,
|
||||||
|
.end = 64 + 29,
|
||||||
|
.flags = IORESOURCE_IRQ,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct platform_device m523x_fec = {
|
||||||
|
.name = "fec",
|
||||||
|
.id = 0,
|
||||||
|
.num_resources = ARRAY_SIZE(m523x_fec_resources),
|
||||||
|
.resource = m523x_fec_resources,
|
||||||
|
};
|
||||||
|
|
||||||
static struct platform_device *m523x_devices[] __initdata = {
|
static struct platform_device *m523x_devices[] __initdata = {
|
||||||
&m523x_uart,
|
&m523x_uart,
|
||||||
|
&m523x_fec,
|
||||||
};
|
};
|
||||||
|
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
|
@ -83,6 +114,25 @@ static void __init m523x_uarts_init(void)
|
||||||
|
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
|
|
||||||
|
static void __init m523x_fec_init(void)
|
||||||
|
{
|
||||||
|
u32 imr;
|
||||||
|
|
||||||
|
/* Unmask FEC interrupts at ColdFire interrupt controller */
|
||||||
|
writeb(0x28, MCF_IPSBAR + MCFICM_INTC0 + MCFINTC_ICR0 + 23);
|
||||||
|
writeb(0x27, MCF_IPSBAR + MCFICM_INTC0 + MCFINTC_ICR0 + 27);
|
||||||
|
writeb(0x26, MCF_IPSBAR + MCFICM_INTC0 + MCFINTC_ICR0 + 29);
|
||||||
|
|
||||||
|
imr = readl(MCF_IPSBAR + MCFICM_INTC0 + MCFINTC_IMRH);
|
||||||
|
imr &= ~0xf;
|
||||||
|
writel(imr, MCF_IPSBAR + MCFICM_INTC0 + MCFINTC_IMRH);
|
||||||
|
imr = readl(MCF_IPSBAR + MCFICM_INTC0 + MCFINTC_IMRL);
|
||||||
|
imr &= ~0xff800001;
|
||||||
|
writel(imr, MCF_IPSBAR + MCFICM_INTC0 + MCFINTC_IMRL);
|
||||||
|
}
|
||||||
|
|
||||||
|
/***************************************************************************/
|
||||||
|
|
||||||
void mcf_disableall(void)
|
void mcf_disableall(void)
|
||||||
{
|
{
|
||||||
*((volatile unsigned long *) (MCF_IPSBAR + MCFICM_INTC0 + MCFINTC_IMRH)) = 0xffffffff;
|
*((volatile unsigned long *) (MCF_IPSBAR + MCFICM_INTC0 + MCFINTC_IMRH)) = 0xffffffff;
|
||||||
|
@ -103,6 +153,7 @@ void __init config_BSP(char *commandp, int size)
|
||||||
mcf_disableall();
|
mcf_disableall();
|
||||||
mach_reset = coldfire_reset;
|
mach_reset = coldfire_reset;
|
||||||
m523x_uarts_init();
|
m523x_uarts_init();
|
||||||
|
m523x_fec_init();
|
||||||
}
|
}
|
||||||
|
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
|
|
|
@ -55,8 +55,39 @@ static struct platform_device m5272_uart = {
|
||||||
.dev.platform_data = m5272_uart_platform,
|
.dev.platform_data = m5272_uart_platform,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static struct resource m5272_fec_resources[] = {
|
||||||
|
{
|
||||||
|
.start = MCF_MBAR + 0x840,
|
||||||
|
.end = MCF_MBAR + 0x840 + 0x1cf,
|
||||||
|
.flags = IORESOURCE_MEM,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.start = 86,
|
||||||
|
.end = 86,
|
||||||
|
.flags = IORESOURCE_IRQ,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.start = 87,
|
||||||
|
.end = 87,
|
||||||
|
.flags = IORESOURCE_IRQ,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.start = 88,
|
||||||
|
.end = 88,
|
||||||
|
.flags = IORESOURCE_IRQ,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct platform_device m5272_fec = {
|
||||||
|
.name = "fec",
|
||||||
|
.id = 0,
|
||||||
|
.num_resources = ARRAY_SIZE(m5272_fec_resources),
|
||||||
|
.resource = m5272_fec_resources,
|
||||||
|
};
|
||||||
|
|
||||||
static struct platform_device *m5272_devices[] __initdata = {
|
static struct platform_device *m5272_devices[] __initdata = {
|
||||||
&m5272_uart,
|
&m5272_uart,
|
||||||
|
&m5272_fec,
|
||||||
};
|
};
|
||||||
|
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
|
@ -91,6 +122,22 @@ static void __init m5272_uarts_init(void)
|
||||||
|
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
|
|
||||||
|
static void __init m5272_fec_init(void)
|
||||||
|
{
|
||||||
|
u32 imr;
|
||||||
|
|
||||||
|
/* Unmask FEC interrupts at ColdFire interrupt controller */
|
||||||
|
imr = readl(MCF_MBAR + MCFSIM_ICR3);
|
||||||
|
imr = (imr & ~0x00000fff) | 0x00000ddd;
|
||||||
|
writel(imr, MCF_MBAR + MCFSIM_ICR3);
|
||||||
|
|
||||||
|
imr = readl(MCF_MBAR + MCFSIM_ICR1);
|
||||||
|
imr = (imr & ~0x0f000000) | 0x0d000000;
|
||||||
|
writel(imr, MCF_MBAR + MCFSIM_ICR1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/***************************************************************************/
|
||||||
|
|
||||||
void mcf_disableall(void)
|
void mcf_disableall(void)
|
||||||
{
|
{
|
||||||
volatile unsigned long *icrp;
|
volatile unsigned long *icrp;
|
||||||
|
@ -155,6 +202,7 @@ void __init config_BSP(char *commandp, int size)
|
||||||
static int __init init_BSP(void)
|
static int __init init_BSP(void)
|
||||||
{
|
{
|
||||||
m5272_uarts_init();
|
m5272_uarts_init();
|
||||||
|
m5272_fec_init();
|
||||||
platform_add_devices(m5272_devices, ARRAY_SIZE(m5272_devices));
|
platform_add_devices(m5272_devices, ARRAY_SIZE(m5272_devices));
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -50,8 +50,73 @@ static struct platform_device m527x_uart = {
|
||||||
.dev.platform_data = m527x_uart_platform,
|
.dev.platform_data = m527x_uart_platform,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static struct resource m527x_fec0_resources[] = {
|
||||||
|
{
|
||||||
|
.start = MCF_MBAR + 0x1000,
|
||||||
|
.end = MCF_MBAR + 0x1000 + 0x7ff,
|
||||||
|
.flags = IORESOURCE_MEM,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.start = 64 + 23,
|
||||||
|
.end = 64 + 23,
|
||||||
|
.flags = IORESOURCE_IRQ,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.start = 64 + 27,
|
||||||
|
.end = 64 + 27,
|
||||||
|
.flags = IORESOURCE_IRQ,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.start = 64 + 29,
|
||||||
|
.end = 64 + 29,
|
||||||
|
.flags = IORESOURCE_IRQ,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct resource m527x_fec1_resources[] = {
|
||||||
|
{
|
||||||
|
.start = MCF_MBAR + 0x1800,
|
||||||
|
.end = MCF_MBAR + 0x1800 + 0x7ff,
|
||||||
|
.flags = IORESOURCE_MEM,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.start = 128 + 23,
|
||||||
|
.end = 128 + 23,
|
||||||
|
.flags = IORESOURCE_IRQ,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.start = 128 + 27,
|
||||||
|
.end = 128 + 27,
|
||||||
|
.flags = IORESOURCE_IRQ,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.start = 128 + 29,
|
||||||
|
.end = 128 + 29,
|
||||||
|
.flags = IORESOURCE_IRQ,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct platform_device m527x_fec[] = {
|
||||||
|
{
|
||||||
|
.name = "fec",
|
||||||
|
.id = 0,
|
||||||
|
.num_resources = ARRAY_SIZE(m527x_fec0_resources),
|
||||||
|
.resource = m527x_fec0_resources,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.name = "fec",
|
||||||
|
.id = 1,
|
||||||
|
.num_resources = ARRAY_SIZE(m527x_fec1_resources),
|
||||||
|
.resource = m527x_fec1_resources,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
static struct platform_device *m527x_devices[] __initdata = {
|
static struct platform_device *m527x_devices[] __initdata = {
|
||||||
&m527x_uart,
|
&m527x_uart,
|
||||||
|
&m527x_fec[0],
|
||||||
|
#ifdef CONFIG_FEC2
|
||||||
|
&m527x_fec[1],
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
|
@ -97,6 +162,51 @@ static void __init m527x_uarts_init(void)
|
||||||
|
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
|
|
||||||
|
static void __init m527x_fec_irq_init(int nr)
|
||||||
|
{
|
||||||
|
unsigned long base;
|
||||||
|
u32 imr;
|
||||||
|
|
||||||
|
base = MCF_IPSBAR + (nr ? MCFICM_INTC1 : MCFICM_INTC0);
|
||||||
|
|
||||||
|
writeb(0x28, base + MCFINTC_ICR0 + 23);
|
||||||
|
writeb(0x27, base + MCFINTC_ICR0 + 27);
|
||||||
|
writeb(0x26, base + MCFINTC_ICR0 + 29);
|
||||||
|
|
||||||
|
imr = readl(base + MCFINTC_IMRH);
|
||||||
|
imr &= ~0xf;
|
||||||
|
writel(imr, base + MCFINTC_IMRH);
|
||||||
|
imr = readl(base + MCFINTC_IMRL);
|
||||||
|
imr &= ~0xff800001;
|
||||||
|
writel(imr, base + MCFINTC_IMRL);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void __init m527x_fec_init(void)
|
||||||
|
{
|
||||||
|
u16 par;
|
||||||
|
u8 v;
|
||||||
|
|
||||||
|
m527x_fec_irq_init(0);
|
||||||
|
|
||||||
|
/* Set multi-function pins to ethernet mode for fec0 */
|
||||||
|
par = readw(MCF_IPSBAR + 0x100082);
|
||||||
|
writew(par | 0xf00, MCF_IPSBAR + 0x100082);
|
||||||
|
v = readb(MCF_IPSBAR + 0x100078);
|
||||||
|
writeb(v | 0xc0, MCF_IPSBAR + 0x100078);
|
||||||
|
|
||||||
|
#ifdef CONFIG_FEC2
|
||||||
|
m527x_fec_irq_init(1);
|
||||||
|
|
||||||
|
/* Set multi-function pins to ethernet mode for fec1 */
|
||||||
|
par = readw(MCF_IPSBAR + 0x100082);
|
||||||
|
writew(par | 0xa0, MCF_IPSBAR + 0x100082);
|
||||||
|
v = readb(MCF_IPSBAR + 0x100079);
|
||||||
|
writeb(v | 0xc0, MCF_IPSBAR + 0x100079);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/***************************************************************************/
|
||||||
|
|
||||||
void mcf_disableall(void)
|
void mcf_disableall(void)
|
||||||
{
|
{
|
||||||
*((volatile unsigned long *) (MCF_IPSBAR + MCFICM_INTC0 + MCFINTC_IMRH)) = 0xffffffff;
|
*((volatile unsigned long *) (MCF_IPSBAR + MCFICM_INTC0 + MCFINTC_IMRH)) = 0xffffffff;
|
||||||
|
@ -116,13 +226,14 @@ void __init config_BSP(char *commandp, int size)
|
||||||
{
|
{
|
||||||
mcf_disableall();
|
mcf_disableall();
|
||||||
mach_reset = coldfire_reset;
|
mach_reset = coldfire_reset;
|
||||||
|
m527x_uarts_init();
|
||||||
|
m527x_fec_init();
|
||||||
}
|
}
|
||||||
|
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
|
|
||||||
static int __init init_BSP(void)
|
static int __init init_BSP(void)
|
||||||
{
|
{
|
||||||
m527x_uarts_init();
|
|
||||||
platform_add_devices(m527x_devices, ARRAY_SIZE(m527x_devices));
|
platform_add_devices(m527x_devices, ARRAY_SIZE(m527x_devices));
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -57,8 +57,40 @@ static struct platform_device m528x_uart = {
|
||||||
.dev.platform_data = m528x_uart_platform,
|
.dev.platform_data = m528x_uart_platform,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static struct resource m528x_fec_resources[] = {
|
||||||
|
{
|
||||||
|
.start = MCF_MBAR + 0x1000,
|
||||||
|
.end = MCF_MBAR + 0x1000 + 0x7ff,
|
||||||
|
.flags = IORESOURCE_MEM,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.start = 64 + 23,
|
||||||
|
.end = 64 + 23,
|
||||||
|
.flags = IORESOURCE_IRQ,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.start = 64 + 27,
|
||||||
|
.end = 64 + 27,
|
||||||
|
.flags = IORESOURCE_IRQ,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.start = 64 + 29,
|
||||||
|
.end = 64 + 29,
|
||||||
|
.flags = IORESOURCE_IRQ,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct platform_device m528x_fec = {
|
||||||
|
.name = "fec",
|
||||||
|
.id = 0,
|
||||||
|
.num_resources = ARRAY_SIZE(m528x_fec_resources),
|
||||||
|
.resource = m528x_fec_resources,
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
static struct platform_device *m528x_devices[] __initdata = {
|
static struct platform_device *m528x_devices[] __initdata = {
|
||||||
&m528x_uart,
|
&m528x_uart,
|
||||||
|
&m528x_fec,
|
||||||
};
|
};
|
||||||
|
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
|
@ -99,6 +131,31 @@ static void __init m528x_uarts_init(void)
|
||||||
|
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
|
|
||||||
|
static void __init m528x_fec_init(void)
|
||||||
|
{
|
||||||
|
u32 imr;
|
||||||
|
u16 v16;
|
||||||
|
|
||||||
|
/* Unmask FEC interrupts at ColdFire interrupt controller */
|
||||||
|
writeb(0x28, MCF_IPSBAR + MCFICM_INTC0 + MCFINTC_ICR0 + 23);
|
||||||
|
writeb(0x27, MCF_IPSBAR + MCFICM_INTC0 + MCFINTC_ICR0 + 27);
|
||||||
|
writeb(0x26, MCF_IPSBAR + MCFICM_INTC0 + MCFINTC_ICR0 + 29);
|
||||||
|
|
||||||
|
imr = readl(MCF_IPSBAR + MCFICM_INTC0 + MCFINTC_IMRH);
|
||||||
|
imr &= ~0xf;
|
||||||
|
writel(imr, MCF_IPSBAR + MCFICM_INTC0 + MCFINTC_IMRH);
|
||||||
|
imr = readl(MCF_IPSBAR + MCFICM_INTC0 + MCFINTC_IMRL);
|
||||||
|
imr &= ~0xff800001;
|
||||||
|
writel(imr, MCF_IPSBAR + MCFICM_INTC0 + MCFINTC_IMRL);
|
||||||
|
|
||||||
|
/* Set multi-function pins to ethernet mode for fec0 */
|
||||||
|
v16 = readw(MCF_IPSBAR + 0x100056);
|
||||||
|
writew(v16 | 0xf00, MCF_IPSBAR + 0x100056);
|
||||||
|
writeb(0xc0, MCF_IPSBAR + 0x100058);
|
||||||
|
}
|
||||||
|
|
||||||
|
/***************************************************************************/
|
||||||
|
|
||||||
void mcf_disableall(void)
|
void mcf_disableall(void)
|
||||||
{
|
{
|
||||||
*((volatile unsigned long *) (MCF_IPSBAR + MCFICM_INTC0 + MCFINTC_IMRH)) = 0xffffffff;
|
*((volatile unsigned long *) (MCF_IPSBAR + MCFICM_INTC0 + MCFINTC_IMRH)) = 0xffffffff;
|
||||||
|
@ -158,6 +215,7 @@ void __init config_BSP(char *commandp, int size)
|
||||||
static int __init init_BSP(void)
|
static int __init init_BSP(void)
|
||||||
{
|
{
|
||||||
m528x_uarts_init();
|
m528x_uarts_init();
|
||||||
|
m528x_fec_init();
|
||||||
platform_add_devices(m528x_devices, ARRAY_SIZE(m528x_devices));
|
platform_add_devices(m528x_devices, ARRAY_SIZE(m528x_devices));
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -61,8 +61,38 @@ static struct platform_device m532x_uart = {
|
||||||
.dev.platform_data = m532x_uart_platform,
|
.dev.platform_data = m532x_uart_platform,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static struct resource m532x_fec_resources[] = {
|
||||||
|
{
|
||||||
|
.start = 0xfc030000,
|
||||||
|
.end = 0xfc0307ff,
|
||||||
|
.flags = IORESOURCE_MEM,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.start = 64 + 36,
|
||||||
|
.end = 64 + 36,
|
||||||
|
.flags = IORESOURCE_IRQ,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.start = 64 + 40,
|
||||||
|
.end = 64 + 40,
|
||||||
|
.flags = IORESOURCE_IRQ,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.start = 64 + 42,
|
||||||
|
.end = 64 + 42,
|
||||||
|
.flags = IORESOURCE_IRQ,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct platform_device m532x_fec = {
|
||||||
|
.name = "fec",
|
||||||
|
.id = 0,
|
||||||
|
.num_resources = ARRAY_SIZE(m532x_fec_resources),
|
||||||
|
.resource = m532x_fec_resources,
|
||||||
|
};
|
||||||
static struct platform_device *m532x_devices[] __initdata = {
|
static struct platform_device *m532x_devices[] __initdata = {
|
||||||
&m532x_uart,
|
&m532x_uart,
|
||||||
|
&m532x_fec,
|
||||||
};
|
};
|
||||||
|
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
|
@ -93,6 +123,24 @@ static void __init m532x_uarts_init(void)
|
||||||
for (line = 0; (line < nrlines); line++)
|
for (line = 0; (line < nrlines); line++)
|
||||||
m532x_uart_init_line(line, m532x_uart_platform[line].irq);
|
m532x_uart_init_line(line, m532x_uart_platform[line].irq);
|
||||||
}
|
}
|
||||||
|
/***************************************************************************/
|
||||||
|
|
||||||
|
static void __init m532x_fec_init(void)
|
||||||
|
{
|
||||||
|
/* Unmask FEC interrupts at ColdFire interrupt controller */
|
||||||
|
MCF_INTC0_ICR36 = 0x2;
|
||||||
|
MCF_INTC0_ICR40 = 0x2;
|
||||||
|
MCF_INTC0_ICR42 = 0x2;
|
||||||
|
|
||||||
|
MCF_INTC0_IMRH &= ~(MCF_INTC_IMRH_INT_MASK36 |
|
||||||
|
MCF_INTC_IMRH_INT_MASK40 | MCF_INTC_IMRH_INT_MASK42);
|
||||||
|
|
||||||
|
/* Set multi-function pins to ethernet mode for fec0 */
|
||||||
|
MCF_GPIO_PAR_FECI2C |= (MCF_GPIO_PAR_FECI2C_PAR_MDC_EMDC |
|
||||||
|
MCF_GPIO_PAR_FECI2C_PAR_MDIO_EMDIO);
|
||||||
|
MCF_GPIO_PAR_FEC = (MCF_GPIO_PAR_FEC_PAR_FEC_7W_FEC |
|
||||||
|
MCF_GPIO_PAR_FEC_PAR_FEC_MII_FEC);
|
||||||
|
}
|
||||||
|
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
|
|
||||||
|
@ -150,6 +198,7 @@ void __init config_BSP(char *commandp, int size)
|
||||||
static int __init init_BSP(void)
|
static int __init init_BSP(void)
|
||||||
{
|
{
|
||||||
m532x_uarts_init();
|
m532x_uarts_init();
|
||||||
|
m532x_fec_init();
|
||||||
platform_add_devices(m532x_devices, ARRAY_SIZE(m532x_devices));
|
platform_add_devices(m532x_devices, ARRAY_SIZE(m532x_devices));
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -75,6 +75,9 @@ To add: #define SO_REUSEPORT 0x0200 /* Allow local address and port reuse. */
|
||||||
|
|
||||||
#define SO_MARK 36
|
#define SO_MARK 36
|
||||||
|
|
||||||
|
#define SO_TIMESTAMPING 37
|
||||||
|
#define SCM_TIMESTAMPING SO_TIMESTAMPING
|
||||||
|
|
||||||
#ifdef __KERNEL__
|
#ifdef __KERNEL__
|
||||||
|
|
||||||
/** sock_type - Socket types
|
/** sock_type - Socket types
|
||||||
|
|
|
@ -54,6 +54,9 @@
|
||||||
|
|
||||||
#define SO_MARK 0x401f
|
#define SO_MARK 0x401f
|
||||||
|
|
||||||
|
#define SO_TIMESTAMPING 0x4020
|
||||||
|
#define SCM_TIMESTAMPING SO_TIMESTAMPING
|
||||||
|
|
||||||
/* O_NONBLOCK clashes with the bits used for socket types. Therefore we
|
/* O_NONBLOCK clashes with the bits used for socket types. Therefore we
|
||||||
* have to define SOCK_NONBLOCK to a different value here.
|
* have to define SOCK_NONBLOCK to a different value here.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -61,4 +61,7 @@
|
||||||
|
|
||||||
#define SO_MARK 36
|
#define SO_MARK 36
|
||||||
|
|
||||||
|
#define SO_TIMESTAMPING 37
|
||||||
|
#define SCM_TIMESTAMPING SO_TIMESTAMPING
|
||||||
|
|
||||||
#endif /* _ASM_POWERPC_SOCKET_H */
|
#endif /* _ASM_POWERPC_SOCKET_H */
|
||||||
|
|
|
@ -62,4 +62,7 @@
|
||||||
|
|
||||||
#define SO_MARK 36
|
#define SO_MARK 36
|
||||||
|
|
||||||
|
#define SO_TIMESTAMPING 37
|
||||||
|
#define SCM_TIMESTAMPING SO_TIMESTAMPING
|
||||||
|
|
||||||
#endif /* _ASM_SOCKET_H */
|
#endif /* _ASM_SOCKET_H */
|
||||||
|
|
|
@ -54,4 +54,7 @@
|
||||||
|
|
||||||
#define SO_MARK 36
|
#define SO_MARK 36
|
||||||
|
|
||||||
|
#define SO_TIMESTAMPING 37
|
||||||
|
#define SCM_TIMESTAMPING SO_TIMESTAMPING
|
||||||
|
|
||||||
#endif /* __ASM_SH_SOCKET_H */
|
#endif /* __ASM_SH_SOCKET_H */
|
||||||
|
|
|
@ -50,6 +50,9 @@
|
||||||
|
|
||||||
#define SO_MARK 0x0022
|
#define SO_MARK 0x0022
|
||||||
|
|
||||||
|
#define SO_TIMESTAMPING 0x0023
|
||||||
|
#define SCM_TIMESTAMPING SO_TIMESTAMPING
|
||||||
|
|
||||||
/* Security levels - as per NRL IPv6 - don't actually do anything */
|
/* Security levels - as per NRL IPv6 - don't actually do anything */
|
||||||
#define SO_SECURITY_AUTHENTICATION 0x5001
|
#define SO_SECURITY_AUTHENTICATION 0x5001
|
||||||
#define SO_SECURITY_ENCRYPTION_TRANSPORT 0x5002
|
#define SO_SECURITY_ENCRYPTION_TRANSPORT 0x5002
|
||||||
|
|
|
@ -54,4 +54,7 @@
|
||||||
|
|
||||||
#define SO_MARK 36
|
#define SO_MARK 36
|
||||||
|
|
||||||
|
#define SO_TIMESTAMPING 37
|
||||||
|
#define SCM_TIMESTAMPING SO_TIMESTAMPING
|
||||||
|
|
||||||
#endif /* _ASM_X86_SOCKET_H */
|
#endif /* _ASM_X86_SOCKET_H */
|
||||||
|
|
|
@ -65,4 +65,7 @@
|
||||||
|
|
||||||
#define SO_MARK 36
|
#define SO_MARK 36
|
||||||
|
|
||||||
|
#define SO_TIMESTAMPING 37
|
||||||
|
#define SCM_TIMESTAMPING SO_TIMESTAMPING
|
||||||
|
|
||||||
#endif /* _XTENSA_SOCKET_H */
|
#endif /* _XTENSA_SOCKET_H */
|
||||||
|
|
|
@ -235,11 +235,7 @@ int acpi_bus_generate_netlink_event(const char *device_class,
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
result =
|
genlmsg_multicast(skb, 0, acpi_event_mcgrp.id, GFP_ATOMIC);
|
||||||
genlmsg_multicast(skb, 0, acpi_event_mcgrp.id, GFP_ATOMIC);
|
|
||||||
if (result)
|
|
||||||
ACPI_DEBUG_PRINT((ACPI_DB_INFO,
|
|
||||||
"Failed to send a Genetlink message!\n"));
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1690,17 +1690,17 @@ static int __devinit fs_init (struct fs_dev *dev)
|
||||||
| (0 * SARMODE0_SHADEN) /* We don't use shadow registers. */
|
| (0 * SARMODE0_SHADEN) /* We don't use shadow registers. */
|
||||||
| (1 * SARMODE0_INTMODE_READCLEAR)
|
| (1 * SARMODE0_INTMODE_READCLEAR)
|
||||||
| (1 * SARMODE0_CWRE)
|
| (1 * SARMODE0_CWRE)
|
||||||
| IS_FS50(dev)?SARMODE0_PRPWT_FS50_5:
|
| (IS_FS50(dev) ? SARMODE0_PRPWT_FS50_5:
|
||||||
SARMODE0_PRPWT_FS155_3
|
SARMODE0_PRPWT_FS155_3)
|
||||||
| (1 * SARMODE0_CALSUP_1)
|
| (1 * SARMODE0_CALSUP_1)
|
||||||
| IS_FS50 (dev)?(0
|
| (IS_FS50(dev) ? (0
|
||||||
| SARMODE0_RXVCS_32
|
| SARMODE0_RXVCS_32
|
||||||
| SARMODE0_ABRVCS_32
|
| SARMODE0_ABRVCS_32
|
||||||
| SARMODE0_TXVCS_32):
|
| SARMODE0_TXVCS_32):
|
||||||
(0
|
(0
|
||||||
| SARMODE0_RXVCS_1k
|
| SARMODE0_RXVCS_1k
|
||||||
| SARMODE0_ABRVCS_1k
|
| SARMODE0_ABRVCS_1k
|
||||||
| SARMODE0_TXVCS_1k));
|
| SARMODE0_TXVCS_1k)));
|
||||||
|
|
||||||
/* 10ms * 100 is 1 second. That should be enough, as AN3:9 says it takes
|
/* 10ms * 100 is 1 second. That should be enough, as AN3:9 says it takes
|
||||||
1ms. */
|
1ms. */
|
||||||
|
|
|
@ -977,9 +977,7 @@ static void xdump( u_char* cp, int length, char* prefix )
|
||||||
else
|
else
|
||||||
pBuf += sprintf( pBuf, "." );
|
pBuf += sprintf( pBuf, "." );
|
||||||
}
|
}
|
||||||
sprintf( pBuf, "\n" );
|
printk("%s\n", prntBuf);
|
||||||
// SPrint(prntBuf);
|
|
||||||
printk(prntBuf);
|
|
||||||
count += col;
|
count += col;
|
||||||
pBuf = prntBuf;
|
pBuf = prntBuf;
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,70 @@
|
||||||
|
SOLOS_ATTR_RO(DriverVersion)
|
||||||
|
SOLOS_ATTR_RO(APIVersion)
|
||||||
|
SOLOS_ATTR_RO(FirmwareVersion)
|
||||||
|
// SOLOS_ATTR_RO(DspVersion)
|
||||||
|
// SOLOS_ATTR_RO(CommonHandshake)
|
||||||
|
SOLOS_ATTR_RO(Connected)
|
||||||
|
SOLOS_ATTR_RO(OperationalMode)
|
||||||
|
SOLOS_ATTR_RO(State)
|
||||||
|
SOLOS_ATTR_RO(Watchdog)
|
||||||
|
SOLOS_ATTR_RO(OperationProgress)
|
||||||
|
SOLOS_ATTR_RO(LastFailed)
|
||||||
|
SOLOS_ATTR_RO(TxBitRate)
|
||||||
|
SOLOS_ATTR_RO(RxBitRate)
|
||||||
|
// SOLOS_ATTR_RO(DeltACTATPds)
|
||||||
|
// SOLOS_ATTR_RO(DeltACTATPus)
|
||||||
|
SOLOS_ATTR_RO(TxATTNDR)
|
||||||
|
SOLOS_ATTR_RO(RxATTNDR)
|
||||||
|
SOLOS_ATTR_RO(AnnexType)
|
||||||
|
SOLOS_ATTR_RO(GeneralFailure)
|
||||||
|
SOLOS_ATTR_RO(InterleaveDpDn)
|
||||||
|
SOLOS_ATTR_RO(InterleaveDpUp)
|
||||||
|
SOLOS_ATTR_RO(RSCorrectedErrorsDn)
|
||||||
|
SOLOS_ATTR_RO(RSUnCorrectedErrorsDn)
|
||||||
|
SOLOS_ATTR_RO(RSCorrectedErrorsUp)
|
||||||
|
SOLOS_ATTR_RO(RSUnCorrectedErrorsUp)
|
||||||
|
SOLOS_ATTR_RO(InterleaveRDn)
|
||||||
|
SOLOS_ATTR_RO(InterleaveRUp)
|
||||||
|
SOLOS_ATTR_RO(ShowtimeStart)
|
||||||
|
SOLOS_ATTR_RO(ATURVendor)
|
||||||
|
SOLOS_ATTR_RO(ATUCCountry)
|
||||||
|
SOLOS_ATTR_RO(ATURANSIRev)
|
||||||
|
SOLOS_ATTR_RO(ATURANSISTD)
|
||||||
|
SOLOS_ATTR_RO(ATUCANSIRev)
|
||||||
|
SOLOS_ATTR_RO(ATUCANSIId)
|
||||||
|
SOLOS_ATTR_RO(ATUCANSISTD)
|
||||||
|
SOLOS_ATTR_RO(DataBoost)
|
||||||
|
SOLOS_ATTR_RO(LocalITUCountryCode)
|
||||||
|
SOLOS_ATTR_RO(LocalSEF)
|
||||||
|
SOLOS_ATTR_RO(LocalEndLOS)
|
||||||
|
SOLOS_ATTR_RO(LocalSNRMargin)
|
||||||
|
SOLOS_ATTR_RO(LocalLineAttn)
|
||||||
|
SOLOS_ATTR_RO(RawAttn)
|
||||||
|
SOLOS_ATTR_RO(LocalTxPower)
|
||||||
|
SOLOS_ATTR_RO(RemoteTxPower)
|
||||||
|
SOLOS_ATTR_RO(RemoteSEF)
|
||||||
|
SOLOS_ATTR_RO(RemoteLOS)
|
||||||
|
SOLOS_ATTR_RO(RemoteLineAttn)
|
||||||
|
SOLOS_ATTR_RO(RemoteSNRMargin)
|
||||||
|
SOLOS_ATTR_RO(LineUpCount)
|
||||||
|
SOLOS_ATTR_RO(SRACnt)
|
||||||
|
SOLOS_ATTR_RO(SRACntUp)
|
||||||
|
SOLOS_ATTR_RO(ProfileStatus)
|
||||||
|
SOLOS_ATTR_RW(Action)
|
||||||
|
SOLOS_ATTR_RW(ActivateLine)
|
||||||
|
SOLOS_ATTR_RO(LineStatus)
|
||||||
|
SOLOS_ATTR_RW(HostControl)
|
||||||
|
SOLOS_ATTR_RW(AutoStart)
|
||||||
|
SOLOS_ATTR_RW(Failsafe)
|
||||||
|
SOLOS_ATTR_RW(ShowtimeLed)
|
||||||
|
SOLOS_ATTR_RW(Retrain)
|
||||||
|
SOLOS_ATTR_RW(Defaults)
|
||||||
|
SOLOS_ATTR_RW(LineMode)
|
||||||
|
SOLOS_ATTR_RW(Profile)
|
||||||
|
SOLOS_ATTR_RW(DetectNoise)
|
||||||
|
SOLOS_ATTR_RO(SupportedAnnexes)
|
||||||
|
SOLOS_ATTR_RO(Status)
|
||||||
|
SOLOS_ATTR_RO(TotalStart)
|
||||||
|
SOLOS_ATTR_RO(RecentShowtimeStart)
|
||||||
|
SOLOS_ATTR_RO(TotalRxBlocks)
|
||||||
|
SOLOS_ATTR_RO(TotalTxBlocks)
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -151,7 +151,7 @@ exit:
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct packet_type aoe_pt = {
|
static struct packet_type aoe_pt __read_mostly = {
|
||||||
.type = __constant_htons(ETH_P_AOE),
|
.type = __constant_htons(ETH_P_AOE),
|
||||||
.func = aoenet_rcv,
|
.func = aoenet_rcv,
|
||||||
};
|
};
|
||||||
|
|
|
@ -257,8 +257,7 @@ static inline int bfusb_recv_block(struct bfusb_data *data, int hdr, unsigned ch
|
||||||
|
|
||||||
if (hdr & 0x10) {
|
if (hdr & 0x10) {
|
||||||
BT_ERR("%s error in block", data->hdev->name);
|
BT_ERR("%s error in block", data->hdev->name);
|
||||||
if (data->reassembly)
|
kfree_skb(data->reassembly);
|
||||||
kfree_skb(data->reassembly);
|
|
||||||
data->reassembly = NULL;
|
data->reassembly = NULL;
|
||||||
return -EIO;
|
return -EIO;
|
||||||
}
|
}
|
||||||
|
|
|
@ -359,9 +359,9 @@ static irqreturn_t bt3c_interrupt(int irq, void *dev_inst)
|
||||||
BT_ERR("Very strange (stat=0x%04x)", stat);
|
BT_ERR("Very strange (stat=0x%04x)", stat);
|
||||||
} else if ((stat & 0xff) != 0xff) {
|
} else if ((stat & 0xff) != 0xff) {
|
||||||
if (stat & 0x0020) {
|
if (stat & 0x0020) {
|
||||||
int stat = bt3c_read(iobase, 0x7002) & 0x10;
|
int status = bt3c_read(iobase, 0x7002) & 0x10;
|
||||||
BT_INFO("%s: Antenna %s", info->hdev->name,
|
BT_INFO("%s: Antenna %s", info->hdev->name,
|
||||||
stat ? "out" : "in");
|
status ? "out" : "in");
|
||||||
}
|
}
|
||||||
if (stat & 0x0001)
|
if (stat & 0x0001)
|
||||||
bt3c_receive(info);
|
bt3c_receive(info);
|
||||||
|
|
|
@ -35,7 +35,7 @@
|
||||||
#include <net/bluetooth/bluetooth.h>
|
#include <net/bluetooth/bluetooth.h>
|
||||||
#include <net/bluetooth/hci_core.h>
|
#include <net/bluetooth/hci_core.h>
|
||||||
|
|
||||||
#define VERSION "0.4"
|
#define VERSION "0.5"
|
||||||
|
|
||||||
static int ignore_dga;
|
static int ignore_dga;
|
||||||
static int ignore_csr;
|
static int ignore_csr;
|
||||||
|
@ -171,6 +171,7 @@ struct btusb_data {
|
||||||
|
|
||||||
__u8 cmdreq_type;
|
__u8 cmdreq_type;
|
||||||
|
|
||||||
|
unsigned int sco_num;
|
||||||
int isoc_altsetting;
|
int isoc_altsetting;
|
||||||
int suspend_count;
|
int suspend_count;
|
||||||
};
|
};
|
||||||
|
@ -496,11 +497,23 @@ static int btusb_open(struct hci_dev *hdev)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
err = btusb_submit_intr_urb(hdev, GFP_KERNEL);
|
err = btusb_submit_intr_urb(hdev, GFP_KERNEL);
|
||||||
|
if (err < 0)
|
||||||
|
goto failed;
|
||||||
|
|
||||||
|
err = btusb_submit_bulk_urb(hdev, GFP_KERNEL);
|
||||||
if (err < 0) {
|
if (err < 0) {
|
||||||
clear_bit(BTUSB_INTR_RUNNING, &data->flags);
|
usb_kill_anchored_urbs(&data->intr_anchor);
|
||||||
clear_bit(HCI_RUNNING, &hdev->flags);
|
goto failed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
set_bit(BTUSB_BULK_RUNNING, &data->flags);
|
||||||
|
btusb_submit_bulk_urb(hdev, GFP_KERNEL);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
failed:
|
||||||
|
clear_bit(BTUSB_INTR_RUNNING, &data->flags);
|
||||||
|
clear_bit(HCI_RUNNING, &hdev->flags);
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -655,19 +668,10 @@ static void btusb_notify(struct hci_dev *hdev, unsigned int evt)
|
||||||
|
|
||||||
BT_DBG("%s evt %d", hdev->name, evt);
|
BT_DBG("%s evt %d", hdev->name, evt);
|
||||||
|
|
||||||
if (hdev->conn_hash.acl_num > 0) {
|
if (hdev->conn_hash.sco_num != data->sco_num) {
|
||||||
if (!test_and_set_bit(BTUSB_BULK_RUNNING, &data->flags)) {
|
data->sco_num = hdev->conn_hash.sco_num;
|
||||||
if (btusb_submit_bulk_urb(hdev, GFP_ATOMIC) < 0)
|
schedule_work(&data->work);
|
||||||
clear_bit(BTUSB_BULK_RUNNING, &data->flags);
|
|
||||||
else
|
|
||||||
btusb_submit_bulk_urb(hdev, GFP_ATOMIC);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
clear_bit(BTUSB_BULK_RUNNING, &data->flags);
|
|
||||||
usb_unlink_anchored_urbs(&data->bulk_anchor);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
schedule_work(&data->work);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int inline __set_isoc_interface(struct hci_dev *hdev, int altsetting)
|
static int inline __set_isoc_interface(struct hci_dev *hdev, int altsetting)
|
||||||
|
@ -982,9 +986,11 @@ static int btusb_resume(struct usb_interface *intf)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (test_bit(BTUSB_BULK_RUNNING, &data->flags)) {
|
if (test_bit(BTUSB_BULK_RUNNING, &data->flags)) {
|
||||||
if (btusb_submit_bulk_urb(hdev, GFP_NOIO) < 0)
|
err = btusb_submit_bulk_urb(hdev, GFP_NOIO);
|
||||||
|
if (err < 0) {
|
||||||
clear_bit(BTUSB_BULK_RUNNING, &data->flags);
|
clear_bit(BTUSB_BULK_RUNNING, &data->flags);
|
||||||
else
|
return err;
|
||||||
|
} else
|
||||||
btusb_submit_bulk_urb(hdev, GFP_NOIO);
|
btusb_submit_bulk_urb(hdev, GFP_NOIO);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -102,8 +102,7 @@ static int h4_close(struct hci_uart *hu)
|
||||||
|
|
||||||
skb_queue_purge(&h4->txq);
|
skb_queue_purge(&h4->txq);
|
||||||
|
|
||||||
if (h4->rx_skb)
|
kfree_skb(h4->rx_skb);
|
||||||
kfree_skb(h4->rx_skb);
|
|
||||||
|
|
||||||
hu->priv = NULL;
|
hu->priv = NULL;
|
||||||
kfree(h4);
|
kfree(h4);
|
||||||
|
|
|
@ -163,8 +163,7 @@ static int ll_close(struct hci_uart *hu)
|
||||||
skb_queue_purge(&ll->tx_wait_q);
|
skb_queue_purge(&ll->tx_wait_q);
|
||||||
skb_queue_purge(&ll->txq);
|
skb_queue_purge(&ll->txq);
|
||||||
|
|
||||||
if (ll->rx_skb)
|
kfree_skb(ll->rx_skb);
|
||||||
kfree_skb(ll->rx_skb);
|
|
||||||
|
|
||||||
hu->priv = NULL;
|
hu->priv = NULL;
|
||||||
|
|
||||||
|
|
|
@ -4311,10 +4311,17 @@ static void hdlcdev_rx(MGSLPC_INFO *info, char *buf, int size)
|
||||||
dev->stats.rx_bytes += size;
|
dev->stats.rx_bytes += size;
|
||||||
|
|
||||||
netif_rx(skb);
|
netif_rx(skb);
|
||||||
|
|
||||||
dev->last_rx = jiffies;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const struct net_device_ops hdlcdev_ops = {
|
||||||
|
.ndo_open = hdlcdev_open,
|
||||||
|
.ndo_stop = hdlcdev_close,
|
||||||
|
.ndo_change_mtu = hdlc_change_mtu,
|
||||||
|
.ndo_start_xmit = hdlc_start_xmit,
|
||||||
|
.ndo_do_ioctl = hdlcdev_ioctl,
|
||||||
|
.ndo_tx_timeout = hdlcdev_tx_timeout,
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* called by device driver when adding device instance
|
* called by device driver when adding device instance
|
||||||
* do generic HDLC initialization
|
* do generic HDLC initialization
|
||||||
|
@ -4341,11 +4348,8 @@ static int hdlcdev_init(MGSLPC_INFO *info)
|
||||||
dev->irq = info->irq_level;
|
dev->irq = info->irq_level;
|
||||||
|
|
||||||
/* network layer callbacks and settings */
|
/* network layer callbacks and settings */
|
||||||
dev->do_ioctl = hdlcdev_ioctl;
|
dev->netdev_ops = &hdlcdev_ops;
|
||||||
dev->open = hdlcdev_open;
|
dev->watchdog_timeo = 10 * HZ;
|
||||||
dev->stop = hdlcdev_close;
|
|
||||||
dev->tx_timeout = hdlcdev_tx_timeout;
|
|
||||||
dev->watchdog_timeo = 10*HZ;
|
|
||||||
dev->tx_queue_len = 50;
|
dev->tx_queue_len = 50;
|
||||||
|
|
||||||
/* generic HDLC layer callbacks and settings */
|
/* generic HDLC layer callbacks and settings */
|
||||||
|
|
|
@ -8007,10 +8007,17 @@ static void hdlcdev_rx(struct mgsl_struct *info, char *buf, int size)
|
||||||
dev->stats.rx_bytes += size;
|
dev->stats.rx_bytes += size;
|
||||||
|
|
||||||
netif_rx(skb);
|
netif_rx(skb);
|
||||||
|
|
||||||
dev->last_rx = jiffies;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const struct net_device_ops hdlcdev_ops = {
|
||||||
|
.ndo_open = hdlcdev_open,
|
||||||
|
.ndo_stop = hdlcdev_close,
|
||||||
|
.ndo_change_mtu = hdlc_change_mtu,
|
||||||
|
.ndo_start_xmit = hdlc_start_xmit,
|
||||||
|
.ndo_do_ioctl = hdlcdev_ioctl,
|
||||||
|
.ndo_tx_timeout = hdlcdev_tx_timeout,
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* called by device driver when adding device instance
|
* called by device driver when adding device instance
|
||||||
* do generic HDLC initialization
|
* do generic HDLC initialization
|
||||||
|
@ -8038,11 +8045,8 @@ static int hdlcdev_init(struct mgsl_struct *info)
|
||||||
dev->dma = info->dma_level;
|
dev->dma = info->dma_level;
|
||||||
|
|
||||||
/* network layer callbacks and settings */
|
/* network layer callbacks and settings */
|
||||||
dev->do_ioctl = hdlcdev_ioctl;
|
dev->netdev_ops = &hdlcdev_ops;
|
||||||
dev->open = hdlcdev_open;
|
dev->watchdog_timeo = 10 * HZ;
|
||||||
dev->stop = hdlcdev_close;
|
|
||||||
dev->tx_timeout = hdlcdev_tx_timeout;
|
|
||||||
dev->watchdog_timeo = 10*HZ;
|
|
||||||
dev->tx_queue_len = 50;
|
dev->tx_queue_len = 50;
|
||||||
|
|
||||||
/* generic HDLC layer callbacks and settings */
|
/* generic HDLC layer callbacks and settings */
|
||||||
|
|
|
@ -1763,10 +1763,17 @@ static void hdlcdev_rx(struct slgt_info *info, char *buf, int size)
|
||||||
dev->stats.rx_bytes += size;
|
dev->stats.rx_bytes += size;
|
||||||
|
|
||||||
netif_rx(skb);
|
netif_rx(skb);
|
||||||
|
|
||||||
dev->last_rx = jiffies;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const struct net_device_ops hdlcdev_ops = {
|
||||||
|
.ndo_open = hdlcdev_open,
|
||||||
|
.ndo_stop = hdlcdev_close,
|
||||||
|
.ndo_change_mtu = hdlc_change_mtu,
|
||||||
|
.ndo_start_xmit = hdlc_start_xmit,
|
||||||
|
.ndo_do_ioctl = hdlcdev_ioctl,
|
||||||
|
.ndo_tx_timeout = hdlcdev_tx_timeout,
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* called by device driver when adding device instance
|
* called by device driver when adding device instance
|
||||||
* do generic HDLC initialization
|
* do generic HDLC initialization
|
||||||
|
@ -1794,11 +1801,8 @@ static int hdlcdev_init(struct slgt_info *info)
|
||||||
dev->irq = info->irq_level;
|
dev->irq = info->irq_level;
|
||||||
|
|
||||||
/* network layer callbacks and settings */
|
/* network layer callbacks and settings */
|
||||||
dev->do_ioctl = hdlcdev_ioctl;
|
dev->netdev_ops = &hdlcdev_ops;
|
||||||
dev->open = hdlcdev_open;
|
dev->watchdog_timeo = 10 * HZ;
|
||||||
dev->stop = hdlcdev_close;
|
|
||||||
dev->tx_timeout = hdlcdev_tx_timeout;
|
|
||||||
dev->watchdog_timeo = 10*HZ;
|
|
||||||
dev->tx_queue_len = 50;
|
dev->tx_queue_len = 50;
|
||||||
|
|
||||||
/* generic HDLC layer callbacks and settings */
|
/* generic HDLC layer callbacks and settings */
|
||||||
|
|
|
@ -1907,10 +1907,17 @@ static void hdlcdev_rx(SLMP_INFO *info, char *buf, int size)
|
||||||
dev->stats.rx_bytes += size;
|
dev->stats.rx_bytes += size;
|
||||||
|
|
||||||
netif_rx(skb);
|
netif_rx(skb);
|
||||||
|
|
||||||
dev->last_rx = jiffies;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const struct net_device_ops hdlcdev_ops = {
|
||||||
|
.ndo_open = hdlcdev_open,
|
||||||
|
.ndo_stop = hdlcdev_close,
|
||||||
|
.ndo_change_mtu = hdlc_change_mtu,
|
||||||
|
.ndo_start_xmit = hdlc_start_xmit,
|
||||||
|
.ndo_do_ioctl = hdlcdev_ioctl,
|
||||||
|
.ndo_tx_timeout = hdlcdev_tx_timeout,
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* called by device driver when adding device instance
|
* called by device driver when adding device instance
|
||||||
* do generic HDLC initialization
|
* do generic HDLC initialization
|
||||||
|
@ -1938,11 +1945,8 @@ static int hdlcdev_init(SLMP_INFO *info)
|
||||||
dev->irq = info->irq_level;
|
dev->irq = info->irq_level;
|
||||||
|
|
||||||
/* network layer callbacks and settings */
|
/* network layer callbacks and settings */
|
||||||
dev->do_ioctl = hdlcdev_ioctl;
|
dev->netdev_ops = &hdlcdev_ops;
|
||||||
dev->open = hdlcdev_open;
|
dev->watchdog_timeo = 10 * HZ;
|
||||||
dev->stop = hdlcdev_close;
|
|
||||||
dev->tx_timeout = hdlcdev_tx_timeout;
|
|
||||||
dev->watchdog_timeo = 10*HZ;
|
|
||||||
dev->tx_queue_len = 50;
|
dev->tx_queue_len = 50;
|
||||||
|
|
||||||
/* generic HDLC layer callbacks and settings */
|
/* generic HDLC layer callbacks and settings */
|
||||||
|
|
|
@ -31,6 +31,48 @@
|
||||||
#include <linux/connector.h>
|
#include <linux/connector.h>
|
||||||
#include <linux/delay.h>
|
#include <linux/delay.h>
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This job is sent to the kevent workqueue.
|
||||||
|
* While no event is once sent to any callback, the connector workqueue
|
||||||
|
* is not created to avoid a useless waiting kernel task.
|
||||||
|
* Once the first event is received, we create this dedicated workqueue which
|
||||||
|
* is necessary because the flow of data can be high and we don't want
|
||||||
|
* to encumber keventd with that.
|
||||||
|
*/
|
||||||
|
static void cn_queue_create(struct work_struct *work)
|
||||||
|
{
|
||||||
|
struct cn_queue_dev *dev;
|
||||||
|
|
||||||
|
dev = container_of(work, struct cn_queue_dev, wq_creation);
|
||||||
|
|
||||||
|
dev->cn_queue = create_singlethread_workqueue(dev->name);
|
||||||
|
/* If we fail, we will use keventd for all following connector jobs */
|
||||||
|
WARN_ON(!dev->cn_queue);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Queue a data sent to a callback.
|
||||||
|
* If the connector workqueue is already created, we queue the job on it.
|
||||||
|
* Otherwise, we queue the job to kevent and queue the connector workqueue
|
||||||
|
* creation too.
|
||||||
|
*/
|
||||||
|
int queue_cn_work(struct cn_callback_entry *cbq, struct work_struct *work)
|
||||||
|
{
|
||||||
|
struct cn_queue_dev *pdev = cbq->pdev;
|
||||||
|
|
||||||
|
if (likely(pdev->cn_queue))
|
||||||
|
return queue_work(pdev->cn_queue, work);
|
||||||
|
|
||||||
|
/* Don't create the connector workqueue twice */
|
||||||
|
if (atomic_inc_return(&pdev->wq_requested) == 1)
|
||||||
|
schedule_work(&pdev->wq_creation);
|
||||||
|
else
|
||||||
|
atomic_dec(&pdev->wq_requested);
|
||||||
|
|
||||||
|
return schedule_work(work);
|
||||||
|
}
|
||||||
|
|
||||||
void cn_queue_wrapper(struct work_struct *work)
|
void cn_queue_wrapper(struct work_struct *work)
|
||||||
{
|
{
|
||||||
struct cn_callback_entry *cbq =
|
struct cn_callback_entry *cbq =
|
||||||
|
@ -65,7 +107,10 @@ static struct cn_callback_entry *cn_queue_alloc_callback_entry(char *name, struc
|
||||||
|
|
||||||
static void cn_queue_free_callback(struct cn_callback_entry *cbq)
|
static void cn_queue_free_callback(struct cn_callback_entry *cbq)
|
||||||
{
|
{
|
||||||
flush_workqueue(cbq->pdev->cn_queue);
|
/* The first jobs have been sent to kevent, flush them too */
|
||||||
|
flush_scheduled_work();
|
||||||
|
if (cbq->pdev->cn_queue)
|
||||||
|
flush_workqueue(cbq->pdev->cn_queue);
|
||||||
|
|
||||||
kfree(cbq);
|
kfree(cbq);
|
||||||
}
|
}
|
||||||
|
@ -143,14 +188,11 @@ struct cn_queue_dev *cn_queue_alloc_dev(char *name, struct sock *nls)
|
||||||
atomic_set(&dev->refcnt, 0);
|
atomic_set(&dev->refcnt, 0);
|
||||||
INIT_LIST_HEAD(&dev->queue_list);
|
INIT_LIST_HEAD(&dev->queue_list);
|
||||||
spin_lock_init(&dev->queue_lock);
|
spin_lock_init(&dev->queue_lock);
|
||||||
|
init_waitqueue_head(&dev->wq_created);
|
||||||
|
|
||||||
dev->nls = nls;
|
dev->nls = nls;
|
||||||
|
|
||||||
dev->cn_queue = create_singlethread_workqueue(dev->name);
|
INIT_WORK(&dev->wq_creation, cn_queue_create);
|
||||||
if (!dev->cn_queue) {
|
|
||||||
kfree(dev);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
return dev;
|
return dev;
|
||||||
}
|
}
|
||||||
|
@ -158,9 +200,25 @@ struct cn_queue_dev *cn_queue_alloc_dev(char *name, struct sock *nls)
|
||||||
void cn_queue_free_dev(struct cn_queue_dev *dev)
|
void cn_queue_free_dev(struct cn_queue_dev *dev)
|
||||||
{
|
{
|
||||||
struct cn_callback_entry *cbq, *n;
|
struct cn_callback_entry *cbq, *n;
|
||||||
|
long timeout;
|
||||||
|
DEFINE_WAIT(wait);
|
||||||
|
|
||||||
flush_workqueue(dev->cn_queue);
|
/* Flush the first pending jobs queued on kevent */
|
||||||
destroy_workqueue(dev->cn_queue);
|
flush_scheduled_work();
|
||||||
|
|
||||||
|
/* If the connector workqueue creation is still pending, wait for it */
|
||||||
|
prepare_to_wait(&dev->wq_created, &wait, TASK_UNINTERRUPTIBLE);
|
||||||
|
if (atomic_read(&dev->wq_requested) && !dev->cn_queue) {
|
||||||
|
timeout = schedule_timeout(HZ * 2);
|
||||||
|
if (!timeout && !dev->cn_queue)
|
||||||
|
WARN_ON(1);
|
||||||
|
}
|
||||||
|
finish_wait(&dev->wq_created, &wait);
|
||||||
|
|
||||||
|
if (dev->cn_queue) {
|
||||||
|
flush_workqueue(dev->cn_queue);
|
||||||
|
destroy_workqueue(dev->cn_queue);
|
||||||
|
}
|
||||||
|
|
||||||
spin_lock_bh(&dev->queue_lock);
|
spin_lock_bh(&dev->queue_lock);
|
||||||
list_for_each_entry_safe(cbq, n, &dev->queue_list, callback_entry)
|
list_for_each_entry_safe(cbq, n, &dev->queue_list, callback_entry)
|
||||||
|
|
|
@ -145,8 +145,7 @@ static int cn_call_callback(struct cn_msg *msg, void (*destruct_data)(void *), v
|
||||||
__cbq->data.ddata = data;
|
__cbq->data.ddata = data;
|
||||||
__cbq->data.destruct_data = destruct_data;
|
__cbq->data.destruct_data = destruct_data;
|
||||||
|
|
||||||
if (queue_work(dev->cbdev->cn_queue,
|
if (queue_cn_work(__cbq, &__cbq->work))
|
||||||
&__cbq->work))
|
|
||||||
err = 0;
|
err = 0;
|
||||||
else
|
else
|
||||||
err = -EINVAL;
|
err = -EINVAL;
|
||||||
|
@ -163,10 +162,12 @@ static int cn_call_callback(struct cn_msg *msg, void (*destruct_data)(void *), v
|
||||||
d->destruct_data = destruct_data;
|
d->destruct_data = destruct_data;
|
||||||
d->free = __new_cbq;
|
d->free = __new_cbq;
|
||||||
|
|
||||||
|
__new_cbq->pdev = __cbq->pdev;
|
||||||
|
|
||||||
INIT_WORK(&__new_cbq->work,
|
INIT_WORK(&__new_cbq->work,
|
||||||
&cn_queue_wrapper);
|
&cn_queue_wrapper);
|
||||||
|
|
||||||
if (queue_work(dev->cbdev->cn_queue,
|
if (queue_cn_work(__new_cbq,
|
||||||
&__new_cbq->work))
|
&__new_cbq->work))
|
||||||
err = 0;
|
err = 0;
|
||||||
else {
|
else {
|
||||||
|
|
|
@ -76,7 +76,6 @@ static irqreturn_t c2_interrupt(int irq, void *dev_id);
|
||||||
static void c2_tx_timeout(struct net_device *netdev);
|
static void c2_tx_timeout(struct net_device *netdev);
|
||||||
static int c2_change_mtu(struct net_device *netdev, int new_mtu);
|
static int c2_change_mtu(struct net_device *netdev, int new_mtu);
|
||||||
static void c2_reset(struct c2_port *c2_port);
|
static void c2_reset(struct c2_port *c2_port);
|
||||||
static struct net_device_stats *c2_get_stats(struct net_device *netdev);
|
|
||||||
|
|
||||||
static struct pci_device_id c2_pci_table[] = {
|
static struct pci_device_id c2_pci_table[] = {
|
||||||
{ PCI_DEVICE(0x18b8, 0xb001) },
|
{ PCI_DEVICE(0x18b8, 0xb001) },
|
||||||
|
@ -349,7 +348,7 @@ static void c2_tx_clean(struct c2_port *c2_port)
|
||||||
elem->hw_desc + C2_TXP_ADDR);
|
elem->hw_desc + C2_TXP_ADDR);
|
||||||
__raw_writew((__force u16) cpu_to_be16(TXP_HTXD_DONE),
|
__raw_writew((__force u16) cpu_to_be16(TXP_HTXD_DONE),
|
||||||
elem->hw_desc + C2_TXP_FLAGS);
|
elem->hw_desc + C2_TXP_FLAGS);
|
||||||
c2_port->netstats.tx_dropped++;
|
c2_port->netdev->stats.tx_dropped++;
|
||||||
break;
|
break;
|
||||||
} else {
|
} else {
|
||||||
__raw_writew(0,
|
__raw_writew(0,
|
||||||
|
@ -457,7 +456,7 @@ static void c2_rx_error(struct c2_port *c2_port, struct c2_element *elem)
|
||||||
elem->hw_desc + C2_RXP_FLAGS);
|
elem->hw_desc + C2_RXP_FLAGS);
|
||||||
|
|
||||||
pr_debug("packet dropped\n");
|
pr_debug("packet dropped\n");
|
||||||
c2_port->netstats.rx_dropped++;
|
c2_port->netdev->stats.rx_dropped++;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void c2_rx_interrupt(struct net_device *netdev)
|
static void c2_rx_interrupt(struct net_device *netdev)
|
||||||
|
@ -532,8 +531,8 @@ static void c2_rx_interrupt(struct net_device *netdev)
|
||||||
netif_rx(skb);
|
netif_rx(skb);
|
||||||
|
|
||||||
netdev->last_rx = jiffies;
|
netdev->last_rx = jiffies;
|
||||||
c2_port->netstats.rx_packets++;
|
netdev->stats.rx_packets++;
|
||||||
c2_port->netstats.rx_bytes += buflen;
|
netdev->stats.rx_bytes += buflen;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Save where we left off */
|
/* Save where we left off */
|
||||||
|
@ -797,8 +796,8 @@ static int c2_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
|
||||||
__raw_writew((__force u16) cpu_to_be16(TXP_HTXD_READY),
|
__raw_writew((__force u16) cpu_to_be16(TXP_HTXD_READY),
|
||||||
elem->hw_desc + C2_TXP_FLAGS);
|
elem->hw_desc + C2_TXP_FLAGS);
|
||||||
|
|
||||||
c2_port->netstats.tx_packets++;
|
netdev->stats.tx_packets++;
|
||||||
c2_port->netstats.tx_bytes += maplen;
|
netdev->stats.tx_bytes += maplen;
|
||||||
|
|
||||||
/* Loop thru additional data fragments and queue them */
|
/* Loop thru additional data fragments and queue them */
|
||||||
if (skb_shinfo(skb)->nr_frags) {
|
if (skb_shinfo(skb)->nr_frags) {
|
||||||
|
@ -823,8 +822,8 @@ static int c2_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
|
||||||
__raw_writew((__force u16) cpu_to_be16(TXP_HTXD_READY),
|
__raw_writew((__force u16) cpu_to_be16(TXP_HTXD_READY),
|
||||||
elem->hw_desc + C2_TXP_FLAGS);
|
elem->hw_desc + C2_TXP_FLAGS);
|
||||||
|
|
||||||
c2_port->netstats.tx_packets++;
|
netdev->stats.tx_packets++;
|
||||||
c2_port->netstats.tx_bytes += maplen;
|
netdev->stats.tx_bytes += maplen;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -845,13 +844,6 @@ static int c2_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
|
||||||
return NETDEV_TX_OK;
|
return NETDEV_TX_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct net_device_stats *c2_get_stats(struct net_device *netdev)
|
|
||||||
{
|
|
||||||
struct c2_port *c2_port = netdev_priv(netdev);
|
|
||||||
|
|
||||||
return &c2_port->netstats;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void c2_tx_timeout(struct net_device *netdev)
|
static void c2_tx_timeout(struct net_device *netdev)
|
||||||
{
|
{
|
||||||
struct c2_port *c2_port = netdev_priv(netdev);
|
struct c2_port *c2_port = netdev_priv(netdev);
|
||||||
|
@ -880,6 +872,16 @@ static int c2_change_mtu(struct net_device *netdev, int new_mtu)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const struct net_device_ops c2_netdev = {
|
||||||
|
.ndo_open = c2_up,
|
||||||
|
.ndo_stop = c2_down,
|
||||||
|
.ndo_start_xmit = c2_xmit_frame,
|
||||||
|
.ndo_tx_timeout = c2_tx_timeout,
|
||||||
|
.ndo_change_mtu = c2_change_mtu,
|
||||||
|
.ndo_set_mac_address = eth_mac_addr,
|
||||||
|
.ndo_validate_addr = eth_validate_addr,
|
||||||
|
};
|
||||||
|
|
||||||
/* Initialize network device */
|
/* Initialize network device */
|
||||||
static struct net_device *c2_devinit(struct c2_dev *c2dev,
|
static struct net_device *c2_devinit(struct c2_dev *c2dev,
|
||||||
void __iomem * mmio_addr)
|
void __iomem * mmio_addr)
|
||||||
|
@ -894,12 +896,7 @@ static struct net_device *c2_devinit(struct c2_dev *c2dev,
|
||||||
|
|
||||||
SET_NETDEV_DEV(netdev, &c2dev->pcidev->dev);
|
SET_NETDEV_DEV(netdev, &c2dev->pcidev->dev);
|
||||||
|
|
||||||
netdev->open = c2_up;
|
netdev->netdev_ops = &c2_netdev;
|
||||||
netdev->stop = c2_down;
|
|
||||||
netdev->hard_start_xmit = c2_xmit_frame;
|
|
||||||
netdev->get_stats = c2_get_stats;
|
|
||||||
netdev->tx_timeout = c2_tx_timeout;
|
|
||||||
netdev->change_mtu = c2_change_mtu;
|
|
||||||
netdev->watchdog_timeo = C2_TX_TIMEOUT;
|
netdev->watchdog_timeo = C2_TX_TIMEOUT;
|
||||||
netdev->irq = c2dev->pcidev->irq;
|
netdev->irq = c2dev->pcidev->irq;
|
||||||
|
|
||||||
|
|
|
@ -369,8 +369,6 @@ struct c2_port {
|
||||||
unsigned long mem_size;
|
unsigned long mem_size;
|
||||||
|
|
||||||
u32 rx_buf_size;
|
u32 rx_buf_size;
|
||||||
|
|
||||||
struct net_device_stats netstats;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -708,26 +708,27 @@ static int c2_pseudo_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
|
||||||
|
|
||||||
static int c2_pseudo_change_mtu(struct net_device *netdev, int new_mtu)
|
static int c2_pseudo_change_mtu(struct net_device *netdev, int new_mtu)
|
||||||
{
|
{
|
||||||
int ret = 0;
|
|
||||||
|
|
||||||
if (new_mtu < ETH_ZLEN || new_mtu > ETH_JUMBO_MTU)
|
if (new_mtu < ETH_ZLEN || new_mtu > ETH_JUMBO_MTU)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
netdev->mtu = new_mtu;
|
netdev->mtu = new_mtu;
|
||||||
|
|
||||||
/* TODO: Tell rnic about new rmda interface mtu */
|
/* TODO: Tell rnic about new rmda interface mtu */
|
||||||
return ret;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const struct net_device_ops c2_pseudo_netdev_ops = {
|
||||||
|
.ndo_open = c2_pseudo_up,
|
||||||
|
.ndo_stop = c2_pseudo_down,
|
||||||
|
.ndo_start_xmit = c2_pseudo_xmit_frame,
|
||||||
|
.ndo_change_mtu = c2_pseudo_change_mtu,
|
||||||
|
.ndo_validate_addr = eth_validate_addr,
|
||||||
|
};
|
||||||
|
|
||||||
static void setup(struct net_device *netdev)
|
static void setup(struct net_device *netdev)
|
||||||
{
|
{
|
||||||
netdev->open = c2_pseudo_up;
|
netdev->netdev_ops = &c2_pseudo_netdev_ops;
|
||||||
netdev->stop = c2_pseudo_down;
|
|
||||||
netdev->hard_start_xmit = c2_pseudo_xmit_frame;
|
|
||||||
netdev->get_stats = NULL;
|
|
||||||
netdev->tx_timeout = NULL;
|
|
||||||
netdev->set_mac_address = NULL;
|
|
||||||
netdev->change_mtu = c2_pseudo_change_mtu;
|
|
||||||
netdev->watchdog_timeo = 0;
|
netdev->watchdog_timeo = 0;
|
||||||
netdev->type = ARPHRD_ETHER;
|
netdev->type = ARPHRD_ETHER;
|
||||||
netdev->mtu = 1500;
|
netdev->mtu = 1500;
|
||||||
|
@ -735,7 +736,6 @@ static void setup(struct net_device *netdev)
|
||||||
netdev->addr_len = ETH_ALEN;
|
netdev->addr_len = ETH_ALEN;
|
||||||
netdev->tx_queue_len = 0;
|
netdev->tx_queue_len = 0;
|
||||||
netdev->flags |= IFF_NOARP;
|
netdev->flags |= IFF_NOARP;
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct net_device *c2_pseudo_netdev_init(struct c2_dev *c2dev)
|
static struct net_device *c2_pseudo_netdev_init(struct c2_dev *c2dev)
|
||||||
|
|
|
@ -701,6 +701,9 @@ static int __cxio_tpt_op(struct cxio_rdev *rdev_p, u32 reset_tpt_entry,
|
||||||
u32 stag_idx;
|
u32 stag_idx;
|
||||||
u32 wptr;
|
u32 wptr;
|
||||||
|
|
||||||
|
if (rdev_p->flags)
|
||||||
|
return -EIO;
|
||||||
|
|
||||||
stag_state = stag_state > 0;
|
stag_state = stag_state > 0;
|
||||||
stag_idx = (*stag) >> 8;
|
stag_idx = (*stag) >> 8;
|
||||||
|
|
||||||
|
|
|
@ -111,6 +111,8 @@ struct cxio_rdev {
|
||||||
struct gen_pool *rqt_pool;
|
struct gen_pool *rqt_pool;
|
||||||
struct list_head entry;
|
struct list_head entry;
|
||||||
struct ch_embedded_info fw_info;
|
struct ch_embedded_info fw_info;
|
||||||
|
u32 flags;
|
||||||
|
#define CXIO_ERROR_FATAL 1
|
||||||
};
|
};
|
||||||
|
|
||||||
static inline int cxio_num_stags(struct cxio_rdev *rdev_p)
|
static inline int cxio_num_stags(struct cxio_rdev *rdev_p)
|
||||||
|
|
|
@ -51,13 +51,15 @@ cxgb3_cpl_handler_func t3c_handlers[NUM_CPL_CMDS];
|
||||||
|
|
||||||
static void open_rnic_dev(struct t3cdev *);
|
static void open_rnic_dev(struct t3cdev *);
|
||||||
static void close_rnic_dev(struct t3cdev *);
|
static void close_rnic_dev(struct t3cdev *);
|
||||||
|
static void iwch_err_handler(struct t3cdev *, u32, u32);
|
||||||
|
|
||||||
struct cxgb3_client t3c_client = {
|
struct cxgb3_client t3c_client = {
|
||||||
.name = "iw_cxgb3",
|
.name = "iw_cxgb3",
|
||||||
.add = open_rnic_dev,
|
.add = open_rnic_dev,
|
||||||
.remove = close_rnic_dev,
|
.remove = close_rnic_dev,
|
||||||
.handlers = t3c_handlers,
|
.handlers = t3c_handlers,
|
||||||
.redirect = iwch_ep_redirect
|
.redirect = iwch_ep_redirect,
|
||||||
|
.err_handler = iwch_err_handler
|
||||||
};
|
};
|
||||||
|
|
||||||
static LIST_HEAD(dev_list);
|
static LIST_HEAD(dev_list);
|
||||||
|
@ -160,6 +162,17 @@ static void close_rnic_dev(struct t3cdev *tdev)
|
||||||
mutex_unlock(&dev_mutex);
|
mutex_unlock(&dev_mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void iwch_err_handler(struct t3cdev *tdev, u32 status, u32 error)
|
||||||
|
{
|
||||||
|
struct cxio_rdev *rdev = tdev->ulp;
|
||||||
|
|
||||||
|
if (status == OFFLOAD_STATUS_DOWN)
|
||||||
|
rdev->flags = CXIO_ERROR_FATAL;
|
||||||
|
|
||||||
|
return;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
static int __init iwch_init_module(void)
|
static int __init iwch_init_module(void)
|
||||||
{
|
{
|
||||||
int err;
|
int err;
|
||||||
|
|
|
@ -2550,7 +2550,7 @@ static void nes_nic_napi_ce_handler(struct nes_device *nesdev, struct nes_hw_nic
|
||||||
{
|
{
|
||||||
struct nes_vnic *nesvnic = container_of(cq, struct nes_vnic, nic_cq);
|
struct nes_vnic *nesvnic = container_of(cq, struct nes_vnic, nic_cq);
|
||||||
|
|
||||||
netif_rx_schedule(&nesvnic->napi);
|
napi_schedule(&nesvnic->napi);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -111,7 +111,7 @@ static int nes_netdev_poll(struct napi_struct *napi, int budget)
|
||||||
nes_nic_ce_handler(nesdev, nescq);
|
nes_nic_ce_handler(nesdev, nescq);
|
||||||
|
|
||||||
if (nescq->cqes_pending == 0) {
|
if (nescq->cqes_pending == 0) {
|
||||||
netif_rx_complete(napi);
|
napi_complete(napi);
|
||||||
/* clear out completed cqes and arm */
|
/* clear out completed cqes and arm */
|
||||||
nes_write32(nesdev->regs+NES_CQE_ALLOC, NES_CQE_ALLOC_NOTIFY_NEXT |
|
nes_write32(nesdev->regs+NES_CQE_ALLOC, NES_CQE_ALLOC_NOTIFY_NEXT |
|
||||||
nescq->cq_number | (nescq->cqe_allocs_pending << 16));
|
nescq->cq_number | (nescq->cqe_allocs_pending << 16));
|
||||||
|
@ -1551,6 +1551,19 @@ static void nes_netdev_vlan_rx_register(struct net_device *netdev, struct vlan_g
|
||||||
spin_unlock_irqrestore(&nesadapter->phy_lock, flags);
|
spin_unlock_irqrestore(&nesadapter->phy_lock, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const struct net_device_ops nes_netdev_ops = {
|
||||||
|
.ndo_open = nes_netdev_open,
|
||||||
|
.ndo_stop = nes_netdev_stop,
|
||||||
|
.ndo_start_xmit = nes_netdev_start_xmit,
|
||||||
|
.ndo_get_stats = nes_netdev_get_stats,
|
||||||
|
.ndo_tx_timeout = nes_netdev_tx_timeout,
|
||||||
|
.ndo_set_mac_address = nes_netdev_set_mac_address,
|
||||||
|
.ndo_set_multicast_list = nes_netdev_set_multicast_list,
|
||||||
|
.ndo_change_mtu = nes_netdev_change_mtu,
|
||||||
|
.ndo_set_mac_address = eth_mac_addr,
|
||||||
|
.ndo_validate_addr = eth_validate_addr,
|
||||||
|
.ndo_vlan_rx_register = nes_netdev_vlan_rx_register,
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* nes_netdev_init - initialize network device
|
* nes_netdev_init - initialize network device
|
||||||
|
@ -1559,7 +1572,7 @@ struct net_device *nes_netdev_init(struct nes_device *nesdev,
|
||||||
void __iomem *mmio_addr)
|
void __iomem *mmio_addr)
|
||||||
{
|
{
|
||||||
u64 u64temp;
|
u64 u64temp;
|
||||||
struct nes_vnic *nesvnic = NULL;
|
struct nes_vnic *nesvnic;
|
||||||
struct net_device *netdev;
|
struct net_device *netdev;
|
||||||
struct nic_qp_map *curr_qp_map;
|
struct nic_qp_map *curr_qp_map;
|
||||||
u32 u32temp;
|
u32 u32temp;
|
||||||
|
@ -1571,22 +1584,12 @@ struct net_device *nes_netdev_init(struct nes_device *nesdev,
|
||||||
printk(KERN_ERR PFX "nesvnic etherdev alloc failed");
|
printk(KERN_ERR PFX "nesvnic etherdev alloc failed");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
nesvnic = netdev_priv(netdev);
|
||||||
|
|
||||||
nes_debug(NES_DBG_INIT, "netdev = %p, %s\n", netdev, netdev->name);
|
nes_debug(NES_DBG_INIT, "netdev = %p, %s\n", netdev, netdev->name);
|
||||||
|
|
||||||
SET_NETDEV_DEV(netdev, &nesdev->pcidev->dev);
|
SET_NETDEV_DEV(netdev, &nesdev->pcidev->dev);
|
||||||
|
|
||||||
nesvnic = netdev_priv(netdev);
|
|
||||||
memset(nesvnic, 0, sizeof(*nesvnic));
|
|
||||||
|
|
||||||
netdev->open = nes_netdev_open;
|
|
||||||
netdev->stop = nes_netdev_stop;
|
|
||||||
netdev->hard_start_xmit = nes_netdev_start_xmit;
|
|
||||||
netdev->get_stats = nes_netdev_get_stats;
|
|
||||||
netdev->tx_timeout = nes_netdev_tx_timeout;
|
|
||||||
netdev->set_mac_address = nes_netdev_set_mac_address;
|
|
||||||
netdev->set_multicast_list = nes_netdev_set_multicast_list;
|
|
||||||
netdev->change_mtu = nes_netdev_change_mtu;
|
|
||||||
netdev->watchdog_timeo = NES_TX_TIMEOUT;
|
netdev->watchdog_timeo = NES_TX_TIMEOUT;
|
||||||
netdev->irq = nesdev->pcidev->irq;
|
netdev->irq = nesdev->pcidev->irq;
|
||||||
netdev->mtu = ETH_DATA_LEN;
|
netdev->mtu = ETH_DATA_LEN;
|
||||||
|
@ -1594,11 +1597,13 @@ struct net_device *nes_netdev_init(struct nes_device *nesdev,
|
||||||
netdev->addr_len = ETH_ALEN;
|
netdev->addr_len = ETH_ALEN;
|
||||||
netdev->type = ARPHRD_ETHER;
|
netdev->type = ARPHRD_ETHER;
|
||||||
netdev->features = NETIF_F_HIGHDMA;
|
netdev->features = NETIF_F_HIGHDMA;
|
||||||
|
netdev->netdev_ops = &nes_netdev_ops;
|
||||||
netdev->ethtool_ops = &nes_ethtool_ops;
|
netdev->ethtool_ops = &nes_ethtool_ops;
|
||||||
netif_napi_add(netdev, &nesvnic->napi, nes_netdev_poll, 128);
|
netif_napi_add(netdev, &nesvnic->napi, nes_netdev_poll, 128);
|
||||||
nes_debug(NES_DBG_INIT, "Enabling VLAN Insert/Delete.\n");
|
nes_debug(NES_DBG_INIT, "Enabling VLAN Insert/Delete.\n");
|
||||||
netdev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX;
|
netdev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX;
|
||||||
netdev->vlan_rx_register = nes_netdev_vlan_rx_register;
|
netdev->vlan_rx_register = nes_netdev_vlan_rx_register;
|
||||||
|
netdev->features |= NETIF_F_LLTX;
|
||||||
|
|
||||||
/* Fill in the port structure */
|
/* Fill in the port structure */
|
||||||
nesvnic->netdev = netdev;
|
nesvnic->netdev = netdev;
|
||||||
|
|
|
@ -446,11 +446,11 @@ poll_more:
|
||||||
if (dev->features & NETIF_F_LRO)
|
if (dev->features & NETIF_F_LRO)
|
||||||
lro_flush_all(&priv->lro.lro_mgr);
|
lro_flush_all(&priv->lro.lro_mgr);
|
||||||
|
|
||||||
netif_rx_complete(napi);
|
napi_complete(napi);
|
||||||
if (unlikely(ib_req_notify_cq(priv->recv_cq,
|
if (unlikely(ib_req_notify_cq(priv->recv_cq,
|
||||||
IB_CQ_NEXT_COMP |
|
IB_CQ_NEXT_COMP |
|
||||||
IB_CQ_REPORT_MISSED_EVENTS)) &&
|
IB_CQ_REPORT_MISSED_EVENTS)) &&
|
||||||
netif_rx_reschedule(napi))
|
napi_reschedule(napi))
|
||||||
goto poll_more;
|
goto poll_more;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -462,7 +462,7 @@ void ipoib_ib_completion(struct ib_cq *cq, void *dev_ptr)
|
||||||
struct net_device *dev = dev_ptr;
|
struct net_device *dev = dev_ptr;
|
||||||
struct ipoib_dev_priv *priv = netdev_priv(dev);
|
struct ipoib_dev_priv *priv = netdev_priv(dev);
|
||||||
|
|
||||||
netif_rx_schedule(&priv->napi);
|
napi_schedule(&priv->napi);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void drain_tx_cq(struct net_device *dev)
|
static void drain_tx_cq(struct net_device *dev)
|
||||||
|
|
|
@ -1021,18 +1021,22 @@ static void ipoib_lro_setup(struct ipoib_dev_priv *priv)
|
||||||
priv->lro.lro_mgr.ip_summed_aggr = CHECKSUM_UNNECESSARY;
|
priv->lro.lro_mgr.ip_summed_aggr = CHECKSUM_UNNECESSARY;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const struct net_device_ops ipoib_netdev_ops = {
|
||||||
|
.ndo_open = ipoib_open,
|
||||||
|
.ndo_stop = ipoib_stop,
|
||||||
|
.ndo_change_mtu = ipoib_change_mtu,
|
||||||
|
.ndo_start_xmit = ipoib_start_xmit,
|
||||||
|
.ndo_tx_timeout = ipoib_timeout,
|
||||||
|
.ndo_set_multicast_list = ipoib_set_mcast_list,
|
||||||
|
.ndo_neigh_setup = ipoib_neigh_setup_dev,
|
||||||
|
};
|
||||||
|
|
||||||
static void ipoib_setup(struct net_device *dev)
|
static void ipoib_setup(struct net_device *dev)
|
||||||
{
|
{
|
||||||
struct ipoib_dev_priv *priv = netdev_priv(dev);
|
struct ipoib_dev_priv *priv = netdev_priv(dev);
|
||||||
|
|
||||||
dev->open = ipoib_open;
|
dev->netdev_ops = &ipoib_netdev_ops;
|
||||||
dev->stop = ipoib_stop;
|
|
||||||
dev->change_mtu = ipoib_change_mtu;
|
|
||||||
dev->hard_start_xmit = ipoib_start_xmit;
|
|
||||||
dev->tx_timeout = ipoib_timeout;
|
|
||||||
dev->header_ops = &ipoib_header_ops;
|
dev->header_ops = &ipoib_header_ops;
|
||||||
dev->set_multicast_list = ipoib_set_mcast_list;
|
|
||||||
dev->neigh_setup = ipoib_neigh_setup_dev;
|
|
||||||
|
|
||||||
ipoib_set_ethtool_ops(dev);
|
ipoib_set_ethtool_ops(dev);
|
||||||
|
|
||||||
|
|
|
@ -257,9 +257,9 @@ act2000_isa_receive(act2000_card *card)
|
||||||
printk(KERN_WARNING
|
printk(KERN_WARNING
|
||||||
"act2000_isa_receive: Invalid CAPI msg\n");
|
"act2000_isa_receive: Invalid CAPI msg\n");
|
||||||
{
|
{
|
||||||
int i; __u8 *p; __u8 *c; __u8 tmp[30];
|
int i; __u8 *p; __u8 *t; __u8 tmp[30];
|
||||||
for (i = 0, p = (__u8 *)&card->idat.isa.rcvhdr, c = tmp; i < 8; i++)
|
for (i = 0, p = (__u8 *)&card->idat.isa.rcvhdr, t = tmp; i < 8; i++)
|
||||||
c += sprintf(c, "%02x ", *(p++));
|
t += sprintf(t, "%02x ", *(p++));
|
||||||
printk(KERN_WARNING "act2000_isa_receive: %s\n", tmp);
|
printk(KERN_WARNING "act2000_isa_receive: %s\n", tmp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -277,7 +277,7 @@ static void capiminor_free(struct capiminor *mp)
|
||||||
list_del(&mp->list);
|
list_del(&mp->list);
|
||||||
write_unlock_irqrestore(&capiminor_list_lock, flags);
|
write_unlock_irqrestore(&capiminor_list_lock, flags);
|
||||||
|
|
||||||
if (mp->ttyskb) kfree_skb(mp->ttyskb);
|
kfree_skb(mp->ttyskb);
|
||||||
mp->ttyskb = NULL;
|
mp->ttyskb = NULL;
|
||||||
skb_queue_purge(&mp->inqueue);
|
skb_queue_purge(&mp->inqueue);
|
||||||
skb_queue_purge(&mp->outqueue);
|
skb_queue_purge(&mp->outqueue);
|
||||||
|
|
|
@ -239,6 +239,7 @@ static const struct file_operations proc_applstats_ops = {
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
static void *capi_driver_start(struct seq_file *seq, loff_t *pos)
|
static void *capi_driver_start(struct seq_file *seq, loff_t *pos)
|
||||||
|
__acquires(&capi_drivers_list_lock)
|
||||||
{
|
{
|
||||||
read_lock(&capi_drivers_list_lock);
|
read_lock(&capi_drivers_list_lock);
|
||||||
return seq_list_start(&capi_drivers, *pos);
|
return seq_list_start(&capi_drivers, *pos);
|
||||||
|
@ -250,6 +251,7 @@ static void *capi_driver_next(struct seq_file *seq, void *v, loff_t *pos)
|
||||||
}
|
}
|
||||||
|
|
||||||
static void capi_driver_stop(struct seq_file *seq, void *v)
|
static void capi_driver_stop(struct seq_file *seq, void *v)
|
||||||
|
__releases(&capi_drivers_list_lock)
|
||||||
{
|
{
|
||||||
read_unlock(&capi_drivers_list_lock);
|
read_unlock(&capi_drivers_list_lock);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
menuconfig ISDN_DRV_GIGASET
|
menuconfig ISDN_DRV_GIGASET
|
||||||
tristate "Siemens Gigaset support (isdn)"
|
tristate "Siemens Gigaset support"
|
||||||
select CRC_CCITT
|
select CRC_CCITT
|
||||||
select BITREVERSE
|
select BITREVERSE
|
||||||
help
|
help
|
||||||
|
@ -11,11 +11,11 @@ menuconfig ISDN_DRV_GIGASET
|
||||||
one of the connection specific parts that follow.
|
one of the connection specific parts that follow.
|
||||||
This will build a module called "gigaset".
|
This will build a module called "gigaset".
|
||||||
|
|
||||||
if ISDN_DRV_GIGASET!=n
|
if ISDN_DRV_GIGASET
|
||||||
|
|
||||||
config GIGASET_BASE
|
config GIGASET_BASE
|
||||||
tristate "Gigaset base station support"
|
tristate "Gigaset base station support"
|
||||||
depends on ISDN_DRV_GIGASET && USB
|
depends on USB
|
||||||
help
|
help
|
||||||
Say M here if you want to use the USB interface of the Gigaset
|
Say M here if you want to use the USB interface of the Gigaset
|
||||||
base for connection to your system.
|
base for connection to your system.
|
||||||
|
@ -23,7 +23,7 @@ config GIGASET_BASE
|
||||||
|
|
||||||
config GIGASET_M105
|
config GIGASET_M105
|
||||||
tristate "Gigaset M105 support"
|
tristate "Gigaset M105 support"
|
||||||
depends on ISDN_DRV_GIGASET && USB
|
depends on USB
|
||||||
help
|
help
|
||||||
Say M here if you want to connect to the Gigaset base via DECT
|
Say M here if you want to connect to the Gigaset base via DECT
|
||||||
using a Gigaset M105 (Sinus 45 Data 2) USB DECT device.
|
using a Gigaset M105 (Sinus 45 Data 2) USB DECT device.
|
||||||
|
@ -31,7 +31,6 @@ config GIGASET_M105
|
||||||
|
|
||||||
config GIGASET_M101
|
config GIGASET_M101
|
||||||
tristate "Gigaset M101 support"
|
tristate "Gigaset M101 support"
|
||||||
depends on ISDN_DRV_GIGASET
|
|
||||||
help
|
help
|
||||||
Say M here if you want to connect to the Gigaset base via DECT
|
Say M here if you want to connect to the Gigaset base via DECT
|
||||||
using a Gigaset M101 (Sinus 45 Data 1) RS232 DECT device.
|
using a Gigaset M101 (Sinus 45 Data 1) RS232 DECT device.
|
||||||
|
@ -48,7 +47,6 @@ config GIGASET_UNDOCREQ
|
||||||
help
|
help
|
||||||
This enables support for USB requests we only know from
|
This enables support for USB requests we only know from
|
||||||
reverse engineering (currently M105 only). If you need
|
reverse engineering (currently M105 only). If you need
|
||||||
features like configuration mode of M105, say yes. If you
|
features like configuration mode of M105, say yes.
|
||||||
care about your device, say no.
|
|
||||||
|
|
||||||
endif # ISDN_DRV_GIGASET != n
|
endif # ISDN_DRV_GIGASET
|
||||||
|
|
|
@ -278,17 +278,17 @@ static int gigaset_set_line_ctrl(struct cardstate *cs, unsigned cflag)
|
||||||
static int gigaset_set_modem_ctrl(struct cardstate *cs, unsigned old_state,
|
static int gigaset_set_modem_ctrl(struct cardstate *cs, unsigned old_state,
|
||||||
unsigned new_state)
|
unsigned new_state)
|
||||||
{
|
{
|
||||||
return -EINVAL;
|
return -ENOTTY;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int gigaset_set_line_ctrl(struct cardstate *cs, unsigned cflag)
|
static int gigaset_set_line_ctrl(struct cardstate *cs, unsigned cflag)
|
||||||
{
|
{
|
||||||
return -EINVAL;
|
return -ENOTTY;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int gigaset_baud_rate(struct cardstate *cs, unsigned cflag)
|
static int gigaset_baud_rate(struct cardstate *cs, unsigned cflag)
|
||||||
{
|
{
|
||||||
return -EINVAL;
|
return -ENOTTY;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -577,7 +577,7 @@ static int gigaset_brkchars(struct cardstate *cs, const unsigned char buf[6])
|
||||||
return usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0x19, 0x41,
|
return usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0x19, 0x41,
|
||||||
0, 0, &buf, 6, 2000);
|
0, 0, &buf, 6, 2000);
|
||||||
#else
|
#else
|
||||||
return -EINVAL;
|
return -ENOTTY;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1198,7 +1198,7 @@ int SuperTraceASSIGN (void* AdapterHandle, byte* data) {
|
||||||
pC->xbuffer[5] = (byte)(rx_dma_magic >> 8);
|
pC->xbuffer[5] = (byte)(rx_dma_magic >> 8);
|
||||||
pC->xbuffer[6] = (byte)(rx_dma_magic >> 16);
|
pC->xbuffer[6] = (byte)(rx_dma_magic >> 16);
|
||||||
pC->xbuffer[7] = (byte)(rx_dma_magic >> 24);
|
pC->xbuffer[7] = (byte)(rx_dma_magic >> 24);
|
||||||
pC->xbuffer[8] = (byte)DIVA_MAX_MANAGEMENT_TRANSFER_SIZE;
|
pC->xbuffer[8] = (byte)(DIVA_MAX_MANAGEMENT_TRANSFER_SIZE & 0xFF);
|
||||||
pC->xbuffer[9] = (byte)(DIVA_MAX_MANAGEMENT_TRANSFER_SIZE >> 8);
|
pC->xbuffer[9] = (byte)(DIVA_MAX_MANAGEMENT_TRANSFER_SIZE >> 8);
|
||||||
pC->xbuffer[10] = 0;
|
pC->xbuffer[10] = 0;
|
||||||
|
|
||||||
|
|
|
@ -1194,7 +1194,8 @@ static char hex_digit_table[0x10] =
|
||||||
/* translation function for each message */
|
/* translation function for each message */
|
||||||
/*------------------------------------------------------------------*/
|
/*------------------------------------------------------------------*/
|
||||||
|
|
||||||
byte connect_req(dword Id, word Number, DIVA_CAPI_ADAPTER * a, PLCI * plci, APPL * appl, API_PARSE * parms)
|
static byte connect_req(dword Id, word Number, DIVA_CAPI_ADAPTER *a,
|
||||||
|
PLCI *plci, APPL *appl, API_PARSE *parms)
|
||||||
{
|
{
|
||||||
word ch;
|
word ch;
|
||||||
word i;
|
word i;
|
||||||
|
@ -1411,7 +1412,8 @@ byte connect_req(dword Id, word Number, DIVA_CAPI_ADAPTER * a, PLCI * plci,
|
||||||
return 2;
|
return 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
byte connect_res(dword Id, word Number, DIVA_CAPI_ADAPTER * a, PLCI * plci, APPL * appl, API_PARSE * parms)
|
static byte connect_res(dword Id, word Number, DIVA_CAPI_ADAPTER *a,
|
||||||
|
PLCI *plci, APPL *appl, API_PARSE *parms)
|
||||||
{
|
{
|
||||||
word i, Info;
|
word i, Info;
|
||||||
word Reject;
|
word Reject;
|
||||||
|
@ -1567,13 +1569,15 @@ byte connect_res(dword Id, word Number, DIVA_CAPI_ADAPTER * a, PLCI * plci,
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
byte connect_a_res(dword Id, word Number, DIVA_CAPI_ADAPTER * a, PLCI * plci, APPL * appl, API_PARSE * msg)
|
static byte connect_a_res(dword Id, word Number, DIVA_CAPI_ADAPTER *a,
|
||||||
|
PLCI *plci, APPL *appl, API_PARSE *msg)
|
||||||
{
|
{
|
||||||
dbug(1,dprintf("connect_a_res"));
|
dbug(1,dprintf("connect_a_res"));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
byte disconnect_req(dword Id, word Number, DIVA_CAPI_ADAPTER * a, PLCI * plci, APPL * appl, API_PARSE * msg)
|
static byte disconnect_req(dword Id, word Number, DIVA_CAPI_ADAPTER *a,
|
||||||
|
PLCI *plci, APPL *appl, API_PARSE *msg)
|
||||||
{
|
{
|
||||||
word Info;
|
word Info;
|
||||||
word i;
|
word i;
|
||||||
|
@ -1628,7 +1632,8 @@ byte disconnect_req(dword Id, word Number, DIVA_CAPI_ADAPTER * a, PLCI * plc
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
byte disconnect_res(dword Id, word Number, DIVA_CAPI_ADAPTER * a, PLCI * plci, APPL * appl, API_PARSE * msg)
|
static byte disconnect_res(dword Id, word Number, DIVA_CAPI_ADAPTER *a,
|
||||||
|
PLCI *plci, APPL *appl, API_PARSE *msg)
|
||||||
{
|
{
|
||||||
dbug(1,dprintf("disconnect_res"));
|
dbug(1,dprintf("disconnect_res"));
|
||||||
if(plci)
|
if(plci)
|
||||||
|
@ -1655,7 +1660,8 @@ byte disconnect_res(dword Id, word Number, DIVA_CAPI_ADAPTER * a, PLCI * plc
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
byte listen_req(dword Id, word Number, DIVA_CAPI_ADAPTER * a, PLCI * plci, APPL * appl, API_PARSE * parms)
|
static byte listen_req(dword Id, word Number, DIVA_CAPI_ADAPTER *a,
|
||||||
|
PLCI *plci, APPL *appl, API_PARSE *parms)
|
||||||
{
|
{
|
||||||
word Info;
|
word Info;
|
||||||
byte i;
|
byte i;
|
||||||
|
@ -1704,7 +1710,8 @@ byte listen_req(dword Id, word Number, DIVA_CAPI_ADAPTER * a, PLCI * plci, A
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
byte info_req(dword Id, word Number, DIVA_CAPI_ADAPTER * a, PLCI * plci, APPL * appl, API_PARSE * msg)
|
static byte info_req(dword Id, word Number, DIVA_CAPI_ADAPTER *a,
|
||||||
|
PLCI *plci, APPL *appl, API_PARSE *msg)
|
||||||
{
|
{
|
||||||
word i;
|
word i;
|
||||||
API_PARSE * ai;
|
API_PARSE * ai;
|
||||||
|
@ -1813,13 +1820,15 @@ byte info_req(dword Id, word Number, DIVA_CAPI_ADAPTER * a, PLCI * plci, APP
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
byte info_res(dword Id, word Number, DIVA_CAPI_ADAPTER * a, PLCI * plci, APPL * appl, API_PARSE * msg)
|
static byte info_res(dword Id, word Number, DIVA_CAPI_ADAPTER *a,
|
||||||
|
PLCI *plci, APPL *appl, API_PARSE *msg)
|
||||||
{
|
{
|
||||||
dbug(1,dprintf("info_res"));
|
dbug(1,dprintf("info_res"));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
byte alert_req(dword Id, word Number, DIVA_CAPI_ADAPTER * a, PLCI * plci, APPL * appl, API_PARSE * msg)
|
static byte alert_req(dword Id, word Number, DIVA_CAPI_ADAPTER *a,
|
||||||
|
PLCI *plci, APPL *appl, API_PARSE *msg)
|
||||||
{
|
{
|
||||||
word Info;
|
word Info;
|
||||||
byte ret;
|
byte ret;
|
||||||
|
@ -1849,7 +1858,8 @@ byte alert_req(dword Id, word Number, DIVA_CAPI_ADAPTER * a, PLCI * plci, AP
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
byte facility_req(dword Id, word Number, DIVA_CAPI_ADAPTER * a, PLCI * plci, APPL * appl, API_PARSE * msg)
|
static byte facility_req(dword Id, word Number, DIVA_CAPI_ADAPTER *a,
|
||||||
|
PLCI *plci, APPL *appl, API_PARSE *msg)
|
||||||
{
|
{
|
||||||
word Info = 0;
|
word Info = 0;
|
||||||
word i = 0;
|
word i = 0;
|
||||||
|
@ -2599,13 +2609,15 @@ byte facility_req(dword Id, word Number, DIVA_CAPI_ADAPTER * a, PLCI * plci,
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
byte facility_res(dword Id, word Number, DIVA_CAPI_ADAPTER * a, PLCI * plci, APPL * appl, API_PARSE * msg)
|
static byte facility_res(dword Id, word Number, DIVA_CAPI_ADAPTER *a,
|
||||||
|
PLCI *plci, APPL *appl, API_PARSE *msg)
|
||||||
{
|
{
|
||||||
dbug(1,dprintf("facility_res"));
|
dbug(1,dprintf("facility_res"));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
byte connect_b3_req(dword Id, word Number, DIVA_CAPI_ADAPTER * a, PLCI * plci, APPL * appl, API_PARSE * parms)
|
static byte connect_b3_req(dword Id, word Number, DIVA_CAPI_ADAPTER *a,
|
||||||
|
PLCI *plci, APPL *appl, API_PARSE *parms)
|
||||||
{
|
{
|
||||||
word Info = 0;
|
word Info = 0;
|
||||||
byte req;
|
byte req;
|
||||||
|
@ -2839,7 +2851,8 @@ byte connect_b3_req(dword Id, word Number, DIVA_CAPI_ADAPTER * a, PLCI * plc
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
byte connect_b3_res(dword Id, word Number, DIVA_CAPI_ADAPTER * a, PLCI * plci, APPL * appl, API_PARSE * parms)
|
static byte connect_b3_res(dword Id, word Number, DIVA_CAPI_ADAPTER *a,
|
||||||
|
PLCI *plci, APPL *appl, API_PARSE *parms)
|
||||||
{
|
{
|
||||||
word ncci;
|
word ncci;
|
||||||
API_PARSE * ncpi;
|
API_PARSE * ncpi;
|
||||||
|
@ -2954,7 +2967,8 @@ byte connect_b3_res(dword Id, word Number, DIVA_CAPI_ADAPTER * a, PLCI * plc
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
byte connect_b3_a_res(dword Id, word Number, DIVA_CAPI_ADAPTER * a, PLCI * plci, APPL * appl, API_PARSE * parms)
|
static byte connect_b3_a_res(dword Id, word Number, DIVA_CAPI_ADAPTER *a,
|
||||||
|
PLCI *plci, APPL *appl, API_PARSE *parms)
|
||||||
{
|
{
|
||||||
word ncci;
|
word ncci;
|
||||||
|
|
||||||
|
@ -2974,7 +2988,8 @@ byte connect_b3_a_res(dword Id, word Number, DIVA_CAPI_ADAPTER * a, PLCI * p
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
byte disconnect_b3_req(dword Id, word Number, DIVA_CAPI_ADAPTER * a, PLCI * plci, APPL * appl, API_PARSE * parms)
|
static byte disconnect_b3_req(dword Id, word Number, DIVA_CAPI_ADAPTER *a,
|
||||||
|
PLCI *plci, APPL *appl, API_PARSE *parms)
|
||||||
{
|
{
|
||||||
word Info;
|
word Info;
|
||||||
word ncci;
|
word ncci;
|
||||||
|
@ -3030,7 +3045,8 @@ byte disconnect_b3_req(dword Id, word Number, DIVA_CAPI_ADAPTER * a, PLCI *
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
byte disconnect_b3_res(dword Id, word Number, DIVA_CAPI_ADAPTER * a, PLCI * plci, APPL * appl, API_PARSE * parms)
|
static byte disconnect_b3_res(dword Id, word Number, DIVA_CAPI_ADAPTER *a,
|
||||||
|
PLCI *plci, APPL *appl, API_PARSE *parms)
|
||||||
{
|
{
|
||||||
word ncci;
|
word ncci;
|
||||||
word i;
|
word i;
|
||||||
|
@ -3086,7 +3102,8 @@ byte disconnect_b3_res(dword Id, word Number, DIVA_CAPI_ADAPTER * a, PLCI *
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
byte data_b3_req(dword Id, word Number, DIVA_CAPI_ADAPTER * a, PLCI * plci, APPL * appl, API_PARSE * parms)
|
static byte data_b3_req(dword Id, word Number, DIVA_CAPI_ADAPTER *a,
|
||||||
|
PLCI *plci, APPL *appl, API_PARSE *parms)
|
||||||
{
|
{
|
||||||
NCCI *ncci_ptr;
|
NCCI *ncci_ptr;
|
||||||
DATA_B3_DESC *data;
|
DATA_B3_DESC *data;
|
||||||
|
@ -3163,7 +3180,8 @@ byte data_b3_req(dword Id, word Number, DIVA_CAPI_ADAPTER * a, PLCI * plci,
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
byte data_b3_res(dword Id, word Number, DIVA_CAPI_ADAPTER * a, PLCI * plci, APPL * appl, API_PARSE * parms)
|
static byte data_b3_res(dword Id, word Number, DIVA_CAPI_ADAPTER *a,
|
||||||
|
PLCI *plci, APPL *appl, API_PARSE *parms)
|
||||||
{
|
{
|
||||||
word n;
|
word n;
|
||||||
word ncci;
|
word ncci;
|
||||||
|
@ -3196,7 +3214,8 @@ byte data_b3_res(dword Id, word Number, DIVA_CAPI_ADAPTER * a, PLCI * plci,
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
byte reset_b3_req(dword Id, word Number, DIVA_CAPI_ADAPTER * a, PLCI * plci, APPL * appl, API_PARSE * parms)
|
static byte reset_b3_req(dword Id, word Number, DIVA_CAPI_ADAPTER *a,
|
||||||
|
PLCI *plci, APPL *appl, API_PARSE *parms)
|
||||||
{
|
{
|
||||||
word Info;
|
word Info;
|
||||||
word ncci;
|
word ncci;
|
||||||
|
@ -3237,7 +3256,8 @@ byte reset_b3_req(dword Id, word Number, DIVA_CAPI_ADAPTER * a, PLCI * plci,
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
byte reset_b3_res(dword Id, word Number, DIVA_CAPI_ADAPTER * a, PLCI * plci, APPL * appl, API_PARSE * parms)
|
static byte reset_b3_res(dword Id, word Number, DIVA_CAPI_ADAPTER *a,
|
||||||
|
PLCI *plci, APPL *appl, API_PARSE *parms)
|
||||||
{
|
{
|
||||||
word ncci;
|
word ncci;
|
||||||
|
|
||||||
|
@ -3261,7 +3281,8 @@ byte reset_b3_res(dword Id, word Number, DIVA_CAPI_ADAPTER * a, PLCI * plci,
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
byte connect_b3_t90_a_res(dword Id, word Number, DIVA_CAPI_ADAPTER * a, PLCI * plci, APPL * appl, API_PARSE * parms)
|
static byte connect_b3_t90_a_res(dword Id, word Number, DIVA_CAPI_ADAPTER *a,
|
||||||
|
PLCI *plci, APPL *appl, API_PARSE *parms)
|
||||||
{
|
{
|
||||||
word ncci;
|
word ncci;
|
||||||
API_PARSE * ncpi;
|
API_PARSE * ncpi;
|
||||||
|
@ -3295,7 +3316,8 @@ byte connect_b3_t90_a_res(dword Id, word Number, DIVA_CAPI_ADAPTER * a, PLCI
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
byte select_b_req(dword Id, word Number, DIVA_CAPI_ADAPTER * a, PLCI * plci, APPL * appl, API_PARSE * msg)
|
static byte select_b_req(dword Id, word Number, DIVA_CAPI_ADAPTER *a,
|
||||||
|
PLCI *plci, APPL *appl, API_PARSE *msg)
|
||||||
{
|
{
|
||||||
word Info=0;
|
word Info=0;
|
||||||
word i;
|
word i;
|
||||||
|
@ -8689,7 +8711,7 @@ static word add_modem_b23 (PLCI * plci, API_PARSE* bp_parms)
|
||||||
/* send a request for the signaling entity */
|
/* send a request for the signaling entity */
|
||||||
/*------------------------------------------------------------------*/
|
/*------------------------------------------------------------------*/
|
||||||
|
|
||||||
void sig_req(PLCI * plci, byte req, byte Id)
|
static void sig_req(PLCI *plci, byte req, byte Id)
|
||||||
{
|
{
|
||||||
if(!plci) return;
|
if(!plci) return;
|
||||||
if(plci->adapter->adapter_disabled) return;
|
if(plci->adapter->adapter_disabled) return;
|
||||||
|
@ -8789,7 +8811,7 @@ static void send_req(PLCI *plci)
|
||||||
dbug(1,dprintf("send_ok"));
|
dbug(1,dprintf("send_ok"));
|
||||||
}
|
}
|
||||||
|
|
||||||
void send_data(PLCI * plci)
|
static void send_data(PLCI *plci)
|
||||||
{
|
{
|
||||||
DIVA_CAPI_ADAPTER * a;
|
DIVA_CAPI_ADAPTER * a;
|
||||||
DATA_B3_DESC * data;
|
DATA_B3_DESC * data;
|
||||||
|
|
|
@ -56,8 +56,8 @@ static const char *hfcpci_revision = "2.0";
|
||||||
static int HFC_cnt;
|
static int HFC_cnt;
|
||||||
static uint debug;
|
static uint debug;
|
||||||
static uint poll, tics;
|
static uint poll, tics;
|
||||||
struct timer_list hfc_tl;
|
static struct timer_list hfc_tl;
|
||||||
u32 hfc_jiffies;
|
static unsigned long hfc_jiffies;
|
||||||
|
|
||||||
MODULE_AUTHOR("Karsten Keil");
|
MODULE_AUTHOR("Karsten Keil");
|
||||||
MODULE_LICENSE("GPL");
|
MODULE_LICENSE("GPL");
|
||||||
|
|
|
@ -35,7 +35,7 @@
|
||||||
#include <linux/mISDNhw.h>
|
#include <linux/mISDNhw.h>
|
||||||
#include "hfcsusb.h"
|
#include "hfcsusb.h"
|
||||||
|
|
||||||
const char *hfcsusb_rev = "Revision: 0.3.3 (socket), 2008-11-05";
|
static const char *hfcsusb_rev = "Revision: 0.3.3 (socket), 2008-11-05";
|
||||||
|
|
||||||
static unsigned int debug;
|
static unsigned int debug;
|
||||||
static int poll = DEFAULT_TRANSP_BURST_SZ;
|
static int poll = DEFAULT_TRANSP_BURST_SZ;
|
||||||
|
@ -974,7 +974,7 @@ hfcsusb_rx_frame(struct usb_fifo *fifo, __u8 *data, unsigned int len,
|
||||||
spin_unlock(&hw->lock);
|
spin_unlock(&hw->lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
static void
|
||||||
fill_isoc_urb(struct urb *urb, struct usb_device *dev, unsigned int pipe,
|
fill_isoc_urb(struct urb *urb, struct usb_device *dev, unsigned int pipe,
|
||||||
void *buf, int num_packets, int packet_size, int interval,
|
void *buf, int num_packets, int packet_size, int interval,
|
||||||
usb_complete_t complete, void *context)
|
usb_complete_t complete, void *context)
|
||||||
|
@ -1720,7 +1720,7 @@ hfcsusb_stop_endpoint(struct hfcsusb *hw, int channel)
|
||||||
|
|
||||||
|
|
||||||
/* Hardware Initialization */
|
/* Hardware Initialization */
|
||||||
int
|
static int
|
||||||
setup_hfcsusb(struct hfcsusb *hw)
|
setup_hfcsusb(struct hfcsusb *hw)
|
||||||
{
|
{
|
||||||
int err;
|
int err;
|
||||||
|
|
|
@ -198,7 +198,7 @@ validconf[][19] = {
|
||||||
};
|
};
|
||||||
|
|
||||||
/* string description of chosen config */
|
/* string description of chosen config */
|
||||||
char *conf_str[] = {
|
static char *conf_str[] = {
|
||||||
"4 Interrupt IN + 3 Isochron OUT",
|
"4 Interrupt IN + 3 Isochron OUT",
|
||||||
"3 Interrupt IN + 3 Isochron OUT",
|
"3 Interrupt IN + 3 Isochron OUT",
|
||||||
"4 Isochron IN + 3 Isochron OUT",
|
"4 Isochron IN + 3 Isochron OUT",
|
||||||
|
@ -316,7 +316,7 @@ struct hfcsusb_vdata {
|
||||||
#define HFC_MAX_TE_LAYER1_STATE 8
|
#define HFC_MAX_TE_LAYER1_STATE 8
|
||||||
#define HFC_MAX_NT_LAYER1_STATE 4
|
#define HFC_MAX_NT_LAYER1_STATE 4
|
||||||
|
|
||||||
const char *HFC_TE_LAYER1_STATES[HFC_MAX_TE_LAYER1_STATE + 1] = {
|
static const char *HFC_TE_LAYER1_STATES[HFC_MAX_TE_LAYER1_STATE + 1] = {
|
||||||
"TE F0 - Reset",
|
"TE F0 - Reset",
|
||||||
"TE F1 - Reset",
|
"TE F1 - Reset",
|
||||||
"TE F2 - Sensing",
|
"TE F2 - Sensing",
|
||||||
|
@ -328,7 +328,7 @@ const char *HFC_TE_LAYER1_STATES[HFC_MAX_TE_LAYER1_STATE + 1] = {
|
||||||
"TE F8 - Lost framing",
|
"TE F8 - Lost framing",
|
||||||
};
|
};
|
||||||
|
|
||||||
const char *HFC_NT_LAYER1_STATES[HFC_MAX_NT_LAYER1_STATE + 1] = {
|
static const char *HFC_NT_LAYER1_STATES[HFC_MAX_NT_LAYER1_STATE + 1] = {
|
||||||
"NT G0 - Reset",
|
"NT G0 - Reset",
|
||||||
"NT G1 - Deactive",
|
"NT G1 - Deactive",
|
||||||
"NT G2 - Pending activation",
|
"NT G2 - Pending activation",
|
||||||
|
|
|
@ -24,7 +24,6 @@
|
||||||
const char *lli_revision = "$Revision: 2.59.2.4 $";
|
const char *lli_revision = "$Revision: 2.59.2.4 $";
|
||||||
|
|
||||||
extern struct IsdnCard cards[];
|
extern struct IsdnCard cards[];
|
||||||
extern int nrcards;
|
|
||||||
|
|
||||||
static int init_b_st(struct Channel *chanp, int incoming);
|
static int init_b_st(struct Channel *chanp, int incoming);
|
||||||
static void release_b_st(struct Channel *chanp);
|
static void release_b_st(struct Channel *chanp);
|
||||||
|
|
|
@ -361,12 +361,6 @@ module_param_array(io1, int, NULL, 0);
|
||||||
|
|
||||||
int nrcards;
|
int nrcards;
|
||||||
|
|
||||||
extern const char *l1_revision;
|
|
||||||
extern const char *l2_revision;
|
|
||||||
extern const char *l3_revision;
|
|
||||||
extern const char *lli_revision;
|
|
||||||
extern const char *tei_revision;
|
|
||||||
|
|
||||||
char *HiSax_getrev(const char *revision)
|
char *HiSax_getrev(const char *revision)
|
||||||
{
|
{
|
||||||
char *rev;
|
char *rev;
|
||||||
|
|
|
@ -16,8 +16,6 @@
|
||||||
#include "hfc_2bds0.h"
|
#include "hfc_2bds0.h"
|
||||||
#include "isdnl1.h"
|
#include "isdnl1.h"
|
||||||
|
|
||||||
extern const char *CardType[];
|
|
||||||
|
|
||||||
static const char *hfcs_revision = "$Revision: 1.10.2.4 $";
|
static const char *hfcs_revision = "$Revision: 1.10.2.4 $";
|
||||||
|
|
||||||
static irqreturn_t
|
static irqreturn_t
|
||||||
|
|
|
@ -121,6 +121,15 @@
|
||||||
|
|
||||||
#ifdef __KERNEL__
|
#ifdef __KERNEL__
|
||||||
|
|
||||||
|
extern const char *CardType[];
|
||||||
|
extern int nrcards;
|
||||||
|
|
||||||
|
extern const char *l1_revision;
|
||||||
|
extern const char *l2_revision;
|
||||||
|
extern const char *l3_revision;
|
||||||
|
extern const char *lli_revision;
|
||||||
|
extern const char *tei_revision;
|
||||||
|
|
||||||
/* include l3dss1 & ni1 specific process structures, but no other defines */
|
/* include l3dss1 & ni1 specific process structures, but no other defines */
|
||||||
#ifdef CONFIG_HISAX_EURO
|
#ifdef CONFIG_HISAX_EURO
|
||||||
#define l3dss1_process
|
#define l3dss1_process
|
||||||
|
|
|
@ -18,12 +18,12 @@
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
const char *l1_revision = "$Revision: 2.46.2.5 $";
|
|
||||||
|
|
||||||
#include <linux/init.h>
|
#include <linux/init.h>
|
||||||
#include "hisax.h"
|
#include "hisax.h"
|
||||||
#include "isdnl1.h"
|
#include "isdnl1.h"
|
||||||
|
|
||||||
|
const char *l1_revision = "$Revision: 2.46.2.5 $";
|
||||||
|
|
||||||
#define TIMER3_VALUE 7000
|
#define TIMER3_VALUE 7000
|
||||||
|
|
||||||
static struct Fsm l1fsm_b;
|
static struct Fsm l1fsm_b;
|
||||||
|
|
|
@ -48,8 +48,6 @@
|
||||||
#include <linux/pci.h>
|
#include <linux/pci.h>
|
||||||
#include <linux/isapnp.h>
|
#include <linux/isapnp.h>
|
||||||
|
|
||||||
extern const char *CardType[];
|
|
||||||
|
|
||||||
static const char *Sedlbauer_revision = "$Revision: 1.34.2.6 $";
|
static const char *Sedlbauer_revision = "$Revision: 1.34.2.6 $";
|
||||||
|
|
||||||
static const char *Sedlbauer_Types[] =
|
static const char *Sedlbauer_Types[] =
|
||||||
|
|
|
@ -21,8 +21,6 @@
|
||||||
#include "isac.h"
|
#include "isac.h"
|
||||||
#include "hscx.h"
|
#include "hscx.h"
|
||||||
|
|
||||||
extern const char *CardType[];
|
|
||||||
|
|
||||||
static const char *teles0_revision = "$Revision: 2.15.2.4 $";
|
static const char *teles0_revision = "$Revision: 2.15.2.4 $";
|
||||||
|
|
||||||
#define TELES_IOMEM_SIZE 0x400
|
#define TELES_IOMEM_SIZE 0x400
|
||||||
|
|
|
@ -20,7 +20,6 @@
|
||||||
#include "hscx.h"
|
#include "hscx.h"
|
||||||
#include "isdnl1.h"
|
#include "isdnl1.h"
|
||||||
|
|
||||||
extern const char *CardType[];
|
|
||||||
static const char *teles3_revision = "$Revision: 2.19.2.4 $";
|
static const char *teles3_revision = "$Revision: 2.19.2.4 $";
|
||||||
|
|
||||||
#define byteout(addr,val) outb(val,addr)
|
#define byteout(addr,val) outb(val,addr)
|
||||||
|
|
|
@ -41,11 +41,11 @@
|
||||||
|
|
||||||
static u_int *debug;
|
static u_int *debug;
|
||||||
static LIST_HEAD(iclock_list);
|
static LIST_HEAD(iclock_list);
|
||||||
DEFINE_RWLOCK(iclock_lock);
|
static DEFINE_RWLOCK(iclock_lock);
|
||||||
u16 iclock_count; /* counter of last clock */
|
static u16 iclock_count; /* counter of last clock */
|
||||||
struct timeval iclock_tv; /* time stamp of last clock */
|
static struct timeval iclock_tv; /* time stamp of last clock */
|
||||||
int iclock_tv_valid; /* already received one timestamp */
|
static int iclock_tv_valid; /* already received one timestamp */
|
||||||
struct mISDNclock *iclock_current;
|
static struct mISDNclock *iclock_current;
|
||||||
|
|
||||||
void
|
void
|
||||||
mISDN_init_clock(u_int *dp)
|
mISDN_init_clock(u_int *dp)
|
||||||
|
|
|
@ -152,8 +152,7 @@ dev_expire_timer(unsigned long data)
|
||||||
u_long flags;
|
u_long flags;
|
||||||
|
|
||||||
spin_lock_irqsave(&timer->dev->lock, flags);
|
spin_lock_irqsave(&timer->dev->lock, flags);
|
||||||
list_del(&timer->list);
|
list_move_tail(&timer->list, &timer->dev->expired);
|
||||||
list_add_tail(&timer->list, &timer->dev->expired);
|
|
||||||
spin_unlock_irqrestore(&timer->dev->lock, flags);
|
spin_unlock_irqrestore(&timer->dev->lock, flags);
|
||||||
wake_up_interruptible(&timer->dev->wait);
|
wake_up_interruptible(&timer->dev->wait);
|
||||||
}
|
}
|
||||||
|
|
|
@ -347,8 +347,7 @@ pcbit_receive(struct pcbit_dev *dev)
|
||||||
if (dev->read_frame) {
|
if (dev->read_frame) {
|
||||||
printk(KERN_DEBUG "pcbit_receive: Type 0 frame and read_frame != NULL\n");
|
printk(KERN_DEBUG "pcbit_receive: Type 0 frame and read_frame != NULL\n");
|
||||||
/* discard previous queued frame */
|
/* discard previous queued frame */
|
||||||
if (dev->read_frame->skb)
|
kfree_skb(dev->read_frame->skb);
|
||||||
kfree_skb(dev->read_frame->skb);
|
|
||||||
kfree(dev->read_frame);
|
kfree(dev->read_frame);
|
||||||
dev->read_frame = NULL;
|
dev->read_frame = NULL;
|
||||||
}
|
}
|
||||||
|
@ -601,8 +600,7 @@ pcbit_l2_err_recover(unsigned long data)
|
||||||
dev->w_busy = dev->r_busy = 1;
|
dev->w_busy = dev->r_busy = 1;
|
||||||
|
|
||||||
if (dev->read_frame) {
|
if (dev->read_frame) {
|
||||||
if (dev->read_frame->skb)
|
kfree_skb(dev->read_frame->skb);
|
||||||
kfree_skb(dev->read_frame->skb);
|
|
||||||
kfree(dev->read_frame);
|
kfree(dev->read_frame);
|
||||||
dev->read_frame = NULL;
|
dev->read_frame = NULL;
|
||||||
}
|
}
|
||||||
|
|
|
@ -223,4 +223,7 @@ config LEDS_TRIGGER_DEFAULT_ON
|
||||||
This allows LEDs to be initialised in the ON state.
|
This allows LEDs to be initialised in the ON state.
|
||||||
If unsure, say Y.
|
If unsure, say Y.
|
||||||
|
|
||||||
|
comment "iptables trigger is under Netfilter config (LED target)"
|
||||||
|
depends on LEDS_TRIGGERS
|
||||||
|
|
||||||
endif # NEW_LEDS
|
endif # NEW_LEDS
|
||||||
|
|
|
@ -197,6 +197,17 @@ out:
|
||||||
return ERR_PTR(err);
|
return ERR_PTR(err);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const struct net_device_ops el_netdev_ops = {
|
||||||
|
.ndo_open = el_open,
|
||||||
|
.ndo_stop = el1_close,
|
||||||
|
.ndo_start_xmit = el_start_xmit,
|
||||||
|
.ndo_tx_timeout = el_timeout,
|
||||||
|
.ndo_set_multicast_list = set_multicast_list,
|
||||||
|
.ndo_change_mtu = eth_change_mtu,
|
||||||
|
.ndo_set_mac_address = eth_mac_addr,
|
||||||
|
.ndo_validate_addr = eth_validate_addr,
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* el1_probe1:
|
* el1_probe1:
|
||||||
* @dev: The device structure to use
|
* @dev: The device structure to use
|
||||||
|
@ -305,12 +316,8 @@ static int __init el1_probe1(struct net_device *dev, int ioaddr)
|
||||||
* The EL1-specific entries in the device structure.
|
* The EL1-specific entries in the device structure.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
dev->open = &el_open;
|
dev->netdev_ops = &el_netdev_ops;
|
||||||
dev->hard_start_xmit = &el_start_xmit;
|
|
||||||
dev->tx_timeout = &el_timeout;
|
|
||||||
dev->watchdog_timeo = HZ;
|
dev->watchdog_timeo = HZ;
|
||||||
dev->stop = &el1_close;
|
|
||||||
dev->set_multicast_list = &set_multicast_list;
|
|
||||||
dev->ethtool_ops = &netdev_ethtool_ops;
|
dev->ethtool_ops = &netdev_ethtool_ops;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1354,6 +1354,17 @@ static int __init elp_autodetect(struct net_device *dev)
|
||||||
return 0; /* Because of this, the layer above will return -ENODEV */
|
return 0; /* Because of this, the layer above will return -ENODEV */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const struct net_device_ops elp_netdev_ops = {
|
||||||
|
.ndo_open = elp_open,
|
||||||
|
.ndo_stop = elp_close,
|
||||||
|
.ndo_get_stats = elp_get_stats,
|
||||||
|
.ndo_start_xmit = elp_start_xmit,
|
||||||
|
.ndo_tx_timeout = elp_timeout,
|
||||||
|
.ndo_set_multicast_list = elp_set_mc_list,
|
||||||
|
.ndo_change_mtu = eth_change_mtu,
|
||||||
|
.ndo_set_mac_address = eth_mac_addr,
|
||||||
|
.ndo_validate_addr = eth_validate_addr,
|
||||||
|
};
|
||||||
|
|
||||||
/******************************************************
|
/******************************************************
|
||||||
*
|
*
|
||||||
|
@ -1558,13 +1569,8 @@ static int __init elplus_setup(struct net_device *dev)
|
||||||
printk(KERN_ERR "%s: adapter configuration failed\n", dev->name);
|
printk(KERN_ERR "%s: adapter configuration failed\n", dev->name);
|
||||||
}
|
}
|
||||||
|
|
||||||
dev->open = elp_open; /* local */
|
dev->netdev_ops = &elp_netdev_ops;
|
||||||
dev->stop = elp_close; /* local */
|
|
||||||
dev->get_stats = elp_get_stats; /* local */
|
|
||||||
dev->hard_start_xmit = elp_start_xmit; /* local */
|
|
||||||
dev->tx_timeout = elp_timeout; /* local */
|
|
||||||
dev->watchdog_timeo = 10*HZ;
|
dev->watchdog_timeo = 10*HZ;
|
||||||
dev->set_multicast_list = elp_set_mc_list; /* local */
|
|
||||||
dev->ethtool_ops = &netdev_ethtool_ops; /* local */
|
dev->ethtool_ops = &netdev_ethtool_ops; /* local */
|
||||||
|
|
||||||
dev->mem_start = dev->mem_end = 0;
|
dev->mem_start = dev->mem_end = 0;
|
||||||
|
|
|
@ -352,6 +352,16 @@ out:
|
||||||
return ERR_PTR(err);
|
return ERR_PTR(err);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const struct net_device_ops netdev_ops = {
|
||||||
|
.ndo_open = el16_open,
|
||||||
|
.ndo_stop = el16_close,
|
||||||
|
.ndo_start_xmit = el16_send_packet,
|
||||||
|
.ndo_tx_timeout = el16_tx_timeout,
|
||||||
|
.ndo_change_mtu = eth_change_mtu,
|
||||||
|
.ndo_set_mac_address = eth_mac_addr,
|
||||||
|
.ndo_validate_addr = eth_validate_addr,
|
||||||
|
};
|
||||||
|
|
||||||
static int __init el16_probe1(struct net_device *dev, int ioaddr)
|
static int __init el16_probe1(struct net_device *dev, int ioaddr)
|
||||||
{
|
{
|
||||||
static unsigned char init_ID_done, version_printed;
|
static unsigned char init_ID_done, version_printed;
|
||||||
|
@ -449,10 +459,7 @@ static int __init el16_probe1(struct net_device *dev, int ioaddr)
|
||||||
goto out1;
|
goto out1;
|
||||||
}
|
}
|
||||||
|
|
||||||
dev->open = el16_open;
|
dev->netdev_ops = &netdev_ops;
|
||||||
dev->stop = el16_close;
|
|
||||||
dev->hard_start_xmit = el16_send_packet;
|
|
||||||
dev->tx_timeout = el16_tx_timeout;
|
|
||||||
dev->watchdog_timeo = TX_TIMEOUT;
|
dev->watchdog_timeo = TX_TIMEOUT;
|
||||||
dev->ethtool_ops = &netdev_ethtool_ops;
|
dev->ethtool_ops = &netdev_ethtool_ops;
|
||||||
dev->flags &= ~IFF_MULTICAST; /* Multicast doesn't work */
|
dev->flags &= ~IFF_MULTICAST; /* Multicast doesn't work */
|
||||||
|
|
|
@ -537,6 +537,21 @@ static struct mca_driver el3_mca_driver = {
|
||||||
static int mca_registered;
|
static int mca_registered;
|
||||||
#endif /* CONFIG_MCA */
|
#endif /* CONFIG_MCA */
|
||||||
|
|
||||||
|
static const struct net_device_ops netdev_ops = {
|
||||||
|
.ndo_open = el3_open,
|
||||||
|
.ndo_stop = el3_close,
|
||||||
|
.ndo_start_xmit = el3_start_xmit,
|
||||||
|
.ndo_get_stats = el3_get_stats,
|
||||||
|
.ndo_set_multicast_list = set_multicast_list,
|
||||||
|
.ndo_tx_timeout = el3_tx_timeout,
|
||||||
|
.ndo_change_mtu = eth_change_mtu,
|
||||||
|
.ndo_set_mac_address = eth_mac_addr,
|
||||||
|
.ndo_validate_addr = eth_validate_addr,
|
||||||
|
#ifdef CONFIG_NET_POLL_CONTROLLER
|
||||||
|
.ndo_poll_controller = el3_poll_controller,
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
static int __devinit el3_common_init(struct net_device *dev)
|
static int __devinit el3_common_init(struct net_device *dev)
|
||||||
{
|
{
|
||||||
struct el3_private *lp = netdev_priv(dev);
|
struct el3_private *lp = netdev_priv(dev);
|
||||||
|
@ -553,16 +568,8 @@ static int __devinit el3_common_init(struct net_device *dev)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* The EL3-specific entries in the device structure. */
|
/* The EL3-specific entries in the device structure. */
|
||||||
dev->open = &el3_open;
|
dev->netdev_ops = &netdev_ops;
|
||||||
dev->hard_start_xmit = &el3_start_xmit;
|
|
||||||
dev->stop = &el3_close;
|
|
||||||
dev->get_stats = &el3_get_stats;
|
|
||||||
dev->set_multicast_list = &set_multicast_list;
|
|
||||||
dev->tx_timeout = el3_tx_timeout;
|
|
||||||
dev->watchdog_timeo = TX_TIMEOUT;
|
dev->watchdog_timeo = TX_TIMEOUT;
|
||||||
#ifdef CONFIG_NET_POLL_CONTROLLER
|
|
||||||
dev->poll_controller = el3_poll_controller;
|
|
||||||
#endif
|
|
||||||
SET_ETHTOOL_OPS(dev, ðtool_ops);
|
SET_ETHTOOL_OPS(dev, ðtool_ops);
|
||||||
|
|
||||||
err = register_netdev(dev);
|
err = register_netdev(dev);
|
||||||
|
|
|
@ -563,6 +563,20 @@ no_pnp:
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static const struct net_device_ops netdev_ops = {
|
||||||
|
.ndo_open = corkscrew_open,
|
||||||
|
.ndo_stop = corkscrew_close,
|
||||||
|
.ndo_start_xmit = corkscrew_start_xmit,
|
||||||
|
.ndo_tx_timeout = corkscrew_timeout,
|
||||||
|
.ndo_get_stats = corkscrew_get_stats,
|
||||||
|
.ndo_set_multicast_list = set_rx_mode,
|
||||||
|
.ndo_change_mtu = eth_change_mtu,
|
||||||
|
.ndo_set_mac_address = eth_mac_addr,
|
||||||
|
.ndo_validate_addr = eth_validate_addr,
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
static int corkscrew_setup(struct net_device *dev, int ioaddr,
|
static int corkscrew_setup(struct net_device *dev, int ioaddr,
|
||||||
struct pnp_dev *idev, int card_number)
|
struct pnp_dev *idev, int card_number)
|
||||||
{
|
{
|
||||||
|
@ -681,13 +695,8 @@ static int corkscrew_setup(struct net_device *dev, int ioaddr,
|
||||||
vp->full_bus_master_rx = (vp->capabilities & 0x20) ? 1 : 0;
|
vp->full_bus_master_rx = (vp->capabilities & 0x20) ? 1 : 0;
|
||||||
|
|
||||||
/* The 3c51x-specific entries in the device structure. */
|
/* The 3c51x-specific entries in the device structure. */
|
||||||
dev->open = &corkscrew_open;
|
dev->netdev_ops = &netdev_ops;
|
||||||
dev->hard_start_xmit = &corkscrew_start_xmit;
|
|
||||||
dev->tx_timeout = &corkscrew_timeout;
|
|
||||||
dev->watchdog_timeo = (400 * HZ) / 1000;
|
dev->watchdog_timeo = (400 * HZ) / 1000;
|
||||||
dev->stop = &corkscrew_close;
|
|
||||||
dev->get_stats = &corkscrew_get_stats;
|
|
||||||
dev->set_multicast_list = &set_rx_mode;
|
|
||||||
dev->ethtool_ops = &netdev_ethtool_ops;
|
dev->ethtool_ops = &netdev_ethtool_ops;
|
||||||
|
|
||||||
return register_netdev(dev);
|
return register_netdev(dev);
|
||||||
|
|
|
@ -403,6 +403,20 @@ static int elmc_getinfo(char *buf, int slot, void *d)
|
||||||
return len;
|
return len;
|
||||||
} /* elmc_getinfo() */
|
} /* elmc_getinfo() */
|
||||||
|
|
||||||
|
static const struct net_device_ops netdev_ops = {
|
||||||
|
.ndo_open = elmc_open,
|
||||||
|
.ndo_stop = elmc_close,
|
||||||
|
.ndo_get_stats = elmc_get_stats,
|
||||||
|
.ndo_start_xmit = elmc_send_packet,
|
||||||
|
.ndo_tx_timeout = elmc_timeout,
|
||||||
|
#ifdef ELMC_MULTICAST
|
||||||
|
.ndo_set_multicast_list = set_multicast_list,
|
||||||
|
#endif
|
||||||
|
.ndo_change_mtu = eth_change_mtu,
|
||||||
|
.ndo_set_mac_address = eth_mac_addr,
|
||||||
|
.ndo_validate_addr = eth_validate_addr,
|
||||||
|
};
|
||||||
|
|
||||||
/*****************************************************************/
|
/*****************************************************************/
|
||||||
|
|
||||||
static int __init do_elmc_probe(struct net_device *dev)
|
static int __init do_elmc_probe(struct net_device *dev)
|
||||||
|
@ -544,17 +558,8 @@ static int __init do_elmc_probe(struct net_device *dev)
|
||||||
printk(KERN_INFO "%s: hardware address %pM\n",
|
printk(KERN_INFO "%s: hardware address %pM\n",
|
||||||
dev->name, dev->dev_addr);
|
dev->name, dev->dev_addr);
|
||||||
|
|
||||||
dev->open = &elmc_open;
|
dev->netdev_ops = &netdev_ops;
|
||||||
dev->stop = &elmc_close;
|
|
||||||
dev->get_stats = &elmc_get_stats;
|
|
||||||
dev->hard_start_xmit = &elmc_send_packet;
|
|
||||||
dev->tx_timeout = &elmc_timeout;
|
|
||||||
dev->watchdog_timeo = HZ;
|
dev->watchdog_timeo = HZ;
|
||||||
#ifdef ELMC_MULTICAST
|
|
||||||
dev->set_multicast_list = &set_multicast_list;
|
|
||||||
#else
|
|
||||||
dev->set_multicast_list = NULL;
|
|
||||||
#endif
|
|
||||||
dev->ethtool_ops = &netdev_ethtool_ops;
|
dev->ethtool_ops = &netdev_ethtool_ops;
|
||||||
|
|
||||||
/* note that we haven't actually requested the IRQ from the kernel.
|
/* note that we haven't actually requested the IRQ from the kernel.
|
||||||
|
|
|
@ -288,6 +288,18 @@ struct net_device *__init mc32_probe(int unit)
|
||||||
return ERR_PTR(-ENODEV);
|
return ERR_PTR(-ENODEV);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const struct net_device_ops netdev_ops = {
|
||||||
|
.ndo_open = mc32_open,
|
||||||
|
.ndo_stop = mc32_close,
|
||||||
|
.ndo_start_xmit = mc32_send_packet,
|
||||||
|
.ndo_get_stats = mc32_get_stats,
|
||||||
|
.ndo_set_multicast_list = mc32_set_multicast_list,
|
||||||
|
.ndo_tx_timeout = mc32_timeout,
|
||||||
|
.ndo_change_mtu = eth_change_mtu,
|
||||||
|
.ndo_set_mac_address = eth_mac_addr,
|
||||||
|
.ndo_validate_addr = eth_validate_addr,
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* mc32_probe1 - Check a given slot for a board and test the card
|
* mc32_probe1 - Check a given slot for a board and test the card
|
||||||
* @dev: Device structure to fill in
|
* @dev: Device structure to fill in
|
||||||
|
@ -518,12 +530,7 @@ static int __init mc32_probe1(struct net_device *dev, int slot)
|
||||||
printk("%s: Firmware Rev %d. %d RX buffers, %d TX buffers. Base of 0x%08X.\n",
|
printk("%s: Firmware Rev %d. %d RX buffers, %d TX buffers. Base of 0x%08X.\n",
|
||||||
dev->name, lp->exec_box->data[12], lp->rx_len, lp->tx_len, lp->base);
|
dev->name, lp->exec_box->data[12], lp->rx_len, lp->tx_len, lp->base);
|
||||||
|
|
||||||
dev->open = mc32_open;
|
dev->netdev_ops = &netdev_ops;
|
||||||
dev->stop = mc32_close;
|
|
||||||
dev->hard_start_xmit = mc32_send_packet;
|
|
||||||
dev->get_stats = mc32_get_stats;
|
|
||||||
dev->set_multicast_list = mc32_set_multicast_list;
|
|
||||||
dev->tx_timeout = mc32_timeout;
|
|
||||||
dev->watchdog_timeo = HZ*5; /* Board does all the work */
|
dev->watchdog_timeo = HZ*5; /* Board does all the work */
|
||||||
dev->ethtool_ops = &netdev_ethtool_ops;
|
dev->ethtool_ops = &netdev_ethtool_ops;
|
||||||
|
|
||||||
|
|
|
@ -102,8 +102,8 @@ static int vortex_debug = 1;
|
||||||
#include <linux/delay.h>
|
#include <linux/delay.h>
|
||||||
|
|
||||||
|
|
||||||
static char version[] __devinitdata =
|
static const char version[] __devinitconst =
|
||||||
DRV_NAME ": Donald Becker and others.\n";
|
DRV_NAME ": Donald Becker and others.\n";
|
||||||
|
|
||||||
MODULE_AUTHOR("Donald Becker <becker@scyld.com>");
|
MODULE_AUTHOR("Donald Becker <becker@scyld.com>");
|
||||||
MODULE_DESCRIPTION("3Com 3c59x/3c9xx ethernet driver ");
|
MODULE_DESCRIPTION("3Com 3c59x/3c9xx ethernet driver ");
|
||||||
|
@ -992,6 +992,42 @@ out:
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const struct net_device_ops boomrang_netdev_ops = {
|
||||||
|
.ndo_open = vortex_open,
|
||||||
|
.ndo_stop = vortex_close,
|
||||||
|
.ndo_start_xmit = boomerang_start_xmit,
|
||||||
|
.ndo_tx_timeout = vortex_tx_timeout,
|
||||||
|
.ndo_get_stats = vortex_get_stats,
|
||||||
|
#ifdef CONFIG_PCI
|
||||||
|
.ndo_do_ioctl = vortex_ioctl,
|
||||||
|
#endif
|
||||||
|
.ndo_set_multicast_list = set_rx_mode,
|
||||||
|
.ndo_change_mtu = eth_change_mtu,
|
||||||
|
.ndo_set_mac_address = eth_mac_addr,
|
||||||
|
.ndo_validate_addr = eth_validate_addr,
|
||||||
|
#ifdef CONFIG_NET_POLL_CONTROLLER
|
||||||
|
.ndo_poll_controller = poll_vortex,
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct net_device_ops vortex_netdev_ops = {
|
||||||
|
.ndo_open = vortex_open,
|
||||||
|
.ndo_stop = vortex_close,
|
||||||
|
.ndo_start_xmit = vortex_start_xmit,
|
||||||
|
.ndo_tx_timeout = vortex_tx_timeout,
|
||||||
|
.ndo_get_stats = vortex_get_stats,
|
||||||
|
#ifdef CONFIG_PCI
|
||||||
|
.ndo_do_ioctl = vortex_ioctl,
|
||||||
|
#endif
|
||||||
|
.ndo_set_multicast_list = set_rx_mode,
|
||||||
|
.ndo_change_mtu = eth_change_mtu,
|
||||||
|
.ndo_set_mac_address = eth_mac_addr,
|
||||||
|
.ndo_validate_addr = eth_validate_addr,
|
||||||
|
#ifdef CONFIG_NET_POLL_CONTROLLER
|
||||||
|
.ndo_poll_controller = poll_vortex,
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Start up the PCI/EISA device which is described by *gendev.
|
* Start up the PCI/EISA device which is described by *gendev.
|
||||||
* Return 0 on success.
|
* Return 0 on success.
|
||||||
|
@ -1366,18 +1402,16 @@ static int __devinit vortex_probe1(struct device *gendev,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* The 3c59x-specific entries in the device structure. */
|
/* The 3c59x-specific entries in the device structure. */
|
||||||
dev->open = vortex_open;
|
|
||||||
if (vp->full_bus_master_tx) {
|
if (vp->full_bus_master_tx) {
|
||||||
dev->hard_start_xmit = boomerang_start_xmit;
|
dev->netdev_ops = &boomrang_netdev_ops;
|
||||||
/* Actually, it still should work with iommu. */
|
/* Actually, it still should work with iommu. */
|
||||||
if (card_idx < MAX_UNITS &&
|
if (card_idx < MAX_UNITS &&
|
||||||
((hw_checksums[card_idx] == -1 && (vp->drv_flags & HAS_HWCKSM)) ||
|
((hw_checksums[card_idx] == -1 && (vp->drv_flags & HAS_HWCKSM)) ||
|
||||||
hw_checksums[card_idx] == 1)) {
|
hw_checksums[card_idx] == 1)) {
|
||||||
dev->features |= NETIF_F_IP_CSUM | NETIF_F_SG;
|
dev->features |= NETIF_F_IP_CSUM | NETIF_F_SG;
|
||||||
}
|
}
|
||||||
} else {
|
} else
|
||||||
dev->hard_start_xmit = vortex_start_xmit;
|
dev->netdev_ops = &vortex_netdev_ops;
|
||||||
}
|
|
||||||
|
|
||||||
if (print_info) {
|
if (print_info) {
|
||||||
printk(KERN_INFO "%s: scatter/gather %sabled. h/w checksums %sabled\n",
|
printk(KERN_INFO "%s: scatter/gather %sabled. h/w checksums %sabled\n",
|
||||||
|
@ -1386,18 +1420,9 @@ static int __devinit vortex_probe1(struct device *gendev,
|
||||||
(dev->features & NETIF_F_IP_CSUM) ? "en":"dis");
|
(dev->features & NETIF_F_IP_CSUM) ? "en":"dis");
|
||||||
}
|
}
|
||||||
|
|
||||||
dev->stop = vortex_close;
|
|
||||||
dev->get_stats = vortex_get_stats;
|
|
||||||
#ifdef CONFIG_PCI
|
|
||||||
dev->do_ioctl = vortex_ioctl;
|
|
||||||
#endif
|
|
||||||
dev->ethtool_ops = &vortex_ethtool_ops;
|
dev->ethtool_ops = &vortex_ethtool_ops;
|
||||||
dev->set_multicast_list = set_rx_mode;
|
|
||||||
dev->tx_timeout = vortex_tx_timeout;
|
|
||||||
dev->watchdog_timeo = (watchdog * HZ) / 1000;
|
dev->watchdog_timeo = (watchdog * HZ) / 1000;
|
||||||
#ifdef CONFIG_NET_POLL_CONTROLLER
|
|
||||||
dev->poll_controller = poll_vortex;
|
|
||||||
#endif
|
|
||||||
if (pdev) {
|
if (pdev) {
|
||||||
vp->pm_state_valid = 1;
|
vp->pm_state_valid = 1;
|
||||||
pci_save_state(VORTEX_PCI(vp));
|
pci_save_state(VORTEX_PCI(vp));
|
||||||
|
@ -2883,7 +2908,7 @@ static void vortex_get_drvinfo(struct net_device *dev,
|
||||||
strcpy(info->bus_info, pci_name(VORTEX_PCI(vp)));
|
strcpy(info->bus_info, pci_name(VORTEX_PCI(vp)));
|
||||||
} else {
|
} else {
|
||||||
if (VORTEX_EISA(vp))
|
if (VORTEX_EISA(vp))
|
||||||
sprintf(info->bus_info, dev_name(vp->gendev));
|
strcpy(info->bus_info, dev_name(vp->gendev));
|
||||||
else
|
else
|
||||||
sprintf(info->bus_info, "EISA 0x%lx %d",
|
sprintf(info->bus_info, "EISA 0x%lx %d",
|
||||||
dev->base_addr, dev->irq);
|
dev->base_addr, dev->irq);
|
||||||
|
|
|
@ -604,7 +604,7 @@ rx_next:
|
||||||
|
|
||||||
spin_lock_irqsave(&cp->lock, flags);
|
spin_lock_irqsave(&cp->lock, flags);
|
||||||
cpw16_f(IntrMask, cp_intr_mask);
|
cpw16_f(IntrMask, cp_intr_mask);
|
||||||
__netif_rx_complete(napi);
|
__napi_complete(napi);
|
||||||
spin_unlock_irqrestore(&cp->lock, flags);
|
spin_unlock_irqrestore(&cp->lock, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -641,9 +641,9 @@ static irqreturn_t cp_interrupt (int irq, void *dev_instance)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (status & (RxOK | RxErr | RxEmpty | RxFIFOOvr))
|
if (status & (RxOK | RxErr | RxEmpty | RxFIFOOvr))
|
||||||
if (netif_rx_schedule_prep(&cp->napi)) {
|
if (napi_schedule_prep(&cp->napi)) {
|
||||||
cpw16_f(IntrMask, cp_norx_intr_mask);
|
cpw16_f(IntrMask, cp_norx_intr_mask);
|
||||||
__netif_rx_schedule(&cp->napi);
|
__napi_schedule(&cp->napi);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (status & (TxOK | TxErr | TxEmpty | SWInt))
|
if (status & (TxOK | TxErr | TxEmpty | SWInt))
|
||||||
|
@ -1602,6 +1602,28 @@ static int cp_ioctl (struct net_device *dev, struct ifreq *rq, int cmd)
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int cp_set_mac_address(struct net_device *dev, void *p)
|
||||||
|
{
|
||||||
|
struct cp_private *cp = netdev_priv(dev);
|
||||||
|
struct sockaddr *addr = p;
|
||||||
|
|
||||||
|
if (!is_valid_ether_addr(addr->sa_data))
|
||||||
|
return -EADDRNOTAVAIL;
|
||||||
|
|
||||||
|
memcpy(dev->dev_addr, addr->sa_data, dev->addr_len);
|
||||||
|
|
||||||
|
spin_lock_irq(&cp->lock);
|
||||||
|
|
||||||
|
cpw8_f(Cfg9346, Cfg9346_Unlock);
|
||||||
|
cpw32_f(MAC0 + 0, le32_to_cpu (*(__le32 *) (dev->dev_addr + 0)));
|
||||||
|
cpw32_f(MAC0 + 4, le32_to_cpu (*(__le32 *) (dev->dev_addr + 4)));
|
||||||
|
cpw8_f(Cfg9346, Cfg9346_Lock);
|
||||||
|
|
||||||
|
spin_unlock_irq(&cp->lock);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/* Serial EEPROM section. */
|
/* Serial EEPROM section. */
|
||||||
|
|
||||||
/* EEPROM_Ctrl bits. */
|
/* EEPROM_Ctrl bits. */
|
||||||
|
@ -1821,7 +1843,7 @@ static const struct net_device_ops cp_netdev_ops = {
|
||||||
.ndo_open = cp_open,
|
.ndo_open = cp_open,
|
||||||
.ndo_stop = cp_close,
|
.ndo_stop = cp_close,
|
||||||
.ndo_validate_addr = eth_validate_addr,
|
.ndo_validate_addr = eth_validate_addr,
|
||||||
.ndo_set_mac_address = eth_mac_addr,
|
.ndo_set_mac_address = cp_set_mac_address,
|
||||||
.ndo_set_multicast_list = cp_set_rx_mode,
|
.ndo_set_multicast_list = cp_set_rx_mode,
|
||||||
.ndo_get_stats = cp_get_stats,
|
.ndo_get_stats = cp_get_stats,
|
||||||
.ndo_do_ioctl = cp_ioctl,
|
.ndo_do_ioctl = cp_ioctl,
|
||||||
|
|
|
@ -640,6 +640,7 @@ static int rtl8139_start_xmit (struct sk_buff *skb,
|
||||||
#ifdef CONFIG_NET_POLL_CONTROLLER
|
#ifdef CONFIG_NET_POLL_CONTROLLER
|
||||||
static void rtl8139_poll_controller(struct net_device *dev);
|
static void rtl8139_poll_controller(struct net_device *dev);
|
||||||
#endif
|
#endif
|
||||||
|
static int rtl8139_set_mac_address(struct net_device *dev, void *p);
|
||||||
static int rtl8139_poll(struct napi_struct *napi, int budget);
|
static int rtl8139_poll(struct napi_struct *napi, int budget);
|
||||||
static irqreturn_t rtl8139_interrupt (int irq, void *dev_instance);
|
static irqreturn_t rtl8139_interrupt (int irq, void *dev_instance);
|
||||||
static int rtl8139_close (struct net_device *dev);
|
static int rtl8139_close (struct net_device *dev);
|
||||||
|
@ -917,7 +918,7 @@ static const struct net_device_ops rtl8139_netdev_ops = {
|
||||||
.ndo_stop = rtl8139_close,
|
.ndo_stop = rtl8139_close,
|
||||||
.ndo_get_stats = rtl8139_get_stats,
|
.ndo_get_stats = rtl8139_get_stats,
|
||||||
.ndo_validate_addr = eth_validate_addr,
|
.ndo_validate_addr = eth_validate_addr,
|
||||||
.ndo_set_mac_address = eth_mac_addr,
|
.ndo_set_mac_address = rtl8139_set_mac_address,
|
||||||
.ndo_start_xmit = rtl8139_start_xmit,
|
.ndo_start_xmit = rtl8139_start_xmit,
|
||||||
.ndo_set_multicast_list = rtl8139_set_rx_mode,
|
.ndo_set_multicast_list = rtl8139_set_rx_mode,
|
||||||
.ndo_do_ioctl = netdev_ioctl,
|
.ndo_do_ioctl = netdev_ioctl,
|
||||||
|
@ -2128,7 +2129,7 @@ static int rtl8139_poll(struct napi_struct *napi, int budget)
|
||||||
*/
|
*/
|
||||||
spin_lock_irqsave(&tp->lock, flags);
|
spin_lock_irqsave(&tp->lock, flags);
|
||||||
RTL_W16_F(IntrMask, rtl8139_intr_mask);
|
RTL_W16_F(IntrMask, rtl8139_intr_mask);
|
||||||
__netif_rx_complete(napi);
|
__napi_complete(napi);
|
||||||
spin_unlock_irqrestore(&tp->lock, flags);
|
spin_unlock_irqrestore(&tp->lock, flags);
|
||||||
}
|
}
|
||||||
spin_unlock(&tp->rx_lock);
|
spin_unlock(&tp->rx_lock);
|
||||||
|
@ -2178,9 +2179,9 @@ static irqreturn_t rtl8139_interrupt (int irq, void *dev_instance)
|
||||||
/* Receive packets are processed by poll routine.
|
/* Receive packets are processed by poll routine.
|
||||||
If not running start it now. */
|
If not running start it now. */
|
||||||
if (status & RxAckBits){
|
if (status & RxAckBits){
|
||||||
if (netif_rx_schedule_prep(&tp->napi)) {
|
if (napi_schedule_prep(&tp->napi)) {
|
||||||
RTL_W16_F (IntrMask, rtl8139_norx_intr_mask);
|
RTL_W16_F (IntrMask, rtl8139_norx_intr_mask);
|
||||||
__netif_rx_schedule(&tp->napi);
|
__napi_schedule(&tp->napi);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2215,6 +2216,29 @@ static void rtl8139_poll_controller(struct net_device *dev)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
static int rtl8139_set_mac_address(struct net_device *dev, void *p)
|
||||||
|
{
|
||||||
|
struct rtl8139_private *tp = netdev_priv(dev);
|
||||||
|
void __iomem *ioaddr = tp->mmio_addr;
|
||||||
|
struct sockaddr *addr = p;
|
||||||
|
|
||||||
|
if (!is_valid_ether_addr(addr->sa_data))
|
||||||
|
return -EADDRNOTAVAIL;
|
||||||
|
|
||||||
|
memcpy(dev->dev_addr, addr->sa_data, dev->addr_len);
|
||||||
|
|
||||||
|
spin_lock_irq(&tp->lock);
|
||||||
|
|
||||||
|
RTL_W8_F(Cfg9346, Cfg9346_Unlock);
|
||||||
|
RTL_W32_F(MAC0 + 0, cpu_to_le32 (*(u32 *) (dev->dev_addr + 0)));
|
||||||
|
RTL_W32_F(MAC0 + 4, cpu_to_le32 (*(u32 *) (dev->dev_addr + 4)));
|
||||||
|
RTL_W8_F(Cfg9346, Cfg9346_Lock);
|
||||||
|
|
||||||
|
spin_unlock_irq(&tp->lock);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int rtl8139_close (struct net_device *dev)
|
static int rtl8139_close (struct net_device *dev)
|
||||||
{
|
{
|
||||||
struct rtl8139_private *tp = netdev_priv(dev);
|
struct rtl8139_private *tp = netdev_priv(dev);
|
||||||
|
|
Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше
Загрузка…
Ссылка в новой задаче