mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-11 12:28:41 +08:00
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next
Pull networking changes from David Miller: 1) Allow to dump, monitor, and change the bridge multicast database using netlink. From Cong Wang. 2) RFC 5961 TCP blind data injection attack mitigation, from Eric Dumazet. 3) Networking user namespace support from Eric W. Biederman. 4) tuntap/virtio-net multiqueue support by Jason Wang. 5) Support for checksum offload of encapsulated packets (basically, tunneled traffic can still be checksummed by HW). From Joseph Gasparakis. 6) Allow BPF filter access to VLAN tags, from Eric Dumazet and Daniel Borkmann. 7) Bridge port parameters over netlink and BPDU blocking support from Stephen Hemminger. 8) Improve data access patterns during inet socket demux by rearranging socket layout, from Eric Dumazet. 9) TIPC protocol updates and cleanups from Ying Xue, Paul Gortmaker, and Jon Maloy. 10) Update TCP socket hash sizing to be more in line with current day realities. The existing heurstics were choosen a decade ago. From Eric Dumazet. 11) Fix races, queue bloat, and excessive wakeups in ATM and associated drivers, from Krzysztof Mazur and David Woodhouse. 12) Support DOVE (Distributed Overlay Virtual Ethernet) extensions in VXLAN driver, from David Stevens. 13) Add "oops_only" mode to netconsole, from Amerigo Wang. 14) Support set and query of VEB/VEPA bridge mode via PF_BRIDGE, also allow DCB netlink to work on namespaces other than the initial namespace. From John Fastabend. 15) Support PTP in the Tigon3 driver, from Matt Carlson. 16) tun/vhost zero copy fixes and improvements, plus turn it on by default, from Michael S. Tsirkin. 17) Support per-association statistics in SCTP, from Michele Baldessari. And many, many, driver updates, cleanups, and improvements. Too numerous to mention individually. * git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next: (1722 commits) net/mlx4_en: Add support for destination MAC in steering rules net/mlx4_en: Use generic etherdevice.h functions. net: ethtool: Add destination MAC address to flow steering API bridge: add support of adding and deleting mdb entries bridge: notify mdb changes via netlink ndisc: Unexport ndisc_{build,send}_skb(). uapi: add missing netconf.h to export list pkt_sched: avoid requeues if possible solos-pci: fix double-free of TX skb in DMA mode bnx2: Fix accidental reversions. bna: Driver Version Updated to 3.1.2.1 bna: Firmware update bna: Add RX State bna: Rx Page Based Allocation bna: TX Intr Coalescing Fix bna: Tx and Rx Optimizations bna: Code Cleanup and Enhancements ath9k: check pdata variable before dereferencing it ath5k: RX timestamp is reported at end of frame ath9k_htc: RX timestamp is reported at end of frame ...
This commit is contained in:
commit
6be35c700f
9
Documentation/ABI/testing/sysfs-bus-mdio
Normal file
9
Documentation/ABI/testing/sysfs-bus-mdio
Normal file
@ -0,0 +1,9 @@
|
||||
What: /sys/bus/mdio_bus/devices/.../phy_id
|
||||
Date: November 2012
|
||||
KernelVersion: 3.8
|
||||
Contact: netdev@vger.kernel.org
|
||||
Description:
|
||||
This attribute contains the 32-bit PHY Identifier as reported
|
||||
by the device during bus enumeration, encoded in hexadecimal.
|
||||
This ID is used to match the device with the appropriate
|
||||
driver.
|
@ -1,4 +1,10 @@
|
||||
|
||||
What: /sys/class/net/<iface>/batman-adv/iface_status
|
||||
Date: May 2010
|
||||
Contact: Marek Lindner <lindner_marek@yahoo.de>
|
||||
Description:
|
||||
Indicates the status of <iface> as it is seen by batman.
|
||||
|
||||
What: /sys/class/net/<iface>/batman-adv/mesh_iface
|
||||
Date: May 2010
|
||||
Contact: Marek Lindner <lindner_marek@yahoo.de>
|
||||
@ -7,8 +13,3 @@ Description:
|
||||
displays the batman mesh interface this <iface>
|
||||
currently is associated with.
|
||||
|
||||
What: /sys/class/net/<iface>/batman-adv/iface_status
|
||||
Date: May 2010
|
||||
Contact: Marek Lindner <lindner_marek@yahoo.de>
|
||||
Description:
|
||||
Indicates the status of <iface> as it is seen by batman.
|
||||
|
35
Documentation/ABI/testing/sysfs-class-net-grcan
Normal file
35
Documentation/ABI/testing/sysfs-class-net-grcan
Normal file
@ -0,0 +1,35 @@
|
||||
|
||||
What: /sys/class/net/<iface>/grcan/enable0
|
||||
Date: October 2012
|
||||
KernelVersion: 3.8
|
||||
Contact: Andreas Larsson <andreas@gaisler.com>
|
||||
Description:
|
||||
Hardware configuration of physical interface 0. This file reads
|
||||
and writes the "Enable 0" bit of the configuration register.
|
||||
Possible values: 0 or 1. See the GRCAN chapter of the GRLIB IP
|
||||
core library documentation for details. The default value is 0
|
||||
or set by the module parameter grcan.enable0 and can be read at
|
||||
/sys/module/grcan/parameters/enable0.
|
||||
|
||||
What: /sys/class/net/<iface>/grcan/enable1
|
||||
Date: October 2012
|
||||
KernelVersion: 3.8
|
||||
Contact: Andreas Larsson <andreas@gaisler.com>
|
||||
Description:
|
||||
Hardware configuration of physical interface 1. This file reads
|
||||
and writes the "Enable 1" bit of the configuration register.
|
||||
Possible values: 0 or 1. See the GRCAN chapter of the GRLIB IP
|
||||
core library documentation for details. The default value is 0
|
||||
or set by the module parameter grcan.enable1 and can be read at
|
||||
/sys/module/grcan/parameters/enable1.
|
||||
|
||||
What: /sys/class/net/<iface>/grcan/select
|
||||
Date: October 2012
|
||||
KernelVersion: 3.8
|
||||
Contact: Andreas Larsson <andreas@gaisler.com>
|
||||
Description:
|
||||
Configuration of which physical interface to be used. Possible
|
||||
values: 0 or 1. See the GRCAN chapter of the GRLIB IP core
|
||||
library documentation for details. The default value is 0 or is
|
||||
set by the module parameter grcan.select and can be read at
|
||||
/sys/module/grcan/parameters/select.
|
@ -6,6 +6,14 @@ Description:
|
||||
Indicates whether the batman protocol messages of the
|
||||
mesh <mesh_iface> shall be aggregated or not.
|
||||
|
||||
What: /sys/class/net/<mesh_iface>/mesh/ap_isolation
|
||||
Date: May 2011
|
||||
Contact: Antonio Quartulli <ordex@autistici.org>
|
||||
Description:
|
||||
Indicates whether the data traffic going from a
|
||||
wireless client to another wireless client will be
|
||||
silently dropped.
|
||||
|
||||
What: /sys/class/net/<mesh_iface>/mesh/bonding
|
||||
Date: June 2010
|
||||
Contact: Simon Wunderlich <siwu@hrz.tu-chemnitz.de>
|
||||
@ -31,14 +39,6 @@ Description:
|
||||
mesh will be fragmented or silently discarded if the
|
||||
packet size exceeds the outgoing interface MTU.
|
||||
|
||||
What: /sys/class/net/<mesh_iface>/mesh/ap_isolation
|
||||
Date: May 2011
|
||||
Contact: Antonio Quartulli <ordex@autistici.org>
|
||||
Description:
|
||||
Indicates whether the data traffic going from a
|
||||
wireless client to another wireless client will be
|
||||
silently dropped.
|
||||
|
||||
What: /sys/class/net/<mesh_iface>/mesh/gw_bandwidth
|
||||
Date: October 2010
|
||||
Contact: Marek Lindner <lindner_marek@yahoo.de>
|
||||
@ -60,6 +60,13 @@ Description:
|
||||
Defines the selection criteria this node will use
|
||||
to choose a gateway if gw_mode was set to 'client'.
|
||||
|
||||
What: /sys/class/net/<mesh_iface>/mesh/hop_penalty
|
||||
Date: Oct 2010
|
||||
Contact: Linus Lüssing <linus.luessing@web.de>
|
||||
Description:
|
||||
Defines the penalty which will be applied to an
|
||||
originator message's tq-field on every hop.
|
||||
|
||||
What: /sys/class/net/<mesh_iface>/mesh/orig_interval
|
||||
Date: May 2010
|
||||
Contact: Marek Lindner <lindner_marek@yahoo.de>
|
||||
@ -67,19 +74,12 @@ Description:
|
||||
Defines the interval in milliseconds in which batman
|
||||
sends its protocol messages.
|
||||
|
||||
What: /sys/class/net/<mesh_iface>/mesh/hop_penalty
|
||||
Date: Oct 2010
|
||||
Contact: Linus Lüssing <linus.luessing@web.de>
|
||||
What: /sys/class/net/<mesh_iface>/mesh/routing_algo
|
||||
Date: Dec 2011
|
||||
Contact: Marek Lindner <lindner_marek@yahoo.de>
|
||||
Description:
|
||||
Defines the penalty which will be applied to an
|
||||
originator message's tq-field on every hop.
|
||||
|
||||
What: /sys/class/net/<mesh_iface>/mesh/routing_algo
|
||||
Date: Dec 2011
|
||||
Contact: Marek Lindner <lindner_marek@yahoo.de>
|
||||
Description:
|
||||
Defines the routing procotol this mesh instance
|
||||
uses to find the optimal paths through the mesh.
|
||||
Defines the routing procotol this mesh instance
|
||||
uses to find the optimal paths through the mesh.
|
||||
|
||||
What: /sys/class/net/<mesh_iface>/mesh/vis_mode
|
||||
Date: May 2010
|
||||
|
28
Documentation/devicetree/bindings/net/can/grcan.txt
Normal file
28
Documentation/devicetree/bindings/net/can/grcan.txt
Normal file
@ -0,0 +1,28 @@
|
||||
Aeroflex Gaisler GRCAN and GRHCAN CAN controllers.
|
||||
|
||||
The GRCAN and CRHCAN CAN controllers are available in the GRLIB VHDL IP core
|
||||
library.
|
||||
|
||||
Note: These properties are built from the AMBA plug&play in a Leon SPARC system
|
||||
(the ordinary environment for GRCAN and GRHCAN). There are no dts files for
|
||||
sparc.
|
||||
|
||||
Required properties:
|
||||
|
||||
- name : Should be "GAISLER_GRCAN", "01_03d", "GAISLER_GRHCAN" or "01_034"
|
||||
|
||||
- reg : Address and length of the register set for the device
|
||||
|
||||
- freq : Frequency of the external oscillator clock in Hz (the frequency of
|
||||
the amba bus in the ordinary case)
|
||||
|
||||
- interrupts : Interrupt number for this device
|
||||
|
||||
Optional properties:
|
||||
|
||||
- systemid : If not present or if the value of the least significant 16 bits
|
||||
of this 32-bit property is smaller than GRCAN_TXBUG_SAFE_GRLIB_VERSION
|
||||
a bug workaround is activated.
|
||||
|
||||
For further information look in the documentation for the GLIB IP core library:
|
||||
http://www.gaisler.com/products/grlib/grip.pdf
|
23
Documentation/devicetree/bindings/net/cdns-emac.txt
Normal file
23
Documentation/devicetree/bindings/net/cdns-emac.txt
Normal file
@ -0,0 +1,23 @@
|
||||
* Cadence EMAC Ethernet controller
|
||||
|
||||
Required properties:
|
||||
- compatible: Should be "cdns,[<chip>-]{emac}"
|
||||
Use "cdns,at91rm9200-emac" Atmel at91rm9200 SoC.
|
||||
or the generic form: "cdns,emac".
|
||||
- reg: Address and length of the register set for the device
|
||||
- interrupts: Should contain macb interrupt
|
||||
- phy-mode: String, operation mode of the PHY interface.
|
||||
Supported values are: "mii", "rmii".
|
||||
|
||||
Optional properties:
|
||||
- local-mac-address: 6 bytes, mac address
|
||||
|
||||
Examples:
|
||||
|
||||
macb0: ethernet@fffc4000 {
|
||||
compatible = "cdns,at91rm9200-emac";
|
||||
reg = <0xfffc4000 0x4000>;
|
||||
interrupts = <21>;
|
||||
phy-mode = "rmii";
|
||||
local-mac-address = [3a 0e 03 04 05 06];
|
||||
};
|
@ -9,21 +9,15 @@ Required properties:
|
||||
number
|
||||
- interrupt-parent : The parent interrupt controller
|
||||
- cpdma_channels : Specifies number of channels in CPDMA
|
||||
- host_port_no : Specifies host port shift
|
||||
- cpdma_reg_ofs : Specifies CPDMA submodule register offset
|
||||
- cpdma_sram_ofs : Specifies CPDMA SRAM offset
|
||||
- ale_reg_ofs : Specifies ALE submodule register offset
|
||||
- ale_entries : Specifies No of entries ALE can hold
|
||||
- host_port_reg_ofs : Specifies host port register offset
|
||||
- hw_stats_reg_ofs : Specifies hardware statistics register offset
|
||||
- bd_ram_ofs : Specifies internal desciptor RAM offset
|
||||
- bd_ram_size : Specifies internal descriptor RAM size
|
||||
- rx_descs : Specifies number of Rx descriptors
|
||||
- mac_control : Specifies Default MAC control register content
|
||||
for the specific platform
|
||||
- slaves : Specifies number for slaves
|
||||
- slave_reg_ofs : Specifies slave register offset
|
||||
- sliver_reg_ofs : Specifies slave sliver register offset
|
||||
- cpts_active_slave : Specifies the slave to use for time stamping
|
||||
- cpts_clock_mult : Numerator to convert input clock ticks into nanoseconds
|
||||
- cpts_clock_shift : Denominator to convert input clock ticks into nanoseconds
|
||||
- phy_id : Specifies slave phy id
|
||||
- mac-address : Specifies slave MAC address
|
||||
|
||||
@ -45,30 +39,22 @@ Examples:
|
||||
interrupts = <55 0x4>;
|
||||
interrupt-parent = <&intc>;
|
||||
cpdma_channels = <8>;
|
||||
host_port_no = <0>;
|
||||
cpdma_reg_ofs = <0x800>;
|
||||
cpdma_sram_ofs = <0xa00>;
|
||||
ale_reg_ofs = <0xd00>;
|
||||
ale_entries = <1024>;
|
||||
host_port_reg_ofs = <0x108>;
|
||||
hw_stats_reg_ofs = <0x900>;
|
||||
bd_ram_ofs = <0x2000>;
|
||||
bd_ram_size = <0x2000>;
|
||||
no_bd_ram = <0>;
|
||||
rx_descs = <64>;
|
||||
mac_control = <0x20>;
|
||||
slaves = <2>;
|
||||
cpts_active_slave = <0>;
|
||||
cpts_clock_mult = <0x80000000>;
|
||||
cpts_clock_shift = <29>;
|
||||
cpsw_emac0: slave@0 {
|
||||
slave_reg_ofs = <0x208>;
|
||||
sliver_reg_ofs = <0xd80>;
|
||||
phy_id = "davinci_mdio.16:00";
|
||||
phy_id = <&davinci_mdio>, <0>;
|
||||
/* Filled in by U-Boot */
|
||||
mac-address = [ 00 00 00 00 00 00 ];
|
||||
};
|
||||
cpsw_emac1: slave@1 {
|
||||
slave_reg_ofs = <0x308>;
|
||||
sliver_reg_ofs = <0xdc0>;
|
||||
phy_id = "davinci_mdio.16:01";
|
||||
phy_id = <&davinci_mdio>, <1>;
|
||||
/* Filled in by U-Boot */
|
||||
mac-address = [ 00 00 00 00 00 00 ];
|
||||
};
|
||||
@ -79,30 +65,22 @@ Examples:
|
||||
compatible = "ti,cpsw";
|
||||
ti,hwmods = "cpgmac0";
|
||||
cpdma_channels = <8>;
|
||||
host_port_no = <0>;
|
||||
cpdma_reg_ofs = <0x800>;
|
||||
cpdma_sram_ofs = <0xa00>;
|
||||
ale_reg_ofs = <0xd00>;
|
||||
ale_entries = <1024>;
|
||||
host_port_reg_ofs = <0x108>;
|
||||
hw_stats_reg_ofs = <0x900>;
|
||||
bd_ram_ofs = <0x2000>;
|
||||
bd_ram_size = <0x2000>;
|
||||
no_bd_ram = <0>;
|
||||
rx_descs = <64>;
|
||||
mac_control = <0x20>;
|
||||
slaves = <2>;
|
||||
cpts_active_slave = <0>;
|
||||
cpts_clock_mult = <0x80000000>;
|
||||
cpts_clock_shift = <29>;
|
||||
cpsw_emac0: slave@0 {
|
||||
slave_reg_ofs = <0x208>;
|
||||
sliver_reg_ofs = <0xd80>;
|
||||
phy_id = "davinci_mdio.16:00";
|
||||
phy_id = <&davinci_mdio>, <0>;
|
||||
/* Filled in by U-Boot */
|
||||
mac-address = [ 00 00 00 00 00 00 ];
|
||||
};
|
||||
cpsw_emac1: slave@1 {
|
||||
slave_reg_ofs = <0x308>;
|
||||
sliver_reg_ofs = <0xdc0>;
|
||||
phy_id = "davinci_mdio.16:01";
|
||||
phy_id = <&davinci_mdio>, <1>;
|
||||
/* Filled in by U-Boot */
|
||||
mac-address = [ 00 00 00 00 00 00 ];
|
||||
};
|
||||
|
@ -905,6 +905,24 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
|
||||
gpt [EFI] Forces disk with valid GPT signature but
|
||||
invalid Protective MBR to be treated as GPT.
|
||||
|
||||
grcan.enable0= [HW] Configuration of physical interface 0. Determines
|
||||
the "Enable 0" bit of the configuration register.
|
||||
Format: 0 | 1
|
||||
Default: 0
|
||||
grcan.enable1= [HW] Configuration of physical interface 1. Determines
|
||||
the "Enable 0" bit of the configuration register.
|
||||
Format: 0 | 1
|
||||
Default: 0
|
||||
grcan.select= [HW] Select which physical interface to use.
|
||||
Format: 0 | 1
|
||||
Default: 0
|
||||
grcan.txsize= [HW] Sets the size of the tx buffer.
|
||||
Format: <unsigned int> such that (txsize & ~0x1fffc0) == 0.
|
||||
Default: 1024
|
||||
grcan.rxsize= [HW] Sets the size of the rx buffer.
|
||||
Format: <unsigned int> such that (rxsize & ~0x1fffc0) == 0.
|
||||
Default: 1024
|
||||
|
||||
hashdist= [KNL,NUMA] Large hashes allocated during boot
|
||||
are distributed across NUMA nodes. Defaults on
|
||||
for 64-bit NUMA, off otherwise.
|
||||
|
@ -203,7 +203,8 @@ abled during run time. Following log_levels are defined:
|
||||
2 - Enable messages related to route added / changed / deleted
|
||||
4 - Enable messages related to translation table operations
|
||||
8 - Enable messages related to bridge loop avoidance
|
||||
15 - enable all messages
|
||||
16 - Enable messaged related to DAT, ARP snooping and parsing
|
||||
31 - Enable all messages
|
||||
|
||||
The debug output can be changed at runtime using the file
|
||||
/sys/class/net/bat0/mesh/log_level. e.g.
|
||||
|
@ -30,16 +30,24 @@ neigh/default/gc_thresh3 - INTEGER
|
||||
Maximum number of neighbor entries allowed. Increase this
|
||||
when using large numbers of interfaces and when communicating
|
||||
with large numbers of directly-connected peers.
|
||||
Default: 1024
|
||||
|
||||
neigh/default/unres_qlen_bytes - INTEGER
|
||||
The maximum number of bytes which may be used by packets
|
||||
queued for each unresolved address by other network layers.
|
||||
(added in linux 3.3)
|
||||
Seting negative value is meaningless and will retrun error.
|
||||
Default: 65536 Bytes(64KB)
|
||||
|
||||
neigh/default/unres_qlen - INTEGER
|
||||
The maximum number of packets which may be queued for each
|
||||
unresolved address by other network layers.
|
||||
(deprecated in linux 3.3) : use unres_qlen_bytes instead.
|
||||
Prior to linux 3.3, the default value is 3 which may cause
|
||||
unexpected packet loss. The current default value is calculated
|
||||
according to default value of unres_qlen_bytes and true size of
|
||||
packet.
|
||||
Default: 31
|
||||
|
||||
mtu_expires - INTEGER
|
||||
Time, in seconds, that cached PMTU information is kept.
|
||||
@ -199,15 +207,16 @@ tcp_early_retrans - INTEGER
|
||||
Default: 2
|
||||
|
||||
tcp_ecn - INTEGER
|
||||
Enable Explicit Congestion Notification (ECN) in TCP. ECN is only
|
||||
used when both ends of the TCP flow support it. It is useful to
|
||||
avoid losses due to congestion (when the bottleneck router supports
|
||||
ECN).
|
||||
Control use of Explicit Congestion Notification (ECN) by TCP.
|
||||
ECN is used only when both ends of the TCP connection indicate
|
||||
support for it. This feature is useful in avoiding losses due
|
||||
to congestion by allowing supporting routers to signal
|
||||
congestion before having to drop packets.
|
||||
Possible values are:
|
||||
0 disable ECN
|
||||
1 ECN enabled
|
||||
2 Only server-side ECN enabled. If the other end does
|
||||
not support ECN, behavior is like with ECN disabled.
|
||||
0 Disable ECN. Neither initiate nor accept ECN.
|
||||
1 Always request ECN on outgoing connection attempts.
|
||||
2 Enable ECN when requested by incomming connections
|
||||
but do not request ECN on outgoing connections.
|
||||
Default: 2
|
||||
|
||||
tcp_fack - BOOLEAN
|
||||
@ -215,15 +224,14 @@ tcp_fack - BOOLEAN
|
||||
The value is not used, if tcp_sack is not enabled.
|
||||
|
||||
tcp_fin_timeout - INTEGER
|
||||
Time to hold socket in state FIN-WAIT-2, if it was closed
|
||||
by our side. Peer can be broken and never close its side,
|
||||
or even died unexpectedly. Default value is 60sec.
|
||||
Usual value used in 2.2 was 180 seconds, you may restore
|
||||
it, but remember that if your machine is even underloaded WEB server,
|
||||
you risk to overflow memory with kilotons of dead sockets,
|
||||
FIN-WAIT-2 sockets are less dangerous than FIN-WAIT-1,
|
||||
because they eat maximum 1.5K of memory, but they tend
|
||||
to live longer. Cf. tcp_max_orphans.
|
||||
The length of time an orphaned (no longer referenced by any
|
||||
application) connection will remain in the FIN_WAIT_2 state
|
||||
before it is aborted at the local end. While a perfectly
|
||||
valid "receive only" state for an un-orphaned connection, an
|
||||
orphaned connection in FIN_WAIT_2 state could otherwise wait
|
||||
forever for the remote to close its end of the connection.
|
||||
Cf. tcp_max_orphans
|
||||
Default: 60 seconds
|
||||
|
||||
tcp_frto - INTEGER
|
||||
Enables Forward RTO-Recovery (F-RTO) defined in RFC4138.
|
||||
@ -1514,6 +1522,20 @@ cookie_preserve_enable - BOOLEAN
|
||||
|
||||
Default: 1
|
||||
|
||||
cookie_hmac_alg - STRING
|
||||
Select the hmac algorithm used when generating the cookie value sent by
|
||||
a listening sctp socket to a connecting client in the INIT-ACK chunk.
|
||||
Valid values are:
|
||||
* md5
|
||||
* sha1
|
||||
* none
|
||||
Ability to assign md5 or sha1 as the selected alg is predicated on the
|
||||
configuarion of those algorithms at build time (CONFIG_CRYPTO_MD5 and
|
||||
CONFIG_CRYPTO_SHA1).
|
||||
|
||||
Default: Dependent on configuration. MD5 if available, else SHA1 if
|
||||
available, else none.
|
||||
|
||||
rcvbuf_policy - INTEGER
|
||||
Determines if the receive buffer is attributed to the socket or to
|
||||
association. SCTP supports the capability to create multiple
|
||||
|
@ -3,9 +3,9 @@
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
This file documents the mmap() facility available with the PACKET
|
||||
socket interface on 2.4 and 2.6 kernels. This type of sockets is used for
|
||||
capture network traffic with utilities like tcpdump or any other that needs
|
||||
raw access to network interface.
|
||||
socket interface on 2.4/2.6/3.x kernels. This type of sockets is used for
|
||||
i) capture network traffic with utilities like tcpdump, ii) transmit network
|
||||
traffic, or any other that needs raw access to network interface.
|
||||
|
||||
You can find the latest version of this document at:
|
||||
http://wiki.ipxwarzone.com/index.php5?title=Linux_packet_mmap
|
||||
@ -21,19 +21,18 @@ Please send your comments to
|
||||
+ Why use PACKET_MMAP
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
In Linux 2.4/2.6 if PACKET_MMAP is not enabled, the capture process is very
|
||||
inefficient. It uses very limited buffers and requires one system call
|
||||
to capture each packet, it requires two if you want to get packet's
|
||||
timestamp (like libpcap always does).
|
||||
In Linux 2.4/2.6/3.x if PACKET_MMAP is not enabled, the capture process is very
|
||||
inefficient. It uses very limited buffers and requires one system call to
|
||||
capture each packet, it requires two if you want to get packet's timestamp
|
||||
(like libpcap always does).
|
||||
|
||||
In the other hand PACKET_MMAP is very efficient. PACKET_MMAP provides a size
|
||||
configurable circular buffer mapped in user space that can be used to either
|
||||
send or receive packets. This way reading packets just needs to wait for them,
|
||||
most of the time there is no need to issue a single system call. Concerning
|
||||
transmission, multiple packets can be sent through one system call to get the
|
||||
highest bandwidth.
|
||||
By using a shared buffer between the kernel and the user also has the benefit
|
||||
of minimizing packet copies.
|
||||
highest bandwidth. By using a shared buffer between the kernel and the user
|
||||
also has the benefit of minimizing packet copies.
|
||||
|
||||
It's fine to use PACKET_MMAP to improve the performance of the capture and
|
||||
transmission process, but it isn't everything. At least, if you are capturing
|
||||
@ -41,7 +40,8 @@ at high speeds (this is relative to the cpu speed), you should check if the
|
||||
device driver of your network interface card supports some sort of interrupt
|
||||
load mitigation or (even better) if it supports NAPI, also make sure it is
|
||||
enabled. For transmission, check the MTU (Maximum Transmission Unit) used and
|
||||
supported by devices of your network.
|
||||
supported by devices of your network. CPU IRQ pinning of your network interface
|
||||
card can also be an advantage.
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
+ How to use mmap() to improve capture process
|
||||
@ -87,9 +87,7 @@ the following process:
|
||||
socket creation and destruction is straight forward, and is done
|
||||
the same way with or without PACKET_MMAP:
|
||||
|
||||
int fd;
|
||||
|
||||
fd= socket(PF_PACKET, mode, htons(ETH_P_ALL))
|
||||
int fd = socket(PF_PACKET, mode, htons(ETH_P_ALL));
|
||||
|
||||
where mode is SOCK_RAW for the raw interface were link level
|
||||
information can be captured or SOCK_DGRAM for the cooked
|
||||
@ -163,11 +161,23 @@ As capture, each frame contains two parts:
|
||||
|
||||
A complete tutorial is available at: http://wiki.gnu-log.net/
|
||||
|
||||
By default, the user should put data at :
|
||||
frame base + TPACKET_HDRLEN - sizeof(struct sockaddr_ll)
|
||||
|
||||
So, whatever you choose for the socket mode (SOCK_DGRAM or SOCK_RAW),
|
||||
the beginning of the user data will be at :
|
||||
frame base + TPACKET_ALIGN(sizeof(struct tpacket_hdr))
|
||||
|
||||
If you wish to put user data at a custom offset from the beginning of
|
||||
the frame (for payload alignment with SOCK_RAW mode for instance) you
|
||||
can set tp_net (with SOCK_DGRAM) or tp_mac (with SOCK_RAW). In order
|
||||
to make this work it must be enabled previously with setsockopt()
|
||||
and the PACKET_TX_HAS_OFF option.
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
+ PACKET_MMAP settings
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
|
||||
To setup PACKET_MMAP from user level code is done with a call like
|
||||
|
||||
- Capture process
|
||||
@ -201,7 +211,6 @@ indeed, packet_set_ring checks that the following condition is true
|
||||
|
||||
frames_per_block * tp_block_nr == tp_frame_nr
|
||||
|
||||
|
||||
Lets see an example, with the following values:
|
||||
|
||||
tp_block_size= 4096
|
||||
@ -227,7 +236,6 @@ be spawned across two blocks, so there are some details you have to take into
|
||||
account when choosing the frame_size. See "Mapping and use of the circular
|
||||
buffer (ring)".
|
||||
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
+ PACKET_MMAP setting constraints
|
||||
--------------------------------------------------------------------------------
|
||||
@ -264,7 +272,6 @@ User space programs can include /usr/include/sys/user.h and
|
||||
The pagesize can also be determined dynamically with the getpagesize (2)
|
||||
system call.
|
||||
|
||||
|
||||
Block number limit
|
||||
--------------------
|
||||
|
||||
@ -284,7 +291,6 @@ called pg_vec, its size limits the number of blocks that can be allocated.
|
||||
v block #2
|
||||
block #1
|
||||
|
||||
|
||||
kmalloc allocates any number of bytes of physically contiguous memory from
|
||||
a pool of pre-determined sizes. This pool of memory is maintained by the slab
|
||||
allocator which is at the end the responsible for doing the allocation and
|
||||
@ -299,7 +305,6 @@ pointers to blocks is
|
||||
|
||||
131072/4 = 32768 blocks
|
||||
|
||||
|
||||
PACKET_MMAP buffer size calculator
|
||||
------------------------------------
|
||||
|
||||
@ -340,7 +345,6 @@ and a value for <frame size> of 2048 bytes. These parameters will yield
|
||||
and hence the buffer will have a 262144 MiB size. So it can hold
|
||||
262144 MiB / 2048 bytes = 134217728 frames
|
||||
|
||||
|
||||
Actually, this buffer size is not possible with an i386 architecture.
|
||||
Remember that the memory is allocated in kernel space, in the case of
|
||||
an i386 kernel's memory size is limited to 1GiB.
|
||||
@ -372,7 +376,6 @@ the following (from include/linux/if_packet.h):
|
||||
- Start+tp_net: Packet data, aligned to TPACKET_ALIGNMENT=16.
|
||||
- Pad to align to TPACKET_ALIGNMENT=16
|
||||
*/
|
||||
|
||||
|
||||
The following are conditions that are checked in packet_set_ring
|
||||
|
||||
@ -413,7 +416,6 @@ and the following flags apply:
|
||||
#define TP_STATUS_LOSING 4
|
||||
#define TP_STATUS_CSUMNOTREADY 8
|
||||
|
||||
|
||||
TP_STATUS_COPY : This flag indicates that the frame (and associated
|
||||
meta information) has been truncated because it's
|
||||
larger than tp_frame_size. This packet can be
|
||||
@ -462,7 +464,6 @@ packets are in the ring:
|
||||
It doesn't incur in a race condition to first check the status value and
|
||||
then poll for frames.
|
||||
|
||||
|
||||
++ Transmission process
|
||||
Those defines are also used for transmission:
|
||||
|
||||
@ -493,6 +494,196 @@ The user can also use poll() to check if a buffer is available:
|
||||
pfd.events = POLLOUT;
|
||||
retval = poll(&pfd, 1, timeout);
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
+ What TPACKET versions are available and when to use them?
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
int val = tpacket_version;
|
||||
setsockopt(fd, SOL_PACKET, PACKET_VERSION, &val, sizeof(val));
|
||||
getsockopt(fd, SOL_PACKET, PACKET_VERSION, &val, sizeof(val));
|
||||
|
||||
where 'tpacket_version' can be TPACKET_V1 (default), TPACKET_V2, TPACKET_V3.
|
||||
|
||||
TPACKET_V1:
|
||||
- Default if not otherwise specified by setsockopt(2)
|
||||
- RX_RING, TX_RING available
|
||||
- VLAN metadata information available for packets
|
||||
(TP_STATUS_VLAN_VALID)
|
||||
|
||||
TPACKET_V1 --> TPACKET_V2:
|
||||
- Made 64 bit clean due to unsigned long usage in TPACKET_V1
|
||||
structures, thus this also works on 64 bit kernel with 32 bit
|
||||
userspace and the like
|
||||
- Timestamp resolution in nanoseconds instead of microseconds
|
||||
- RX_RING, TX_RING available
|
||||
- How to switch to TPACKET_V2:
|
||||
1. Replace struct tpacket_hdr by struct tpacket2_hdr
|
||||
2. Query header len and save
|
||||
3. Set protocol version to 2, set up ring as usual
|
||||
4. For getting the sockaddr_ll,
|
||||
use (void *)hdr + TPACKET_ALIGN(hdrlen) instead of
|
||||
(void *)hdr + TPACKET_ALIGN(sizeof(struct tpacket_hdr))
|
||||
|
||||
TPACKET_V2 --> TPACKET_V3:
|
||||
- Flexible buffer implementation:
|
||||
1. Blocks can be configured with non-static frame-size
|
||||
2. Read/poll is at a block-level (as opposed to packet-level)
|
||||
3. Added poll timeout to avoid indefinite user-space wait
|
||||
on idle links
|
||||
4. Added user-configurable knobs:
|
||||
4.1 block::timeout
|
||||
4.2 tpkt_hdr::sk_rxhash
|
||||
- RX Hash data available in user space
|
||||
- Currently only RX_RING available
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
+ AF_PACKET fanout mode
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
In the AF_PACKET fanout mode, packet reception can be load balanced among
|
||||
processes. This also works in combination with mmap(2) on packet sockets.
|
||||
|
||||
Minimal example code by David S. Miller (try things like "./test eth0 hash",
|
||||
"./test eth0 lb", etc.):
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/wait.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/ioctl.h>
|
||||
|
||||
#include <unistd.h>
|
||||
|
||||
#include <linux/if_ether.h>
|
||||
#include <linux/if_packet.h>
|
||||
|
||||
#include <net/if.h>
|
||||
|
||||
static const char *device_name;
|
||||
static int fanout_type;
|
||||
static int fanout_id;
|
||||
|
||||
#ifndef PACKET_FANOUT
|
||||
# define PACKET_FANOUT 18
|
||||
# define PACKET_FANOUT_HASH 0
|
||||
# define PACKET_FANOUT_LB 1
|
||||
#endif
|
||||
|
||||
static int setup_socket(void)
|
||||
{
|
||||
int err, fd = socket(AF_PACKET, SOCK_RAW, htons(ETH_P_IP));
|
||||
struct sockaddr_ll ll;
|
||||
struct ifreq ifr;
|
||||
int fanout_arg;
|
||||
|
||||
if (fd < 0) {
|
||||
perror("socket");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
memset(&ifr, 0, sizeof(ifr));
|
||||
strcpy(ifr.ifr_name, device_name);
|
||||
err = ioctl(fd, SIOCGIFINDEX, &ifr);
|
||||
if (err < 0) {
|
||||
perror("SIOCGIFINDEX");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
memset(&ll, 0, sizeof(ll));
|
||||
ll.sll_family = AF_PACKET;
|
||||
ll.sll_ifindex = ifr.ifr_ifindex;
|
||||
err = bind(fd, (struct sockaddr *) &ll, sizeof(ll));
|
||||
if (err < 0) {
|
||||
perror("bind");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
fanout_arg = (fanout_id | (fanout_type << 16));
|
||||
err = setsockopt(fd, SOL_PACKET, PACKET_FANOUT,
|
||||
&fanout_arg, sizeof(fanout_arg));
|
||||
if (err) {
|
||||
perror("setsockopt");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
return fd;
|
||||
}
|
||||
|
||||
static void fanout_thread(void)
|
||||
{
|
||||
int fd = setup_socket();
|
||||
int limit = 10000;
|
||||
|
||||
if (fd < 0)
|
||||
exit(fd);
|
||||
|
||||
while (limit-- > 0) {
|
||||
char buf[1600];
|
||||
int err;
|
||||
|
||||
err = read(fd, buf, sizeof(buf));
|
||||
if (err < 0) {
|
||||
perror("read");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
if ((limit % 10) == 0)
|
||||
fprintf(stdout, "(%d) \n", getpid());
|
||||
}
|
||||
|
||||
fprintf(stdout, "%d: Received 10000 packets\n", getpid());
|
||||
|
||||
close(fd);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
int main(int argc, char **argp)
|
||||
{
|
||||
int fd, err;
|
||||
int i;
|
||||
|
||||
if (argc != 3) {
|
||||
fprintf(stderr, "Usage: %s INTERFACE {hash|lb}\n", argp[0]);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
if (!strcmp(argp[2], "hash"))
|
||||
fanout_type = PACKET_FANOUT_HASH;
|
||||
else if (!strcmp(argp[2], "lb"))
|
||||
fanout_type = PACKET_FANOUT_LB;
|
||||
else {
|
||||
fprintf(stderr, "Unknown fanout type [%s]\n", argp[2]);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
device_name = argp[1];
|
||||
fanout_id = getpid() & 0xffff;
|
||||
|
||||
for (i = 0; i < 4; i++) {
|
||||
pid_t pid = fork();
|
||||
|
||||
switch (pid) {
|
||||
case 0:
|
||||
fanout_thread();
|
||||
|
||||
case -1:
|
||||
perror("fork");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < 4; i++) {
|
||||
int status;
|
||||
|
||||
wait(&status);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
+ PACKET_TIMESTAMP
|
||||
-------------------------------------------------------------------------------
|
||||
@ -519,6 +710,13 @@ the networking stack is used (the behavior before this setting was added).
|
||||
See include/linux/net_tstamp.h and Documentation/networking/timestamping
|
||||
for more information on hardware timestamps.
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
+ Miscellaneous bits
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
- Packet sockets work well together with Linux socket filters, thus you also
|
||||
might want to have a look at Documentation/networking/filter.txt
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
+ THANKS
|
||||
--------------------------------------------------------------------------------
|
||||
|
@ -29,11 +29,9 @@ The kernel configuration option is STMMAC_ETH:
|
||||
dma_txsize: DMA tx ring size;
|
||||
buf_sz: DMA buffer size;
|
||||
tc: control the HW FIFO threshold;
|
||||
tx_coe: Enable/Disable Tx Checksum Offload engine;
|
||||
watchdog: transmit timeout (in milliseconds);
|
||||
flow_ctrl: Flow control ability [on/off];
|
||||
pause: Flow Control Pause Time;
|
||||
tmrate: timer period (only if timer optimisation is configured).
|
||||
|
||||
3) Command line options
|
||||
Driver parameters can be also passed in command line by using:
|
||||
@ -60,17 +58,19 @@ Then the poll method will be scheduled at some future point.
|
||||
The incoming packets are stored, by the DMA, in a list of pre-allocated socket
|
||||
buffers in order to avoid the memcpy (Zero-copy).
|
||||
|
||||
4.3) Timer-Driver Interrupt
|
||||
Instead of having the device that asynchronously notifies the frame receptions,
|
||||
the driver configures a timer to generate an interrupt at regular intervals.
|
||||
Based on the granularity of the timer, the frames that are received by the
|
||||
device will experience different levels of latency. Some NICs have dedicated
|
||||
timer device to perform this task. STMMAC can use either the RTC device or the
|
||||
TMU channel 2 on STLinux platforms.
|
||||
The timers frequency can be passed to the driver as parameter; when change it,
|
||||
take care of both hardware capability and network stability/performance impact.
|
||||
Several performance tests on STM platforms showed this optimisation allows to
|
||||
spare the CPU while having the maximum throughput.
|
||||
4.3) Interrupt Mitigation
|
||||
The driver is able to mitigate the number of its DMA interrupts
|
||||
using NAPI for the reception on chips older than the 3.50.
|
||||
New chips have an HW RX-Watchdog used for this mitigation.
|
||||
|
||||
On Tx-side, the mitigation schema is based on a SW timer that calls the
|
||||
tx function (stmmac_tx) to reclaim the resource after transmitting the
|
||||
frames.
|
||||
Also there is another parameter (like a threshold) used to program
|
||||
the descriptors avoiding to set the interrupt on completion bit in
|
||||
when the frame is sent (xmit).
|
||||
|
||||
Mitigation parameters can be tuned by ethtool.
|
||||
|
||||
4.4) WOL
|
||||
Wake up on Lan feature through Magic and Unicast frames are supported for the
|
||||
@ -121,6 +121,7 @@ struct plat_stmmacenet_data {
|
||||
int bugged_jumbo;
|
||||
int pmt;
|
||||
int force_sf_dma_mode;
|
||||
int riwt_off;
|
||||
void (*fix_mac_speed)(void *priv, unsigned int speed);
|
||||
void (*bus_setup)(void __iomem *ioaddr);
|
||||
int (*init)(struct platform_device *pdev);
|
||||
@ -156,6 +157,7 @@ Where:
|
||||
o pmt: core has the embedded power module (optional).
|
||||
o force_sf_dma_mode: force DMA to use the Store and Forward mode
|
||||
instead of the Threshold.
|
||||
o riwt_off: force to disable the RX watchdog feature and switch to NAPI mode.
|
||||
o fix_mac_speed: this callback is used for modifying some syscfg registers
|
||||
(on ST SoCs) according to the link speed negotiated by the
|
||||
physical layer .
|
||||
|
27
MAINTAINERS
27
MAINTAINERS
@ -1680,10 +1680,9 @@ F: drivers/net/ethernet/broadcom/tg3.*
|
||||
|
||||
BROADCOM BRCM80211 IEEE802.11n WIRELESS DRIVER
|
||||
M: Brett Rudley <brudley@broadcom.com>
|
||||
M: Roland Vossen <rvossen@broadcom.com>
|
||||
M: Arend van Spriel <arend@broadcom.com>
|
||||
M: Franky (Zhenhui) Lin <frankyl@broadcom.com>
|
||||
M: Kan Yan <kanyan@broadcom.com>
|
||||
M: Hante Meuleman <meuleman@broadcom.com>
|
||||
L: linux-wireless@vger.kernel.org
|
||||
L: brcm80211-dev-list@broadcom.com
|
||||
S: Supported
|
||||
@ -3949,7 +3948,9 @@ M: Greg Rose <gregory.v.rose@intel.com>
|
||||
M: Peter P Waskiewicz Jr <peter.p.waskiewicz.jr@intel.com>
|
||||
M: Alex Duyck <alexander.h.duyck@intel.com>
|
||||
M: John Ronciak <john.ronciak@intel.com>
|
||||
M: Tushar Dave <tushar.n.dave@intel.com>
|
||||
L: e1000-devel@lists.sourceforge.net
|
||||
W: http://www.intel.com/support/feedback.htm
|
||||
W: http://e1000.sourceforge.net/
|
||||
T: git git://git.kernel.org/pub/scm/linux/kernel/git/jkirsher/net.git
|
||||
T: git git://git.kernel.org/pub/scm/linux/kernel/git/jkirsher/net-next.git
|
||||
@ -4833,6 +4834,14 @@ F: Documentation/scsi/megaraid.txt
|
||||
F: drivers/scsi/megaraid.*
|
||||
F: drivers/scsi/megaraid/
|
||||
|
||||
MELLANOX ETHERNET DRIVER (mlx4_en)
|
||||
M: Amir Vadai <amirv@mellanox.com>
|
||||
L: netdev@vger.kernel.org
|
||||
S: Supported
|
||||
W: http://www.mellanox.com
|
||||
Q: http://patchwork.ozlabs.org/project/netdev/list/
|
||||
F: drivers/net/ethernet/mellanox/mlx4/en_*
|
||||
|
||||
MEMORY MANAGEMENT
|
||||
L: linux-mm@kvack.org
|
||||
W: http://www.linux-mm.org
|
||||
@ -5075,7 +5084,7 @@ NETWORKING [GENERAL]
|
||||
M: "David S. Miller" <davem@davemloft.net>
|
||||
L: netdev@vger.kernel.org
|
||||
W: http://www.linuxfoundation.org/en/Net
|
||||
W: http://patchwork.ozlabs.org/project/netdev/list/
|
||||
Q: http://patchwork.ozlabs.org/project/netdev/list/
|
||||
T: git git://git.kernel.org/pub/scm/linux/kernel/git/davem/net.git
|
||||
T: git git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next.git
|
||||
S: Maintained
|
||||
@ -5135,6 +5144,7 @@ F: drivers/net/wireless/
|
||||
NETWORKING DRIVERS
|
||||
L: netdev@vger.kernel.org
|
||||
W: http://www.linuxfoundation.org/en/Net
|
||||
Q: http://patchwork.ozlabs.org/project/netdev/list/
|
||||
T: git git://git.kernel.org/pub/scm/linux/kernel/git/davem/net.git
|
||||
T: git git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next.git
|
||||
S: Odd Fixes
|
||||
@ -5167,6 +5177,7 @@ F: net/nfc/
|
||||
F: include/linux/nfc.h
|
||||
F: include/net/nfc/
|
||||
F: drivers/nfc/
|
||||
F: include/linux/platform_data/pn544.h
|
||||
|
||||
NFS, SUNRPC, AND LOCKD CLIENTS
|
||||
M: Trond Myklebust <Trond.Myklebust@netapp.com>
|
||||
@ -6442,6 +6453,7 @@ F: drivers/scsi/st*
|
||||
SCTP PROTOCOL
|
||||
M: Vlad Yasevich <vyasevich@gmail.com>
|
||||
M: Sridhar Samudrala <sri@us.ibm.com>
|
||||
M: Neil Horman <nhorman@tuxdriver.com>
|
||||
L: linux-sctp@vger.kernel.org
|
||||
W: http://lksctp.sourceforge.net
|
||||
S: Maintained
|
||||
@ -7469,8 +7481,7 @@ S: Maintained
|
||||
F: drivers/net/ethernet/dec/tulip/
|
||||
|
||||
TUN/TAP driver
|
||||
M: Maxim Krasnyansky <maxk@qualcomm.com>
|
||||
L: vtun@office.satix.net
|
||||
M: Maxim Krasnyansky <maxk@qti.qualcomm.com>
|
||||
W: http://vtun.sourceforge.net/tun
|
||||
S: Maintained
|
||||
F: Documentation/networking/tuntap.txt
|
||||
@ -7592,6 +7603,12 @@ S: Maintained
|
||||
F: Documentation/usb/acm.txt
|
||||
F: drivers/usb/class/cdc-acm.*
|
||||
|
||||
USB AR5523 WIRELESS DRIVER
|
||||
M: Pontus Fuchs <pontus.fuchs@gmail.com>
|
||||
L: linux-wireless@vger.kernel.org
|
||||
S: Maintained
|
||||
F: drivers/net/wireless/ath/ar5523/
|
||||
|
||||
USB ATTACHED SCSI
|
||||
M: Matthew Wilcox <willy@linux.intel.com>
|
||||
M: Sarah Sharp <sarah.a.sharp@linux.intel.com>
|
||||
|
@ -47,6 +47,7 @@
|
||||
/* Socket filtering */
|
||||
#define SO_ATTACH_FILTER 26
|
||||
#define SO_DETACH_FILTER 27
|
||||
#define SO_GET_FILTER SO_ATTACH_FILTER
|
||||
|
||||
#define SO_PEERNAME 28
|
||||
#define SO_TIMESTAMP 29
|
||||
|
@ -128,3 +128,11 @@
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
&cpsw_emac0 {
|
||||
phy_id = <&davinci_mdio>, <0>;
|
||||
};
|
||||
|
||||
&cpsw_emac1 {
|
||||
phy_id = <&davinci_mdio>, <1>;
|
||||
};
|
||||
|
@ -236,3 +236,11 @@
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
&cpsw_emac0 {
|
||||
phy_id = <&davinci_mdio>, <0>;
|
||||
};
|
||||
|
||||
&cpsw_emac1 {
|
||||
phy_id = <&davinci_mdio>, <1>;
|
||||
};
|
||||
|
@ -338,5 +338,52 @@
|
||||
power = <250>;
|
||||
ti,hwmods = "usb_otg_hs";
|
||||
};
|
||||
|
||||
mac: ethernet@4a100000 {
|
||||
compatible = "ti,cpsw";
|
||||
ti,hwmods = "cpgmac0";
|
||||
cpdma_channels = <8>;
|
||||
ale_entries = <1024>;
|
||||
bd_ram_size = <0x2000>;
|
||||
no_bd_ram = <0>;
|
||||
rx_descs = <64>;
|
||||
mac_control = <0x20>;
|
||||
slaves = <2>;
|
||||
cpts_active_slave = <0>;
|
||||
cpts_clock_mult = <0x80000000>;
|
||||
cpts_clock_shift = <29>;
|
||||
reg = <0x4a100000 0x800
|
||||
0x4a101200 0x100>;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
interrupt-parent = <&intc>;
|
||||
/*
|
||||
* c0_rx_thresh_pend
|
||||
* c0_rx_pend
|
||||
* c0_tx_pend
|
||||
* c0_misc_pend
|
||||
*/
|
||||
interrupts = <40 41 42 43>;
|
||||
ranges;
|
||||
|
||||
davinci_mdio: mdio@4a101000 {
|
||||
compatible = "ti,davinci_mdio";
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
ti,hwmods = "davinci_mdio";
|
||||
bus_freq = <1000000>;
|
||||
reg = <0x4a101000 0x100>;
|
||||
};
|
||||
|
||||
cpsw_emac0: slave@4a100200 {
|
||||
/* Filled in by U-Boot */
|
||||
mac-address = [ 00 00 00 00 00 00 ];
|
||||
};
|
||||
|
||||
cpsw_emac1: slave@4a100300 {
|
||||
/* Filled in by U-Boot */
|
||||
mac-address = [ 00 00 00 00 00 00 ];
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
@ -596,6 +596,7 @@
|
||||
66 0x1b0b0 /* MX6Q_PAD_RGMII_RD2__ENET_RGMII_RD2 */
|
||||
70 0x1b0b0 /* MX6Q_PAD_RGMII_RD3__ENET_RGMII_RD3 */
|
||||
48 0x1b0b0 /* MX6Q_PAD_RGMII_RX_CTL__RGMII_RX_CTL */
|
||||
1033 0x4001b0a8 /* MX6Q_PAD_GPIO_16__ENET_ANATOP_ETHERNET_REF_OUT*/
|
||||
>;
|
||||
};
|
||||
|
||||
@ -849,8 +850,8 @@
|
||||
compatible = "fsl,imx6q-fec";
|
||||
reg = <0x02188000 0x4000>;
|
||||
interrupts = <0 118 0x04 0 119 0x04>;
|
||||
clocks = <&clks 117>, <&clks 117>;
|
||||
clock-names = "ipg", "ahb";
|
||||
clocks = <&clks 117>, <&clks 117>, <&clks 177>;
|
||||
clock-names = "ipg", "ahb", "ptp";
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
|
@ -240,3 +240,6 @@ CONFIG_CRC_ITU_T=y
|
||||
CONFIG_CRC7=y
|
||||
CONFIG_LIBCRC32C=y
|
||||
CONFIG_SOC_OMAP5=y
|
||||
CONFIG_TI_DAVINCI_MDIO=y
|
||||
CONFIG_TI_DAVINCI_CPDMA=y
|
||||
CONFIG_TI_CPSW=y
|
||||
|
@ -39,7 +39,6 @@ config SOC_AT91RM9200
|
||||
config SOC_AT91SAM9260
|
||||
bool "AT91SAM9260, AT91SAM9XE or AT91SAM9G20"
|
||||
select HAVE_AT91_DBGU0
|
||||
select HAVE_NET_MACB
|
||||
select SOC_AT91SAM9
|
||||
help
|
||||
Select this if you are using one of Atmel's AT91SAM9260, AT91SAM9XE
|
||||
@ -57,7 +56,6 @@ config SOC_AT91SAM9263
|
||||
bool "AT91SAM9263"
|
||||
select HAVE_AT91_DBGU1
|
||||
select HAVE_FB_ATMEL
|
||||
select HAVE_NET_MACB
|
||||
select SOC_AT91SAM9
|
||||
|
||||
config SOC_AT91SAM9RL
|
||||
@ -70,7 +68,6 @@ config SOC_AT91SAM9G45
|
||||
bool "AT91SAM9G45 or AT91SAM9M10 families"
|
||||
select HAVE_AT91_DBGU1
|
||||
select HAVE_FB_ATMEL
|
||||
select HAVE_NET_MACB
|
||||
select SOC_AT91SAM9
|
||||
help
|
||||
Select this if you are using one of Atmel's AT91SAM9G45 family SoC.
|
||||
@ -80,7 +77,6 @@ config SOC_AT91SAM9X5
|
||||
bool "AT91SAM9x5 family"
|
||||
select HAVE_AT91_DBGU0
|
||||
select HAVE_FB_ATMEL
|
||||
select HAVE_NET_MACB
|
||||
select SOC_AT91SAM9
|
||||
help
|
||||
Select this if you are using one of Atmel's AT91SAM9x5 family SoC.
|
||||
|
@ -53,6 +53,8 @@ static void __init csb337_init_early(void)
|
||||
static struct macb_platform_data __initdata csb337_eth_data = {
|
||||
.phy_irq_pin = AT91_PIN_PC2,
|
||||
.is_rmii = 0,
|
||||
/* The CSB337 bootloader stores the MAC the wrong-way around */
|
||||
.rev_eth_addr = 1,
|
||||
};
|
||||
|
||||
static struct at91_usbh_data __initdata csb337_usbh_data = {
|
||||
|
@ -1,138 +0,0 @@
|
||||
/*
|
||||
* arch/arm/mach-at91/include/mach/at91rm9200_emac.h
|
||||
*
|
||||
* Copyright (C) 2005 Ivan Kokshaysky
|
||||
* Copyright (C) SAN People
|
||||
*
|
||||
* Ethernet MAC registers.
|
||||
* Based on AT91RM9200 datasheet revision E.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*/
|
||||
|
||||
#ifndef AT91RM9200_EMAC_H
|
||||
#define AT91RM9200_EMAC_H
|
||||
|
||||
#define AT91_EMAC_CTL 0x00 /* Control Register */
|
||||
#define AT91_EMAC_LB (1 << 0) /* Loopback */
|
||||
#define AT91_EMAC_LBL (1 << 1) /* Loopback Local */
|
||||
#define AT91_EMAC_RE (1 << 2) /* Receive Enable */
|
||||
#define AT91_EMAC_TE (1 << 3) /* Transmit Enable */
|
||||
#define AT91_EMAC_MPE (1 << 4) /* Management Port Enable */
|
||||
#define AT91_EMAC_CSR (1 << 5) /* Clear Statistics Registers */
|
||||
#define AT91_EMAC_INCSTAT (1 << 6) /* Increment Statistics Registers */
|
||||
#define AT91_EMAC_WES (1 << 7) /* Write Enable for Statistics Registers */
|
||||
#define AT91_EMAC_BP (1 << 8) /* Back Pressure */
|
||||
|
||||
#define AT91_EMAC_CFG 0x04 /* Configuration Register */
|
||||
#define AT91_EMAC_SPD (1 << 0) /* Speed */
|
||||
#define AT91_EMAC_FD (1 << 1) /* Full Duplex */
|
||||
#define AT91_EMAC_BR (1 << 2) /* Bit Rate */
|
||||
#define AT91_EMAC_CAF (1 << 4) /* Copy All Frames */
|
||||
#define AT91_EMAC_NBC (1 << 5) /* No Broadcast */
|
||||
#define AT91_EMAC_MTI (1 << 6) /* Multicast Hash Enable */
|
||||
#define AT91_EMAC_UNI (1 << 7) /* Unicast Hash Enable */
|
||||
#define AT91_EMAC_BIG (1 << 8) /* Receive 1522 Bytes */
|
||||
#define AT91_EMAC_EAE (1 << 9) /* External Address Match Enable */
|
||||
#define AT91_EMAC_CLK (3 << 10) /* MDC Clock Divisor */
|
||||
#define AT91_EMAC_CLK_DIV8 (0 << 10)
|
||||
#define AT91_EMAC_CLK_DIV16 (1 << 10)
|
||||
#define AT91_EMAC_CLK_DIV32 (2 << 10)
|
||||
#define AT91_EMAC_CLK_DIV64 (3 << 10)
|
||||
#define AT91_EMAC_RTY (1 << 12) /* Retry Test */
|
||||
#define AT91_EMAC_RMII (1 << 13) /* Reduce MII (RMII) */
|
||||
|
||||
#define AT91_EMAC_SR 0x08 /* Status Register */
|
||||
#define AT91_EMAC_SR_LINK (1 << 0) /* Link */
|
||||
#define AT91_EMAC_SR_MDIO (1 << 1) /* MDIO pin */
|
||||
#define AT91_EMAC_SR_IDLE (1 << 2) /* PHY idle */
|
||||
|
||||
#define AT91_EMAC_TAR 0x0c /* Transmit Address Register */
|
||||
|
||||
#define AT91_EMAC_TCR 0x10 /* Transmit Control Register */
|
||||
#define AT91_EMAC_LEN (0x7ff << 0) /* Transmit Frame Length */
|
||||
#define AT91_EMAC_NCRC (1 << 15) /* No CRC */
|
||||
|
||||
#define AT91_EMAC_TSR 0x14 /* Transmit Status Register */
|
||||
#define AT91_EMAC_TSR_OVR (1 << 0) /* Transmit Buffer Overrun */
|
||||
#define AT91_EMAC_TSR_COL (1 << 1) /* Collision Occurred */
|
||||
#define AT91_EMAC_TSR_RLE (1 << 2) /* Retry Limit Exceeded */
|
||||
#define AT91_EMAC_TSR_IDLE (1 << 3) /* Transmitter Idle */
|
||||
#define AT91_EMAC_TSR_BNQ (1 << 4) /* Transmit Buffer not Queued */
|
||||
#define AT91_EMAC_TSR_COMP (1 << 5) /* Transmit Complete */
|
||||
#define AT91_EMAC_TSR_UND (1 << 6) /* Transmit Underrun */
|
||||
|
||||
#define AT91_EMAC_RBQP 0x18 /* Receive Buffer Queue Pointer */
|
||||
|
||||
#define AT91_EMAC_RSR 0x20 /* Receive Status Register */
|
||||
#define AT91_EMAC_RSR_BNA (1 << 0) /* Buffer Not Available */
|
||||
#define AT91_EMAC_RSR_REC (1 << 1) /* Frame Received */
|
||||
#define AT91_EMAC_RSR_OVR (1 << 2) /* RX Overrun */
|
||||
|
||||
#define AT91_EMAC_ISR 0x24 /* Interrupt Status Register */
|
||||
#define AT91_EMAC_DONE (1 << 0) /* Management Done */
|
||||
#define AT91_EMAC_RCOM (1 << 1) /* Receive Complete */
|
||||
#define AT91_EMAC_RBNA (1 << 2) /* Receive Buffer Not Available */
|
||||
#define AT91_EMAC_TOVR (1 << 3) /* Transmit Buffer Overrun */
|
||||
#define AT91_EMAC_TUND (1 << 4) /* Transmit Buffer Underrun */
|
||||
#define AT91_EMAC_RTRY (1 << 5) /* Retry Limit */
|
||||
#define AT91_EMAC_TBRE (1 << 6) /* Transmit Buffer Register Empty */
|
||||
#define AT91_EMAC_TCOM (1 << 7) /* Transmit Complete */
|
||||
#define AT91_EMAC_TIDLE (1 << 8) /* Transmit Idle */
|
||||
#define AT91_EMAC_LINK (1 << 9) /* Link */
|
||||
#define AT91_EMAC_ROVR (1 << 10) /* RX Overrun */
|
||||
#define AT91_EMAC_ABT (1 << 11) /* Abort */
|
||||
|
||||
#define AT91_EMAC_IER 0x28 /* Interrupt Enable Register */
|
||||
#define AT91_EMAC_IDR 0x2c /* Interrupt Disable Register */
|
||||
#define AT91_EMAC_IMR 0x30 /* Interrupt Mask Register */
|
||||
|
||||
#define AT91_EMAC_MAN 0x34 /* PHY Maintenance Register */
|
||||
#define AT91_EMAC_DATA (0xffff << 0) /* MDIO Data */
|
||||
#define AT91_EMAC_REGA (0x1f << 18) /* MDIO Register */
|
||||
#define AT91_EMAC_PHYA (0x1f << 23) /* MDIO PHY Address */
|
||||
#define AT91_EMAC_RW (3 << 28) /* Read/Write operation */
|
||||
#define AT91_EMAC_RW_W (1 << 28)
|
||||
#define AT91_EMAC_RW_R (2 << 28)
|
||||
#define AT91_EMAC_MAN_802_3 0x40020000 /* IEEE 802.3 value */
|
||||
|
||||
/*
|
||||
* Statistics Registers.
|
||||
*/
|
||||
#define AT91_EMAC_FRA 0x40 /* Frames Transmitted OK */
|
||||
#define AT91_EMAC_SCOL 0x44 /* Single Collision Frame */
|
||||
#define AT91_EMAC_MCOL 0x48 /* Multiple Collision Frame */
|
||||
#define AT91_EMAC_OK 0x4c /* Frames Received OK */
|
||||
#define AT91_EMAC_SEQE 0x50 /* Frame Check Sequence Error */
|
||||
#define AT91_EMAC_ALE 0x54 /* Alignmemt Error */
|
||||
#define AT91_EMAC_DTE 0x58 /* Deffered Transmission Frame */
|
||||
#define AT91_EMAC_LCOL 0x5c /* Late Collision */
|
||||
#define AT91_EMAC_ECOL 0x60 /* Excessive Collision */
|
||||
#define AT91_EMAC_TUE 0x64 /* Transmit Underrun Error */
|
||||
#define AT91_EMAC_CSE 0x68 /* Carrier Sense Error */
|
||||
#define AT91_EMAC_DRFC 0x6c /* Discard RX Frame */
|
||||
#define AT91_EMAC_ROV 0x70 /* Receive Overrun */
|
||||
#define AT91_EMAC_CDE 0x74 /* Code Error */
|
||||
#define AT91_EMAC_ELR 0x78 /* Excessive Length Error */
|
||||
#define AT91_EMAC_RJB 0x7c /* Receive Jabber */
|
||||
#define AT91_EMAC_USF 0x80 /* Undersize Frame */
|
||||
#define AT91_EMAC_SQEE 0x84 /* SQE Test Error */
|
||||
|
||||
/*
|
||||
* Address Registers.
|
||||
*/
|
||||
#define AT91_EMAC_HSL 0x90 /* Hash Address Low [31:0] */
|
||||
#define AT91_EMAC_HSH 0x94 /* Hash Address High [63:32] */
|
||||
#define AT91_EMAC_SA1L 0x98 /* Specific Address 1 Low, bytes 0-3 */
|
||||
#define AT91_EMAC_SA1H 0x9c /* Specific Address 1 High, bytes 4-5 */
|
||||
#define AT91_EMAC_SA2L 0xa0 /* Specific Address 2 Low, bytes 0-3 */
|
||||
#define AT91_EMAC_SA2H 0xa4 /* Specific Address 2 High, bytes 4-5 */
|
||||
#define AT91_EMAC_SA3L 0xa8 /* Specific Address 3 Low, bytes 0-3 */
|
||||
#define AT91_EMAC_SA3H 0xac /* Specific Address 3 High, bytes 4-5 */
|
||||
#define AT91_EMAC_SA4L 0xb0 /* Specific Address 4 Low, bytes 0-3 */
|
||||
#define AT91_EMAC_SA4H 0xb4 /* Specific Address 4 High, bytes 4-5 */
|
||||
|
||||
#endif
|
@ -117,6 +117,17 @@ static void __init imx6q_sabrelite_init(void)
|
||||
imx6q_sabrelite_cko1_setup();
|
||||
}
|
||||
|
||||
static void __init imx6q_1588_init(void)
|
||||
{
|
||||
struct regmap *gpr;
|
||||
|
||||
gpr = syscon_regmap_lookup_by_compatible("fsl,imx6q-iomuxc-gpr");
|
||||
if (!IS_ERR(gpr))
|
||||
regmap_update_bits(gpr, 0x4, 1 << 21, 1 << 21);
|
||||
else
|
||||
pr_err("failed to find fsl,imx6q-iomux-gpr regmap\n");
|
||||
|
||||
}
|
||||
static void __init imx6q_usb_init(void)
|
||||
{
|
||||
struct regmap *anatop;
|
||||
@ -153,6 +164,7 @@ static void __init imx6q_init_machine(void)
|
||||
|
||||
imx6q_pm_init();
|
||||
imx6q_usb_init();
|
||||
imx6q_1588_init();
|
||||
}
|
||||
|
||||
static struct cpuidle_driver imx6q_cpuidle_driver = {
|
||||
|
@ -674,6 +674,7 @@ static struct omap_hwmod am33xx_cpgmac0_hwmod = {
|
||||
.name = "cpgmac0",
|
||||
.class = &am33xx_cpgmac0_hwmod_class,
|
||||
.clkdm_name = "cpsw_125mhz_clkdm",
|
||||
.flags = (HWMOD_SWSUP_SIDLE | HWMOD_SWSUP_MSTANDBY),
|
||||
.mpu_irqs = am33xx_cpgmac0_irqs,
|
||||
.main_clk = "cpsw_125mhz_gclk",
|
||||
.prcm = {
|
||||
@ -684,6 +685,20 @@ static struct omap_hwmod am33xx_cpgmac0_hwmod = {
|
||||
},
|
||||
};
|
||||
|
||||
/*
|
||||
* mdio class
|
||||
*/
|
||||
static struct omap_hwmod_class am33xx_mdio_hwmod_class = {
|
||||
.name = "davinci_mdio",
|
||||
};
|
||||
|
||||
static struct omap_hwmod am33xx_mdio_hwmod = {
|
||||
.name = "davinci_mdio",
|
||||
.class = &am33xx_mdio_hwmod_class,
|
||||
.clkdm_name = "cpsw_125mhz_clkdm",
|
||||
.main_clk = "cpsw_125mhz_gclk",
|
||||
};
|
||||
|
||||
/*
|
||||
* dcan class
|
||||
*/
|
||||
@ -2501,6 +2516,21 @@ static struct omap_hwmod_ocp_if am33xx_l4_hs__cpgmac0 = {
|
||||
.user = OCP_USER_MPU,
|
||||
};
|
||||
|
||||
struct omap_hwmod_addr_space am33xx_mdio_addr_space[] = {
|
||||
{
|
||||
.pa_start = 0x4A101000,
|
||||
.pa_end = 0x4A101000 + SZ_256 - 1,
|
||||
},
|
||||
{ }
|
||||
};
|
||||
|
||||
struct omap_hwmod_ocp_if am33xx_cpgmac0__mdio = {
|
||||
.master = &am33xx_cpgmac0_hwmod,
|
||||
.slave = &am33xx_mdio_hwmod,
|
||||
.addr = am33xx_mdio_addr_space,
|
||||
.user = OCP_USER_MPU,
|
||||
};
|
||||
|
||||
static struct omap_hwmod_addr_space am33xx_elm_addr_space[] = {
|
||||
{
|
||||
.pa_start = 0x48080000,
|
||||
@ -3371,6 +3401,7 @@ static struct omap_hwmod_ocp_if *am33xx_hwmod_ocp_ifs[] __initdata = {
|
||||
&am33xx_l3_main__tptc2,
|
||||
&am33xx_l3_s__usbss,
|
||||
&am33xx_l4_hs__cpgmac0,
|
||||
&am33xx_cpgmac0__mdio,
|
||||
NULL,
|
||||
};
|
||||
|
||||
|
@ -16,6 +16,7 @@
|
||||
#include <linux/netdevice.h>
|
||||
#include <linux/string.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/if_vlan.h>
|
||||
#include <asm/cacheflush.h>
|
||||
#include <asm/hwcap.h>
|
||||
|
||||
@ -168,6 +169,8 @@ static inline bool is_load_to_a(u16 inst)
|
||||
case BPF_S_ANC_MARK:
|
||||
case BPF_S_ANC_PROTOCOL:
|
||||
case BPF_S_ANC_RXHASH:
|
||||
case BPF_S_ANC_VLAN_TAG:
|
||||
case BPF_S_ANC_VLAN_TAG_PRESENT:
|
||||
case BPF_S_ANC_QUEUE:
|
||||
return true;
|
||||
default:
|
||||
@ -646,6 +649,16 @@ load_ind:
|
||||
update_on_xread(ctx);
|
||||
emit(ARM_ORR_R(r_A, r_A, r_X), ctx);
|
||||
break;
|
||||
case BPF_S_ALU_XOR_K:
|
||||
/* A ^= K; */
|
||||
OP_IMM3(ARM_EOR, r_A, r_A, k, ctx);
|
||||
break;
|
||||
case BPF_S_ANC_ALU_XOR_X:
|
||||
case BPF_S_ALU_XOR_X:
|
||||
/* A ^= X */
|
||||
update_on_xread(ctx);
|
||||
emit(ARM_EOR_R(r_A, r_A, r_X), ctx);
|
||||
break;
|
||||
case BPF_S_ALU_AND_K:
|
||||
/* A &= K */
|
||||
OP_IMM3(ARM_AND, r_A, r_A, k, ctx);
|
||||
@ -762,11 +775,6 @@ b_epilogue:
|
||||
update_on_xread(ctx);
|
||||
emit(ARM_MOV_R(r_A, r_X), ctx);
|
||||
break;
|
||||
case BPF_S_ANC_ALU_XOR_X:
|
||||
/* A ^= X */
|
||||
update_on_xread(ctx);
|
||||
emit(ARM_EOR_R(r_A, r_A, r_X), ctx);
|
||||
break;
|
||||
case BPF_S_ANC_PROTOCOL:
|
||||
/* A = ntohs(skb->protocol) */
|
||||
ctx->seen |= SEEN_SKB;
|
||||
@ -810,6 +818,17 @@ b_epilogue:
|
||||
off = offsetof(struct sk_buff, rxhash);
|
||||
emit(ARM_LDR_I(r_A, r_skb, off), ctx);
|
||||
break;
|
||||
case BPF_S_ANC_VLAN_TAG:
|
||||
case BPF_S_ANC_VLAN_TAG_PRESENT:
|
||||
ctx->seen |= SEEN_SKB;
|
||||
BUILD_BUG_ON(FIELD_SIZEOF(struct sk_buff, vlan_tci) != 2);
|
||||
off = offsetof(struct sk_buff, vlan_tci);
|
||||
emit(ARM_LDRH_I(r_A, r_skb, off), ctx);
|
||||
if (inst->code == BPF_S_ANC_VLAN_TAG)
|
||||
OP_IMM3(ARM_AND, r_A, r_A, VLAN_VID_MASK, ctx);
|
||||
else
|
||||
OP_IMM3(ARM_AND, r_A, r_A, VLAN_TAG_PRESENT, ctx);
|
||||
break;
|
||||
case BPF_S_ANC_QUEUE:
|
||||
ctx->seen |= SEEN_SKB;
|
||||
BUILD_BUG_ON(FIELD_SIZEOF(struct sk_buff,
|
||||
|
@ -69,6 +69,7 @@
|
||||
#define ARM_INST_CMP_I 0x03500000
|
||||
|
||||
#define ARM_INST_EOR_R 0x00200000
|
||||
#define ARM_INST_EOR_I 0x02200000
|
||||
|
||||
#define ARM_INST_LDRB_I 0x05d00000
|
||||
#define ARM_INST_LDRB_R 0x07d00000
|
||||
@ -135,6 +136,7 @@
|
||||
#define ARM_CMP_I(rn, imm) _AL3_I(ARM_INST_CMP, 0, rn, imm)
|
||||
|
||||
#define ARM_EOR_R(rd, rn, rm) _AL3_R(ARM_INST_EOR, rd, rn, rm)
|
||||
#define ARM_EOR_I(rd, rn, imm) _AL3_I(ARM_INST_EOR, rd, rn, imm)
|
||||
|
||||
#define ARM_LDR_I(rt, rn, off) (ARM_INST_LDR_I | (rt) << 12 | (rn) << 16 \
|
||||
| (off))
|
||||
|
@ -82,7 +82,6 @@ config PLATFORM_AT32AP
|
||||
select ARCH_REQUIRE_GPIOLIB
|
||||
select GENERIC_ALLOCATOR
|
||||
select HAVE_FB_ATMEL
|
||||
select HAVE_NET_MACB
|
||||
|
||||
#
|
||||
# CPU types
|
||||
|
@ -40,6 +40,7 @@
|
||||
/* Socket filtering */
|
||||
#define SO_ATTACH_FILTER 26
|
||||
#define SO_DETACH_FILTER 27
|
||||
#define SO_GET_FILTER SO_ATTACH_FILTER
|
||||
|
||||
#define SO_PEERNAME 28
|
||||
#define SO_TIMESTAMP 29
|
||||
|
@ -42,6 +42,7 @@
|
||||
/* Socket filtering */
|
||||
#define SO_ATTACH_FILTER 26
|
||||
#define SO_DETACH_FILTER 27
|
||||
#define SO_GET_FILTER SO_ATTACH_FILTER
|
||||
|
||||
#define SO_PEERNAME 28
|
||||
#define SO_TIMESTAMP 29
|
||||
|
@ -40,6 +40,7 @@
|
||||
/* Socket filtering */
|
||||
#define SO_ATTACH_FILTER 26
|
||||
#define SO_DETACH_FILTER 27
|
||||
#define SO_GET_FILTER SO_ATTACH_FILTER
|
||||
|
||||
#define SO_PEERNAME 28
|
||||
#define SO_TIMESTAMP 29
|
||||
|
@ -40,6 +40,7 @@
|
||||
/* Socket filtering */
|
||||
#define SO_ATTACH_FILTER 26
|
||||
#define SO_DETACH_FILTER 27
|
||||
#define SO_GET_FILTER SO_ATTACH_FILTER
|
||||
|
||||
#define SO_PEERNAME 28
|
||||
#define SO_TIMESTAMP 29
|
||||
|
@ -49,6 +49,7 @@
|
||||
/* Socket filtering */
|
||||
#define SO_ATTACH_FILTER 26
|
||||
#define SO_DETACH_FILTER 27
|
||||
#define SO_GET_FILTER SO_ATTACH_FILTER
|
||||
|
||||
#define SO_PEERNAME 28
|
||||
#define SO_TIMESTAMP 29
|
||||
|
@ -40,6 +40,7 @@
|
||||
/* Socket filtering */
|
||||
#define SO_ATTACH_FILTER 26
|
||||
#define SO_DETACH_FILTER 27
|
||||
#define SO_GET_FILTER SO_ATTACH_FILTER
|
||||
|
||||
#define SO_PEERNAME 28
|
||||
#define SO_TIMESTAMP 29
|
||||
|
@ -40,6 +40,7 @@
|
||||
/* Socket filtering */
|
||||
#define SO_ATTACH_FILTER 26
|
||||
#define SO_DETACH_FILTER 27
|
||||
#define SO_GET_FILTER SO_ATTACH_FILTER
|
||||
|
||||
#define SO_PEERNAME 28
|
||||
#define SO_TIMESTAMP 29
|
||||
|
@ -43,8 +43,8 @@ static void early_nvram_init(void)
|
||||
#ifdef CONFIG_BCM47XX_SSB
|
||||
case BCM47XX_BUS_TYPE_SSB:
|
||||
mcore_ssb = &bcm47xx_bus.ssb.mipscore;
|
||||
base = mcore_ssb->flash_window;
|
||||
lim = mcore_ssb->flash_window_size;
|
||||
base = mcore_ssb->pflash.window;
|
||||
lim = mcore_ssb->pflash.window_size;
|
||||
break;
|
||||
#endif
|
||||
#ifdef CONFIG_BCM47XX_BCMA
|
||||
|
@ -156,10 +156,10 @@ static int __init wgt634u_init(void)
|
||||
SSB_CHIPCO_IRQ_GPIO);
|
||||
}
|
||||
|
||||
wgt634u_flash_data.width = mcore->flash_buswidth;
|
||||
wgt634u_flash_resource.start = mcore->flash_window;
|
||||
wgt634u_flash_resource.end = mcore->flash_window
|
||||
+ mcore->flash_window_size
|
||||
wgt634u_flash_data.width = mcore->pflash.buswidth;
|
||||
wgt634u_flash_resource.start = mcore->pflash.window;
|
||||
wgt634u_flash_resource.end = mcore->pflash.window
|
||||
+ mcore->pflash.window_size
|
||||
- 1;
|
||||
return platform_add_devices(wgt634u_devices,
|
||||
ARRAY_SIZE(wgt634u_devices));
|
||||
|
@ -63,6 +63,7 @@ To add: #define SO_REUSEPORT 0x0200 /* Allow local address and port reuse. */
|
||||
/* Socket filtering */
|
||||
#define SO_ATTACH_FILTER 26
|
||||
#define SO_DETACH_FILTER 27
|
||||
#define SO_GET_FILTER SO_ATTACH_FILTER
|
||||
|
||||
#define SO_PEERNAME 28
|
||||
#define SO_TIMESTAMP 29
|
||||
|
@ -40,6 +40,7 @@
|
||||
/* Socket filtering */
|
||||
#define SO_ATTACH_FILTER 26
|
||||
#define SO_DETACH_FILTER 27
|
||||
#define SO_GET_FILTER SO_ATTACH_FILTER
|
||||
|
||||
#define SO_PEERNAME 28
|
||||
#define SO_TIMESTAMP 29
|
||||
|
@ -48,6 +48,7 @@
|
||||
/* Socket filtering */
|
||||
#define SO_ATTACH_FILTER 0x401a
|
||||
#define SO_DETACH_FILTER 0x401b
|
||||
#define SO_GET_FILTER SO_ATTACH_FILTER
|
||||
|
||||
#define SO_ACCEPTCONN 0x401c
|
||||
|
||||
|
@ -168,9 +168,12 @@
|
||||
#define PPC_INST_AND 0x7c000038
|
||||
#define PPC_INST_ANDDOT 0x7c000039
|
||||
#define PPC_INST_OR 0x7c000378
|
||||
#define PPC_INST_XOR 0x7c000278
|
||||
#define PPC_INST_ANDI 0x70000000
|
||||
#define PPC_INST_ORI 0x60000000
|
||||
#define PPC_INST_ORIS 0x64000000
|
||||
#define PPC_INST_XORI 0x68000000
|
||||
#define PPC_INST_XORIS 0x6c000000
|
||||
#define PPC_INST_NEG 0x7c0000d0
|
||||
#define PPC_INST_BRANCH 0x48000000
|
||||
#define PPC_INST_BRANCH_COND 0x40800000
|
||||
|
@ -47,6 +47,7 @@
|
||||
/* Socket filtering */
|
||||
#define SO_ATTACH_FILTER 26
|
||||
#define SO_DETACH_FILTER 27
|
||||
#define SO_GET_FILTER SO_ATTACH_FILTER
|
||||
|
||||
#define SO_PEERNAME 28
|
||||
#define SO_TIMESTAMP 29
|
||||
|
@ -134,6 +134,12 @@ DECLARE_LOAD_FUNC(sk_load_byte_msh);
|
||||
___PPC_RS(a) | IMM_L(i))
|
||||
#define PPC_ORIS(d, a, i) EMIT(PPC_INST_ORIS | ___PPC_RA(d) | \
|
||||
___PPC_RS(a) | IMM_L(i))
|
||||
#define PPC_XOR(d, a, b) EMIT(PPC_INST_XOR | ___PPC_RA(d) | \
|
||||
___PPC_RS(a) | ___PPC_RB(b))
|
||||
#define PPC_XORI(d, a, i) EMIT(PPC_INST_XORI | ___PPC_RA(d) | \
|
||||
___PPC_RS(a) | IMM_L(i))
|
||||
#define PPC_XORIS(d, a, i) EMIT(PPC_INST_XORIS | ___PPC_RA(d) | \
|
||||
___PPC_RS(a) | IMM_L(i))
|
||||
#define PPC_SLW(d, a, s) EMIT(PPC_INST_SLW | ___PPC_RA(d) | \
|
||||
___PPC_RS(a) | ___PPC_RB(s))
|
||||
#define PPC_SRW(d, a, s) EMIT(PPC_INST_SRW | ___PPC_RA(d) | \
|
||||
|
@ -13,6 +13,8 @@
|
||||
#include <asm/cacheflush.h>
|
||||
#include <linux/netdevice.h>
|
||||
#include <linux/filter.h>
|
||||
#include <linux/if_vlan.h>
|
||||
|
||||
#include "bpf_jit.h"
|
||||
|
||||
#ifndef __BIG_ENDIAN
|
||||
@ -89,6 +91,8 @@ static void bpf_jit_build_prologue(struct sk_filter *fp, u32 *image,
|
||||
case BPF_S_ANC_IFINDEX:
|
||||
case BPF_S_ANC_MARK:
|
||||
case BPF_S_ANC_RXHASH:
|
||||
case BPF_S_ANC_VLAN_TAG:
|
||||
case BPF_S_ANC_VLAN_TAG_PRESENT:
|
||||
case BPF_S_ANC_CPU:
|
||||
case BPF_S_ANC_QUEUE:
|
||||
case BPF_S_LD_W_ABS:
|
||||
@ -232,6 +236,17 @@ static int bpf_jit_build_body(struct sk_filter *fp, u32 *image,
|
||||
if (K >= 65536)
|
||||
PPC_ORIS(r_A, r_A, IMM_H(K));
|
||||
break;
|
||||
case BPF_S_ANC_ALU_XOR_X:
|
||||
case BPF_S_ALU_XOR_X: /* A ^= X */
|
||||
ctx->seen |= SEEN_XREG;
|
||||
PPC_XOR(r_A, r_A, r_X);
|
||||
break;
|
||||
case BPF_S_ALU_XOR_K: /* A ^= K */
|
||||
if (IMM_L(K))
|
||||
PPC_XORI(r_A, r_A, IMM_L(K));
|
||||
if (K >= 65536)
|
||||
PPC_XORIS(r_A, r_A, IMM_H(K));
|
||||
break;
|
||||
case BPF_S_ALU_LSH_X: /* A <<= X; */
|
||||
ctx->seen |= SEEN_XREG;
|
||||
PPC_SLW(r_A, r_A, r_X);
|
||||
@ -371,6 +386,16 @@ static int bpf_jit_build_body(struct sk_filter *fp, u32 *image,
|
||||
PPC_LWZ_OFFS(r_A, r_skb, offsetof(struct sk_buff,
|
||||
rxhash));
|
||||
break;
|
||||
case BPF_S_ANC_VLAN_TAG:
|
||||
case BPF_S_ANC_VLAN_TAG_PRESENT:
|
||||
BUILD_BUG_ON(FIELD_SIZEOF(struct sk_buff, vlan_tci) != 2);
|
||||
PPC_LHZ_OFFS(r_A, r_skb, offsetof(struct sk_buff,
|
||||
vlan_tci));
|
||||
if (filter[i].code == BPF_S_ANC_VLAN_TAG)
|
||||
PPC_ANDI(r_A, r_A, VLAN_VID_MASK);
|
||||
else
|
||||
PPC_ANDI(r_A, r_A, VLAN_TAG_PRESENT);
|
||||
break;
|
||||
case BPF_S_ANC_QUEUE:
|
||||
BUILD_BUG_ON(FIELD_SIZEOF(struct sk_buff,
|
||||
queue_mapping) != 2);
|
||||
|
@ -46,6 +46,7 @@
|
||||
/* Socket filtering */
|
||||
#define SO_ATTACH_FILTER 26
|
||||
#define SO_DETACH_FILTER 27
|
||||
#define SO_GET_FILTER SO_ATTACH_FILTER
|
||||
|
||||
#define SO_PEERNAME 28
|
||||
#define SO_TIMESTAMP 29
|
||||
|
@ -41,6 +41,7 @@
|
||||
|
||||
#define SO_ATTACH_FILTER 0x001a
|
||||
#define SO_DETACH_FILTER 0x001b
|
||||
#define SO_GET_FILTER SO_ATTACH_FILTER
|
||||
|
||||
#define SO_PEERNAME 0x001c
|
||||
#define SO_TIMESTAMP 0x001d
|
||||
|
@ -3,6 +3,7 @@
|
||||
#include <linux/netdevice.h>
|
||||
#include <linux/filter.h>
|
||||
#include <linux/cache.h>
|
||||
#include <linux/if_vlan.h>
|
||||
|
||||
#include <asm/cacheflush.h>
|
||||
#include <asm/ptrace.h>
|
||||
@ -312,6 +313,12 @@ do { *prog++ = BR_OPC | WDISP22(OFF); \
|
||||
#define emit_addi(R1, IMM, R3) \
|
||||
*prog++ = (ADD | IMMED | RS1(R1) | S13(IMM) | RD(R3))
|
||||
|
||||
#define emit_and(R1, R2, R3) \
|
||||
*prog++ = (AND | RS1(R1) | RS2(R2) | RD(R3))
|
||||
|
||||
#define emit_andi(R1, IMM, R3) \
|
||||
*prog++ = (AND | IMMED | RS1(R1) | S13(IMM) | RD(R3))
|
||||
|
||||
#define emit_alloc_stack(SZ) \
|
||||
*prog++ = (SUB | IMMED | RS1(SP) | S13(SZ) | RD(SP))
|
||||
|
||||
@ -415,6 +422,8 @@ void bpf_jit_compile(struct sk_filter *fp)
|
||||
case BPF_S_ANC_IFINDEX:
|
||||
case BPF_S_ANC_MARK:
|
||||
case BPF_S_ANC_RXHASH:
|
||||
case BPF_S_ANC_VLAN_TAG:
|
||||
case BPF_S_ANC_VLAN_TAG_PRESENT:
|
||||
case BPF_S_ANC_CPU:
|
||||
case BPF_S_ANC_QUEUE:
|
||||
case BPF_S_LD_W_ABS:
|
||||
@ -600,6 +609,16 @@ void bpf_jit_compile(struct sk_filter *fp)
|
||||
case BPF_S_ANC_RXHASH:
|
||||
emit_skb_load32(rxhash, r_A);
|
||||
break;
|
||||
case BPF_S_ANC_VLAN_TAG:
|
||||
case BPF_S_ANC_VLAN_TAG_PRESENT:
|
||||
emit_skb_load16(vlan_tci, r_A);
|
||||
if (filter[i].code == BPF_S_ANC_VLAN_TAG) {
|
||||
emit_andi(r_A, VLAN_VID_MASK, r_A);
|
||||
} else {
|
||||
emit_loadimm(VLAN_TAG_PRESENT, r_TMP);
|
||||
emit_and(r_A, r_TMP, r_A);
|
||||
}
|
||||
break;
|
||||
|
||||
case BPF_S_LD_IMM:
|
||||
emit_loadimm(K, r_A);
|
||||
|
@ -11,6 +11,7 @@
|
||||
#include <asm/cacheflush.h>
|
||||
#include <linux/netdevice.h>
|
||||
#include <linux/filter.h>
|
||||
#include <linux/if_vlan.h>
|
||||
|
||||
/*
|
||||
* Conventions :
|
||||
@ -212,6 +213,8 @@ void bpf_jit_compile(struct sk_filter *fp)
|
||||
case BPF_S_ANC_MARK:
|
||||
case BPF_S_ANC_RXHASH:
|
||||
case BPF_S_ANC_CPU:
|
||||
case BPF_S_ANC_VLAN_TAG:
|
||||
case BPF_S_ANC_VLAN_TAG_PRESENT:
|
||||
case BPF_S_ANC_QUEUE:
|
||||
case BPF_S_LD_W_ABS:
|
||||
case BPF_S_LD_H_ABS:
|
||||
@ -515,6 +518,24 @@ void bpf_jit_compile(struct sk_filter *fp)
|
||||
CLEAR_A();
|
||||
#endif
|
||||
break;
|
||||
case BPF_S_ANC_VLAN_TAG:
|
||||
case BPF_S_ANC_VLAN_TAG_PRESENT:
|
||||
BUILD_BUG_ON(FIELD_SIZEOF(struct sk_buff, vlan_tci) != 2);
|
||||
if (is_imm8(offsetof(struct sk_buff, vlan_tci))) {
|
||||
/* movzwl off8(%rdi),%eax */
|
||||
EMIT4(0x0f, 0xb7, 0x47, offsetof(struct sk_buff, vlan_tci));
|
||||
} else {
|
||||
EMIT3(0x0f, 0xb7, 0x87); /* movzwl off32(%rdi),%eax */
|
||||
EMIT(offsetof(struct sk_buff, vlan_tci), 4);
|
||||
}
|
||||
BUILD_BUG_ON(VLAN_TAG_PRESENT != 0x1000);
|
||||
if (filter[i].code == BPF_S_ANC_VLAN_TAG) {
|
||||
EMIT3(0x80, 0xe4, 0xef); /* and $0xef,%ah */
|
||||
} else {
|
||||
EMIT3(0xc1, 0xe8, 0x0c); /* shr $0xc,%eax */
|
||||
EMIT3(0x83, 0xe0, 0x01); /* and $0x1,%eax */
|
||||
}
|
||||
break;
|
||||
case BPF_S_LD_W_ABS:
|
||||
func = CHOOSE_LOAD_FUNC(K, sk_load_word);
|
||||
common_load: seen |= SEEN_DATAREF;
|
||||
|
@ -52,6 +52,7 @@
|
||||
|
||||
#define SO_ATTACH_FILTER 26
|
||||
#define SO_DETACH_FILTER 27
|
||||
#define SO_GET_FILTER SO_ATTACH_FILTER
|
||||
|
||||
#define SO_PEERNAME 28
|
||||
#define SO_TIMESTAMP 29
|
||||
|
@ -164,7 +164,6 @@ static void fpga_queue(struct solos_card *card, int port, struct sk_buff *skb,
|
||||
static uint32_t fpga_tx(struct solos_card *);
|
||||
static irqreturn_t solos_irq(int irq, void *dev_id);
|
||||
static struct atm_vcc* find_vcc(struct atm_dev *dev, short vpi, int vci);
|
||||
static int list_vccs(int vci);
|
||||
static int atm_init(struct solos_card *, struct device *);
|
||||
static void atm_remove(struct solos_card *);
|
||||
static int send_command(struct solos_card *card, int dev, const char *buf, size_t size);
|
||||
@ -710,7 +709,8 @@ void solos_bh(unsigned long card_arg)
|
||||
dev_warn(&card->dev->dev, "Received packet for unknown VPI.VCI %d.%d on port %d\n",
|
||||
le16_to_cpu(header->vpi), le16_to_cpu(header->vci),
|
||||
port);
|
||||
continue;
|
||||
dev_kfree_skb_any(skb);
|
||||
break;
|
||||
}
|
||||
atm_charge(vcc, skb->truesize);
|
||||
vcc->push(vcc, skb);
|
||||
@ -790,44 +790,6 @@ static struct atm_vcc *find_vcc(struct atm_dev *dev, short vpi, int vci)
|
||||
return vcc;
|
||||
}
|
||||
|
||||
static int list_vccs(int vci)
|
||||
{
|
||||
struct hlist_head *head;
|
||||
struct atm_vcc *vcc;
|
||||
struct hlist_node *node;
|
||||
struct sock *s;
|
||||
int num_found = 0;
|
||||
int i;
|
||||
|
||||
read_lock(&vcc_sklist_lock);
|
||||
if (vci != 0){
|
||||
head = &vcc_hash[vci & (VCC_HTABLE_SIZE -1)];
|
||||
sk_for_each(s, node, head) {
|
||||
num_found ++;
|
||||
vcc = atm_sk(s);
|
||||
printk(KERN_DEBUG "Device: %d Vpi: %d Vci: %d\n",
|
||||
vcc->dev->number,
|
||||
vcc->vpi,
|
||||
vcc->vci);
|
||||
}
|
||||
} else {
|
||||
for(i = 0; i < VCC_HTABLE_SIZE; i++){
|
||||
head = &vcc_hash[i];
|
||||
sk_for_each(s, node, head) {
|
||||
num_found ++;
|
||||
vcc = atm_sk(s);
|
||||
printk(KERN_DEBUG "Device: %d Vpi: %d Vci: %d\n",
|
||||
vcc->dev->number,
|
||||
vcc->vpi,
|
||||
vcc->vci);
|
||||
}
|
||||
}
|
||||
}
|
||||
read_unlock(&vcc_sklist_lock);
|
||||
return num_found;
|
||||
}
|
||||
|
||||
|
||||
static int popen(struct atm_vcc *vcc)
|
||||
{
|
||||
struct solos_card *card = vcc->dev->dev_data;
|
||||
@ -840,7 +802,7 @@ static int popen(struct atm_vcc *vcc)
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
skb = alloc_skb(sizeof(*header), GFP_ATOMIC);
|
||||
skb = alloc_skb(sizeof(*header), GFP_KERNEL);
|
||||
if (!skb) {
|
||||
if (net_ratelimit())
|
||||
dev_warn(&card->dev->dev, "Failed to allocate sk_buff in popen()\n");
|
||||
@ -857,8 +819,6 @@ static int popen(struct atm_vcc *vcc)
|
||||
|
||||
set_bit(ATM_VF_ADDR, &vcc->flags);
|
||||
set_bit(ATM_VF_READY, &vcc->flags);
|
||||
list_vccs(0);
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -866,10 +826,21 @@ static int popen(struct atm_vcc *vcc)
|
||||
static void pclose(struct atm_vcc *vcc)
|
||||
{
|
||||
struct solos_card *card = vcc->dev->dev_data;
|
||||
struct sk_buff *skb;
|
||||
unsigned char port = SOLOS_CHAN(vcc->dev);
|
||||
struct sk_buff *skb, *tmpskb;
|
||||
struct pkt_hdr *header;
|
||||
|
||||
skb = alloc_skb(sizeof(*header), GFP_ATOMIC);
|
||||
/* Remove any yet-to-be-transmitted packets from the pending queue */
|
||||
spin_lock(&card->tx_queue_lock);
|
||||
skb_queue_walk_safe(&card->tx_queue[port], skb, tmpskb) {
|
||||
if (SKB_CB(skb)->vcc == vcc) {
|
||||
skb_unlink(skb, &card->tx_queue[port]);
|
||||
solos_pop(vcc, skb);
|
||||
}
|
||||
}
|
||||
spin_unlock(&card->tx_queue_lock);
|
||||
|
||||
skb = alloc_skb(sizeof(*header), GFP_KERNEL);
|
||||
if (!skb) {
|
||||
dev_warn(&card->dev->dev, "Failed to allocate sk_buff in pclose()\n");
|
||||
return;
|
||||
@ -881,15 +852,22 @@ static void pclose(struct atm_vcc *vcc)
|
||||
header->vci = cpu_to_le16(vcc->vci);
|
||||
header->type = cpu_to_le16(PKT_PCLOSE);
|
||||
|
||||
fpga_queue(card, SOLOS_CHAN(vcc->dev), skb, NULL);
|
||||
skb_get(skb);
|
||||
fpga_queue(card, port, skb, NULL);
|
||||
|
||||
clear_bit(ATM_VF_ADDR, &vcc->flags);
|
||||
clear_bit(ATM_VF_READY, &vcc->flags);
|
||||
if (!wait_event_timeout(card->param_wq, !skb_shared(skb), 5 * HZ))
|
||||
dev_warn(&card->dev->dev,
|
||||
"Timeout waiting for VCC close on port %d\n", port);
|
||||
|
||||
dev_kfree_skb(skb);
|
||||
|
||||
/* Hold up vcc_destroy_socket() (our caller) until solos_bh() in the
|
||||
tasklet has finished processing any incoming packets (and, more to
|
||||
the point, using the vcc pointer). */
|
||||
tasklet_unlock_wait(&card->tlet);
|
||||
|
||||
clear_bit(ATM_VF_ADDR, &vcc->flags);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
@ -967,10 +945,11 @@ static uint32_t fpga_tx(struct solos_card *card)
|
||||
for (port = 0; tx_pending; tx_pending >>= 1, port++) {
|
||||
if (tx_pending & 1) {
|
||||
struct sk_buff *oldskb = card->tx_skb[port];
|
||||
if (oldskb)
|
||||
if (oldskb) {
|
||||
pci_unmap_single(card->dev, SKB_CB(oldskb)->dma_addr,
|
||||
oldskb->len, PCI_DMA_TODEVICE);
|
||||
|
||||
card->tx_skb[port] = NULL;
|
||||
}
|
||||
spin_lock(&card->tx_queue_lock);
|
||||
skb = skb_dequeue(&card->tx_queue[port]);
|
||||
if (!skb)
|
||||
@ -1011,9 +990,10 @@ static uint32_t fpga_tx(struct solos_card *card)
|
||||
if (vcc) {
|
||||
atomic_inc(&vcc->stats->tx);
|
||||
solos_pop(vcc, oldskb);
|
||||
} else
|
||||
} else {
|
||||
dev_kfree_skb_irq(oldskb);
|
||||
|
||||
wake_up(&card->param_wq);
|
||||
}
|
||||
}
|
||||
}
|
||||
/* For non-DMA TX, write the 'TX start' bit for all four ports simultaneously */
|
||||
@ -1248,7 +1228,7 @@ static int atm_init(struct solos_card *card, struct device *parent)
|
||||
card->atmdev[i]->phy_data = (void *)(unsigned long)i;
|
||||
atm_dev_signal_change(card->atmdev[i], ATM_PHY_SIG_FOUND);
|
||||
|
||||
skb = alloc_skb(sizeof(*header), GFP_ATOMIC);
|
||||
skb = alloc_skb(sizeof(*header), GFP_KERNEL);
|
||||
if (!skb) {
|
||||
dev_warn(&card->dev->dev, "Failed to allocate sk_buff in atm_init()\n");
|
||||
continue;
|
||||
@ -1345,6 +1325,8 @@ static struct pci_driver fpga_driver = {
|
||||
|
||||
static int __init solos_pci_init(void)
|
||||
{
|
||||
BUILD_BUG_ON(sizeof(struct solos_skb_cb) > sizeof(((struct sk_buff *)0)->cb));
|
||||
|
||||
printk(KERN_INFO "Solos PCI Driver Version %s\n", VERSION);
|
||||
return pci_register_driver(&fpga_driver);
|
||||
}
|
||||
|
@ -48,8 +48,8 @@ void bcma_chipco_serial_init(struct bcma_drv_cc *cc);
|
||||
#endif /* CONFIG_BCMA_DRIVER_MIPS */
|
||||
|
||||
/* driver_chipcommon_pmu.c */
|
||||
u32 bcma_pmu_alp_clock(struct bcma_drv_cc *cc);
|
||||
u32 bcma_pmu_get_clockcpu(struct bcma_drv_cc *cc);
|
||||
u32 bcma_pmu_get_alp_clock(struct bcma_drv_cc *cc);
|
||||
u32 bcma_pmu_get_cpu_clock(struct bcma_drv_cc *cc);
|
||||
|
||||
#ifdef CONFIG_BCMA_SFLASH
|
||||
/* driver_chipcommon_sflash.c */
|
||||
@ -84,6 +84,8 @@ extern void __exit bcma_host_pci_exit(void);
|
||||
/* driver_pci.c */
|
||||
u32 bcma_pcie_read(struct bcma_drv_pci *pc, u32 address);
|
||||
|
||||
extern int bcma_chipco_watchdog_register(struct bcma_drv_cc *cc);
|
||||
|
||||
#ifdef CONFIG_BCMA_DRIVER_PCI_HOSTMODE
|
||||
bool __devinit bcma_core_pci_is_in_hostmode(struct bcma_drv_pci *pc);
|
||||
void __devinit bcma_core_pci_hostmode_init(struct bcma_drv_pci *pc);
|
||||
|
@ -4,12 +4,15 @@
|
||||
*
|
||||
* Copyright 2005, Broadcom Corporation
|
||||
* Copyright 2006, 2007, Michael Buesch <m@bues.ch>
|
||||
* Copyright 2012, Hauke Mehrtens <hauke@hauke-m.de>
|
||||
*
|
||||
* Licensed under the GNU/GPL. See COPYING for details.
|
||||
*/
|
||||
|
||||
#include "bcma_private.h"
|
||||
#include <linux/bcm47xx_wdt.h>
|
||||
#include <linux/export.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/bcma/bcma.h>
|
||||
|
||||
static inline u32 bcma_cc_write32_masked(struct bcma_drv_cc *cc, u16 offset,
|
||||
@ -22,6 +25,107 @@ static inline u32 bcma_cc_write32_masked(struct bcma_drv_cc *cc, u16 offset,
|
||||
return value;
|
||||
}
|
||||
|
||||
static u32 bcma_chipco_get_alp_clock(struct bcma_drv_cc *cc)
|
||||
{
|
||||
if (cc->capabilities & BCMA_CC_CAP_PMU)
|
||||
return bcma_pmu_get_alp_clock(cc);
|
||||
|
||||
return 20000000;
|
||||
}
|
||||
|
||||
static u32 bcma_chipco_watchdog_get_max_timer(struct bcma_drv_cc *cc)
|
||||
{
|
||||
struct bcma_bus *bus = cc->core->bus;
|
||||
u32 nb;
|
||||
|
||||
if (cc->capabilities & BCMA_CC_CAP_PMU) {
|
||||
if (bus->chipinfo.id == BCMA_CHIP_ID_BCM4706)
|
||||
nb = 32;
|
||||
else if (cc->core->id.rev < 26)
|
||||
nb = 16;
|
||||
else
|
||||
nb = (cc->core->id.rev >= 37) ? 32 : 24;
|
||||
} else {
|
||||
nb = 28;
|
||||
}
|
||||
if (nb == 32)
|
||||
return 0xffffffff;
|
||||
else
|
||||
return (1 << nb) - 1;
|
||||
}
|
||||
|
||||
static u32 bcma_chipco_watchdog_timer_set_wdt(struct bcm47xx_wdt *wdt,
|
||||
u32 ticks)
|
||||
{
|
||||
struct bcma_drv_cc *cc = bcm47xx_wdt_get_drvdata(wdt);
|
||||
|
||||
return bcma_chipco_watchdog_timer_set(cc, ticks);
|
||||
}
|
||||
|
||||
static u32 bcma_chipco_watchdog_timer_set_ms_wdt(struct bcm47xx_wdt *wdt,
|
||||
u32 ms)
|
||||
{
|
||||
struct bcma_drv_cc *cc = bcm47xx_wdt_get_drvdata(wdt);
|
||||
u32 ticks;
|
||||
|
||||
ticks = bcma_chipco_watchdog_timer_set(cc, cc->ticks_per_ms * ms);
|
||||
return ticks / cc->ticks_per_ms;
|
||||
}
|
||||
|
||||
static int bcma_chipco_watchdog_ticks_per_ms(struct bcma_drv_cc *cc)
|
||||
{
|
||||
struct bcma_bus *bus = cc->core->bus;
|
||||
|
||||
if (cc->capabilities & BCMA_CC_CAP_PMU) {
|
||||
if (bus->chipinfo.id == BCMA_CHIP_ID_BCM4706)
|
||||
/* 4706 CC and PMU watchdogs are clocked at 1/4 of ALP clock */
|
||||
return bcma_chipco_get_alp_clock(cc) / 4000;
|
||||
else
|
||||
/* based on 32KHz ILP clock */
|
||||
return 32;
|
||||
} else {
|
||||
return bcma_chipco_get_alp_clock(cc) / 1000;
|
||||
}
|
||||
}
|
||||
|
||||
int bcma_chipco_watchdog_register(struct bcma_drv_cc *cc)
|
||||
{
|
||||
struct bcm47xx_wdt wdt = {};
|
||||
struct platform_device *pdev;
|
||||
|
||||
wdt.driver_data = cc;
|
||||
wdt.timer_set = bcma_chipco_watchdog_timer_set_wdt;
|
||||
wdt.timer_set_ms = bcma_chipco_watchdog_timer_set_ms_wdt;
|
||||
wdt.max_timer_ms = bcma_chipco_watchdog_get_max_timer(cc) / cc->ticks_per_ms;
|
||||
|
||||
pdev = platform_device_register_data(NULL, "bcm47xx-wdt",
|
||||
cc->core->bus->num, &wdt,
|
||||
sizeof(wdt));
|
||||
if (IS_ERR(pdev))
|
||||
return PTR_ERR(pdev);
|
||||
|
||||
cc->watchdog = pdev;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void bcma_core_chipcommon_early_init(struct bcma_drv_cc *cc)
|
||||
{
|
||||
if (cc->early_setup_done)
|
||||
return;
|
||||
|
||||
if (cc->core->id.rev >= 11)
|
||||
cc->status = bcma_cc_read32(cc, BCMA_CC_CHIPSTAT);
|
||||
cc->capabilities = bcma_cc_read32(cc, BCMA_CC_CAP);
|
||||
if (cc->core->id.rev >= 35)
|
||||
cc->capabilities_ext = bcma_cc_read32(cc, BCMA_CC_CAP_EXT);
|
||||
|
||||
if (cc->capabilities & BCMA_CC_CAP_PMU)
|
||||
bcma_pmu_early_init(cc);
|
||||
|
||||
cc->early_setup_done = true;
|
||||
}
|
||||
|
||||
void bcma_core_chipcommon_init(struct bcma_drv_cc *cc)
|
||||
{
|
||||
u32 leddc_on = 10;
|
||||
@ -30,11 +134,7 @@ void bcma_core_chipcommon_init(struct bcma_drv_cc *cc)
|
||||
if (cc->setup_done)
|
||||
return;
|
||||
|
||||
if (cc->core->id.rev >= 11)
|
||||
cc->status = bcma_cc_read32(cc, BCMA_CC_CHIPSTAT);
|
||||
cc->capabilities = bcma_cc_read32(cc, BCMA_CC_CAP);
|
||||
if (cc->core->id.rev >= 35)
|
||||
cc->capabilities_ext = bcma_cc_read32(cc, BCMA_CC_CAP_EXT);
|
||||
bcma_core_chipcommon_early_init(cc);
|
||||
|
||||
if (cc->core->id.rev >= 20) {
|
||||
bcma_cc_write32(cc, BCMA_CC_GPIOPULLUP, 0);
|
||||
@ -56,15 +156,33 @@ void bcma_core_chipcommon_init(struct bcma_drv_cc *cc)
|
||||
((leddc_on << BCMA_CC_GPIOTIMER_ONTIME_SHIFT) |
|
||||
(leddc_off << BCMA_CC_GPIOTIMER_OFFTIME_SHIFT)));
|
||||
}
|
||||
cc->ticks_per_ms = bcma_chipco_watchdog_ticks_per_ms(cc);
|
||||
|
||||
cc->setup_done = true;
|
||||
}
|
||||
|
||||
/* Set chip watchdog reset timer to fire in 'ticks' backplane cycles */
|
||||
void bcma_chipco_watchdog_timer_set(struct bcma_drv_cc *cc, u32 ticks)
|
||||
u32 bcma_chipco_watchdog_timer_set(struct bcma_drv_cc *cc, u32 ticks)
|
||||
{
|
||||
/* instant NMI */
|
||||
bcma_cc_write32(cc, BCMA_CC_WATCHDOG, ticks);
|
||||
u32 maxt;
|
||||
enum bcma_clkmode clkmode;
|
||||
|
||||
maxt = bcma_chipco_watchdog_get_max_timer(cc);
|
||||
if (cc->capabilities & BCMA_CC_CAP_PMU) {
|
||||
if (ticks == 1)
|
||||
ticks = 2;
|
||||
else if (ticks > maxt)
|
||||
ticks = maxt;
|
||||
bcma_cc_write32(cc, BCMA_CC_PMU_WATCHDOG, ticks);
|
||||
} else {
|
||||
clkmode = ticks ? BCMA_CLKMODE_FAST : BCMA_CLKMODE_DYNAMIC;
|
||||
bcma_core_set_clockmode(cc->core, clkmode);
|
||||
if (ticks > maxt)
|
||||
ticks = maxt;
|
||||
/* instant NMI */
|
||||
bcma_cc_write32(cc, BCMA_CC_WATCHDOG, ticks);
|
||||
}
|
||||
return ticks;
|
||||
}
|
||||
|
||||
void bcma_chipco_irq_mask(struct bcma_drv_cc *cc, u32 mask, u32 value)
|
||||
@ -118,8 +236,7 @@ void bcma_chipco_serial_init(struct bcma_drv_cc *cc)
|
||||
struct bcma_serial_port *ports = cc->serial_ports;
|
||||
|
||||
if (ccrev >= 11 && ccrev != 15) {
|
||||
/* Fixed ALP clock */
|
||||
baud_base = bcma_pmu_alp_clock(cc);
|
||||
baud_base = bcma_chipco_get_alp_clock(cc);
|
||||
if (ccrev >= 21) {
|
||||
/* Turn off UART clock before switching clocksource. */
|
||||
bcma_cc_write32(cc, BCMA_CC_CORECTL,
|
||||
|
@ -32,6 +32,9 @@ int bcma_nflash_init(struct bcma_drv_cc *cc)
|
||||
}
|
||||
|
||||
cc->nflash.present = true;
|
||||
if (cc->core->id.rev == 38 &&
|
||||
(cc->status & BCMA_CC_CHIPST_5357_NAND_BOOT))
|
||||
cc->nflash.boot = true;
|
||||
|
||||
/* Prepare platform device, but don't register it yet. It's too early,
|
||||
* malloc (required by device_private_init) is not available yet. */
|
||||
|
@ -144,7 +144,7 @@ static void bcma_pmu_workarounds(struct bcma_drv_cc *cc)
|
||||
}
|
||||
}
|
||||
|
||||
void bcma_pmu_init(struct bcma_drv_cc *cc)
|
||||
void bcma_pmu_early_init(struct bcma_drv_cc *cc)
|
||||
{
|
||||
u32 pmucap;
|
||||
|
||||
@ -153,7 +153,10 @@ void bcma_pmu_init(struct bcma_drv_cc *cc)
|
||||
|
||||
bcma_debug(cc->core->bus, "Found rev %u PMU (capabilities 0x%08X)\n",
|
||||
cc->pmu.rev, pmucap);
|
||||
}
|
||||
|
||||
void bcma_pmu_init(struct bcma_drv_cc *cc)
|
||||
{
|
||||
if (cc->pmu.rev == 1)
|
||||
bcma_cc_mask32(cc, BCMA_CC_PMU_CTL,
|
||||
~BCMA_CC_PMU_CTL_NOILPONW);
|
||||
@ -165,7 +168,7 @@ void bcma_pmu_init(struct bcma_drv_cc *cc)
|
||||
bcma_pmu_workarounds(cc);
|
||||
}
|
||||
|
||||
u32 bcma_pmu_alp_clock(struct bcma_drv_cc *cc)
|
||||
u32 bcma_pmu_get_alp_clock(struct bcma_drv_cc *cc)
|
||||
{
|
||||
struct bcma_bus *bus = cc->core->bus;
|
||||
|
||||
@ -193,7 +196,7 @@ u32 bcma_pmu_alp_clock(struct bcma_drv_cc *cc)
|
||||
/* Find the output of the "m" pll divider given pll controls that start with
|
||||
* pllreg "pll0" i.e. 12 for main 6 for phy, 0 for misc.
|
||||
*/
|
||||
static u32 bcma_pmu_clock(struct bcma_drv_cc *cc, u32 pll0, u32 m)
|
||||
static u32 bcma_pmu_pll_clock(struct bcma_drv_cc *cc, u32 pll0, u32 m)
|
||||
{
|
||||
u32 tmp, div, ndiv, p1, p2, fc;
|
||||
struct bcma_bus *bus = cc->core->bus;
|
||||
@ -222,14 +225,14 @@ static u32 bcma_pmu_clock(struct bcma_drv_cc *cc, u32 pll0, u32 m)
|
||||
ndiv = (tmp & BCMA_CC_PPL_NDIV_MASK) >> BCMA_CC_PPL_NDIV_SHIFT;
|
||||
|
||||
/* Do calculation in Mhz */
|
||||
fc = bcma_pmu_alp_clock(cc) / 1000000;
|
||||
fc = bcma_pmu_get_alp_clock(cc) / 1000000;
|
||||
fc = (p1 * ndiv * fc) / p2;
|
||||
|
||||
/* Return clock in Hertz */
|
||||
return (fc / div) * 1000000;
|
||||
}
|
||||
|
||||
static u32 bcma_pmu_clock_bcm4706(struct bcma_drv_cc *cc, u32 pll0, u32 m)
|
||||
static u32 bcma_pmu_pll_clock_bcm4706(struct bcma_drv_cc *cc, u32 pll0, u32 m)
|
||||
{
|
||||
u32 tmp, ndiv, p1div, p2div;
|
||||
u32 clock;
|
||||
@ -260,7 +263,7 @@ static u32 bcma_pmu_clock_bcm4706(struct bcma_drv_cc *cc, u32 pll0, u32 m)
|
||||
}
|
||||
|
||||
/* query bus clock frequency for PMU-enabled chipcommon */
|
||||
static u32 bcma_pmu_get_clockcontrol(struct bcma_drv_cc *cc)
|
||||
static u32 bcma_pmu_get_bus_clock(struct bcma_drv_cc *cc)
|
||||
{
|
||||
struct bcma_bus *bus = cc->core->bus;
|
||||
|
||||
@ -268,40 +271,42 @@ static u32 bcma_pmu_get_clockcontrol(struct bcma_drv_cc *cc)
|
||||
case BCMA_CHIP_ID_BCM4716:
|
||||
case BCMA_CHIP_ID_BCM4748:
|
||||
case BCMA_CHIP_ID_BCM47162:
|
||||
return bcma_pmu_clock(cc, BCMA_CC_PMU4716_MAINPLL_PLL0,
|
||||
BCMA_CC_PMU5_MAINPLL_SSB);
|
||||
return bcma_pmu_pll_clock(cc, BCMA_CC_PMU4716_MAINPLL_PLL0,
|
||||
BCMA_CC_PMU5_MAINPLL_SSB);
|
||||
case BCMA_CHIP_ID_BCM5356:
|
||||
return bcma_pmu_clock(cc, BCMA_CC_PMU5356_MAINPLL_PLL0,
|
||||
BCMA_CC_PMU5_MAINPLL_SSB);
|
||||
return bcma_pmu_pll_clock(cc, BCMA_CC_PMU5356_MAINPLL_PLL0,
|
||||
BCMA_CC_PMU5_MAINPLL_SSB);
|
||||
case BCMA_CHIP_ID_BCM5357:
|
||||
case BCMA_CHIP_ID_BCM4749:
|
||||
return bcma_pmu_clock(cc, BCMA_CC_PMU5357_MAINPLL_PLL0,
|
||||
BCMA_CC_PMU5_MAINPLL_SSB);
|
||||
return bcma_pmu_pll_clock(cc, BCMA_CC_PMU5357_MAINPLL_PLL0,
|
||||
BCMA_CC_PMU5_MAINPLL_SSB);
|
||||
case BCMA_CHIP_ID_BCM4706:
|
||||
return bcma_pmu_clock_bcm4706(cc, BCMA_CC_PMU4706_MAINPLL_PLL0,
|
||||
BCMA_CC_PMU5_MAINPLL_SSB);
|
||||
return bcma_pmu_pll_clock_bcm4706(cc,
|
||||
BCMA_CC_PMU4706_MAINPLL_PLL0,
|
||||
BCMA_CC_PMU5_MAINPLL_SSB);
|
||||
case BCMA_CHIP_ID_BCM53572:
|
||||
return 75000000;
|
||||
default:
|
||||
bcma_warn(bus, "No backplane clock specified for %04X device, pmu rev. %d, using default %d Hz\n",
|
||||
bcma_warn(bus, "No bus clock specified for %04X device, pmu rev. %d, using default %d Hz\n",
|
||||
bus->chipinfo.id, cc->pmu.rev, BCMA_CC_PMU_HT_CLOCK);
|
||||
}
|
||||
return BCMA_CC_PMU_HT_CLOCK;
|
||||
}
|
||||
|
||||
/* query cpu clock frequency for PMU-enabled chipcommon */
|
||||
u32 bcma_pmu_get_clockcpu(struct bcma_drv_cc *cc)
|
||||
u32 bcma_pmu_get_cpu_clock(struct bcma_drv_cc *cc)
|
||||
{
|
||||
struct bcma_bus *bus = cc->core->bus;
|
||||
|
||||
if (bus->chipinfo.id == BCMA_CHIP_ID_BCM53572)
|
||||
return 300000000;
|
||||
|
||||
/* New PMUs can have different clock for bus and CPU */
|
||||
if (cc->pmu.rev >= 5) {
|
||||
u32 pll;
|
||||
switch (bus->chipinfo.id) {
|
||||
case BCMA_CHIP_ID_BCM4706:
|
||||
return bcma_pmu_clock_bcm4706(cc,
|
||||
return bcma_pmu_pll_clock_bcm4706(cc,
|
||||
BCMA_CC_PMU4706_MAINPLL_PLL0,
|
||||
BCMA_CC_PMU5_MAINPLL_CPU);
|
||||
case BCMA_CHIP_ID_BCM5356:
|
||||
@ -316,10 +321,11 @@ u32 bcma_pmu_get_clockcpu(struct bcma_drv_cc *cc)
|
||||
break;
|
||||
}
|
||||
|
||||
return bcma_pmu_clock(cc, pll, BCMA_CC_PMU5_MAINPLL_CPU);
|
||||
return bcma_pmu_pll_clock(cc, pll, BCMA_CC_PMU5_MAINPLL_CPU);
|
||||
}
|
||||
|
||||
return bcma_pmu_get_clockcontrol(cc);
|
||||
/* On old PMUs CPU has the same clock as the bus */
|
||||
return bcma_pmu_get_bus_clock(cc);
|
||||
}
|
||||
|
||||
static void bcma_pmu_spuravoid_pll_write(struct bcma_drv_cc *cc, u32 offset,
|
||||
|
@ -12,7 +12,7 @@
|
||||
|
||||
static struct resource bcma_sflash_resource = {
|
||||
.name = "bcma_sflash",
|
||||
.start = BCMA_SFLASH,
|
||||
.start = BCMA_SOC_FLASH2,
|
||||
.end = 0,
|
||||
.flags = IORESOURCE_MEM | IORESOURCE_READONLY,
|
||||
};
|
||||
@ -31,15 +31,42 @@ struct bcma_sflash_tbl_e {
|
||||
};
|
||||
|
||||
static struct bcma_sflash_tbl_e bcma_sflash_st_tbl[] = {
|
||||
{ "", 0x14, 0x10000, 32, },
|
||||
{ "M25P20", 0x11, 0x10000, 4, },
|
||||
{ "M25P40", 0x12, 0x10000, 8, },
|
||||
|
||||
{ "M25P16", 0x14, 0x10000, 32, },
|
||||
{ "M25P32", 0x14, 0x10000, 64, },
|
||||
{ "M25P64", 0x16, 0x10000, 128, },
|
||||
{ "M25FL128", 0x17, 0x10000, 256, },
|
||||
{ 0 },
|
||||
};
|
||||
|
||||
static struct bcma_sflash_tbl_e bcma_sflash_sst_tbl[] = {
|
||||
{ "SST25WF512", 1, 0x1000, 16, },
|
||||
{ "SST25VF512", 0x48, 0x1000, 16, },
|
||||
{ "SST25WF010", 2, 0x1000, 32, },
|
||||
{ "SST25VF010", 0x49, 0x1000, 32, },
|
||||
{ "SST25WF020", 3, 0x1000, 64, },
|
||||
{ "SST25VF020", 0x43, 0x1000, 64, },
|
||||
{ "SST25WF040", 4, 0x1000, 128, },
|
||||
{ "SST25VF040", 0x44, 0x1000, 128, },
|
||||
{ "SST25VF040B", 0x8d, 0x1000, 128, },
|
||||
{ "SST25WF080", 5, 0x1000, 256, },
|
||||
{ "SST25VF080B", 0x8e, 0x1000, 256, },
|
||||
{ "SST25VF016", 0x41, 0x1000, 512, },
|
||||
{ "SST25VF032", 0x4a, 0x1000, 1024, },
|
||||
{ "SST25VF064", 0x4b, 0x1000, 2048, },
|
||||
{ 0 },
|
||||
};
|
||||
|
||||
static struct bcma_sflash_tbl_e bcma_sflash_at_tbl[] = {
|
||||
{ "AT45DB011", 0xc, 256, 512, },
|
||||
{ "AT45DB021", 0x14, 256, 1024, },
|
||||
{ "AT45DB041", 0x1c, 256, 2048, },
|
||||
{ "AT45DB081", 0x24, 256, 4096, },
|
||||
{ "AT45DB161", 0x2c, 512, 4096, },
|
||||
{ "AT45DB321", 0x34, 512, 8192, },
|
||||
{ "AT45DB642", 0x3c, 1024, 8192, },
|
||||
{ 0 },
|
||||
};
|
||||
|
||||
@ -84,6 +111,8 @@ int bcma_sflash_init(struct bcma_drv_cc *cc)
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 0x13:
|
||||
return -ENOTSUPP;
|
||||
default:
|
||||
for (e = bcma_sflash_st_tbl; e->name; e++) {
|
||||
if (e->id == id)
|
||||
@ -116,7 +145,7 @@ int bcma_sflash_init(struct bcma_drv_cc *cc)
|
||||
return -ENOTSUPP;
|
||||
}
|
||||
|
||||
sflash->window = BCMA_SFLASH;
|
||||
sflash->window = BCMA_SOC_FLASH2;
|
||||
sflash->blocksize = e->blocksize;
|
||||
sflash->numblocks = e->numblocks;
|
||||
sflash->size = sflash->blocksize * sflash->numblocks;
|
||||
|
@ -115,7 +115,7 @@ static void bcma_core_mips_set_irq(struct bcma_device *dev, unsigned int irq)
|
||||
bcma_read32(mdev, BCMA_MIPS_MIPS74K_INTMASK(0)) &
|
||||
~(1 << irqflag));
|
||||
else
|
||||
bcma_write32(mdev, BCMA_MIPS_MIPS74K_INTMASK(irq), 0);
|
||||
bcma_write32(mdev, BCMA_MIPS_MIPS74K_INTMASK(oldirq), 0);
|
||||
|
||||
/* assign the new one */
|
||||
if (irq == 0) {
|
||||
@ -171,7 +171,7 @@ u32 bcma_cpu_clock(struct bcma_drv_mips *mcore)
|
||||
struct bcma_bus *bus = mcore->core->bus;
|
||||
|
||||
if (bus->drv_cc.capabilities & BCMA_CC_CAP_PMU)
|
||||
return bcma_pmu_get_clockcpu(&bus->drv_cc);
|
||||
return bcma_pmu_get_cpu_clock(&bus->drv_cc);
|
||||
|
||||
bcma_err(bus, "No PMU available, need this to get the cpu clock\n");
|
||||
return 0;
|
||||
@ -181,47 +181,66 @@ EXPORT_SYMBOL(bcma_cpu_clock);
|
||||
static void bcma_core_mips_flash_detect(struct bcma_drv_mips *mcore)
|
||||
{
|
||||
struct bcma_bus *bus = mcore->core->bus;
|
||||
struct bcma_drv_cc *cc = &bus->drv_cc;
|
||||
|
||||
switch (bus->drv_cc.capabilities & BCMA_CC_CAP_FLASHT) {
|
||||
switch (cc->capabilities & BCMA_CC_CAP_FLASHT) {
|
||||
case BCMA_CC_FLASHT_STSER:
|
||||
case BCMA_CC_FLASHT_ATSER:
|
||||
bcma_debug(bus, "Found serial flash\n");
|
||||
bcma_sflash_init(&bus->drv_cc);
|
||||
bcma_sflash_init(cc);
|
||||
break;
|
||||
case BCMA_CC_FLASHT_PARA:
|
||||
bcma_debug(bus, "Found parallel flash\n");
|
||||
bus->drv_cc.pflash.window = 0x1c000000;
|
||||
bus->drv_cc.pflash.window_size = 0x02000000;
|
||||
cc->pflash.present = true;
|
||||
cc->pflash.window = BCMA_SOC_FLASH2;
|
||||
cc->pflash.window_size = BCMA_SOC_FLASH2_SZ;
|
||||
|
||||
if ((bcma_read32(bus->drv_cc.core, BCMA_CC_FLASH_CFG) &
|
||||
if ((bcma_read32(cc->core, BCMA_CC_FLASH_CFG) &
|
||||
BCMA_CC_FLASH_CFG_DS) == 0)
|
||||
bus->drv_cc.pflash.buswidth = 1;
|
||||
cc->pflash.buswidth = 1;
|
||||
else
|
||||
bus->drv_cc.pflash.buswidth = 2;
|
||||
cc->pflash.buswidth = 2;
|
||||
break;
|
||||
default:
|
||||
bcma_err(bus, "Flash type not supported\n");
|
||||
}
|
||||
|
||||
if (bus->drv_cc.core->id.rev == 38 ||
|
||||
if (cc->core->id.rev == 38 ||
|
||||
bus->chipinfo.id == BCMA_CHIP_ID_BCM4706) {
|
||||
if (bus->drv_cc.capabilities & BCMA_CC_CAP_NFLASH) {
|
||||
if (cc->capabilities & BCMA_CC_CAP_NFLASH) {
|
||||
bcma_debug(bus, "Found NAND flash\n");
|
||||
bcma_nflash_init(&bus->drv_cc);
|
||||
bcma_nflash_init(cc);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void bcma_core_mips_early_init(struct bcma_drv_mips *mcore)
|
||||
{
|
||||
struct bcma_bus *bus = mcore->core->bus;
|
||||
|
||||
if (mcore->early_setup_done)
|
||||
return;
|
||||
|
||||
bcma_chipco_serial_init(&bus->drv_cc);
|
||||
bcma_core_mips_flash_detect(mcore);
|
||||
|
||||
mcore->early_setup_done = true;
|
||||
}
|
||||
|
||||
void bcma_core_mips_init(struct bcma_drv_mips *mcore)
|
||||
{
|
||||
struct bcma_bus *bus;
|
||||
struct bcma_device *core;
|
||||
bus = mcore->core->bus;
|
||||
|
||||
if (mcore->setup_done)
|
||||
return;
|
||||
|
||||
bcma_info(bus, "Initializing MIPS core...\n");
|
||||
|
||||
if (!mcore->setup_done)
|
||||
mcore->assigned_irqs = 1;
|
||||
bcma_core_mips_early_init(mcore);
|
||||
|
||||
mcore->assigned_irqs = 1;
|
||||
|
||||
/* Assign IRQs to all cores on the bus */
|
||||
list_for_each_entry(core, &bus->cores, list) {
|
||||
@ -256,10 +275,5 @@ void bcma_core_mips_init(struct bcma_drv_mips *mcore)
|
||||
bcma_info(bus, "IRQ reconfiguration done\n");
|
||||
bcma_core_mips_dump_irq(bus);
|
||||
|
||||
if (mcore->setup_done)
|
||||
return;
|
||||
|
||||
bcma_chipco_serial_init(&bus->drv_cc);
|
||||
bcma_core_mips_flash_detect(mcore);
|
||||
mcore->setup_done = true;
|
||||
}
|
||||
|
@ -35,11 +35,6 @@ bool __devinit bcma_core_pci_is_in_hostmode(struct bcma_drv_pci *pc)
|
||||
chipid_top != 0x5300)
|
||||
return false;
|
||||
|
||||
if (bus->sprom.boardflags_lo & BCMA_CORE_PCI_BFL_NOPCI) {
|
||||
bcma_info(bus, "This PCI core is disabled and not working\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
bcma_core_enable(pc->core, 0);
|
||||
|
||||
return !mips_busprobe32(tmp, pc->core->io_addr);
|
||||
@ -396,6 +391,11 @@ void __devinit bcma_core_pci_hostmode_init(struct bcma_drv_pci *pc)
|
||||
|
||||
bcma_info(bus, "PCIEcore in host mode found\n");
|
||||
|
||||
if (bus->sprom.boardflags_lo & BCMA_CORE_PCI_BFL_NOPCI) {
|
||||
bcma_info(bus, "This PCIE core is disabled and not working\n");
|
||||
return;
|
||||
}
|
||||
|
||||
pc_host = kzalloc(sizeof(*pc_host), GFP_KERNEL);
|
||||
if (!pc_host) {
|
||||
bcma_err(bus, "can not allocate memory");
|
||||
@ -452,6 +452,8 @@ void __devinit bcma_core_pci_hostmode_init(struct bcma_drv_pci *pc)
|
||||
pc_host->mem_resource.start = BCMA_SOC_PCI_MEM;
|
||||
pc_host->mem_resource.end = BCMA_SOC_PCI_MEM +
|
||||
BCMA_SOC_PCI_MEM_SZ - 1;
|
||||
pc_host->io_resource.start = 0x100;
|
||||
pc_host->io_resource.end = 0x47F;
|
||||
pci_membase_1G = BCMA_SOC_PCIE_DMA_H32;
|
||||
pcicore_write32(pc, BCMA_CORE_PCI_SBTOPCI0,
|
||||
tmp | BCMA_SOC_PCI_MEM);
|
||||
@ -459,6 +461,8 @@ void __devinit bcma_core_pci_hostmode_init(struct bcma_drv_pci *pc)
|
||||
pc_host->mem_resource.start = BCMA_SOC_PCI1_MEM;
|
||||
pc_host->mem_resource.end = BCMA_SOC_PCI1_MEM +
|
||||
BCMA_SOC_PCI_MEM_SZ - 1;
|
||||
pc_host->io_resource.start = 0x480;
|
||||
pc_host->io_resource.end = 0x7FF;
|
||||
pci_membase_1G = BCMA_SOC_PCIE1_DMA_H32;
|
||||
pc_host->host_cfg_addr = BCMA_SOC_PCI1_CFG;
|
||||
pcicore_write32(pc, BCMA_CORE_PCI_SBTOPCI0,
|
||||
@ -534,7 +538,7 @@ DECLARE_PCI_FIXUP_EARLY(PCI_ANY_ID, PCI_ANY_ID, bcma_core_pci_fixup_pcibridge);
|
||||
static void bcma_core_pci_fixup_addresses(struct pci_dev *dev)
|
||||
{
|
||||
struct resource *res;
|
||||
int pos;
|
||||
int pos, err;
|
||||
|
||||
if (dev->bus->ops->read != bcma_core_pci_hostmode_read_config) {
|
||||
/* This is not a device on the PCI-core bridge. */
|
||||
@ -547,8 +551,12 @@ static void bcma_core_pci_fixup_addresses(struct pci_dev *dev)
|
||||
|
||||
for (pos = 0; pos < 6; pos++) {
|
||||
res = &dev->resource[pos];
|
||||
if (res->flags & (IORESOURCE_IO | IORESOURCE_MEM))
|
||||
pci_assign_resource(dev, pos);
|
||||
if (res->flags & (IORESOURCE_IO | IORESOURCE_MEM)) {
|
||||
err = pci_assign_resource(dev, pos);
|
||||
if (err)
|
||||
pr_err("PCI: Problem fixing up the addresses on %s\n",
|
||||
pci_name(dev));
|
||||
}
|
||||
}
|
||||
}
|
||||
DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID, PCI_ANY_ID, bcma_core_pci_fixup_addresses);
|
||||
|
@ -238,7 +238,7 @@ static void __devexit bcma_host_pci_remove(struct pci_dev *dev)
|
||||
pci_set_drvdata(dev, NULL);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
#ifdef CONFIG_PM_SLEEP
|
||||
static int bcma_host_pci_suspend(struct device *dev)
|
||||
{
|
||||
struct pci_dev *pdev = to_pci_dev(dev);
|
||||
@ -261,11 +261,11 @@ static SIMPLE_DEV_PM_OPS(bcma_pm_ops, bcma_host_pci_suspend,
|
||||
bcma_host_pci_resume);
|
||||
#define BCMA_PM_OPS (&bcma_pm_ops)
|
||||
|
||||
#else /* CONFIG_PM */
|
||||
#else /* CONFIG_PM_SLEEP */
|
||||
|
||||
#define BCMA_PM_OPS NULL
|
||||
|
||||
#endif /* CONFIG_PM */
|
||||
#endif /* CONFIG_PM_SLEEP */
|
||||
|
||||
static DEFINE_PCI_DEVICE_TABLE(bcma_pci_bridge_tbl) = {
|
||||
{ PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x0576) },
|
||||
|
@ -81,6 +81,18 @@ struct bcma_device *bcma_find_core(struct bcma_bus *bus, u16 coreid)
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(bcma_find_core);
|
||||
|
||||
static struct bcma_device *bcma_find_core_unit(struct bcma_bus *bus, u16 coreid,
|
||||
u8 unit)
|
||||
{
|
||||
struct bcma_device *core;
|
||||
|
||||
list_for_each_entry(core, &bus->cores, list) {
|
||||
if (core->id.id == coreid && core->core_unit == unit)
|
||||
return core;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void bcma_release_core_dev(struct device *dev)
|
||||
{
|
||||
struct bcma_device *core = container_of(dev, struct bcma_device, dev);
|
||||
@ -153,6 +165,12 @@ static int bcma_register_cores(struct bcma_bus *bus)
|
||||
}
|
||||
#endif
|
||||
|
||||
if (bus->hosttype == BCMA_HOSTTYPE_SOC) {
|
||||
err = bcma_chipco_watchdog_register(&bus->drv_cc);
|
||||
if (err)
|
||||
bcma_err(bus, "Error registering watchdog driver\n");
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -165,6 +183,8 @@ static void bcma_unregister_cores(struct bcma_bus *bus)
|
||||
if (core->dev_registered)
|
||||
device_unregister(&core->dev);
|
||||
}
|
||||
if (bus->hosttype == BCMA_HOSTTYPE_SOC)
|
||||
platform_device_unregister(bus->drv_cc.watchdog);
|
||||
}
|
||||
|
||||
int __devinit bcma_bus_register(struct bcma_bus *bus)
|
||||
@ -183,6 +203,20 @@ int __devinit bcma_bus_register(struct bcma_bus *bus)
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Early init CC core */
|
||||
core = bcma_find_core(bus, bcma_cc_core_id(bus));
|
||||
if (core) {
|
||||
bus->drv_cc.core = core;
|
||||
bcma_core_chipcommon_early_init(&bus->drv_cc);
|
||||
}
|
||||
|
||||
/* Try to get SPROM */
|
||||
err = bcma_sprom_get(bus);
|
||||
if (err == -ENOENT) {
|
||||
bcma_err(bus, "No SPROM available\n");
|
||||
} else if (err)
|
||||
bcma_err(bus, "Failed to get SPROM: %d\n", err);
|
||||
|
||||
/* Init CC core */
|
||||
core = bcma_find_core(bus, bcma_cc_core_id(bus));
|
||||
if (core) {
|
||||
@ -198,10 +232,17 @@ int __devinit bcma_bus_register(struct bcma_bus *bus)
|
||||
}
|
||||
|
||||
/* Init PCIE core */
|
||||
core = bcma_find_core(bus, BCMA_CORE_PCIE);
|
||||
core = bcma_find_core_unit(bus, BCMA_CORE_PCIE, 0);
|
||||
if (core) {
|
||||
bus->drv_pci.core = core;
|
||||
bcma_core_pci_init(&bus->drv_pci);
|
||||
bus->drv_pci[0].core = core;
|
||||
bcma_core_pci_init(&bus->drv_pci[0]);
|
||||
}
|
||||
|
||||
/* Init PCIE core */
|
||||
core = bcma_find_core_unit(bus, BCMA_CORE_PCIE, 1);
|
||||
if (core) {
|
||||
bus->drv_pci[1].core = core;
|
||||
bcma_core_pci_init(&bus->drv_pci[1]);
|
||||
}
|
||||
|
||||
/* Init GBIT MAC COMMON core */
|
||||
@ -211,13 +252,6 @@ int __devinit bcma_bus_register(struct bcma_bus *bus)
|
||||
bcma_core_gmac_cmn_init(&bus->drv_gmac_cmn);
|
||||
}
|
||||
|
||||
/* Try to get SPROM */
|
||||
err = bcma_sprom_get(bus);
|
||||
if (err == -ENOENT) {
|
||||
bcma_err(bus, "No SPROM available\n");
|
||||
} else if (err)
|
||||
bcma_err(bus, "Failed to get SPROM: %d\n", err);
|
||||
|
||||
/* Register found cores */
|
||||
bcma_register_cores(bus);
|
||||
|
||||
@ -275,18 +309,18 @@ int __init bcma_bus_early_register(struct bcma_bus *bus,
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Init CC core */
|
||||
/* Early init CC core */
|
||||
core = bcma_find_core(bus, bcma_cc_core_id(bus));
|
||||
if (core) {
|
||||
bus->drv_cc.core = core;
|
||||
bcma_core_chipcommon_init(&bus->drv_cc);
|
||||
bcma_core_chipcommon_early_init(&bus->drv_cc);
|
||||
}
|
||||
|
||||
/* Init MIPS core */
|
||||
/* Early init MIPS core */
|
||||
core = bcma_find_core(bus, BCMA_CORE_MIPS_74K);
|
||||
if (core) {
|
||||
bus->drv_mips.core = core;
|
||||
bcma_core_mips_init(&bus->drv_mips);
|
||||
bcma_core_mips_early_init(&bus->drv_mips);
|
||||
}
|
||||
|
||||
bcma_info(bus, "Early bus registered\n");
|
||||
|
@ -595,8 +595,11 @@ int bcma_sprom_get(struct bcma_bus *bus)
|
||||
bcma_chipco_bcm4331_ext_pa_lines_ctl(&bus->drv_cc, true);
|
||||
|
||||
err = bcma_sprom_valid(sprom);
|
||||
if (err)
|
||||
if (err) {
|
||||
bcma_warn(bus, "invalid sprom read from the PCIe card, try to use fallback sprom\n");
|
||||
err = bcma_fill_sprom_with_fallback(bus, &bus->sprom);
|
||||
goto out;
|
||||
}
|
||||
|
||||
bcma_sprom_extract_r8(bus, sprom);
|
||||
|
||||
|
@ -492,7 +492,7 @@ done:
|
||||
static int btmrvl_sdio_card_to_host(struct btmrvl_private *priv)
|
||||
{
|
||||
u16 buf_len = 0;
|
||||
int ret, buf_block_len, blksz;
|
||||
int ret, num_blocks, blksz;
|
||||
struct sk_buff *skb = NULL;
|
||||
u32 type;
|
||||
u8 *payload = NULL;
|
||||
@ -514,18 +514,17 @@ static int btmrvl_sdio_card_to_host(struct btmrvl_private *priv)
|
||||
}
|
||||
|
||||
blksz = SDIO_BLOCK_SIZE;
|
||||
buf_block_len = (buf_len + blksz - 1) / blksz;
|
||||
num_blocks = DIV_ROUND_UP(buf_len, blksz);
|
||||
|
||||
if (buf_len <= SDIO_HEADER_LEN
|
||||
|| (buf_block_len * blksz) > ALLOC_BUF_SIZE) {
|
||||
|| (num_blocks * blksz) > ALLOC_BUF_SIZE) {
|
||||
BT_ERR("invalid packet length: %d", buf_len);
|
||||
ret = -EINVAL;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
/* Allocate buffer */
|
||||
skb = bt_skb_alloc(buf_block_len * blksz + BTSDIO_DMA_ALIGN,
|
||||
GFP_ATOMIC);
|
||||
skb = bt_skb_alloc(num_blocks * blksz + BTSDIO_DMA_ALIGN, GFP_ATOMIC);
|
||||
if (skb == NULL) {
|
||||
BT_ERR("No free skb");
|
||||
goto exit;
|
||||
@ -541,7 +540,7 @@ static int btmrvl_sdio_card_to_host(struct btmrvl_private *priv)
|
||||
payload = skb->data;
|
||||
|
||||
ret = sdio_readsb(card->func, payload, card->ioport,
|
||||
buf_block_len * blksz);
|
||||
num_blocks * blksz);
|
||||
if (ret < 0) {
|
||||
BT_ERR("readsb failed: %d", ret);
|
||||
ret = -EIO;
|
||||
@ -553,7 +552,16 @@ static int btmrvl_sdio_card_to_host(struct btmrvl_private *priv)
|
||||
*/
|
||||
|
||||
buf_len = payload[0];
|
||||
buf_len |= (u16) payload[1] << 8;
|
||||
buf_len |= payload[1] << 8;
|
||||
buf_len |= payload[2] << 16;
|
||||
|
||||
if (buf_len > blksz * num_blocks) {
|
||||
BT_ERR("Skip incorrect packet: hdrlen %d buffer %d",
|
||||
buf_len, blksz * num_blocks);
|
||||
ret = -EIO;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
type = payload[3];
|
||||
|
||||
switch (type) {
|
||||
@ -589,8 +597,7 @@ static int btmrvl_sdio_card_to_host(struct btmrvl_private *priv)
|
||||
|
||||
default:
|
||||
BT_ERR("Unknown packet type:%d", type);
|
||||
print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, payload,
|
||||
blksz * buf_block_len);
|
||||
BT_ERR("hex: %*ph", blksz * num_blocks, payload);
|
||||
|
||||
kfree_skb(skb);
|
||||
skb = NULL;
|
||||
@ -849,8 +856,7 @@ static int btmrvl_sdio_host_to_card(struct btmrvl_private *priv,
|
||||
if (ret < 0) {
|
||||
i++;
|
||||
BT_ERR("i=%d writesb failed: %d", i, ret);
|
||||
print_hex_dump_bytes("", DUMP_PREFIX_OFFSET,
|
||||
payload, nb);
|
||||
BT_ERR("hex: %*ph", nb, payload);
|
||||
ret = -EIO;
|
||||
if (i > MAX_WRITE_IOMEM_RETRY)
|
||||
goto exit;
|
||||
|
@ -96,6 +96,7 @@ static struct usb_device_id btusb_table[] = {
|
||||
{ USB_DEVICE(0x0c10, 0x0000) },
|
||||
|
||||
/* Broadcom BCM20702A0 */
|
||||
{ USB_DEVICE(0x0b05, 0x17b5) },
|
||||
{ USB_DEVICE(0x04ca, 0x2003) },
|
||||
{ USB_DEVICE(0x0489, 0xe042) },
|
||||
{ USB_DEVICE(0x413c, 0x8197) },
|
||||
|
@ -604,6 +604,23 @@ static int ioat3_dca_count_dca_slots(void *iobase, u16 dca_offset)
|
||||
return slots;
|
||||
}
|
||||
|
||||
static inline int dca3_tag_map_invalid(u8 *tag_map)
|
||||
{
|
||||
/*
|
||||
* If the tag map is not programmed by the BIOS the default is:
|
||||
* 0x80 0x80 0x80 0x80 0x80 0x00 0x00 0x00
|
||||
*
|
||||
* This an invalid map and will result in only 2 possible tags
|
||||
* 0x1F and 0x00. 0x00 is an invalid DCA tag so we know that
|
||||
* this entire definition is invalid.
|
||||
*/
|
||||
return ((tag_map[0] == DCA_TAG_MAP_VALID) &&
|
||||
(tag_map[1] == DCA_TAG_MAP_VALID) &&
|
||||
(tag_map[2] == DCA_TAG_MAP_VALID) &&
|
||||
(tag_map[3] == DCA_TAG_MAP_VALID) &&
|
||||
(tag_map[4] == DCA_TAG_MAP_VALID));
|
||||
}
|
||||
|
||||
struct dca_provider * __devinit
|
||||
ioat3_dca_init(struct pci_dev *pdev, void __iomem *iobase)
|
||||
{
|
||||
@ -674,6 +691,12 @@ ioat3_dca_init(struct pci_dev *pdev, void __iomem *iobase)
|
||||
ioatdca->tag_map[i] = bit & DCA_TAG_MAP_MASK;
|
||||
}
|
||||
|
||||
if (dca3_tag_map_invalid(ioatdca->tag_map)) {
|
||||
dev_err(&pdev->dev, "APICID_TAG_MAP set incorrectly by BIOS, disabling DCA\n");
|
||||
free_dca_provider(dca);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
err = register_dca_provider(dca, &pdev->dev);
|
||||
if (err) {
|
||||
free_dca_provider(dca);
|
||||
|
@ -490,7 +490,7 @@ receive_dmsg(struct hfc_pci *hc)
|
||||
(df->data[le16_to_cpu(zp->z1)])) {
|
||||
if (dch->debug & DEBUG_HW)
|
||||
printk(KERN_DEBUG
|
||||
"empty_fifo hfcpci paket inv. len "
|
||||
"empty_fifo hfcpci packet inv. len "
|
||||
"%d or crc %d\n",
|
||||
rcnt,
|
||||
df->data[le16_to_cpu(zp->z1)]);
|
||||
|
@ -1302,7 +1302,7 @@ modeisar(struct isar_ch *ch, u32 bprotocol)
|
||||
&ch->is->Flags))
|
||||
ch->dpath = 1;
|
||||
else {
|
||||
pr_info("modeisar both pathes in use\n");
|
||||
pr_info("modeisar both paths in use\n");
|
||||
return -EBUSY;
|
||||
}
|
||||
if (bprotocol == ISDN_P_B_HDLC)
|
||||
|
@ -35,7 +35,7 @@ static int chancount;
|
||||
/* experimental REJECT after ALERTING for CALLBACK to beat the 4s delay */
|
||||
#define ALERT_REJECT 0
|
||||
|
||||
/* Value to delay the sending of the first B-channel paket after CONNECT
|
||||
/* Value to delay the sending of the first B-channel packet after CONNECT
|
||||
* here is no value given by ITU, but experience shows that 300 ms will
|
||||
* work on many networks, if you or your other side is behind local exchanges
|
||||
* a greater value may be recommented. If the delay is to short the first paket
|
||||
|
@ -354,7 +354,7 @@ receive_dmsg(struct IsdnCardState *cs)
|
||||
if ((rcnt > MAX_DFRAME_LEN + 3) || (rcnt < 4) ||
|
||||
(df->data[zp->z1])) {
|
||||
if (cs->debug & L1_DEB_WARN)
|
||||
debugl1(cs, "empty_fifo hfcpci paket inv. len %d or crc %d", rcnt, df->data[zp->z1]);
|
||||
debugl1(cs, "empty_fifo hfcpci packet inv. len %d or crc %d", rcnt, df->data[zp->z1]);
|
||||
#ifdef ERROR_STATISTIC
|
||||
cs->err_rx++;
|
||||
#endif
|
||||
|
@ -270,7 +270,7 @@ read_fifo(struct IsdnCardState *cs, u_char fifo, int trans_max)
|
||||
|
||||
if ((count > fifo_size) || (count < 4)) {
|
||||
if (cs->debug & L1_DEB_WARN)
|
||||
debugl1(cs, "hfcsx_read_fifo %d paket inv. len %d ", fifo , count);
|
||||
debugl1(cs, "hfcsx_read_fifo %d packet inv. len %d ", fifo , count);
|
||||
while (count) {
|
||||
count--; /* empty fifo */
|
||||
Read_hfc(cs, HFCSX_FIF_DRD);
|
||||
|
@ -277,7 +277,6 @@ l1oip_socket_send(struct l1oip *hc, u8 localcodec, u8 channel, u32 chanmask,
|
||||
u16 timebase, u8 *buf, int len)
|
||||
{
|
||||
u8 *p;
|
||||
int multi = 0;
|
||||
u8 frame[len + 32];
|
||||
struct socket *socket = NULL;
|
||||
|
||||
@ -317,9 +316,7 @@ l1oip_socket_send(struct l1oip *hc, u8 localcodec, u8 channel, u32 chanmask,
|
||||
*p++ = hc->id >> 8;
|
||||
*p++ = hc->id;
|
||||
}
|
||||
*p++ = (multi == 1) ? 0x80 : 0x00 + channel; /* m-flag, channel */
|
||||
if (multi == 1)
|
||||
*p++ = len; /* length */
|
||||
*p++ = 0x00 + channel; /* m-flag, channel */
|
||||
*p++ = timebase >> 8; /* time base */
|
||||
*p++ = timebase;
|
||||
|
||||
|
@ -250,7 +250,7 @@ tei_debug(struct FsmInst *fi, char *fmt, ...)
|
||||
static int
|
||||
get_free_id(struct manager *mgr)
|
||||
{
|
||||
u64 ids = 0;
|
||||
DECLARE_BITMAP(ids, 64) = { [0 ... BITS_TO_LONGS(64) - 1] = 0 };
|
||||
int i;
|
||||
struct layer2 *l2;
|
||||
|
||||
@ -261,11 +261,11 @@ get_free_id(struct manager *mgr)
|
||||
__func__);
|
||||
return -EBUSY;
|
||||
}
|
||||
test_and_set_bit(l2->ch.nr, (u_long *)&ids);
|
||||
__set_bit(l2->ch.nr, ids);
|
||||
}
|
||||
for (i = 1; i < 64; i++)
|
||||
if (!test_bit(i, (u_long *)&ids))
|
||||
return i;
|
||||
i = find_next_zero_bit(ids, 64, 1);
|
||||
if (i < 64)
|
||||
return i;
|
||||
printk(KERN_WARNING "%s: more as 63 layer2 for one device\n",
|
||||
__func__);
|
||||
return -EBUSY;
|
||||
@ -274,7 +274,7 @@ get_free_id(struct manager *mgr)
|
||||
static int
|
||||
get_free_tei(struct manager *mgr)
|
||||
{
|
||||
u64 ids = 0;
|
||||
DECLARE_BITMAP(ids, 64) = { [0 ... BITS_TO_LONGS(64) - 1] = 0 };
|
||||
int i;
|
||||
struct layer2 *l2;
|
||||
|
||||
@ -288,11 +288,11 @@ get_free_tei(struct manager *mgr)
|
||||
continue;
|
||||
i -= 64;
|
||||
|
||||
test_and_set_bit(i, (u_long *)&ids);
|
||||
__set_bit(i, ids);
|
||||
}
|
||||
for (i = 0; i < 64; i++)
|
||||
if (!test_bit(i, (u_long *)&ids))
|
||||
return i + 64;
|
||||
i = find_first_zero_bit(ids, 64);
|
||||
if (i < 64)
|
||||
return i + 64;
|
||||
printk(KERN_WARNING "%s: more as 63 dynamic tei for one device\n",
|
||||
__func__);
|
||||
return -1;
|
||||
|
@ -508,7 +508,7 @@ pcbit_irq_handler(int interrupt, void *devptr)
|
||||
return IRQ_NONE;
|
||||
}
|
||||
if (dev->interrupt) {
|
||||
printk(KERN_DEBUG "pcbit: reentering interrupt hander\n");
|
||||
printk(KERN_DEBUG "pcbit: reentering interrupt handler\n");
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
dev->interrupt = 1;
|
||||
|
@ -61,7 +61,7 @@ module_param(clockp, int, 0);
|
||||
module_param(clockm, int, 0);
|
||||
MODULE_LICENSE("GPL");
|
||||
|
||||
static int __devinit com20020pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
|
||||
static int com20020pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
|
||||
{
|
||||
struct net_device *dev;
|
||||
struct arcnet_local *lp;
|
||||
@ -135,7 +135,7 @@ out_dev:
|
||||
return err;
|
||||
}
|
||||
|
||||
static void __devexit com20020pci_remove(struct pci_dev *pdev)
|
||||
static void com20020pci_remove(struct pci_dev *pdev)
|
||||
{
|
||||
struct net_device *dev = pci_get_drvdata(pdev);
|
||||
unregister_netdev(dev);
|
||||
@ -178,7 +178,7 @@ static struct pci_driver com20020pci_driver = {
|
||||
.name = "com20020",
|
||||
.id_table = com20020pci_id_table,
|
||||
.probe = com20020pci_probe,
|
||||
.remove = __devexit_p(com20020pci_remove),
|
||||
.remove = com20020pci_remove,
|
||||
};
|
||||
|
||||
static int __init com20020pci_init(void)
|
||||
|
@ -84,6 +84,10 @@ static inline struct arp_pkt *arp_pkt(const struct sk_buff *skb)
|
||||
|
||||
/* Forward declaration */
|
||||
static void alb_send_learning_packets(struct slave *slave, u8 mac_addr[]);
|
||||
static void rlb_purge_src_ip(struct bonding *bond, struct arp_pkt *arp);
|
||||
static void rlb_src_unlink(struct bonding *bond, u32 index);
|
||||
static void rlb_src_link(struct bonding *bond, u32 ip_src_hash,
|
||||
u32 ip_dst_hash);
|
||||
|
||||
static inline u8 _simple_hash(const u8 *hash_start, int hash_size)
|
||||
{
|
||||
@ -354,6 +358,18 @@ static int rlb_arp_recv(const struct sk_buff *skb, struct bonding *bond,
|
||||
if (!arp)
|
||||
goto out;
|
||||
|
||||
/* We received an ARP from arp->ip_src.
|
||||
* We might have used this IP address previously (on the bonding host
|
||||
* itself or on a system that is bridged together with the bond).
|
||||
* However, if arp->mac_src is different than what is stored in
|
||||
* rx_hashtbl, some other host is now using the IP and we must prevent
|
||||
* sending out client updates with this IP address and the old MAC
|
||||
* address.
|
||||
* Clean up all hash table entries that have this address as ip_src but
|
||||
* have a different mac_src.
|
||||
*/
|
||||
rlb_purge_src_ip(bond, arp);
|
||||
|
||||
if (arp->op_code == htons(ARPOP_REPLY)) {
|
||||
/* update rx hash table for this ARP */
|
||||
rlb_update_entry_from_arp(bond, arp);
|
||||
@ -432,9 +448,9 @@ static void rlb_clear_slave(struct bonding *bond, struct slave *slave)
|
||||
_lock_rx_hashtbl_bh(bond);
|
||||
|
||||
rx_hash_table = bond_info->rx_hashtbl;
|
||||
index = bond_info->rx_hashtbl_head;
|
||||
index = bond_info->rx_hashtbl_used_head;
|
||||
for (; index != RLB_NULL_INDEX; index = next_index) {
|
||||
next_index = rx_hash_table[index].next;
|
||||
next_index = rx_hash_table[index].used_next;
|
||||
if (rx_hash_table[index].slave == slave) {
|
||||
struct slave *assigned_slave = rlb_next_rx_slave(bond);
|
||||
|
||||
@ -519,8 +535,9 @@ static void rlb_update_rx_clients(struct bonding *bond)
|
||||
|
||||
_lock_rx_hashtbl_bh(bond);
|
||||
|
||||
hash_index = bond_info->rx_hashtbl_head;
|
||||
for (; hash_index != RLB_NULL_INDEX; hash_index = client_info->next) {
|
||||
hash_index = bond_info->rx_hashtbl_used_head;
|
||||
for (; hash_index != RLB_NULL_INDEX;
|
||||
hash_index = client_info->used_next) {
|
||||
client_info = &(bond_info->rx_hashtbl[hash_index]);
|
||||
if (client_info->ntt) {
|
||||
rlb_update_client(client_info);
|
||||
@ -548,8 +565,9 @@ static void rlb_req_update_slave_clients(struct bonding *bond, struct slave *sla
|
||||
|
||||
_lock_rx_hashtbl_bh(bond);
|
||||
|
||||
hash_index = bond_info->rx_hashtbl_head;
|
||||
for (; hash_index != RLB_NULL_INDEX; hash_index = client_info->next) {
|
||||
hash_index = bond_info->rx_hashtbl_used_head;
|
||||
for (; hash_index != RLB_NULL_INDEX;
|
||||
hash_index = client_info->used_next) {
|
||||
client_info = &(bond_info->rx_hashtbl[hash_index]);
|
||||
|
||||
if ((client_info->slave == slave) &&
|
||||
@ -578,8 +596,9 @@ static void rlb_req_update_subnet_clients(struct bonding *bond, __be32 src_ip)
|
||||
|
||||
_lock_rx_hashtbl(bond);
|
||||
|
||||
hash_index = bond_info->rx_hashtbl_head;
|
||||
for (; hash_index != RLB_NULL_INDEX; hash_index = client_info->next) {
|
||||
hash_index = bond_info->rx_hashtbl_used_head;
|
||||
for (; hash_index != RLB_NULL_INDEX;
|
||||
hash_index = client_info->used_next) {
|
||||
client_info = &(bond_info->rx_hashtbl[hash_index]);
|
||||
|
||||
if (!client_info->slave) {
|
||||
@ -625,6 +644,7 @@ static struct slave *rlb_choose_channel(struct sk_buff *skb, struct bonding *bon
|
||||
/* update mac address from arp */
|
||||
memcpy(client_info->mac_dst, arp->mac_dst, ETH_ALEN);
|
||||
}
|
||||
memcpy(client_info->mac_src, arp->mac_src, ETH_ALEN);
|
||||
|
||||
assigned_slave = client_info->slave;
|
||||
if (assigned_slave) {
|
||||
@ -647,6 +667,17 @@ static struct slave *rlb_choose_channel(struct sk_buff *skb, struct bonding *bon
|
||||
assigned_slave = rlb_next_rx_slave(bond);
|
||||
|
||||
if (assigned_slave) {
|
||||
if (!(client_info->assigned &&
|
||||
client_info->ip_src == arp->ip_src)) {
|
||||
/* ip_src is going to be updated,
|
||||
* fix the src hash list
|
||||
*/
|
||||
u32 hash_src = _simple_hash((u8 *)&arp->ip_src,
|
||||
sizeof(arp->ip_src));
|
||||
rlb_src_unlink(bond, hash_index);
|
||||
rlb_src_link(bond, hash_src, hash_index);
|
||||
}
|
||||
|
||||
client_info->ip_src = arp->ip_src;
|
||||
client_info->ip_dst = arp->ip_dst;
|
||||
/* arp->mac_dst is broadcast for arp reqeusts.
|
||||
@ -654,6 +685,7 @@ static struct slave *rlb_choose_channel(struct sk_buff *skb, struct bonding *bon
|
||||
* upon receiving an arp reply.
|
||||
*/
|
||||
memcpy(client_info->mac_dst, arp->mac_dst, ETH_ALEN);
|
||||
memcpy(client_info->mac_src, arp->mac_src, ETH_ALEN);
|
||||
client_info->slave = assigned_slave;
|
||||
|
||||
if (!ether_addr_equal_64bits(client_info->mac_dst, mac_bcast)) {
|
||||
@ -669,11 +701,11 @@ static struct slave *rlb_choose_channel(struct sk_buff *skb, struct bonding *bon
|
||||
}
|
||||
|
||||
if (!client_info->assigned) {
|
||||
u32 prev_tbl_head = bond_info->rx_hashtbl_head;
|
||||
bond_info->rx_hashtbl_head = hash_index;
|
||||
client_info->next = prev_tbl_head;
|
||||
u32 prev_tbl_head = bond_info->rx_hashtbl_used_head;
|
||||
bond_info->rx_hashtbl_used_head = hash_index;
|
||||
client_info->used_next = prev_tbl_head;
|
||||
if (prev_tbl_head != RLB_NULL_INDEX) {
|
||||
bond_info->rx_hashtbl[prev_tbl_head].prev =
|
||||
bond_info->rx_hashtbl[prev_tbl_head].used_prev =
|
||||
hash_index;
|
||||
}
|
||||
client_info->assigned = 1;
|
||||
@ -694,6 +726,12 @@ static struct slave *rlb_arp_xmit(struct sk_buff *skb, struct bonding *bond)
|
||||
struct arp_pkt *arp = arp_pkt(skb);
|
||||
struct slave *tx_slave = NULL;
|
||||
|
||||
/* Don't modify or load balance ARPs that do not originate locally
|
||||
* (e.g.,arrive via a bridge).
|
||||
*/
|
||||
if (!bond_slave_has_mac(bond, arp->mac_src))
|
||||
return NULL;
|
||||
|
||||
if (arp->op_code == htons(ARPOP_REPLY)) {
|
||||
/* the arp must be sent on the selected
|
||||
* rx channel
|
||||
@ -740,8 +778,9 @@ static void rlb_rebalance(struct bonding *bond)
|
||||
_lock_rx_hashtbl_bh(bond);
|
||||
|
||||
ntt = 0;
|
||||
hash_index = bond_info->rx_hashtbl_head;
|
||||
for (; hash_index != RLB_NULL_INDEX; hash_index = client_info->next) {
|
||||
hash_index = bond_info->rx_hashtbl_used_head;
|
||||
for (; hash_index != RLB_NULL_INDEX;
|
||||
hash_index = client_info->used_next) {
|
||||
client_info = &(bond_info->rx_hashtbl[hash_index]);
|
||||
assigned_slave = rlb_next_rx_slave(bond);
|
||||
if (assigned_slave && (client_info->slave != assigned_slave)) {
|
||||
@ -759,11 +798,113 @@ static void rlb_rebalance(struct bonding *bond)
|
||||
}
|
||||
|
||||
/* Caller must hold rx_hashtbl lock */
|
||||
static void rlb_init_table_entry_dst(struct rlb_client_info *entry)
|
||||
{
|
||||
entry->used_next = RLB_NULL_INDEX;
|
||||
entry->used_prev = RLB_NULL_INDEX;
|
||||
entry->assigned = 0;
|
||||
entry->slave = NULL;
|
||||
entry->tag = 0;
|
||||
}
|
||||
static void rlb_init_table_entry_src(struct rlb_client_info *entry)
|
||||
{
|
||||
entry->src_first = RLB_NULL_INDEX;
|
||||
entry->src_prev = RLB_NULL_INDEX;
|
||||
entry->src_next = RLB_NULL_INDEX;
|
||||
}
|
||||
|
||||
static void rlb_init_table_entry(struct rlb_client_info *entry)
|
||||
{
|
||||
memset(entry, 0, sizeof(struct rlb_client_info));
|
||||
entry->next = RLB_NULL_INDEX;
|
||||
entry->prev = RLB_NULL_INDEX;
|
||||
rlb_init_table_entry_dst(entry);
|
||||
rlb_init_table_entry_src(entry);
|
||||
}
|
||||
|
||||
static void rlb_delete_table_entry_dst(struct bonding *bond, u32 index)
|
||||
{
|
||||
struct alb_bond_info *bond_info = &(BOND_ALB_INFO(bond));
|
||||
u32 next_index = bond_info->rx_hashtbl[index].used_next;
|
||||
u32 prev_index = bond_info->rx_hashtbl[index].used_prev;
|
||||
|
||||
if (index == bond_info->rx_hashtbl_used_head)
|
||||
bond_info->rx_hashtbl_used_head = next_index;
|
||||
if (prev_index != RLB_NULL_INDEX)
|
||||
bond_info->rx_hashtbl[prev_index].used_next = next_index;
|
||||
if (next_index != RLB_NULL_INDEX)
|
||||
bond_info->rx_hashtbl[next_index].used_prev = prev_index;
|
||||
}
|
||||
|
||||
/* unlink a rlb hash table entry from the src list */
|
||||
static void rlb_src_unlink(struct bonding *bond, u32 index)
|
||||
{
|
||||
struct alb_bond_info *bond_info = &(BOND_ALB_INFO(bond));
|
||||
u32 next_index = bond_info->rx_hashtbl[index].src_next;
|
||||
u32 prev_index = bond_info->rx_hashtbl[index].src_prev;
|
||||
|
||||
bond_info->rx_hashtbl[index].src_next = RLB_NULL_INDEX;
|
||||
bond_info->rx_hashtbl[index].src_prev = RLB_NULL_INDEX;
|
||||
|
||||
if (next_index != RLB_NULL_INDEX)
|
||||
bond_info->rx_hashtbl[next_index].src_prev = prev_index;
|
||||
|
||||
if (prev_index == RLB_NULL_INDEX)
|
||||
return;
|
||||
|
||||
/* is prev_index pointing to the head of this list? */
|
||||
if (bond_info->rx_hashtbl[prev_index].src_first == index)
|
||||
bond_info->rx_hashtbl[prev_index].src_first = next_index;
|
||||
else
|
||||
bond_info->rx_hashtbl[prev_index].src_next = next_index;
|
||||
|
||||
}
|
||||
|
||||
static void rlb_delete_table_entry(struct bonding *bond, u32 index)
|
||||
{
|
||||
struct alb_bond_info *bond_info = &(BOND_ALB_INFO(bond));
|
||||
struct rlb_client_info *entry = &(bond_info->rx_hashtbl[index]);
|
||||
|
||||
rlb_delete_table_entry_dst(bond, index);
|
||||
rlb_init_table_entry_dst(entry);
|
||||
|
||||
rlb_src_unlink(bond, index);
|
||||
}
|
||||
|
||||
/* add the rx_hashtbl[ip_dst_hash] entry to the list
|
||||
* of entries with identical ip_src_hash
|
||||
*/
|
||||
static void rlb_src_link(struct bonding *bond, u32 ip_src_hash, u32 ip_dst_hash)
|
||||
{
|
||||
struct alb_bond_info *bond_info = &(BOND_ALB_INFO(bond));
|
||||
u32 next;
|
||||
|
||||
bond_info->rx_hashtbl[ip_dst_hash].src_prev = ip_src_hash;
|
||||
next = bond_info->rx_hashtbl[ip_src_hash].src_first;
|
||||
bond_info->rx_hashtbl[ip_dst_hash].src_next = next;
|
||||
if (next != RLB_NULL_INDEX)
|
||||
bond_info->rx_hashtbl[next].src_prev = ip_dst_hash;
|
||||
bond_info->rx_hashtbl[ip_src_hash].src_first = ip_dst_hash;
|
||||
}
|
||||
|
||||
/* deletes all rx_hashtbl entries with arp->ip_src if their mac_src does
|
||||
* not match arp->mac_src */
|
||||
static void rlb_purge_src_ip(struct bonding *bond, struct arp_pkt *arp)
|
||||
{
|
||||
struct alb_bond_info *bond_info = &(BOND_ALB_INFO(bond));
|
||||
u32 ip_src_hash = _simple_hash((u8*)&(arp->ip_src), sizeof(arp->ip_src));
|
||||
u32 index;
|
||||
|
||||
_lock_rx_hashtbl_bh(bond);
|
||||
|
||||
index = bond_info->rx_hashtbl[ip_src_hash].src_first;
|
||||
while (index != RLB_NULL_INDEX) {
|
||||
struct rlb_client_info *entry = &(bond_info->rx_hashtbl[index]);
|
||||
u32 next_index = entry->src_next;
|
||||
if (entry->ip_src == arp->ip_src &&
|
||||
!ether_addr_equal_64bits(arp->mac_src, entry->mac_src))
|
||||
rlb_delete_table_entry(bond, index);
|
||||
index = next_index;
|
||||
}
|
||||
_unlock_rx_hashtbl_bh(bond);
|
||||
}
|
||||
|
||||
static int rlb_initialize(struct bonding *bond)
|
||||
@ -781,7 +922,7 @@ static int rlb_initialize(struct bonding *bond)
|
||||
|
||||
bond_info->rx_hashtbl = new_hashtbl;
|
||||
|
||||
bond_info->rx_hashtbl_head = RLB_NULL_INDEX;
|
||||
bond_info->rx_hashtbl_used_head = RLB_NULL_INDEX;
|
||||
|
||||
for (i = 0; i < RLB_HASH_TABLE_SIZE; i++) {
|
||||
rlb_init_table_entry(bond_info->rx_hashtbl + i);
|
||||
@ -803,7 +944,7 @@ static void rlb_deinitialize(struct bonding *bond)
|
||||
|
||||
kfree(bond_info->rx_hashtbl);
|
||||
bond_info->rx_hashtbl = NULL;
|
||||
bond_info->rx_hashtbl_head = RLB_NULL_INDEX;
|
||||
bond_info->rx_hashtbl_used_head = RLB_NULL_INDEX;
|
||||
|
||||
_unlock_rx_hashtbl_bh(bond);
|
||||
}
|
||||
@ -815,25 +956,13 @@ static void rlb_clear_vlan(struct bonding *bond, unsigned short vlan_id)
|
||||
|
||||
_lock_rx_hashtbl_bh(bond);
|
||||
|
||||
curr_index = bond_info->rx_hashtbl_head;
|
||||
curr_index = bond_info->rx_hashtbl_used_head;
|
||||
while (curr_index != RLB_NULL_INDEX) {
|
||||
struct rlb_client_info *curr = &(bond_info->rx_hashtbl[curr_index]);
|
||||
u32 next_index = bond_info->rx_hashtbl[curr_index].next;
|
||||
u32 prev_index = bond_info->rx_hashtbl[curr_index].prev;
|
||||
u32 next_index = bond_info->rx_hashtbl[curr_index].used_next;
|
||||
|
||||
if (curr->tag && (curr->vlan_id == vlan_id)) {
|
||||
if (curr_index == bond_info->rx_hashtbl_head) {
|
||||
bond_info->rx_hashtbl_head = next_index;
|
||||
}
|
||||
if (prev_index != RLB_NULL_INDEX) {
|
||||
bond_info->rx_hashtbl[prev_index].next = next_index;
|
||||
}
|
||||
if (next_index != RLB_NULL_INDEX) {
|
||||
bond_info->rx_hashtbl[next_index].prev = prev_index;
|
||||
}
|
||||
|
||||
rlb_init_table_entry(curr);
|
||||
}
|
||||
if (curr->tag && (curr->vlan_id == vlan_id))
|
||||
rlb_delete_table_entry(bond, curr_index);
|
||||
|
||||
curr_index = next_index;
|
||||
}
|
||||
|
@ -94,15 +94,35 @@ struct tlb_client_info {
|
||||
|
||||
/* -------------------------------------------------------------------------
|
||||
* struct rlb_client_info contains all info related to a specific rx client
|
||||
* connection. This is the Clients Hash Table entry struct
|
||||
* connection. This is the Clients Hash Table entry struct.
|
||||
* Note that this is not a proper hash table; if a new client's IP address
|
||||
* hash collides with an existing client entry, the old entry is replaced.
|
||||
*
|
||||
* There is a linked list (linked by the used_next and used_prev members)
|
||||
* linking all the used entries of the hash table. This allows updating
|
||||
* all the clients without walking over all the unused elements of the table.
|
||||
*
|
||||
* There are also linked lists of entries with identical hash(ip_src). These
|
||||
* allow cleaning up the table from ip_src<->mac_src associations that have
|
||||
* become outdated and would cause sending out invalid ARP updates to the
|
||||
* network. These are linked by the (src_next and src_prev members).
|
||||
* -------------------------------------------------------------------------
|
||||
*/
|
||||
struct rlb_client_info {
|
||||
__be32 ip_src; /* the server IP address */
|
||||
__be32 ip_dst; /* the client IP address */
|
||||
u8 mac_src[ETH_ALEN]; /* the server MAC address */
|
||||
u8 mac_dst[ETH_ALEN]; /* the client MAC address */
|
||||
u32 next; /* The next Hash table entry index */
|
||||
u32 prev; /* The previous Hash table entry index */
|
||||
|
||||
/* list of used hash table entries, starting at rx_hashtbl_used_head */
|
||||
u32 used_next;
|
||||
u32 used_prev;
|
||||
|
||||
/* ip_src based hashing */
|
||||
u32 src_next; /* next entry with same hash(ip_src) */
|
||||
u32 src_prev; /* prev entry with same hash(ip_src) */
|
||||
u32 src_first; /* first entry with hash(ip_src) == this entry's index */
|
||||
|
||||
u8 assigned; /* checking whether this entry is assigned */
|
||||
u8 ntt; /* flag - need to transmit client info */
|
||||
struct slave *slave; /* the slave assigned to this client */
|
||||
@ -131,7 +151,7 @@ struct alb_bond_info {
|
||||
int rlb_enabled;
|
||||
struct rlb_client_info *rx_hashtbl; /* Receive hash table */
|
||||
spinlock_t rx_hashtbl_lock;
|
||||
u32 rx_hashtbl_head;
|
||||
u32 rx_hashtbl_used_head;
|
||||
u8 rx_ntt; /* flag - need to transmit
|
||||
* to all rx clients
|
||||
*/
|
||||
|
@ -31,8 +31,9 @@ static int bond_debug_rlb_hash_show(struct seq_file *m, void *v)
|
||||
|
||||
spin_lock_bh(&(BOND_ALB_INFO(bond).rx_hashtbl_lock));
|
||||
|
||||
hash_index = bond_info->rx_hashtbl_head;
|
||||
for (; hash_index != RLB_NULL_INDEX; hash_index = client_info->next) {
|
||||
hash_index = bond_info->rx_hashtbl_used_head;
|
||||
for (; hash_index != RLB_NULL_INDEX;
|
||||
hash_index = client_info->used_next) {
|
||||
client_info = &(bond_info->rx_hashtbl[hash_index]);
|
||||
seq_printf(m, "%-15pI4 %-15pI4 %-17pM %s\n",
|
||||
&client_info->ip_src,
|
||||
|
@ -615,15 +615,9 @@ static int bond_check_dev_link(struct bonding *bond,
|
||||
return netif_carrier_ok(slave_dev) ? BMSR_LSTATUS : 0;
|
||||
|
||||
/* Try to get link status using Ethtool first. */
|
||||
if (slave_dev->ethtool_ops) {
|
||||
if (slave_dev->ethtool_ops->get_link) {
|
||||
u32 link;
|
||||
|
||||
link = slave_dev->ethtool_ops->get_link(slave_dev);
|
||||
|
||||
return link ? BMSR_LSTATUS : 0;
|
||||
}
|
||||
}
|
||||
if (slave_dev->ethtool_ops->get_link)
|
||||
return slave_dev->ethtool_ops->get_link(slave_dev) ?
|
||||
BMSR_LSTATUS : 0;
|
||||
|
||||
/* Ethtool can't be used, fallback to MII ioctls. */
|
||||
ioctl = slave_ops->ndo_do_ioctl;
|
||||
@ -1510,8 +1504,9 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev)
|
||||
int link_reporting;
|
||||
int res = 0;
|
||||
|
||||
if (!bond->params.use_carrier && slave_dev->ethtool_ops == NULL &&
|
||||
slave_ops->ndo_do_ioctl == NULL) {
|
||||
if (!bond->params.use_carrier &&
|
||||
slave_dev->ethtool_ops->get_link == NULL &&
|
||||
slave_ops->ndo_do_ioctl == NULL) {
|
||||
pr_warning("%s: Warning: no link monitoring support for %s\n",
|
||||
bond_dev->name, slave_dev->name);
|
||||
}
|
||||
@ -1838,7 +1833,7 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev)
|
||||
* anyway (it holds no special properties of the bond device),
|
||||
* so we can change it without calling change_active_interface()
|
||||
*/
|
||||
if (!bond->curr_active_slave)
|
||||
if (!bond->curr_active_slave && new_slave->link == BOND_LINK_UP)
|
||||
bond->curr_active_slave = new_slave;
|
||||
|
||||
break;
|
||||
|
@ -22,6 +22,7 @@
|
||||
#include <linux/in6.h>
|
||||
#include <linux/netpoll.h>
|
||||
#include <linux/inetdevice.h>
|
||||
#include <linux/etherdevice.h>
|
||||
#include "bond_3ad.h"
|
||||
#include "bond_alb.h"
|
||||
|
||||
@ -450,6 +451,18 @@ static inline void bond_destroy_proc_dir(struct bond_net *bn)
|
||||
}
|
||||
#endif
|
||||
|
||||
static inline struct slave *bond_slave_has_mac(struct bonding *bond,
|
||||
const u8 *mac)
|
||||
{
|
||||
int i = 0;
|
||||
struct slave *tmp;
|
||||
|
||||
bond_for_each_slave(bond, tmp, i)
|
||||
if (ether_addr_equal_64bits(mac, tmp->dev->dev_addr))
|
||||
return tmp;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* exported from bond_main.c */
|
||||
extern int bond_net_id;
|
||||
|
@ -110,6 +110,15 @@ config PCH_CAN
|
||||
is an IOH for x86 embedded processor (Intel Atom E6xx series).
|
||||
This driver can access CAN bus.
|
||||
|
||||
config CAN_GRCAN
|
||||
tristate "Aeroflex Gaisler GRCAN and GRHCAN CAN devices"
|
||||
depends on CAN_DEV && OF
|
||||
---help---
|
||||
Say Y here if you want to use Aeroflex Gaisler GRCAN or GRHCAN.
|
||||
Note that the driver supports little endian, even though little
|
||||
endian syntheses of the cores would need some modifications on
|
||||
the hardware level to work.
|
||||
|
||||
source "drivers/net/can/mscan/Kconfig"
|
||||
|
||||
source "drivers/net/can/sja1000/Kconfig"
|
||||
|
@ -22,5 +22,6 @@ obj-$(CONFIG_CAN_BFIN) += bfin_can.o
|
||||
obj-$(CONFIG_CAN_JANZ_ICAN3) += janz-ican3.o
|
||||
obj-$(CONFIG_CAN_FLEXCAN) += flexcan.o
|
||||
obj-$(CONFIG_PCH_CAN) += pch_can.o
|
||||
obj-$(CONFIG_CAN_GRCAN) += grcan.o
|
||||
|
||||
ccflags-$(CONFIG_CAN_DEBUG_DEVICES) := -DDEBUG
|
||||
|
@ -154,7 +154,7 @@ struct at91_priv {
|
||||
canid_t mb0_id;
|
||||
};
|
||||
|
||||
static const struct at91_devtype_data at91_devtype_data[] __devinitconst = {
|
||||
static const struct at91_devtype_data at91_devtype_data[] = {
|
||||
[AT91_DEVTYPE_SAM9263] = {
|
||||
.rx_first = 1,
|
||||
.rx_split = 8,
|
||||
@ -1241,7 +1241,7 @@ static struct attribute_group at91_sysfs_attr_group = {
|
||||
.attrs = at91_sysfs_attrs,
|
||||
};
|
||||
|
||||
static int __devinit at91_can_probe(struct platform_device *pdev)
|
||||
static int at91_can_probe(struct platform_device *pdev)
|
||||
{
|
||||
const struct at91_devtype_data *devtype_data;
|
||||
enum at91_devtype devtype;
|
||||
@ -1338,7 +1338,7 @@ static int __devinit at91_can_probe(struct platform_device *pdev)
|
||||
return err;
|
||||
}
|
||||
|
||||
static int __devexit at91_can_remove(struct platform_device *pdev)
|
||||
static int at91_can_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct net_device *dev = platform_get_drvdata(pdev);
|
||||
struct at91_priv *priv = netdev_priv(dev);
|
||||
@ -1371,10 +1371,11 @@ static const struct platform_device_id at91_can_id_table[] = {
|
||||
/* sentinel */
|
||||
}
|
||||
};
|
||||
MODULE_DEVICE_TABLE(platform, at91_can_id_table);
|
||||
|
||||
static struct platform_driver at91_can_driver = {
|
||||
.probe = at91_can_probe,
|
||||
.remove = __devexit_p(at91_can_remove),
|
||||
.remove = at91_can_remove,
|
||||
.driver = {
|
||||
.name = KBUILD_MODNAME,
|
||||
.owner = THIS_MODULE,
|
||||
|
@ -531,7 +531,7 @@ static const struct net_device_ops bfin_can_netdev_ops = {
|
||||
.ndo_start_xmit = bfin_can_start_xmit,
|
||||
};
|
||||
|
||||
static int __devinit bfin_can_probe(struct platform_device *pdev)
|
||||
static int bfin_can_probe(struct platform_device *pdev)
|
||||
{
|
||||
int err;
|
||||
struct net_device *dev;
|
||||
@ -611,7 +611,7 @@ exit:
|
||||
return err;
|
||||
}
|
||||
|
||||
static int __devexit bfin_can_remove(struct platform_device *pdev)
|
||||
static int bfin_can_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct net_device *dev = dev_get_drvdata(&pdev->dev);
|
||||
struct bfin_can_priv *priv = netdev_priv(dev);
|
||||
@ -677,7 +677,7 @@ static int bfin_can_resume(struct platform_device *pdev)
|
||||
|
||||
static struct platform_driver bfin_can_driver = {
|
||||
.probe = bfin_can_probe,
|
||||
.remove = __devexit_p(bfin_can_remove),
|
||||
.remove = bfin_can_remove,
|
||||
.suspend = bfin_can_suspend,
|
||||
.resume = bfin_can_resume,
|
||||
.driver = {
|
||||
@ -691,3 +691,4 @@ module_platform_driver(bfin_can_driver);
|
||||
MODULE_AUTHOR("Barry Song <21cnbao@gmail.com>");
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_DESCRIPTION("Blackfin on-chip CAN netdevice driver");
|
||||
MODULE_ALIAS("platform:" DRV_NAME);
|
||||
|
@ -233,6 +233,12 @@ static inline void c_can_pm_runtime_put_sync(const struct c_can_priv *priv)
|
||||
pm_runtime_put_sync(priv->device);
|
||||
}
|
||||
|
||||
static inline void c_can_reset_ram(const struct c_can_priv *priv, bool enable)
|
||||
{
|
||||
if (priv->raminit)
|
||||
priv->raminit(priv, enable);
|
||||
}
|
||||
|
||||
static inline int get_tx_next_msg_obj(const struct c_can_priv *priv)
|
||||
{
|
||||
return (priv->tx_next & C_CAN_NEXT_MSG_OBJ_MASK) +
|
||||
@ -1090,6 +1096,7 @@ static int c_can_open(struct net_device *dev)
|
||||
struct c_can_priv *priv = netdev_priv(dev);
|
||||
|
||||
c_can_pm_runtime_get_sync(priv);
|
||||
c_can_reset_ram(priv, true);
|
||||
|
||||
/* open the can device */
|
||||
err = open_candev(dev);
|
||||
@ -1118,6 +1125,7 @@ static int c_can_open(struct net_device *dev)
|
||||
exit_irq_fail:
|
||||
close_candev(dev);
|
||||
exit_open_fail:
|
||||
c_can_reset_ram(priv, false);
|
||||
c_can_pm_runtime_put_sync(priv);
|
||||
return err;
|
||||
}
|
||||
@ -1131,6 +1139,8 @@ static int c_can_close(struct net_device *dev)
|
||||
c_can_stop(dev);
|
||||
free_irq(dev->irq, dev);
|
||||
close_candev(dev);
|
||||
|
||||
c_can_reset_ram(priv, false);
|
||||
c_can_pm_runtime_put_sync(priv);
|
||||
|
||||
return 0;
|
||||
@ -1188,6 +1198,7 @@ int c_can_power_down(struct net_device *dev)
|
||||
|
||||
c_can_stop(dev);
|
||||
|
||||
c_can_reset_ram(priv, false);
|
||||
c_can_pm_runtime_put_sync(priv);
|
||||
|
||||
return 0;
|
||||
@ -1206,6 +1217,7 @@ int c_can_power_up(struct net_device *dev)
|
||||
WARN_ON(priv->type != BOSCH_D_CAN);
|
||||
|
||||
c_can_pm_runtime_get_sync(priv);
|
||||
c_can_reset_ram(priv, true);
|
||||
|
||||
/* Clear PDR and INIT bits */
|
||||
val = priv->read_reg(priv, C_CAN_CTRL_EX_REG);
|
||||
|
@ -169,6 +169,9 @@ struct c_can_priv {
|
||||
void *priv; /* for board-specific data */
|
||||
u16 irqstatus;
|
||||
enum c_can_dev_id type;
|
||||
u32 __iomem *raminit_ctrlreg;
|
||||
unsigned int instance;
|
||||
void (*raminit) (const struct c_can_priv *priv, bool enable);
|
||||
};
|
||||
|
||||
struct net_device *alloc_c_can_dev(void);
|
||||
|
@ -63,8 +63,8 @@ static void c_can_pci_write_reg_aligned_to_32bit(struct c_can_priv *priv,
|
||||
writew(val, priv->base + 2 * priv->regs[index]);
|
||||
}
|
||||
|
||||
static int __devinit c_can_pci_probe(struct pci_dev *pdev,
|
||||
const struct pci_device_id *ent)
|
||||
static int c_can_pci_probe(struct pci_dev *pdev,
|
||||
const struct pci_device_id *ent)
|
||||
{
|
||||
struct c_can_pci_data *c_can_pci_data = (void *)ent->driver_data;
|
||||
struct c_can_priv *priv;
|
||||
@ -174,7 +174,7 @@ out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void __devexit c_can_pci_remove(struct pci_dev *pdev)
|
||||
static void c_can_pci_remove(struct pci_dev *pdev)
|
||||
{
|
||||
struct net_device *dev = pci_get_drvdata(pdev);
|
||||
struct c_can_priv *priv = netdev_priv(dev);
|
||||
@ -210,7 +210,7 @@ static struct pci_driver c_can_pci_driver = {
|
||||
.name = KBUILD_MODNAME,
|
||||
.id_table = c_can_pci_tbl,
|
||||
.probe = c_can_pci_probe,
|
||||
.remove = __devexit_p(c_can_pci_remove),
|
||||
.remove = c_can_pci_remove,
|
||||
};
|
||||
|
||||
module_pci_driver(c_can_pci_driver);
|
||||
|
@ -38,6 +38,8 @@
|
||||
|
||||
#include "c_can.h"
|
||||
|
||||
#define CAN_RAMINIT_START_MASK(i) (1 << (i))
|
||||
|
||||
/*
|
||||
* 16-bit c_can registers can be arranged differently in the memory
|
||||
* architecture of different implementations. For example: 16-bit
|
||||
@ -68,6 +70,18 @@ static void c_can_plat_write_reg_aligned_to_32bit(struct c_can_priv *priv,
|
||||
writew(val, priv->base + 2 * priv->regs[index]);
|
||||
}
|
||||
|
||||
static void c_can_hw_raminit(const struct c_can_priv *priv, bool enable)
|
||||
{
|
||||
u32 val;
|
||||
|
||||
val = readl(priv->raminit_ctrlreg);
|
||||
if (enable)
|
||||
val |= CAN_RAMINIT_START_MASK(priv->instance);
|
||||
else
|
||||
val &= ~CAN_RAMINIT_START_MASK(priv->instance);
|
||||
writel(val, priv->raminit_ctrlreg);
|
||||
}
|
||||
|
||||
static struct platform_device_id c_can_id_table[] = {
|
||||
[BOSCH_C_CAN_PLATFORM] = {
|
||||
.name = KBUILD_MODNAME,
|
||||
@ -83,14 +97,16 @@ static struct platform_device_id c_can_id_table[] = {
|
||||
}, {
|
||||
}
|
||||
};
|
||||
MODULE_DEVICE_TABLE(platform, c_can_id_table);
|
||||
|
||||
static const struct of_device_id c_can_of_table[] = {
|
||||
{ .compatible = "bosch,c_can", .data = &c_can_id_table[BOSCH_C_CAN] },
|
||||
{ .compatible = "bosch,d_can", .data = &c_can_id_table[BOSCH_D_CAN] },
|
||||
{ /* sentinel */ },
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, c_can_of_table);
|
||||
|
||||
static int __devinit c_can_plat_probe(struct platform_device *pdev)
|
||||
static int c_can_plat_probe(struct platform_device *pdev)
|
||||
{
|
||||
int ret;
|
||||
void __iomem *addr;
|
||||
@ -99,7 +115,7 @@ static int __devinit c_can_plat_probe(struct platform_device *pdev)
|
||||
const struct of_device_id *match;
|
||||
const struct platform_device_id *id;
|
||||
struct pinctrl *pinctrl;
|
||||
struct resource *mem;
|
||||
struct resource *mem, *res;
|
||||
int irq;
|
||||
struct clk *clk;
|
||||
|
||||
@ -178,6 +194,18 @@ static int __devinit c_can_plat_probe(struct platform_device *pdev)
|
||||
priv->can.ctrlmode_supported |= CAN_CTRLMODE_3_SAMPLES;
|
||||
priv->read_reg = c_can_plat_read_reg_aligned_to_16bit;
|
||||
priv->write_reg = c_can_plat_write_reg_aligned_to_16bit;
|
||||
|
||||
if (pdev->dev.of_node)
|
||||
priv->instance = of_alias_get_id(pdev->dev.of_node, "d_can");
|
||||
else
|
||||
priv->instance = pdev->id;
|
||||
|
||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
|
||||
priv->raminit_ctrlreg = devm_request_and_ioremap(&pdev->dev, res);
|
||||
if (!priv->raminit_ctrlreg || priv->instance < 0)
|
||||
dev_info(&pdev->dev, "control memory is not used for raminit\n");
|
||||
else
|
||||
priv->raminit = c_can_hw_raminit;
|
||||
break;
|
||||
default:
|
||||
ret = -EINVAL;
|
||||
@ -220,7 +248,7 @@ exit:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int __devexit c_can_plat_remove(struct platform_device *pdev)
|
||||
static int c_can_plat_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct net_device *dev = platform_get_drvdata(pdev);
|
||||
struct c_can_priv *priv = netdev_priv(dev);
|
||||
@ -306,7 +334,7 @@ static struct platform_driver c_can_plat_driver = {
|
||||
.of_match_table = of_match_ptr(c_can_of_table),
|
||||
},
|
||||
.probe = c_can_plat_probe,
|
||||
.remove = __devexit_p(c_can_plat_remove),
|
||||
.remove = c_can_plat_remove,
|
||||
.suspend = c_can_suspend,
|
||||
.resume = c_can_resume,
|
||||
.id_table = c_can_id_table,
|
||||
|
@ -75,12 +75,12 @@ MODULE_LICENSE("GPL v2");
|
||||
|
||||
static unsigned long port[MAXDEV];
|
||||
static unsigned long mem[MAXDEV];
|
||||
static int __devinitdata irq[MAXDEV];
|
||||
static int __devinitdata clk[MAXDEV];
|
||||
static u8 __devinitdata cir[MAXDEV] = {[0 ... (MAXDEV - 1)] = 0xff};
|
||||
static u8 __devinitdata cor[MAXDEV] = {[0 ... (MAXDEV - 1)] = 0xff};
|
||||
static u8 __devinitdata bcr[MAXDEV] = {[0 ... (MAXDEV - 1)] = 0xff};
|
||||
static int __devinitdata indirect[MAXDEV] = {[0 ... (MAXDEV - 1)] = -1};
|
||||
static int irq[MAXDEV];
|
||||
static int clk[MAXDEV];
|
||||
static u8 cir[MAXDEV] = {[0 ... (MAXDEV - 1)] = 0xff};
|
||||
static u8 cor[MAXDEV] = {[0 ... (MAXDEV - 1)] = 0xff};
|
||||
static u8 bcr[MAXDEV] = {[0 ... (MAXDEV - 1)] = 0xff};
|
||||
static int indirect[MAXDEV] = {[0 ... (MAXDEV - 1)] = -1};
|
||||
|
||||
module_param_array(port, ulong, NULL, S_IRUGO);
|
||||
MODULE_PARM_DESC(port, "I/O port number");
|
||||
@ -166,7 +166,7 @@ static void cc770_isa_port_write_reg_indirect(const struct cc770_priv *priv,
|
||||
spin_unlock_irqrestore(&cc770_isa_port_lock, flags);
|
||||
}
|
||||
|
||||
static int __devinit cc770_isa_probe(struct platform_device *pdev)
|
||||
static int cc770_isa_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct net_device *dev;
|
||||
struct cc770_priv *priv;
|
||||
@ -291,7 +291,7 @@ static int __devinit cc770_isa_probe(struct platform_device *pdev)
|
||||
return err;
|
||||
}
|
||||
|
||||
static int __devexit cc770_isa_remove(struct platform_device *pdev)
|
||||
static int cc770_isa_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct net_device *dev = dev_get_drvdata(&pdev->dev);
|
||||
struct cc770_priv *priv = netdev_priv(dev);
|
||||
@ -316,7 +316,7 @@ static int __devexit cc770_isa_remove(struct platform_device *pdev)
|
||||
|
||||
static struct platform_driver cc770_isa_driver = {
|
||||
.probe = cc770_isa_probe,
|
||||
.remove = __devexit_p(cc770_isa_remove),
|
||||
.remove = cc770_isa_remove,
|
||||
.driver = {
|
||||
.name = KBUILD_MODNAME,
|
||||
.owner = THIS_MODULE,
|
||||
|
@ -60,6 +60,7 @@
|
||||
MODULE_AUTHOR("Wolfgang Grandegger <wg@grandegger.com>");
|
||||
MODULE_DESCRIPTION("Socket-CAN driver for CC770 on the platform bus");
|
||||
MODULE_LICENSE("GPL v2");
|
||||
MODULE_ALIAS("platform:" DRV_NAME);
|
||||
|
||||
#define CC770_PLATFORM_CAN_CLOCK 16000000
|
||||
|
||||
@ -74,8 +75,8 @@ static void cc770_platform_write_reg(const struct cc770_priv *priv, int reg,
|
||||
iowrite8(val, priv->reg_base + reg);
|
||||
}
|
||||
|
||||
static int __devinit cc770_get_of_node_data(struct platform_device *pdev,
|
||||
struct cc770_priv *priv)
|
||||
static int cc770_get_of_node_data(struct platform_device *pdev,
|
||||
struct cc770_priv *priv)
|
||||
{
|
||||
struct device_node *np = pdev->dev.of_node;
|
||||
const u32 *prop;
|
||||
@ -147,8 +148,8 @@ static int __devinit cc770_get_of_node_data(struct platform_device *pdev,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int __devinit cc770_get_platform_data(struct platform_device *pdev,
|
||||
struct cc770_priv *priv)
|
||||
static int cc770_get_platform_data(struct platform_device *pdev,
|
||||
struct cc770_priv *priv)
|
||||
{
|
||||
|
||||
struct cc770_platform_data *pdata = pdev->dev.platform_data;
|
||||
@ -163,7 +164,7 @@ static int __devinit cc770_get_platform_data(struct platform_device *pdev,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int __devinit cc770_platform_probe(struct platform_device *pdev)
|
||||
static int cc770_platform_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct net_device *dev;
|
||||
struct cc770_priv *priv;
|
||||
@ -237,7 +238,7 @@ exit_release_mem:
|
||||
return err;
|
||||
}
|
||||
|
||||
static int __devexit cc770_platform_remove(struct platform_device *pdev)
|
||||
static int cc770_platform_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct net_device *dev = dev_get_drvdata(&pdev->dev);
|
||||
struct cc770_priv *priv = netdev_priv(dev);
|
||||
@ -253,11 +254,12 @@ static int __devexit cc770_platform_remove(struct platform_device *pdev)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct of_device_id __devinitdata cc770_platform_table[] = {
|
||||
static struct of_device_id cc770_platform_table[] = {
|
||||
{.compatible = "bosch,cc770"}, /* CC770 from Bosch */
|
||||
{.compatible = "intc,82527"}, /* AN82527 from Intel CP */
|
||||
{},
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, cc770_platform_table);
|
||||
|
||||
static struct platform_driver cc770_platform_driver = {
|
||||
.driver = {
|
||||
@ -266,7 +268,7 @@ static struct platform_driver cc770_platform_driver = {
|
||||
.of_match_table = cc770_platform_table,
|
||||
},
|
||||
.probe = cc770_platform_probe,
|
||||
.remove = __devexit_p(cc770_platform_remove),
|
||||
.remove = cc770_platform_remove,
|
||||
};
|
||||
|
||||
module_platform_driver(cc770_platform_driver);
|
||||
|
@ -609,8 +609,7 @@ void close_candev(struct net_device *dev)
|
||||
{
|
||||
struct can_priv *priv = netdev_priv(dev);
|
||||
|
||||
if (del_timer_sync(&priv->restart_timer))
|
||||
dev_put(dev);
|
||||
del_timer_sync(&priv->restart_timer);
|
||||
can_flush_echo_skb(dev);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(close_candev);
|
||||
|
@ -922,7 +922,7 @@ static const struct net_device_ops flexcan_netdev_ops = {
|
||||
.ndo_start_xmit = flexcan_start_xmit,
|
||||
};
|
||||
|
||||
static int __devinit register_flexcandev(struct net_device *dev)
|
||||
static int register_flexcandev(struct net_device *dev)
|
||||
{
|
||||
struct flexcan_priv *priv = netdev_priv(dev);
|
||||
struct flexcan_regs __iomem *regs = priv->base;
|
||||
@ -968,7 +968,7 @@ static int __devinit register_flexcandev(struct net_device *dev)
|
||||
return err;
|
||||
}
|
||||
|
||||
static void __devexit unregister_flexcandev(struct net_device *dev)
|
||||
static void unregister_flexcandev(struct net_device *dev)
|
||||
{
|
||||
unregister_candev(dev);
|
||||
}
|
||||
@ -979,13 +979,15 @@ static const struct of_device_id flexcan_of_match[] = {
|
||||
{ .compatible = "fsl,imx6q-flexcan", .data = &fsl_imx6q_devtype_data, },
|
||||
{ /* sentinel */ },
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, flexcan_of_match);
|
||||
|
||||
static const struct platform_device_id flexcan_id_table[] = {
|
||||
{ .name = "flexcan", .driver_data = (kernel_ulong_t)&fsl_p1010_devtype_data, },
|
||||
{ /* sentinel */ },
|
||||
};
|
||||
MODULE_DEVICE_TABLE(platform, flexcan_id_table);
|
||||
|
||||
static int __devinit flexcan_probe(struct platform_device *pdev)
|
||||
static int flexcan_probe(struct platform_device *pdev)
|
||||
{
|
||||
const struct of_device_id *of_id;
|
||||
const struct flexcan_devtype_data *devtype_data;
|
||||
@ -1107,7 +1109,7 @@ static int __devinit flexcan_probe(struct platform_device *pdev)
|
||||
return err;
|
||||
}
|
||||
|
||||
static int __devexit flexcan_remove(struct platform_device *pdev)
|
||||
static int flexcan_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct net_device *dev = platform_get_drvdata(pdev);
|
||||
struct flexcan_priv *priv = netdev_priv(dev);
|
||||
@ -1168,7 +1170,7 @@ static struct platform_driver flexcan_driver = {
|
||||
.of_match_table = flexcan_of_match,
|
||||
},
|
||||
.probe = flexcan_probe,
|
||||
.remove = __devexit_p(flexcan_remove),
|
||||
.remove = flexcan_remove,
|
||||
.suspend = flexcan_suspend,
|
||||
.resume = flexcan_resume,
|
||||
.id_table = flexcan_id_table,
|
||||
|
1756
drivers/net/can/grcan.c
Normal file
1756
drivers/net/can/grcan.c
Normal file
File diff suppressed because it is too large
Load Diff
@ -365,7 +365,7 @@ static int ican3_old_send_msg(struct ican3_dev *mod, struct ican3_msg *msg)
|
||||
* ICAN3 "new-style" Host Interface Setup
|
||||
*/
|
||||
|
||||
static void __devinit ican3_init_new_host_interface(struct ican3_dev *mod)
|
||||
static void ican3_init_new_host_interface(struct ican3_dev *mod)
|
||||
{
|
||||
struct ican3_new_desc desc;
|
||||
unsigned long flags;
|
||||
@ -444,7 +444,7 @@ static void __devinit ican3_init_new_host_interface(struct ican3_dev *mod)
|
||||
* ICAN3 Fast Host Interface Setup
|
||||
*/
|
||||
|
||||
static void __devinit ican3_init_fast_host_interface(struct ican3_dev *mod)
|
||||
static void ican3_init_fast_host_interface(struct ican3_dev *mod)
|
||||
{
|
||||
struct ican3_fast_desc desc;
|
||||
unsigned long flags;
|
||||
@ -631,7 +631,7 @@ static int ican3_recv_msg(struct ican3_dev *mod, struct ican3_msg *msg)
|
||||
* Quick Pre-constructed Messages
|
||||
*/
|
||||
|
||||
static int __devinit ican3_msg_connect(struct ican3_dev *mod)
|
||||
static int ican3_msg_connect(struct ican3_dev *mod)
|
||||
{
|
||||
struct ican3_msg msg;
|
||||
|
||||
@ -642,7 +642,7 @@ static int __devinit ican3_msg_connect(struct ican3_dev *mod)
|
||||
return ican3_send_msg(mod, &msg);
|
||||
}
|
||||
|
||||
static int __devexit ican3_msg_disconnect(struct ican3_dev *mod)
|
||||
static int ican3_msg_disconnect(struct ican3_dev *mod)
|
||||
{
|
||||
struct ican3_msg msg;
|
||||
|
||||
@ -653,7 +653,7 @@ static int __devexit ican3_msg_disconnect(struct ican3_dev *mod)
|
||||
return ican3_send_msg(mod, &msg);
|
||||
}
|
||||
|
||||
static int __devinit ican3_msg_newhostif(struct ican3_dev *mod)
|
||||
static int ican3_msg_newhostif(struct ican3_dev *mod)
|
||||
{
|
||||
struct ican3_msg msg;
|
||||
int ret;
|
||||
@ -674,7 +674,7 @@ static int __devinit ican3_msg_newhostif(struct ican3_dev *mod)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int __devinit ican3_msg_fasthostif(struct ican3_dev *mod)
|
||||
static int ican3_msg_fasthostif(struct ican3_dev *mod)
|
||||
{
|
||||
struct ican3_msg msg;
|
||||
unsigned int addr;
|
||||
@ -707,7 +707,7 @@ static int __devinit ican3_msg_fasthostif(struct ican3_dev *mod)
|
||||
* Setup the CAN filter to either accept or reject all
|
||||
* messages from the CAN bus.
|
||||
*/
|
||||
static int __devinit ican3_set_id_filter(struct ican3_dev *mod, bool accept)
|
||||
static int ican3_set_id_filter(struct ican3_dev *mod, bool accept)
|
||||
{
|
||||
struct ican3_msg msg;
|
||||
int ret;
|
||||
@ -1421,7 +1421,7 @@ static int ican3_reset_module(struct ican3_dev *mod)
|
||||
return -ETIMEDOUT;
|
||||
}
|
||||
|
||||
static void __devexit ican3_shutdown_module(struct ican3_dev *mod)
|
||||
static void ican3_shutdown_module(struct ican3_dev *mod)
|
||||
{
|
||||
ican3_msg_disconnect(mod);
|
||||
ican3_reset_module(mod);
|
||||
@ -1430,7 +1430,7 @@ static void __devexit ican3_shutdown_module(struct ican3_dev *mod)
|
||||
/*
|
||||
* Startup an ICAN module, bringing it into fast mode
|
||||
*/
|
||||
static int __devinit ican3_startup_module(struct ican3_dev *mod)
|
||||
static int ican3_startup_module(struct ican3_dev *mod)
|
||||
{
|
||||
int ret;
|
||||
|
||||
@ -1692,7 +1692,7 @@ static int ican3_get_berr_counter(const struct net_device *ndev,
|
||||
return ret;
|
||||
|
||||
ret = wait_for_completion_timeout(&mod->buserror_comp, HZ);
|
||||
if (ret <= 0) {
|
||||
if (ret == 0) {
|
||||
dev_info(mod->dev, "%s timed out\n", __func__);
|
||||
return -ETIMEDOUT;
|
||||
}
|
||||
@ -1718,7 +1718,7 @@ static ssize_t ican3_sysfs_show_term(struct device *dev,
|
||||
return ret;
|
||||
|
||||
ret = wait_for_completion_timeout(&mod->termination_comp, HZ);
|
||||
if (ret <= 0) {
|
||||
if (ret == 0) {
|
||||
dev_info(mod->dev, "%s timed out\n", __func__);
|
||||
return -ETIMEDOUT;
|
||||
}
|
||||
@ -1760,7 +1760,7 @@ static struct attribute_group ican3_sysfs_attr_group = {
|
||||
* PCI Subsystem
|
||||
*/
|
||||
|
||||
static int __devinit ican3_probe(struct platform_device *pdev)
|
||||
static int ican3_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct janz_platform_data *pdata;
|
||||
struct net_device *ndev;
|
||||
@ -1898,7 +1898,7 @@ out_return:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int __devexit ican3_remove(struct platform_device *pdev)
|
||||
static int ican3_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct net_device *ndev = platform_get_drvdata(pdev);
|
||||
struct ican3_dev *mod = netdev_priv(ndev);
|
||||
@ -1927,7 +1927,7 @@ static struct platform_driver ican3_driver = {
|
||||
.owner = THIS_MODULE,
|
||||
},
|
||||
.probe = ican3_probe,
|
||||
.remove = __devexit_p(ican3_remove),
|
||||
.remove = ican3_remove,
|
||||
};
|
||||
|
||||
module_platform_driver(ican3_driver);
|
||||
|
@ -981,7 +981,7 @@ static const struct net_device_ops mcp251x_netdev_ops = {
|
||||
.ndo_start_xmit = mcp251x_hard_start_xmit,
|
||||
};
|
||||
|
||||
static int __devinit mcp251x_can_probe(struct spi_device *spi)
|
||||
static int mcp251x_can_probe(struct spi_device *spi)
|
||||
{
|
||||
struct net_device *net;
|
||||
struct mcp251x_priv *priv;
|
||||
@ -1100,7 +1100,7 @@ error_out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int __devexit mcp251x_can_remove(struct spi_device *spi)
|
||||
static int mcp251x_can_remove(struct spi_device *spi)
|
||||
{
|
||||
struct mcp251x_platform_data *pdata = spi->dev.platform_data;
|
||||
struct mcp251x_priv *priv = dev_get_drvdata(&spi->dev);
|
||||
@ -1198,7 +1198,7 @@ static struct spi_driver mcp251x_can_driver = {
|
||||
|
||||
.id_table = mcp251x_id_table,
|
||||
.probe = mcp251x_can_probe,
|
||||
.remove = __devexit_p(mcp251x_can_remove),
|
||||
.remove = mcp251x_can_remove,
|
||||
.suspend = mcp251x_can_suspend,
|
||||
.resume = mcp251x_can_resume,
|
||||
};
|
||||
|
@ -43,14 +43,13 @@ struct mpc5xxx_can_data {
|
||||
};
|
||||
|
||||
#ifdef CONFIG_PPC_MPC52xx
|
||||
static struct of_device_id __devinitdata mpc52xx_cdm_ids[] = {
|
||||
static struct of_device_id mpc52xx_cdm_ids[] = {
|
||||
{ .compatible = "fsl,mpc5200-cdm", },
|
||||
{}
|
||||
};
|
||||
|
||||
static u32 __devinit mpc52xx_can_get_clock(struct platform_device *ofdev,
|
||||
const char *clock_name,
|
||||
int *mscan_clksrc)
|
||||
static u32 mpc52xx_can_get_clock(struct platform_device *ofdev,
|
||||
const char *clock_name, int *mscan_clksrc)
|
||||
{
|
||||
unsigned int pvr;
|
||||
struct mpc52xx_cdm __iomem *cdm;
|
||||
@ -101,9 +100,8 @@ static u32 __devinit mpc52xx_can_get_clock(struct platform_device *ofdev,
|
||||
return freq;
|
||||
}
|
||||
#else /* !CONFIG_PPC_MPC52xx */
|
||||
static u32 __devinit mpc52xx_can_get_clock(struct platform_device *ofdev,
|
||||
const char *clock_name,
|
||||
int *mscan_clksrc)
|
||||
static u32 mpc52xx_can_get_clock(struct platform_device *ofdev,
|
||||
const char *clock_name, int *mscan_clksrc)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
@ -124,14 +122,13 @@ struct mpc512x_clockctl {
|
||||
u32 mccr[4]; /* MSCAN Clk Ctrl Reg 1-3 */
|
||||
};
|
||||
|
||||
static struct of_device_id __devinitdata mpc512x_clock_ids[] = {
|
||||
static struct of_device_id mpc512x_clock_ids[] = {
|
||||
{ .compatible = "fsl,mpc5121-clock", },
|
||||
{}
|
||||
};
|
||||
|
||||
static u32 __devinit mpc512x_can_get_clock(struct platform_device *ofdev,
|
||||
const char *clock_name,
|
||||
int *mscan_clksrc)
|
||||
static u32 mpc512x_can_get_clock(struct platform_device *ofdev,
|
||||
const char *clock_name, int *mscan_clksrc)
|
||||
{
|
||||
struct mpc512x_clockctl __iomem *clockctl;
|
||||
struct device_node *np_clock;
|
||||
@ -239,16 +236,15 @@ exit_put:
|
||||
return freq;
|
||||
}
|
||||
#else /* !CONFIG_PPC_MPC512x */
|
||||
static u32 __devinit mpc512x_can_get_clock(struct platform_device *ofdev,
|
||||
const char *clock_name,
|
||||
int *mscan_clksrc)
|
||||
static u32 mpc512x_can_get_clock(struct platform_device *ofdev,
|
||||
const char *clock_name, int *mscan_clksrc)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
#endif /* CONFIG_PPC_MPC512x */
|
||||
|
||||
static const struct of_device_id mpc5xxx_can_table[];
|
||||
static int __devinit mpc5xxx_can_probe(struct platform_device *ofdev)
|
||||
static int mpc5xxx_can_probe(struct platform_device *ofdev)
|
||||
{
|
||||
const struct of_device_id *match;
|
||||
const struct mpc5xxx_can_data *data;
|
||||
@ -323,7 +319,7 @@ exit_unmap_mem:
|
||||
return err;
|
||||
}
|
||||
|
||||
static int __devexit mpc5xxx_can_remove(struct platform_device *ofdev)
|
||||
static int mpc5xxx_can_remove(struct platform_device *ofdev)
|
||||
{
|
||||
struct net_device *dev = dev_get_drvdata(&ofdev->dev);
|
||||
struct mscan_priv *priv = netdev_priv(dev);
|
||||
@ -380,22 +376,23 @@ static int mpc5xxx_can_resume(struct platform_device *ofdev)
|
||||
}
|
||||
#endif
|
||||
|
||||
static const struct mpc5xxx_can_data __devinitconst mpc5200_can_data = {
|
||||
static const struct mpc5xxx_can_data mpc5200_can_data = {
|
||||
.type = MSCAN_TYPE_MPC5200,
|
||||
.get_clock = mpc52xx_can_get_clock,
|
||||
};
|
||||
|
||||
static const struct mpc5xxx_can_data __devinitconst mpc5121_can_data = {
|
||||
static const struct mpc5xxx_can_data mpc5121_can_data = {
|
||||
.type = MSCAN_TYPE_MPC5121,
|
||||
.get_clock = mpc512x_can_get_clock,
|
||||
};
|
||||
|
||||
static const struct of_device_id __devinitconst mpc5xxx_can_table[] = {
|
||||
static const struct of_device_id mpc5xxx_can_table[] = {
|
||||
{ .compatible = "fsl,mpc5200-mscan", .data = &mpc5200_can_data, },
|
||||
/* Note that only MPC5121 Rev. 2 (and later) is supported */
|
||||
{ .compatible = "fsl,mpc5121-mscan", .data = &mpc5121_can_data, },
|
||||
{},
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, mpc5xxx_can_table);
|
||||
|
||||
static struct platform_driver mpc5xxx_can_driver = {
|
||||
.driver = {
|
||||
@ -404,7 +401,7 @@ static struct platform_driver mpc5xxx_can_driver = {
|
||||
.of_match_table = mpc5xxx_can_table,
|
||||
},
|
||||
.probe = mpc5xxx_can_probe,
|
||||
.remove = __devexit_p(mpc5xxx_can_remove),
|
||||
.remove = mpc5xxx_can_remove,
|
||||
#ifdef CONFIG_PM
|
||||
.suspend = mpc5xxx_can_suspend,
|
||||
.resume = mpc5xxx_can_resume,
|
||||
|
@ -517,12 +517,8 @@ static irqreturn_t mscan_isr(int irq, void *dev_id)
|
||||
|
||||
static int mscan_do_set_mode(struct net_device *dev, enum can_mode mode)
|
||||
{
|
||||
struct mscan_priv *priv = netdev_priv(dev);
|
||||
int ret = 0;
|
||||
|
||||
if (!priv->open_time)
|
||||
return -EINVAL;
|
||||
|
||||
switch (mode) {
|
||||
case CAN_MODE_START:
|
||||
ret = mscan_restart(dev);
|
||||
@ -590,8 +586,6 @@ static int mscan_open(struct net_device *dev)
|
||||
goto exit_napi_disable;
|
||||
}
|
||||
|
||||
priv->open_time = jiffies;
|
||||
|
||||
if (priv->can.ctrlmode & CAN_CTRLMODE_LISTENONLY)
|
||||
setbits8(®s->canctl1, MSCAN_LISTEN);
|
||||
else
|
||||
@ -606,7 +600,6 @@ static int mscan_open(struct net_device *dev)
|
||||
return 0;
|
||||
|
||||
exit_free_irq:
|
||||
priv->open_time = 0;
|
||||
free_irq(dev->irq, dev);
|
||||
exit_napi_disable:
|
||||
napi_disable(&priv->napi);
|
||||
@ -627,7 +620,6 @@ static int mscan_close(struct net_device *dev)
|
||||
mscan_set_mode(dev, MSCAN_INIT_MODE);
|
||||
close_candev(dev);
|
||||
free_irq(dev->irq, dev);
|
||||
priv->open_time = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -281,7 +281,6 @@ struct tx_queue_entry {
|
||||
struct mscan_priv {
|
||||
struct can_priv can; /* must be the first member */
|
||||
unsigned int type; /* MSCAN type variants */
|
||||
long open_time;
|
||||
unsigned long flags;
|
||||
void __iomem *reg_base; /* ioremap'ed address to registers */
|
||||
u8 shadow_statflg;
|
||||
|
@ -954,7 +954,7 @@ static const struct net_device_ops pch_can_netdev_ops = {
|
||||
.ndo_start_xmit = pch_xmit,
|
||||
};
|
||||
|
||||
static void __devexit pch_can_remove(struct pci_dev *pdev)
|
||||
static void pch_can_remove(struct pci_dev *pdev)
|
||||
{
|
||||
struct net_device *ndev = pci_get_drvdata(pdev);
|
||||
struct pch_can_priv *priv = netdev_priv(ndev);
|
||||
@ -1178,7 +1178,7 @@ static int pch_can_get_berr_counter(const struct net_device *dev,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int __devinit pch_can_probe(struct pci_dev *pdev,
|
||||
static int pch_can_probe(struct pci_dev *pdev,
|
||||
const struct pci_device_id *id)
|
||||
{
|
||||
struct net_device *ndev;
|
||||
@ -1269,7 +1269,7 @@ static struct pci_driver pch_can_pci_driver = {
|
||||
.name = "pch_can",
|
||||
.id_table = pch_pci_tbl,
|
||||
.probe = pch_can_probe,
|
||||
.remove = __devexit_p(pch_can_remove),
|
||||
.remove = pch_can_remove,
|
||||
.suspend = pch_can_suspend,
|
||||
.resume = pch_can_resume,
|
||||
};
|
||||
|
@ -21,7 +21,7 @@ config CAN_SJA1000_PLATFORM
|
||||
|
||||
config CAN_SJA1000_OF_PLATFORM
|
||||
tristate "Generic OF Platform Bus based SJA1000 driver"
|
||||
depends on PPC_OF
|
||||
depends on OF
|
||||
---help---
|
||||
This driver adds support for the SJA1000 chips connected to
|
||||
the OpenFirmware "platform bus" found on embedded systems with
|
||||
@ -93,6 +93,7 @@ config CAN_PLX_PCI
|
||||
- Marathon CAN-bus-PCI card (http://www.marathon.ru/)
|
||||
- TEWS TECHNOLOGIES TPMC810 card (http://www.tews.com/)
|
||||
- IXXAT Automation PC-I 04/PCI card (http://www.ixxat.com/)
|
||||
- Connect Tech Inc. CANpro/104-Plus Opto (CRG001) card (http://www.connecttech.com)
|
||||
|
||||
config CAN_TSCAN1
|
||||
tristate "TS-CAN1 PC104 boards"
|
||||
|
@ -220,8 +220,8 @@ static void ems_pci_card_reset(struct ems_pci_card *card)
|
||||
* Probe PCI device for EMS CAN signature and register each available
|
||||
* CAN channel to SJA1000 Socket-CAN subsystem.
|
||||
*/
|
||||
static int __devinit ems_pci_add_card(struct pci_dev *pdev,
|
||||
const struct pci_device_id *ent)
|
||||
static int ems_pci_add_card(struct pci_dev *pdev,
|
||||
const struct pci_device_id *ent)
|
||||
{
|
||||
struct sja1000_priv *priv;
|
||||
struct net_device *dev;
|
||||
|
@ -166,8 +166,7 @@ static void ems_pcmcia_del_card(struct pcmcia_device *pdev)
|
||||
* Probe PCI device for EMS CAN signature and register each available
|
||||
* CAN channel to SJA1000 Socket-CAN subsystem.
|
||||
*/
|
||||
static int __devinit ems_pcmcia_add_card(struct pcmcia_device *pdev,
|
||||
unsigned long base)
|
||||
static int ems_pcmcia_add_card(struct pcmcia_device *pdev, unsigned long base)
|
||||
{
|
||||
struct sja1000_priv *priv;
|
||||
struct net_device *dev;
|
||||
@ -256,7 +255,7 @@ failure_cleanup:
|
||||
/*
|
||||
* Setup PCMCIA socket and probe for EMS CPC-CARD
|
||||
*/
|
||||
static int __devinit ems_pcmcia_probe(struct pcmcia_device *dev)
|
||||
static int ems_pcmcia_probe(struct pcmcia_device *dev)
|
||||
{
|
||||
int csval;
|
||||
|
||||
|
@ -290,8 +290,8 @@ failure:
|
||||
return err;
|
||||
}
|
||||
|
||||
static int __devinit kvaser_pci_init_one(struct pci_dev *pdev,
|
||||
const struct pci_device_id *ent)
|
||||
static int kvaser_pci_init_one(struct pci_dev *pdev,
|
||||
const struct pci_device_id *ent)
|
||||
{
|
||||
int err;
|
||||
struct net_device *master_dev = NULL;
|
||||
@ -379,7 +379,7 @@ failure:
|
||||
|
||||
}
|
||||
|
||||
static void __devexit kvaser_pci_remove_one(struct pci_dev *pdev)
|
||||
static void kvaser_pci_remove_one(struct pci_dev *pdev)
|
||||
{
|
||||
struct net_device *dev = pci_get_drvdata(pdev);
|
||||
|
||||
@ -394,7 +394,7 @@ static struct pci_driver kvaser_pci_driver = {
|
||||
.name = DRV_NAME,
|
||||
.id_table = kvaser_pci_tbl,
|
||||
.probe = kvaser_pci_init_one,
|
||||
.remove = __devexit_p(kvaser_pci_remove_one),
|
||||
.remove = kvaser_pci_remove_one,
|
||||
};
|
||||
|
||||
module_pci_driver(kvaser_pci_driver);
|
||||
|
@ -551,8 +551,7 @@ static void peak_pci_post_irq(const struct sja1000_priv *priv)
|
||||
writew(chan->icr_mask, chan->cfg_base + PITA_ICR);
|
||||
}
|
||||
|
||||
static int __devinit peak_pci_probe(struct pci_dev *pdev,
|
||||
const struct pci_device_id *ent)
|
||||
static int peak_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
|
||||
{
|
||||
struct sja1000_priv *priv;
|
||||
struct peak_pci_chan *chan;
|
||||
@ -717,7 +716,7 @@ failure_disable_pci:
|
||||
return err;
|
||||
}
|
||||
|
||||
static void __devexit peak_pci_remove(struct pci_dev *pdev)
|
||||
static void peak_pci_remove(struct pci_dev *pdev)
|
||||
{
|
||||
struct net_device *dev = pci_get_drvdata(pdev); /* Last device */
|
||||
struct sja1000_priv *priv = netdev_priv(dev);
|
||||
@ -757,7 +756,7 @@ static struct pci_driver peak_pci_driver = {
|
||||
.name = DRV_NAME,
|
||||
.id_table = peak_pci_tbl,
|
||||
.probe = peak_pci_probe,
|
||||
.remove = __devexit_p(peak_pci_remove),
|
||||
.remove = peak_pci_remove,
|
||||
};
|
||||
|
||||
module_pci_driver(peak_pci_driver);
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user