Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next

* git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next: (1287 commits)
  icmp: Fix regression in nexthop resolution during replies.
  net: Fix ppc64 BPF JIT dependencies.
  acenic: include NET_SKB_PAD headroom to incoming skbs
  ixgbe: convert to ndo_fix_features
  ixgbe: only enable WoL for magic packet by default
  ixgbe: remove ifdef check for non-existent define
  ixgbe: Pass staterr instead of re-reading status and error bits from descriptor
  ixgbe: Move interrupt related values out of ring and into q_vector
  ixgbe: add structure for containing RX/TX rings to q_vector
  ixgbe: inline the ixgbe_maybe_stop_tx function
  ixgbe: Update ATR to use recorded TX queues instead of CPU for routing
  igb: Fix for DH89xxCC near end loopback test
  e1000: always call e1000_check_for_link() on e1000_ce4100 MACs.
  netxen: add fw version compatibility check
  be2net: request native mode each time the card is reset
  ipv4: Constrain UFO fragment sizes to multiples of 8 bytes
  virtio_net: Fix panic in virtnet_remove
  ipv6: make fragment identifications less predictable
  ipv6: unshare inetpeers
  can: make function can_get_bittiming static
  ...
This commit is contained in:
Linus Torvalds 2011-07-22 14:43:13 -07:00
commit 951cc93a74
1296 changed files with 94404 additions and 36792 deletions

View File

@ -402,8 +402,9 @@
!Finclude/net/mac80211.h set_key_cmd
!Finclude/net/mac80211.h ieee80211_key_conf
!Finclude/net/mac80211.h ieee80211_key_flags
!Finclude/net/mac80211.h ieee80211_tkip_key_type
!Finclude/net/mac80211.h ieee80211_get_tkip_key
!Finclude/net/mac80211.h ieee80211_get_tkip_p1k
!Finclude/net/mac80211.h ieee80211_get_tkip_p1k_iv
!Finclude/net/mac80211.h ieee80211_get_tkip_p2k
!Finclude/net/mac80211.h ieee80211_key_removed
</chapter>

View File

@ -260,7 +260,7 @@ int main(int argc, char *argv[])
case 'V': opt_V++; exclusive++; break;
case '?':
fprintf(stderr, usage_msg);
fprintf(stderr, "%s", usage_msg);
res = 2;
goto out;
}
@ -268,13 +268,13 @@ int main(int argc, char *argv[])
/* options check */
if (exclusive > 1) {
fprintf(stderr, usage_msg);
fprintf(stderr, "%s", usage_msg);
res = 2;
goto out;
}
if (opt_v || opt_V) {
printf(version);
printf("%s", version);
if (opt_V) {
res = 0;
goto out;
@ -282,14 +282,14 @@ int main(int argc, char *argv[])
}
if (opt_u) {
printf(usage_msg);
printf("%s", usage_msg);
res = 0;
goto out;
}
if (opt_h) {
printf(usage_msg);
printf(help_msg);
printf("%s", usage_msg);
printf("%s", help_msg);
res = 0;
goto out;
}
@ -309,7 +309,7 @@ int main(int argc, char *argv[])
goto out;
} else {
/* Just show usage */
fprintf(stderr, usage_msg);
fprintf(stderr, "%s", usage_msg);
res = 2;
goto out;
}
@ -320,7 +320,7 @@ int main(int argc, char *argv[])
master_ifname = *spp++;
if (master_ifname == NULL) {
fprintf(stderr, usage_msg);
fprintf(stderr, "%s", usage_msg);
res = 2;
goto out;
}
@ -339,7 +339,7 @@ int main(int argc, char *argv[])
if (slave_ifname == NULL) {
if (opt_d || opt_c) {
fprintf(stderr, usage_msg);
fprintf(stderr, "%s", usage_msg);
res = 2;
goto out;
}

View File

@ -106,16 +106,6 @@ inet_peer_maxttl - INTEGER
when the number of entries in the pool is very small).
Measured in seconds.
inet_peer_gc_mintime - INTEGER
Minimum interval between garbage collection passes. This interval is
in effect under high memory pressure on the pool.
Measured in seconds.
inet_peer_gc_maxtime - INTEGER
Minimum interval between garbage collection passes. This interval is
in effect under low (or absent) memory pressure on the pool.
Measured in seconds.
TCP variables:
somaxconn - INTEGER
@ -394,7 +384,7 @@ tcp_rmem - vector of 3 INTEGERs: min, default, max
min: Minimal size of receive buffer used by TCP sockets.
It is guaranteed to each TCP socket, even under moderate memory
pressure.
Default: 8K
Default: 1 page
default: initial size of receive buffer used by TCP sockets.
This value overrides net.core.rmem_default used by other protocols.
@ -483,7 +473,7 @@ tcp_window_scaling - BOOLEAN
tcp_wmem - vector of 3 INTEGERs: min, default, max
min: Amount of memory reserved for send buffers for TCP sockets.
Each TCP socket has rights to use it due to fact of its birth.
Default: 4K
Default: 1 page
default: initial size of send buffer used by TCP sockets. This
value overrides net.core.wmem_default used by other protocols.
@ -553,13 +543,13 @@ udp_rmem_min - INTEGER
Minimal size of receive buffer used by UDP sockets in moderation.
Each UDP socket is able to use the size for receiving data, even if
total pages of UDP sockets exceed udp_mem pressure. The unit is byte.
Default: 4096
Default: 1 page
udp_wmem_min - INTEGER
Minimal size of send buffer used by UDP sockets in moderation.
Each UDP socket is able to use the size for sending data, even if
total pages of UDP sockets exceed udp_mem pressure. The unit is byte.
Default: 4096
Default: 1 page
CIPSOv4 Variables:
@ -1465,10 +1455,17 @@ sctp_mem - vector of 3 INTEGERs: min, pressure, max
Default is calculated at boot time from amount of available memory.
sctp_rmem - vector of 3 INTEGERs: min, default, max
See tcp_rmem for a description.
Only the first value ("min") is used, "default" and "max" are
ignored.
min: Minimal size of receive buffer used by SCTP socket.
It is guaranteed to each SCTP socket (but not association) even
under moderate memory pressure.
Default: 1 page
sctp_wmem - vector of 3 INTEGERs: min, default, max
See tcp_wmem for a description.
Currently this tunable has no effect.
addr_scope_policy - INTEGER
Control IPv4 address scoping - draft-stewart-tsvwg-sctp-ipv4-00

View File

@ -0,0 +1,154 @@
Netdev features mess and how to get out from it alive
=====================================================
Author:
Michał Mirosław <mirq-linux@rere.qmqm.pl>
Part I: Feature sets
======================
Long gone are the days when a network card would just take and give packets
verbatim. Today's devices add multiple features and bugs (read: offloads)
that relieve an OS of various tasks like generating and checking checksums,
splitting packets, classifying them. Those capabilities and their state
are commonly referred to as netdev features in Linux kernel world.
There are currently three sets of features relevant to the driver, and
one used internally by network core:
1. netdev->hw_features set contains features whose state may possibly
be changed (enabled or disabled) for a particular device by user's
request. This set should be initialized in ndo_init callback and not
changed later.
2. netdev->features set contains features which are currently enabled
for a device. This should be changed only by network core or in
error paths of ndo_set_features callback.
3. netdev->vlan_features set contains features whose state is inherited
by child VLAN devices (limits netdev->features set). This is currently
used for all VLAN devices whether tags are stripped or inserted in
hardware or software.
4. netdev->wanted_features set contains feature set requested by user.
This set is filtered by ndo_fix_features callback whenever it or
some device-specific conditions change. This set is internal to
networking core and should not be referenced in drivers.
Part II: Controlling enabled features
=======================================
When current feature set (netdev->features) is to be changed, new set
is calculated and filtered by calling ndo_fix_features callback
and netdev_fix_features(). If the resulting set differs from current
set, it is passed to ndo_set_features callback and (if the callback
returns success) replaces value stored in netdev->features.
NETDEV_FEAT_CHANGE notification is issued after that whenever current
set might have changed.
The following events trigger recalculation:
1. device's registration, after ndo_init returned success
2. user requested changes in features state
3. netdev_update_features() is called
ndo_*_features callbacks are called with rtnl_lock held. Missing callbacks
are treated as always returning success.
A driver that wants to trigger recalculation must do so by calling
netdev_update_features() while holding rtnl_lock. This should not be done
from ndo_*_features callbacks. netdev->features should not be modified by
driver except by means of ndo_fix_features callback.
Part III: Implementation hints
================================
* ndo_fix_features:
All dependencies between features should be resolved here. The resulting
set can be reduced further by networking core imposed limitations (as coded
in netdev_fix_features()). For this reason it is safer to disable a feature
when its dependencies are not met instead of forcing the dependency on.
This callback should not modify hardware nor driver state (should be
stateless). It can be called multiple times between successive
ndo_set_features calls.
Callback must not alter features contained in NETIF_F_SOFT_FEATURES or
NETIF_F_NEVER_CHANGE sets. The exception is NETIF_F_VLAN_CHALLENGED but
care must be taken as the change won't affect already configured VLANs.
* ndo_set_features:
Hardware should be reconfigured to match passed feature set. The set
should not be altered unless some error condition happens that can't
be reliably detected in ndo_fix_features. In this case, the callback
should update netdev->features to match resulting hardware state.
Errors returned are not (and cannot be) propagated anywhere except dmesg.
(Note: successful return is zero, >0 means silent error.)
Part IV: Features
===================
For current list of features, see include/linux/netdev_features.h.
This section describes semantics of some of them.
* Transmit checksumming
For complete description, see comments near the top of include/linux/skbuff.h.
Note: NETIF_F_HW_CSUM is a superset of NETIF_F_IP_CSUM + NETIF_F_IPV6_CSUM.
It means that device can fill TCP/UDP-like checksum anywhere in the packets
whatever headers there might be.
* Transmit TCP segmentation offload
NETIF_F_TSO_ECN means that hardware can properly split packets with CWR bit
set, be it TCPv4 (when NETIF_F_TSO is enabled) or TCPv6 (NETIF_F_TSO6).
* Transmit DMA from high memory
On platforms where this is relevant, NETIF_F_HIGHDMA signals that
ndo_start_xmit can handle skbs with frags in high memory.
* Transmit scatter-gather
Those features say that ndo_start_xmit can handle fragmented skbs:
NETIF_F_SG --- paged skbs (skb_shinfo()->frags), NETIF_F_FRAGLIST ---
chained skbs (skb->next/prev list).
* Software features
Features contained in NETIF_F_SOFT_FEATURES are features of networking
stack. Driver should not change behaviour based on them.
* LLTX driver (deprecated for hardware drivers)
NETIF_F_LLTX should be set in drivers that implement their own locking in
transmit path or don't need locking at all (e.g. software tunnels).
In ndo_start_xmit, it is recommended to use a try_lock and return
NETDEV_TX_LOCKED when the spin lock fails. The locking should also properly
protect against other callbacks (the rules you need to find out).
Don't use it for new drivers.
* netns-local device
NETIF_F_NETNS_LOCAL is set for devices that are not allowed to move between
network namespaces (e.g. loopback).
Don't use it in drivers.
* VLAN challenged
NETIF_F_VLAN_CHALLENGED should be set for devices which can't cope with VLAN
headers. Some drivers set this because the cards can't handle the bigger MTU.
[FIXME: Those cases could be fixed in VLAN code by allowing only reduced-MTU
VLANs. This may be not useful, though.]

View File

@ -0,0 +1,128 @@
Linux NFC subsystem
===================
The Near Field Communication (NFC) subsystem is required to standardize the
NFC device drivers development and to create an unified userspace interface.
This document covers the architecture overview, the device driver interface
description and the userspace interface description.
Architecture overview
---------------------
The NFC subsystem is responsible for:
- NFC adapters management;
- Polling for targets;
- Low-level data exchange;
The subsystem is divided in some parts. The 'core' is responsible for
providing the device driver interface. On the other side, it is also
responsible for providing an interface to control operations and low-level
data exchange.
The control operations are available to userspace via generic netlink.
The low-level data exchange interface is provided by the new socket family
PF_NFC. The NFC_SOCKPROTO_RAW performs raw communication with NFC targets.
+--------------------------------------+
| USER SPACE |
+--------------------------------------+
^ ^
| low-level | control
| data exchange | operations
| |
| v
| +-----------+
| AF_NFC | netlink |
| socket +-----------+
| raw ^
| |
v v
+---------+ +-----------+
| rawsock | <--------> | core |
+---------+ +-----------+
^
|
v
+-----------+
| driver |
+-----------+
Device Driver Interface
-----------------------
When registering on the NFC subsystem, the device driver must inform the core
of the set of supported NFC protocols and the set of ops callbacks. The ops
callbacks that must be implemented are the following:
* start_poll - setup the device to poll for targets
* stop_poll - stop on progress polling operation
* activate_target - select and initialize one of the targets found
* deactivate_target - deselect and deinitialize the selected target
* data_exchange - send data and receive the response (transceive operation)
Userspace interface
--------------------
The userspace interface is divided in control operations and low-level data
exchange operation.
CONTROL OPERATIONS:
Generic netlink is used to implement the interface to the control operations.
The operations are composed by commands and events, all listed below:
* NFC_CMD_GET_DEVICE - get specific device info or dump the device list
* NFC_CMD_START_POLL - setup a specific device to polling for targets
* NFC_CMD_STOP_POLL - stop the polling operation in a specific device
* NFC_CMD_GET_TARGET - dump the list of targets found by a specific device
* NFC_EVENT_DEVICE_ADDED - reports an NFC device addition
* NFC_EVENT_DEVICE_REMOVED - reports an NFC device removal
* NFC_EVENT_TARGETS_FOUND - reports START_POLL results when 1 or more targets
are found
The user must call START_POLL to poll for NFC targets, passing the desired NFC
protocols through NFC_ATTR_PROTOCOLS attribute. The device remains in polling
state until it finds any target. However, the user can stop the polling
operation by calling STOP_POLL command. In this case, it will be checked if
the requester of STOP_POLL is the same of START_POLL.
If the polling operation finds one or more targets, the event TARGETS_FOUND is
sent (including the device id). The user must call GET_TARGET to get the list of
all targets found by such device. Each reply message has target attributes with
relevant information such as the supported NFC protocols.
All polling operations requested through one netlink socket are stopped when
it's closed.
LOW-LEVEL DATA EXCHANGE:
The userspace must use PF_NFC sockets to perform any data communication with
targets. All NFC sockets use AF_NFC:
struct sockaddr_nfc {
sa_family_t sa_family;
__u32 dev_idx;
__u32 target_idx;
__u32 nfc_protocol;
};
To establish a connection with one target, the user must create an
NFC_SOCKPROTO_RAW socket and call the 'connect' syscall with the sockaddr_nfc
struct correctly filled. All information comes from NFC_EVENT_TARGETS_FOUND
netlink event. As a target can support more than one NFC protocol, the user
must inform which protocol it wants to use.
Internally, 'connect' will result in an activate_target call to the driver.
When the socket is closed, the target is deactivated.
The data format exchanged through the sockets is NFC protocol dependent. For
instance, when communicating with MIFARE tags, the data exchanged are MIFARE
commands and their responses.
The first received package is the response to the first sent package and so
on. In order to allow valid "empty" responses, every data received has a NULL
header of 1 byte.

View File

@ -7,7 +7,7 @@ This is the driver for the MAC 10/100/1000 on-chip Ethernet controllers
(Synopsys IP blocks); it has been fully tested on STLinux platforms.
Currently this network device driver is for all STM embedded MAC/GMAC
(7xxx SoCs). Other platforms start using it i.e. ARM SPEAr.
(i.e. 7xxx/5xxx SoCs) and it's known working on other platforms i.e. ARM SPEAr.
DWC Ether MAC 10/100/1000 Universal version 3.41a and DWC Ether MAC 10/100
Universal version 4.0 have been used for developing the first code
@ -71,7 +71,7 @@ Several performance tests on STM platforms showed this optimisation allows to sp
the CPU while having the maximum throughput.
4.4) WOL
Wake up on Lan feature through Magic Frame is only supported for the GMAC
Wake up on Lan feature through Magic and Unicast frames are supported for the GMAC
core.
4.5) DMA descriptors
@ -91,11 +91,15 @@ LRO is not supported.
The driver is compatible with PAL to work with PHY and GPHY devices.
4.9) Platform information
Several information came from the platform; please refer to the
driver's Header file in include/linux directory.
Several driver's information can be passed through the platform
These are included in the include/linux/stmmac.h header file
and detailed below as well:
struct plat_stmmacenet_data {
struct plat_stmmacenet_data {
int bus_id;
int phy_addr;
int interface;
struct stmmac_mdio_bus_data *mdio_bus_data;
int pbl;
int clk_csr;
int has_gmac;
@ -103,67 +107,135 @@ struct plat_stmmacenet_data {
int tx_coe;
int bugged_jumbo;
int pmt;
void (*fix_mac_speed)(void *priv, unsigned int speed);
void (*bus_setup)(unsigned long ioaddr);
#ifdef CONFIG_STM_DRIVERS
struct stm_pad_config *pad_config;
#endif
void *bsp_priv;
};
int force_sf_dma_mode;
void (*fix_mac_speed)(void *priv, unsigned int speed);
void (*bus_setup)(void __iomem *ioaddr);
int (*init)(struct platform_device *pdev);
void (*exit)(struct platform_device *pdev);
void *bsp_priv;
};
Where:
- pbl (Programmable Burst Length) is maximum number of
beats to be transferred in one DMA transaction.
GMAC also enables the 4xPBL by default.
- fix_mac_speed and bus_setup are used to configure internal target
registers (on STM platforms);
- has_gmac: GMAC core is on board (get it at run-time in the next step);
- bus_id: bus identifier.
- tx_coe: core is able to perform the tx csum in HW.
- enh_desc: if sets the MAC will use the enhanced descriptor structure.
- clk_csr: CSR Clock range selection.
- bugged_jumbo: some HWs are not able to perform the csum in HW for
over-sized frames due to limited buffer sizes. Setting this
flag the csum will be done in SW on JUMBO frames.
o bus_id: bus identifier.
o phy_addr: the physical address can be passed from the platform.
If it is set to -1 the driver will automatically
detect it at run-time by probing all the 32 addresses.
o interface: PHY device's interface.
o mdio_bus_data: specific platform fields for the MDIO bus.
o pbl: the Programmable Burst Length is maximum number of beats to
be transferred in one DMA transaction.
GMAC also enables the 4xPBL by default.
o clk_csr: CSR Clock range selection.
o has_gmac: uses the GMAC core.
o enh_desc: if sets the MAC will use the enhanced descriptor structure.
o tx_coe: core is able to perform the tx csum in HW.
o bugged_jumbo: some HWs are not able to perform the csum in HW for
over-sized frames due to limited buffer sizes.
Setting this flag the csum will be done in SW on
JUMBO frames.
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 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 .
o bus_setup: perform HW setup of the bus. For example, on some ST platforms
this field is used to configure the AMBA bridge to generate more
efficient STBus traffic.
o init/exit: callbacks used for calling a custom initialisation;
this is sometime necessary on some platforms (e.g. ST boxes)
where the HW needs to have set some PIO lines or system cfg
registers.
o custom_cfg: this is a custom configuration that can be passed while
initialising the resources.
struct plat_stmmacphy_data {
int bus_id;
int phy_addr;
unsigned int phy_mask;
int interface;
int (*phy_reset)(void *priv);
void *priv;
};
The we have:
struct stmmac_mdio_bus_data {
int bus_id;
int (*phy_reset)(void *priv);
unsigned int phy_mask;
int *irqs;
int probed_phy_irq;
};
Where:
- bus_id: bus identifier;
- phy_addr: physical address used for the attached phy device;
set it to -1 to get it at run-time;
- interface: physical MII interface mode;
- phy_reset: hook to reset HW function.
o bus_id: bus identifier;
o phy_reset: hook to reset the phy device attached to the bus.
o phy_mask: phy mask passed when register the MDIO bus within the driver.
o irqs: list of IRQs, one per PHY.
o probed_phy_irq: if irqs is NULL, use this for probed PHY.
SOURCES:
- Kconfig
- Makefile
- stmmac_main.c: main network device driver;
- stmmac_mdio.c: mdio functions;
- stmmac_ethtool.c: ethtool support;
- stmmac_timer.[ch]: timer code used for mitigating the driver dma interrupts
Only tested on ST40 platforms based.
- stmmac.h: private driver structure;
- common.h: common definitions and VFTs;
- descs.h: descriptor structure definitions;
- dwmac1000_core.c: GMAC core functions;
- dwmac1000_dma.c: dma functions for the GMAC chip;
- dwmac1000.h: specific header file for the GMAC;
- dwmac100_core: MAC 100 core and dma code;
- dwmac100_dma.c: dma funtions for the MAC chip;
- dwmac1000.h: specific header file for the MAC;
- dwmac_lib.c: generic DMA functions shared among chips
- enh_desc.c: functions for handling enhanced descriptors
- norm_desc.c: functions for handling normal descriptors
Below an example how the structures above are using on ST platforms.
TODO:
- XGMAC controller is not supported.
- Review the timer optimisation code to use an embedded device that seems to be
static struct plat_stmmacenet_data stxYYY_ethernet_platform_data = {
.pbl = 32,
.has_gmac = 0,
.enh_desc = 0,
.fix_mac_speed = stxYYY_ethernet_fix_mac_speed,
|
|-> to write an internal syscfg
| on this platform when the
| link speed changes from 10 to
| 100 and viceversa
.init = &stmmac_claim_resource,
|
|-> On ST SoC this calls own "PAD"
| manager framework to claim
| all the resources necessary
| (GPIO ...). The .custom_cfg field
| is used to pass a custom config.
};
Below the usage of the stmmac_mdio_bus_data: on this SoC, in fact,
there are two MAC cores: one MAC is for MDIO Bus/PHY emulation
with fixed_link support.
static struct stmmac_mdio_bus_data stmmac1_mdio_bus = {
.bus_id = 1,
|
|-> phy device on the bus_id 1
.phy_reset = phy_reset;
|
|-> function to provide the phy_reset on this board
.phy_mask = 0,
};
static struct fixed_phy_status stmmac0_fixed_phy_status = {
.link = 1,
.speed = 100,
.duplex = 1,
};
During the board's device_init we can configure the first
MAC for fixed_link by calling:
fixed_phy_add(PHY_POLL, 1, &stmmac0_fixed_phy_status));)
and the second one, with a real PHY device attached to the bus,
by using the stmmac_mdio_bus_data structure (to provide the id, the
reset procedure etc).
4.10) List of source files:
o Kconfig
o Makefile
o stmmac_main.c: main network device driver;
o stmmac_mdio.c: mdio functions;
o stmmac_ethtool.c: ethtool support;
o stmmac_timer.[ch]: timer code used for mitigating the driver dma interrupts
Only tested on ST40 platforms based.
o stmmac.h: private driver structure;
o common.h: common definitions and VFTs;
o descs.h: descriptor structure definitions;
o dwmac1000_core.c: GMAC core functions;
o dwmac1000_dma.c: dma functions for the GMAC chip;
o dwmac1000.h: specific header file for the GMAC;
o dwmac100_core: MAC 100 core and dma code;
o dwmac100_dma.c: dma funtions for the MAC chip;
o dwmac1000.h: specific header file for the MAC;
o dwmac_lib.c: generic DMA functions shared among chips
o enh_desc.c: functions for handling enhanced descriptors
o norm_desc.c: functions for handling normal descriptors
5) TODO:
o XGMAC is not supported.
o Review the timer optimisation code to use an embedded device that will be
available in new chip generations.

View File

@ -4290,8 +4290,8 @@ S: Maintained
F: drivers/usb/musb/
MYRICOM MYRI-10G 10GbE DRIVER (MYRI10GE)
M: Jon Mason <mason@myri.com>
M: Andrew Gallatin <gallatin@myri.com>
M: Brice Goglin <brice@myri.com>
L: netdev@vger.kernel.org
W: http://www.myri.com/scs/download-Myri10GE.html
S: Supported

View File

@ -20,6 +20,7 @@
#include <linux/spi/spi.h>
#include <linux/spi/flash.h>
#include <asm/io.h>
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
#include <mach/common.h>

View File

@ -8,6 +8,7 @@
* is licensed "as is" without any warranty of any kind, whether express
* or implied.
*/
#include <linux/dma-mapping.h>
#include <linux/init.h>
#include <linux/clk.h>
#include <linux/serial_8250.h>

View File

@ -17,6 +17,7 @@
#include <asm/cacheflush.h>
#include <asm/delay.h>
#include <asm/io.h>
#include <mach/da8xx.h>
#include <mach/sram.h>

View File

@ -26,6 +26,7 @@
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/interrupt.h>
#include <linux/err.h>
#include <linux/errno.h>
#include <linux/clk.h>
#include <linux/scatterlist.h>

View File

@ -13,6 +13,7 @@
*/
#include <linux/delay.h>
#include <linux/dma-mapping.h>
#include <linux/types.h>
#include <linux/init.h>
#include <linux/clk.h>

View File

@ -17,6 +17,7 @@
*
*/
#include <linux/dma-mapping.h>
#include <linux/serial_8250.h>
#include <linux/io.h>
#ifdef CONFIG_MTD_PHYSMAP

View File

@ -6,6 +6,7 @@
* the terms of the GNU General Public License version 2 as published by the
* Free Software Foundation.
*/
#include <linux/dma-mapping.h>
#include <asm/sizes.h>
#include <mach/mx23.h>
#include <mach/mx28.h>

View File

@ -6,6 +6,7 @@
* Free Software Foundation.
*/
#include <linux/compiler.h>
#include <linux/dma-mapping.h>
#include <linux/err.h>
#include <linux/init.h>

View File

@ -6,6 +6,7 @@
* the terms of the GNU General Public License version 2 as published by the
* Free Software Foundation.
*/
#include <linux/dma-mapping.h>
#include <asm/sizes.h>
#include <mach/mx28.h>
#include <mach/devices-common.h>

View File

@ -6,6 +6,7 @@
* the terms of the GNU General Public License version 2 as published by the
* Free Software Foundation.
*/
#include <linux/dma-mapping.h>
#include <asm/sizes.h>
#include <mach/hardware.h>
#include <mach/devices-common.h>

View File

@ -6,6 +6,7 @@
* the terms of the GNU General Public License version 2 as published by the
* Free Software Foundation.
*/
#include <linux/dma-mapping.h>
#include <mach/hardware.h>
#include <mach/devices-common.h>

View File

@ -6,6 +6,7 @@
* the terms of the GNU General Public License version 2 as published by the
* Free Software Foundation.
*/
#include <linux/dma-mapping.h>
#include <mach/hardware.h>
#include <mach/devices-common.h>

View File

@ -6,6 +6,7 @@
* the terms of the GNU General Public License version 2 as published by the
* Free Software Foundation.
*/
#include <linux/dma-mapping.h>
#include <mach/hardware.h>
#include <mach/devices-common.h>

View File

@ -6,6 +6,7 @@
* the terms of the GNU General Public License version 2 as published by the
* Free Software Foundation.
*/
#include <linux/dma-mapping.h>
#include <mach/hardware.h>
#include <mach/devices-common.h>

View File

@ -6,6 +6,7 @@
* the terms of the GNU General Public License version 2 as published by the
* Free Software Foundation.
*/
#include <linux/dma-mapping.h>
#include <mach/hardware.h>
#include <mach/devices-common.h>

View File

@ -10,6 +10,7 @@
#define STE_DMA40_H
#include <linux/dmaengine.h>
#include <linux/scatterlist.h>
#include <linux/workqueue.h>
#include <linux/interrupt.h>

View File

@ -16,6 +16,7 @@
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
#include <linux/interrupt.h>
#include <linux/module.h>
#include <asm/natfeat.h>
#include <asm/virtconvert.h>
@ -204,7 +205,6 @@ static struct net_device * __init nfeth_probe(int unit)
dev->irq = nfEtherIRQ;
dev->netdev_ops = &nfeth_netdev_ops;
dev->flags |= NETIF_F_NO_CSUM;
memcpy(dev->dev_addr, mac, ETH_ALEN);
priv = netdev_priv(dev);

View File

@ -134,6 +134,7 @@ config PPC
select GENERIC_IRQ_SHOW_LEVEL
select HAVE_RCU_TABLE_FREE if SMP
select HAVE_SYSCALL_TRACEPOINTS
select HAVE_BPF_JIT if (PPC64 && NET)
config EARLY_PRINTK
bool

View File

@ -154,7 +154,8 @@ core-y += arch/powerpc/kernel/ \
arch/powerpc/lib/ \
arch/powerpc/sysdev/ \
arch/powerpc/platforms/ \
arch/powerpc/math-emu/
arch/powerpc/math-emu/ \
arch/powerpc/net/
core-$(CONFIG_XMON) += arch/powerpc/xmon/
core-$(CONFIG_KVM) += arch/powerpc/kvm/

View File

@ -71,6 +71,42 @@
#define PPC_INST_ERATSX 0x7c000126
#define PPC_INST_ERATSX_DOT 0x7c000127
/* Misc instructions for BPF compiler */
#define PPC_INST_LD 0xe8000000
#define PPC_INST_LHZ 0xa0000000
#define PPC_INST_LWZ 0x80000000
#define PPC_INST_STD 0xf8000000
#define PPC_INST_STDU 0xf8000001
#define PPC_INST_MFLR 0x7c0802a6
#define PPC_INST_MTLR 0x7c0803a6
#define PPC_INST_CMPWI 0x2c000000
#define PPC_INST_CMPDI 0x2c200000
#define PPC_INST_CMPLW 0x7c000040
#define PPC_INST_CMPLWI 0x28000000
#define PPC_INST_ADDI 0x38000000
#define PPC_INST_ADDIS 0x3c000000
#define PPC_INST_ADD 0x7c000214
#define PPC_INST_SUB 0x7c000050
#define PPC_INST_BLR 0x4e800020
#define PPC_INST_BLRL 0x4e800021
#define PPC_INST_MULLW 0x7c0001d6
#define PPC_INST_MULHWU 0x7c000016
#define PPC_INST_MULLI 0x1c000000
#define PPC_INST_DIVWU 0x7c0003d6
#define PPC_INST_RLWINM 0x54000000
#define PPC_INST_RLDICR 0x78000004
#define PPC_INST_SLW 0x7c000030
#define PPC_INST_SRW 0x7c000430
#define PPC_INST_AND 0x7c000038
#define PPC_INST_ANDDOT 0x7c000039
#define PPC_INST_OR 0x7c000378
#define PPC_INST_ANDI 0x70000000
#define PPC_INST_ORI 0x60000000
#define PPC_INST_ORIS 0x64000000
#define PPC_INST_NEG 0x7c0000d0
#define PPC_INST_BRANCH 0x48000000
#define PPC_INST_BRANCH_COND 0x40800000
/* macros to insert fields into opcodes */
#define __PPC_RA(a) (((a) & 0x1f) << 16)
#define __PPC_RB(b) (((b) & 0x1f) << 11)
@ -83,6 +119,10 @@
#define __PPC_T_TLB(t) (((t) & 0x3) << 21)
#define __PPC_WC(w) (((w) & 0x3) << 21)
#define __PPC_WS(w) (((w) & 0x1f) << 11)
#define __PPC_SH(s) __PPC_WS(s)
#define __PPC_MB(s) (((s) & 0x1f) << 6)
#define __PPC_ME(s) (((s) & 0x1f) << 1)
#define __PPC_BI(s) (((s) & 0x1f) << 16)
/*
* Only use the larx hint bit on 64bit CPUs. e500v1/v2 based CPUs will treat a

View File

@ -0,0 +1,4 @@
#
# Arch-specific network modules
#
obj-$(CONFIG_BPF_JIT) += bpf_jit_64.o bpf_jit_comp.o

227
arch/powerpc/net/bpf_jit.h Normal file
View File

@ -0,0 +1,227 @@
/* bpf_jit.h: BPF JIT compiler for PPC64
*
* Copyright 2011 Matt Evans <matt@ozlabs.org>, IBM Corporation
*
* 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; version 2
* of the License.
*/
#ifndef _BPF_JIT_H
#define _BPF_JIT_H
#define BPF_PPC_STACK_LOCALS 32
#define BPF_PPC_STACK_BASIC (48+64)
#define BPF_PPC_STACK_SAVE (18*8)
#define BPF_PPC_STACKFRAME (BPF_PPC_STACK_BASIC+BPF_PPC_STACK_LOCALS+ \
BPF_PPC_STACK_SAVE)
#define BPF_PPC_SLOWPATH_FRAME (48+64)
/*
* Generated code register usage:
*
* As normal PPC C ABI (e.g. r1=sp, r2=TOC), with:
*
* skb r3 (Entry parameter)
* A register r4
* X register r5
* addr param r6
* r7-r10 scratch
* skb->data r14
* skb headlen r15 (skb->len - skb->data_len)
* m[0] r16
* m[...] ...
* m[15] r31
*/
#define r_skb 3
#define r_ret 3
#define r_A 4
#define r_X 5
#define r_addr 6
#define r_scratch1 7
#define r_D 14
#define r_HL 15
#define r_M 16
#ifndef __ASSEMBLY__
/*
* Assembly helpers from arch/powerpc/net/bpf_jit.S:
*/
extern u8 sk_load_word[], sk_load_half[], sk_load_byte[], sk_load_byte_msh[];
#define FUNCTION_DESCR_SIZE 24
/*
* 16-bit immediate helper macros: HA() is for use with sign-extending instrs
* (e.g. LD, ADDI). If the bottom 16 bits is "-ve", add another bit into the
* top half to negate the effect (i.e. 0xffff + 1 = 0x(1)0000).
*/
#define IMM_H(i) ((uintptr_t)(i)>>16)
#define IMM_HA(i) (((uintptr_t)(i)>>16) + \
(((uintptr_t)(i) & 0x8000) >> 15))
#define IMM_L(i) ((uintptr_t)(i) & 0xffff)
#define PLANT_INSTR(d, idx, instr) \
do { if (d) { (d)[idx] = instr; } idx++; } while (0)
#define EMIT(instr) PLANT_INSTR(image, ctx->idx, instr)
#define PPC_NOP() EMIT(PPC_INST_NOP)
#define PPC_BLR() EMIT(PPC_INST_BLR)
#define PPC_BLRL() EMIT(PPC_INST_BLRL)
#define PPC_MTLR(r) EMIT(PPC_INST_MTLR | __PPC_RT(r))
#define PPC_ADDI(d, a, i) EMIT(PPC_INST_ADDI | __PPC_RT(d) | \
__PPC_RA(a) | IMM_L(i))
#define PPC_MR(d, a) PPC_OR(d, a, a)
#define PPC_LI(r, i) PPC_ADDI(r, 0, i)
#define PPC_ADDIS(d, a, i) EMIT(PPC_INST_ADDIS | \
__PPC_RS(d) | __PPC_RA(a) | IMM_L(i))
#define PPC_LIS(r, i) PPC_ADDIS(r, 0, i)
#define PPC_STD(r, base, i) EMIT(PPC_INST_STD | __PPC_RS(r) | \
__PPC_RA(base) | ((i) & 0xfffc))
#define PPC_LD(r, base, i) EMIT(PPC_INST_LD | __PPC_RT(r) | \
__PPC_RA(base) | IMM_L(i))
#define PPC_LWZ(r, base, i) EMIT(PPC_INST_LWZ | __PPC_RT(r) | \
__PPC_RA(base) | IMM_L(i))
#define PPC_LHZ(r, base, i) EMIT(PPC_INST_LHZ | __PPC_RT(r) | \
__PPC_RA(base) | IMM_L(i))
/* Convenience helpers for the above with 'far' offsets: */
#define PPC_LD_OFFS(r, base, i) do { if ((i) < 32768) PPC_LD(r, base, i); \
else { PPC_ADDIS(r, base, IMM_HA(i)); \
PPC_LD(r, r, IMM_L(i)); } } while(0)
#define PPC_LWZ_OFFS(r, base, i) do { if ((i) < 32768) PPC_LWZ(r, base, i); \
else { PPC_ADDIS(r, base, IMM_HA(i)); \
PPC_LWZ(r, r, IMM_L(i)); } } while(0)
#define PPC_LHZ_OFFS(r, base, i) do { if ((i) < 32768) PPC_LHZ(r, base, i); \
else { PPC_ADDIS(r, base, IMM_HA(i)); \
PPC_LHZ(r, r, IMM_L(i)); } } while(0)
#define PPC_CMPWI(a, i) EMIT(PPC_INST_CMPWI | __PPC_RA(a) | IMM_L(i))
#define PPC_CMPDI(a, i) EMIT(PPC_INST_CMPDI | __PPC_RA(a) | IMM_L(i))
#define PPC_CMPLWI(a, i) EMIT(PPC_INST_CMPLWI | __PPC_RA(a) | IMM_L(i))
#define PPC_CMPLW(a, b) EMIT(PPC_INST_CMPLW | __PPC_RA(a) | __PPC_RB(b))
#define PPC_SUB(d, a, b) EMIT(PPC_INST_SUB | __PPC_RT(d) | \
__PPC_RB(a) | __PPC_RA(b))
#define PPC_ADD(d, a, b) EMIT(PPC_INST_ADD | __PPC_RT(d) | \
__PPC_RA(a) | __PPC_RB(b))
#define PPC_MUL(d, a, b) EMIT(PPC_INST_MULLW | __PPC_RT(d) | \
__PPC_RA(a) | __PPC_RB(b))
#define PPC_MULHWU(d, a, b) EMIT(PPC_INST_MULHWU | __PPC_RT(d) | \
__PPC_RA(a) | __PPC_RB(b))
#define PPC_MULI(d, a, i) EMIT(PPC_INST_MULLI | __PPC_RT(d) | \
__PPC_RA(a) | IMM_L(i))
#define PPC_DIVWU(d, a, b) EMIT(PPC_INST_DIVWU | __PPC_RT(d) | \
__PPC_RA(a) | __PPC_RB(b))
#define PPC_AND(d, a, b) EMIT(PPC_INST_AND | __PPC_RA(d) | \
__PPC_RS(a) | __PPC_RB(b))
#define PPC_ANDI(d, a, i) EMIT(PPC_INST_ANDI | __PPC_RA(d) | \
__PPC_RS(a) | IMM_L(i))
#define PPC_AND_DOT(d, a, b) EMIT(PPC_INST_ANDDOT | __PPC_RA(d) | \
__PPC_RS(a) | __PPC_RB(b))
#define PPC_OR(d, a, b) EMIT(PPC_INST_OR | __PPC_RA(d) | \
__PPC_RS(a) | __PPC_RB(b))
#define PPC_ORI(d, a, i) EMIT(PPC_INST_ORI | __PPC_RA(d) | \
__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_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) | \
__PPC_RS(a) | __PPC_RB(s))
/* slwi = rlwinm Rx, Ry, n, 0, 31-n */
#define PPC_SLWI(d, a, i) EMIT(PPC_INST_RLWINM | __PPC_RA(d) | \
__PPC_RS(a) | __PPC_SH(i) | \
__PPC_MB(0) | __PPC_ME(31-(i)))
/* srwi = rlwinm Rx, Ry, 32-n, n, 31 */
#define PPC_SRWI(d, a, i) EMIT(PPC_INST_RLWINM | __PPC_RA(d) | \
__PPC_RS(a) | __PPC_SH(32-(i)) | \
__PPC_MB(i) | __PPC_ME(31))
/* sldi = rldicr Rx, Ry, n, 63-n */
#define PPC_SLDI(d, a, i) EMIT(PPC_INST_RLDICR | __PPC_RA(d) | \
__PPC_RS(a) | __PPC_SH(i) | \
__PPC_MB(63-(i)) | (((i) & 0x20) >> 4))
#define PPC_NEG(d, a) EMIT(PPC_INST_NEG | __PPC_RT(d) | __PPC_RA(a))
/* Long jump; (unconditional 'branch') */
#define PPC_JMP(dest) EMIT(PPC_INST_BRANCH | \
(((dest) - (ctx->idx * 4)) & 0x03fffffc))
/* "cond" here covers BO:BI fields. */
#define PPC_BCC_SHORT(cond, dest) EMIT(PPC_INST_BRANCH_COND | \
(((cond) & 0x3ff) << 16) | \
(((dest) - (ctx->idx * 4)) & \
0xfffc))
#define PPC_LI32(d, i) do { PPC_LI(d, IMM_L(i)); \
if ((u32)(uintptr_t)(i) >= 32768) { \
PPC_ADDIS(d, d, IMM_HA(i)); \
} } while(0)
#define PPC_LI64(d, i) do { \
if (!((uintptr_t)(i) & 0xffffffff00000000ULL)) \
PPC_LI32(d, i); \
else { \
PPC_LIS(d, ((uintptr_t)(i) >> 48)); \
if ((uintptr_t)(i) & 0x0000ffff00000000ULL) \
PPC_ORI(d, d, \
((uintptr_t)(i) >> 32) & 0xffff); \
PPC_SLDI(d, d, 32); \
if ((uintptr_t)(i) & 0x00000000ffff0000ULL) \
PPC_ORIS(d, d, \
((uintptr_t)(i) >> 16) & 0xffff); \
if ((uintptr_t)(i) & 0x000000000000ffffULL) \
PPC_ORI(d, d, (uintptr_t)(i) & 0xffff); \
} } while (0);
static inline bool is_nearbranch(int offset)
{
return (offset < 32768) && (offset >= -32768);
}
/*
* The fly in the ointment of code size changing from pass to pass is
* avoided by padding the short branch case with a NOP. If code size differs
* with different branch reaches we will have the issue of code moving from
* one pass to the next and will need a few passes to converge on a stable
* state.
*/
#define PPC_BCC(cond, dest) do { \
if (is_nearbranch((dest) - (ctx->idx * 4))) { \
PPC_BCC_SHORT(cond, dest); \
PPC_NOP(); \
} else { \
/* Flip the 'T or F' bit to invert comparison */ \
PPC_BCC_SHORT(cond ^ COND_CMP_TRUE, (ctx->idx+2)*4); \
PPC_JMP(dest); \
} } while(0)
/* To create a branch condition, select a bit of cr0... */
#define CR0_LT 0
#define CR0_GT 1
#define CR0_EQ 2
/* ...and modify BO[3] */
#define COND_CMP_TRUE 0x100
#define COND_CMP_FALSE 0x000
/* Together, they make all required comparisons: */
#define COND_GT (CR0_GT | COND_CMP_TRUE)
#define COND_GE (CR0_LT | COND_CMP_FALSE)
#define COND_EQ (CR0_EQ | COND_CMP_TRUE)
#define COND_NE (CR0_EQ | COND_CMP_FALSE)
#define COND_LT (CR0_LT | COND_CMP_TRUE)
#define SEEN_DATAREF 0x10000 /* might call external helpers */
#define SEEN_XREG 0x20000 /* X reg is used */
#define SEEN_MEM 0x40000 /* SEEN_MEM+(1<<n) = use mem[n] for temporary
* storage */
#define SEEN_MEM_MSK 0x0ffff
struct codegen_context {
unsigned int seen;
unsigned int idx;
int pc_ret0; /* bpf index of first RET #0 instruction (if any) */
};
#endif
#endif

View File

@ -0,0 +1,138 @@
/* bpf_jit.S: Packet/header access helper functions
* for PPC64 BPF compiler.
*
* Copyright 2011 Matt Evans <matt@ozlabs.org>, IBM Corporation
*
* 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; version 2
* of the License.
*/
#include <asm/ppc_asm.h>
#include "bpf_jit.h"
/*
* All of these routines are called directly from generated code,
* whose register usage is:
*
* r3 skb
* r4,r5 A,X
* r6 *** address parameter to helper ***
* r7-r10 scratch
* r14 skb->data
* r15 skb headlen
* r16-31 M[]
*/
/*
* To consider: These helpers are so small it could be better to just
* generate them inline. Inline code can do the simple headlen check
* then branch directly to slow_path_XXX if required. (In fact, could
* load a spare GPR with the address of slow_path_generic and pass size
* as an argument, making the call site a mtlr, li and bllr.)
*
* Technically, the "is addr < 0" check is unnecessary & slowing down
* the ABS path, as it's statically checked on generation.
*/
.globl sk_load_word
sk_load_word:
cmpdi r_addr, 0
blt bpf_error
/* Are we accessing past headlen? */
subi r_scratch1, r_HL, 4
cmpd r_scratch1, r_addr
blt bpf_slow_path_word
/* Nope, just hitting the header. cr0 here is eq or gt! */
lwzx r_A, r_D, r_addr
/* When big endian we don't need to byteswap. */
blr /* Return success, cr0 != LT */
.globl sk_load_half
sk_load_half:
cmpdi r_addr, 0
blt bpf_error
subi r_scratch1, r_HL, 2
cmpd r_scratch1, r_addr
blt bpf_slow_path_half
lhzx r_A, r_D, r_addr
blr
.globl sk_load_byte
sk_load_byte:
cmpdi r_addr, 0
blt bpf_error
cmpd r_HL, r_addr
ble bpf_slow_path_byte
lbzx r_A, r_D, r_addr
blr
/*
* BPF_S_LDX_B_MSH: ldxb 4*([offset]&0xf)
* r_addr is the offset value, already known positive
*/
.globl sk_load_byte_msh
sk_load_byte_msh:
cmpd r_HL, r_addr
ble bpf_slow_path_byte_msh
lbzx r_X, r_D, r_addr
rlwinm r_X, r_X, 2, 32-4-2, 31-2
blr
bpf_error:
/* Entered with cr0 = lt */
li r3, 0
/* Generated code will 'blt epilogue', returning 0. */
blr
/* Call out to skb_copy_bits:
* We'll need to back up our volatile regs first; we have
* local variable space at r1+(BPF_PPC_STACK_BASIC).
* Allocate a new stack frame here to remain ABI-compliant in
* stashing LR.
*/
#define bpf_slow_path_common(SIZE) \
mflr r0; \
std r0, 16(r1); \
/* R3 goes in parameter space of caller's frame */ \
std r_skb, (BPF_PPC_STACKFRAME+48)(r1); \
std r_A, (BPF_PPC_STACK_BASIC+(0*8))(r1); \
std r_X, (BPF_PPC_STACK_BASIC+(1*8))(r1); \
addi r5, r1, BPF_PPC_STACK_BASIC+(2*8); \
stdu r1, -BPF_PPC_SLOWPATH_FRAME(r1); \
/* R3 = r_skb, as passed */ \
mr r4, r_addr; \
li r6, SIZE; \
bl skb_copy_bits; \
/* R3 = 0 on success */ \
addi r1, r1, BPF_PPC_SLOWPATH_FRAME; \
ld r0, 16(r1); \
ld r_A, (BPF_PPC_STACK_BASIC+(0*8))(r1); \
ld r_X, (BPF_PPC_STACK_BASIC+(1*8))(r1); \
mtlr r0; \
cmpdi r3, 0; \
blt bpf_error; /* cr0 = LT */ \
ld r_skb, (BPF_PPC_STACKFRAME+48)(r1); \
/* Great success! */
bpf_slow_path_word:
bpf_slow_path_common(4)
/* Data value is on stack, and cr0 != LT */
lwz r_A, BPF_PPC_STACK_BASIC+(2*8)(r1)
blr
bpf_slow_path_half:
bpf_slow_path_common(2)
lhz r_A, BPF_PPC_STACK_BASIC+(2*8)(r1)
blr
bpf_slow_path_byte:
bpf_slow_path_common(1)
lbz r_A, BPF_PPC_STACK_BASIC+(2*8)(r1)
blr
bpf_slow_path_byte_msh:
bpf_slow_path_common(1)
lbz r_X, BPF_PPC_STACK_BASIC+(2*8)(r1)
rlwinm r_X, r_X, 2, 32-4-2, 31-2
blr

View File

@ -0,0 +1,694 @@
/* bpf_jit_comp.c: BPF JIT compiler for PPC64
*
* Copyright 2011 Matt Evans <matt@ozlabs.org>, IBM Corporation
*
* Based on the x86 BPF compiler, by Eric Dumazet (eric.dumazet@gmail.com)
*
* 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; version 2
* of the License.
*/
#include <linux/moduleloader.h>
#include <asm/cacheflush.h>
#include <linux/netdevice.h>
#include <linux/filter.h>
#include "bpf_jit.h"
#ifndef __BIG_ENDIAN
/* There are endianness assumptions herein. */
#error "Little-endian PPC not supported in BPF compiler"
#endif
int bpf_jit_enable __read_mostly;
static inline void bpf_flush_icache(void *start, void *end)
{
smp_wmb();
flush_icache_range((unsigned long)start, (unsigned long)end);
}
static void bpf_jit_build_prologue(struct sk_filter *fp, u32 *image,
struct codegen_context *ctx)
{
int i;
const struct sock_filter *filter = fp->insns;
if (ctx->seen & (SEEN_MEM | SEEN_DATAREF)) {
/* Make stackframe */
if (ctx->seen & SEEN_DATAREF) {
/* If we call any helpers (for loads), save LR */
EMIT(PPC_INST_MFLR | __PPC_RT(0));
PPC_STD(0, 1, 16);
/* Back up non-volatile regs. */
PPC_STD(r_D, 1, -(8*(32-r_D)));
PPC_STD(r_HL, 1, -(8*(32-r_HL)));
}
if (ctx->seen & SEEN_MEM) {
/*
* Conditionally save regs r15-r31 as some will be used
* for M[] data.
*/
for (i = r_M; i < (r_M+16); i++) {
if (ctx->seen & (1 << (i-r_M)))
PPC_STD(i, 1, -(8*(32-i)));
}
}
EMIT(PPC_INST_STDU | __PPC_RS(1) | __PPC_RA(1) |
(-BPF_PPC_STACKFRAME & 0xfffc));
}
if (ctx->seen & SEEN_DATAREF) {
/*
* If this filter needs to access skb data,
* prepare r_D and r_HL:
* r_HL = skb->len - skb->data_len
* r_D = skb->data
*/
PPC_LWZ_OFFS(r_scratch1, r_skb, offsetof(struct sk_buff,
data_len));
PPC_LWZ_OFFS(r_HL, r_skb, offsetof(struct sk_buff, len));
PPC_SUB(r_HL, r_HL, r_scratch1);
PPC_LD_OFFS(r_D, r_skb, offsetof(struct sk_buff, data));
}
if (ctx->seen & SEEN_XREG) {
/*
* TODO: Could also detect whether first instr. sets X and
* avoid this (as below, with A).
*/
PPC_LI(r_X, 0);
}
switch (filter[0].code) {
case BPF_S_RET_K:
case BPF_S_LD_W_LEN:
case BPF_S_ANC_PROTOCOL:
case BPF_S_ANC_IFINDEX:
case BPF_S_ANC_MARK:
case BPF_S_ANC_RXHASH:
case BPF_S_ANC_CPU:
case BPF_S_ANC_QUEUE:
case BPF_S_LD_W_ABS:
case BPF_S_LD_H_ABS:
case BPF_S_LD_B_ABS:
/* first instruction sets A register (or is RET 'constant') */
break;
default:
/* make sure we dont leak kernel information to user */
PPC_LI(r_A, 0);
}
}
static void bpf_jit_build_epilogue(u32 *image, struct codegen_context *ctx)
{
int i;
if (ctx->seen & (SEEN_MEM | SEEN_DATAREF)) {
PPC_ADDI(1, 1, BPF_PPC_STACKFRAME);
if (ctx->seen & SEEN_DATAREF) {
PPC_LD(0, 1, 16);
PPC_MTLR(0);
PPC_LD(r_D, 1, -(8*(32-r_D)));
PPC_LD(r_HL, 1, -(8*(32-r_HL)));
}
if (ctx->seen & SEEN_MEM) {
/* Restore any saved non-vol registers */
for (i = r_M; i < (r_M+16); i++) {
if (ctx->seen & (1 << (i-r_M)))
PPC_LD(i, 1, -(8*(32-i)));
}
}
}
/* The RETs have left a return value in R3. */
PPC_BLR();
}
/* Assemble the body code between the prologue & epilogue. */
static int bpf_jit_build_body(struct sk_filter *fp, u32 *image,
struct codegen_context *ctx,
unsigned int *addrs)
{
const struct sock_filter *filter = fp->insns;
int flen = fp->len;
u8 *func;
unsigned int true_cond;
int i;
/* Start of epilogue code */
unsigned int exit_addr = addrs[flen];
for (i = 0; i < flen; i++) {
unsigned int K = filter[i].k;
/*
* addrs[] maps a BPF bytecode address into a real offset from
* the start of the body code.
*/
addrs[i] = ctx->idx * 4;
switch (filter[i].code) {
/*** ALU ops ***/
case BPF_S_ALU_ADD_X: /* A += X; */
ctx->seen |= SEEN_XREG;
PPC_ADD(r_A, r_A, r_X);
break;
case BPF_S_ALU_ADD_K: /* A += K; */
if (!K)
break;
PPC_ADDI(r_A, r_A, IMM_L(K));
if (K >= 32768)
PPC_ADDIS(r_A, r_A, IMM_HA(K));
break;
case BPF_S_ALU_SUB_X: /* A -= X; */
ctx->seen |= SEEN_XREG;
PPC_SUB(r_A, r_A, r_X);
break;
case BPF_S_ALU_SUB_K: /* A -= K */
if (!K)
break;
PPC_ADDI(r_A, r_A, IMM_L(-K));
if (K >= 32768)
PPC_ADDIS(r_A, r_A, IMM_HA(-K));
break;
case BPF_S_ALU_MUL_X: /* A *= X; */
ctx->seen |= SEEN_XREG;
PPC_MUL(r_A, r_A, r_X);
break;
case BPF_S_ALU_MUL_K: /* A *= K */
if (K < 32768)
PPC_MULI(r_A, r_A, K);
else {
PPC_LI32(r_scratch1, K);
PPC_MUL(r_A, r_A, r_scratch1);
}
break;
case BPF_S_ALU_DIV_X: /* A /= X; */
ctx->seen |= SEEN_XREG;
PPC_CMPWI(r_X, 0);
if (ctx->pc_ret0 != -1) {
PPC_BCC(COND_EQ, addrs[ctx->pc_ret0]);
} else {
/*
* Exit, returning 0; first pass hits here
* (longer worst-case code size).
*/
PPC_BCC_SHORT(COND_NE, (ctx->idx*4)+12);
PPC_LI(r_ret, 0);
PPC_JMP(exit_addr);
}
PPC_DIVWU(r_A, r_A, r_X);
break;
case BPF_S_ALU_DIV_K: /* A = reciprocal_divide(A, K); */
PPC_LI32(r_scratch1, K);
/* Top 32 bits of 64bit result -> A */
PPC_MULHWU(r_A, r_A, r_scratch1);
break;
case BPF_S_ALU_AND_X:
ctx->seen |= SEEN_XREG;
PPC_AND(r_A, r_A, r_X);
break;
case BPF_S_ALU_AND_K:
if (!IMM_H(K))
PPC_ANDI(r_A, r_A, K);
else {
PPC_LI32(r_scratch1, K);
PPC_AND(r_A, r_A, r_scratch1);
}
break;
case BPF_S_ALU_OR_X:
ctx->seen |= SEEN_XREG;
PPC_OR(r_A, r_A, r_X);
break;
case BPF_S_ALU_OR_K:
if (IMM_L(K))
PPC_ORI(r_A, r_A, IMM_L(K));
if (K >= 65536)
PPC_ORIS(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);
break;
case BPF_S_ALU_LSH_K:
if (K == 0)
break;
else
PPC_SLWI(r_A, r_A, K);
break;
case BPF_S_ALU_RSH_X: /* A >>= X; */
ctx->seen |= SEEN_XREG;
PPC_SRW(r_A, r_A, r_X);
break;
case BPF_S_ALU_RSH_K: /* A >>= K; */
if (K == 0)
break;
else
PPC_SRWI(r_A, r_A, K);
break;
case BPF_S_ALU_NEG:
PPC_NEG(r_A, r_A);
break;
case BPF_S_RET_K:
PPC_LI32(r_ret, K);
if (!K) {
if (ctx->pc_ret0 == -1)
ctx->pc_ret0 = i;
}
/*
* If this isn't the very last instruction, branch to
* the epilogue if we've stuff to clean up. Otherwise,
* if there's nothing to tidy, just return. If we /are/
* the last instruction, we're about to fall through to
* the epilogue to return.
*/
if (i != flen - 1) {
/*
* Note: 'seen' is properly valid only on pass
* #2. Both parts of this conditional are the
* same instruction size though, meaning the
* first pass will still correctly determine the
* code size/addresses.
*/
if (ctx->seen)
PPC_JMP(exit_addr);
else
PPC_BLR();
}
break;
case BPF_S_RET_A:
PPC_MR(r_ret, r_A);
if (i != flen - 1) {
if (ctx->seen)
PPC_JMP(exit_addr);
else
PPC_BLR();
}
break;
case BPF_S_MISC_TAX: /* X = A */
PPC_MR(r_X, r_A);
break;
case BPF_S_MISC_TXA: /* A = X */
ctx->seen |= SEEN_XREG;
PPC_MR(r_A, r_X);
break;
/*** Constant loads/M[] access ***/
case BPF_S_LD_IMM: /* A = K */
PPC_LI32(r_A, K);
break;
case BPF_S_LDX_IMM: /* X = K */
PPC_LI32(r_X, K);
break;
case BPF_S_LD_MEM: /* A = mem[K] */
PPC_MR(r_A, r_M + (K & 0xf));
ctx->seen |= SEEN_MEM | (1<<(K & 0xf));
break;
case BPF_S_LDX_MEM: /* X = mem[K] */
PPC_MR(r_X, r_M + (K & 0xf));
ctx->seen |= SEEN_MEM | (1<<(K & 0xf));
break;
case BPF_S_ST: /* mem[K] = A */
PPC_MR(r_M + (K & 0xf), r_A);
ctx->seen |= SEEN_MEM | (1<<(K & 0xf));
break;
case BPF_S_STX: /* mem[K] = X */
PPC_MR(r_M + (K & 0xf), r_X);
ctx->seen |= SEEN_XREG | SEEN_MEM | (1<<(K & 0xf));
break;
case BPF_S_LD_W_LEN: /* A = skb->len; */
BUILD_BUG_ON(FIELD_SIZEOF(struct sk_buff, len) != 4);
PPC_LWZ_OFFS(r_A, r_skb, offsetof(struct sk_buff, len));
break;
case BPF_S_LDX_W_LEN: /* X = skb->len; */
PPC_LWZ_OFFS(r_X, r_skb, offsetof(struct sk_buff, len));
break;
/*** Ancillary info loads ***/
/* None of the BPF_S_ANC* codes appear to be passed by
* sk_chk_filter(). The interpreter and the x86 BPF
* compiler implement them so we do too -- they may be
* planted in future.
*/
case BPF_S_ANC_PROTOCOL: /* A = ntohs(skb->protocol); */
BUILD_BUG_ON(FIELD_SIZEOF(struct sk_buff,
protocol) != 2);
PPC_LHZ_OFFS(r_A, r_skb, offsetof(struct sk_buff,
protocol));
/* ntohs is a NOP with BE loads. */
break;
case BPF_S_ANC_IFINDEX:
PPC_LD_OFFS(r_scratch1, r_skb, offsetof(struct sk_buff,
dev));
PPC_CMPDI(r_scratch1, 0);
if (ctx->pc_ret0 != -1) {
PPC_BCC(COND_EQ, addrs[ctx->pc_ret0]);
} else {
/* Exit, returning 0; first pass hits here. */
PPC_BCC_SHORT(COND_NE, (ctx->idx*4)+12);
PPC_LI(r_ret, 0);
PPC_JMP(exit_addr);
}
BUILD_BUG_ON(FIELD_SIZEOF(struct net_device,
ifindex) != 4);
PPC_LWZ_OFFS(r_A, r_scratch1,
offsetof(struct net_device, ifindex));
break;
case BPF_S_ANC_MARK:
BUILD_BUG_ON(FIELD_SIZEOF(struct sk_buff, mark) != 4);
PPC_LWZ_OFFS(r_A, r_skb, offsetof(struct sk_buff,
mark));
break;
case BPF_S_ANC_RXHASH:
BUILD_BUG_ON(FIELD_SIZEOF(struct sk_buff, rxhash) != 4);
PPC_LWZ_OFFS(r_A, r_skb, offsetof(struct sk_buff,
rxhash));
break;
case BPF_S_ANC_QUEUE:
BUILD_BUG_ON(FIELD_SIZEOF(struct sk_buff,
queue_mapping) != 2);
PPC_LHZ_OFFS(r_A, r_skb, offsetof(struct sk_buff,
queue_mapping));
break;
case BPF_S_ANC_CPU:
#ifdef CONFIG_SMP
/*
* PACA ptr is r13:
* raw_smp_processor_id() = local_paca->paca_index
*/
BUILD_BUG_ON(FIELD_SIZEOF(struct paca_struct,
paca_index) != 2);
PPC_LHZ_OFFS(r_A, 13,
offsetof(struct paca_struct, paca_index));
#else
PPC_LI(r_A, 0);
#endif
break;
/*** Absolute loads from packet header/data ***/
case BPF_S_LD_W_ABS:
func = sk_load_word;
goto common_load;
case BPF_S_LD_H_ABS:
func = sk_load_half;
goto common_load;
case BPF_S_LD_B_ABS:
func = sk_load_byte;
common_load:
/*
* Load from [K]. Reference with the (negative)
* SKF_NET_OFF/SKF_LL_OFF offsets is unsupported.
*/
ctx->seen |= SEEN_DATAREF;
if ((int)K < 0)
return -ENOTSUPP;
PPC_LI64(r_scratch1, func);
PPC_MTLR(r_scratch1);
PPC_LI32(r_addr, K);
PPC_BLRL();
/*
* Helper returns 'lt' condition on error, and an
* appropriate return value in r3
*/
PPC_BCC(COND_LT, exit_addr);
break;
/*** Indirect loads from packet header/data ***/
case BPF_S_LD_W_IND:
func = sk_load_word;
goto common_load_ind;
case BPF_S_LD_H_IND:
func = sk_load_half;
goto common_load_ind;
case BPF_S_LD_B_IND:
func = sk_load_byte;
common_load_ind:
/*
* Load from [X + K]. Negative offsets are tested for
* in the helper functions, and result in a 'ret 0'.
*/
ctx->seen |= SEEN_DATAREF | SEEN_XREG;
PPC_LI64(r_scratch1, func);
PPC_MTLR(r_scratch1);
PPC_ADDI(r_addr, r_X, IMM_L(K));
if (K >= 32768)
PPC_ADDIS(r_addr, r_addr, IMM_HA(K));
PPC_BLRL();
/* If error, cr0.LT set */
PPC_BCC(COND_LT, exit_addr);
break;
case BPF_S_LDX_B_MSH:
/*
* x86 version drops packet (RET 0) when K<0, whereas
* interpreter does allow K<0 (__load_pointer, special
* ancillary data). common_load returns ENOTSUPP if K<0,
* so we fall back to interpreter & filter works.
*/
func = sk_load_byte_msh;
goto common_load;
break;
/*** Jump and branches ***/
case BPF_S_JMP_JA:
if (K != 0)
PPC_JMP(addrs[i + 1 + K]);
break;
case BPF_S_JMP_JGT_K:
case BPF_S_JMP_JGT_X:
true_cond = COND_GT;
goto cond_branch;
case BPF_S_JMP_JGE_K:
case BPF_S_JMP_JGE_X:
true_cond = COND_GE;
goto cond_branch;
case BPF_S_JMP_JEQ_K:
case BPF_S_JMP_JEQ_X:
true_cond = COND_EQ;
goto cond_branch;
case BPF_S_JMP_JSET_K:
case BPF_S_JMP_JSET_X:
true_cond = COND_NE;
/* Fall through */
cond_branch:
/* same targets, can avoid doing the test :) */
if (filter[i].jt == filter[i].jf) {
if (filter[i].jt > 0)
PPC_JMP(addrs[i + 1 + filter[i].jt]);
break;
}
switch (filter[i].code) {
case BPF_S_JMP_JGT_X:
case BPF_S_JMP_JGE_X:
case BPF_S_JMP_JEQ_X:
ctx->seen |= SEEN_XREG;
PPC_CMPLW(r_A, r_X);
break;
case BPF_S_JMP_JSET_X:
ctx->seen |= SEEN_XREG;
PPC_AND_DOT(r_scratch1, r_A, r_X);
break;
case BPF_S_JMP_JEQ_K:
case BPF_S_JMP_JGT_K:
case BPF_S_JMP_JGE_K:
if (K < 32768)
PPC_CMPLWI(r_A, K);
else {
PPC_LI32(r_scratch1, K);
PPC_CMPLW(r_A, r_scratch1);
}
break;
case BPF_S_JMP_JSET_K:
if (K < 32768)
/* PPC_ANDI is /only/ dot-form */
PPC_ANDI(r_scratch1, r_A, K);
else {
PPC_LI32(r_scratch1, K);
PPC_AND_DOT(r_scratch1, r_A,
r_scratch1);
}
break;
}
/* Sometimes branches are constructed "backward", with
* the false path being the branch and true path being
* a fallthrough to the next instruction.
*/
if (filter[i].jt == 0)
/* Swap the sense of the branch */
PPC_BCC(true_cond ^ COND_CMP_TRUE,
addrs[i + 1 + filter[i].jf]);
else {
PPC_BCC(true_cond, addrs[i + 1 + filter[i].jt]);
if (filter[i].jf != 0)
PPC_JMP(addrs[i + 1 + filter[i].jf]);
}
break;
default:
/* The filter contains something cruel & unusual.
* We don't handle it, but also there shouldn't be
* anything missing from our list.
*/
if (printk_ratelimit())
pr_err("BPF filter opcode %04x (@%d) unsupported\n",
filter[i].code, i);
return -ENOTSUPP;
}
}
/* Set end-of-body-code address for exit. */
addrs[i] = ctx->idx * 4;
return 0;
}
void bpf_jit_compile(struct sk_filter *fp)
{
unsigned int proglen;
unsigned int alloclen;
u32 *image = NULL;
u32 *code_base;
unsigned int *addrs;
struct codegen_context cgctx;
int pass;
int flen = fp->len;
if (!bpf_jit_enable)
return;
addrs = kzalloc((flen+1) * sizeof(*addrs), GFP_KERNEL);
if (addrs == NULL)
return;
/*
* There are multiple assembly passes as the generated code will change
* size as it settles down, figuring out the max branch offsets/exit
* paths required.
*
* The range of standard conditional branches is +/- 32Kbytes. Since
* BPF_MAXINSNS = 4096, we can only jump from (worst case) start to
* finish with 8 bytes/instruction. Not feasible, so long jumps are
* used, distinct from short branches.
*
* Current:
*
* For now, both branch types assemble to 2 words (short branches padded
* with a NOP); this is less efficient, but assembly will always complete
* after exactly 3 passes:
*
* First pass: No code buffer; Program is "faux-generated" -- no code
* emitted but maximum size of output determined (and addrs[] filled
* in). Also, we note whether we use M[], whether we use skb data, etc.
* All generation choices assumed to be 'worst-case', e.g. branches all
* far (2 instructions), return path code reduction not available, etc.
*
* Second pass: Code buffer allocated with size determined previously.
* Prologue generated to support features we have seen used. Exit paths
* determined and addrs[] is filled in again, as code may be slightly
* smaller as a result.
*
* Third pass: Code generated 'for real', and branch destinations
* determined from now-accurate addrs[] map.
*
* Ideal:
*
* If we optimise this, near branches will be shorter. On the
* first assembly pass, we should err on the side of caution and
* generate the biggest code. On subsequent passes, branches will be
* generated short or long and code size will reduce. With smaller
* code, more branches may fall into the short category, and code will
* reduce more.
*
* Finally, if we see one pass generate code the same size as the
* previous pass we have converged and should now generate code for
* real. Allocating at the end will also save the memory that would
* otherwise be wasted by the (small) current code shrinkage.
* Preferably, we should do a small number of passes (e.g. 5) and if we
* haven't converged by then, get impatient and force code to generate
* as-is, even if the odd branch would be left long. The chances of a
* long jump are tiny with all but the most enormous of BPF filter
* inputs, so we should usually converge on the third pass.
*/
cgctx.idx = 0;
cgctx.seen = 0;
cgctx.pc_ret0 = -1;
/* Scouting faux-generate pass 0 */
if (bpf_jit_build_body(fp, 0, &cgctx, addrs))
/* We hit something illegal or unsupported. */
goto out;
/*
* Pretend to build prologue, given the features we've seen. This will
* update ctgtx.idx as it pretends to output instructions, then we can
* calculate total size from idx.
*/
bpf_jit_build_prologue(fp, 0, &cgctx);
bpf_jit_build_epilogue(0, &cgctx);
proglen = cgctx.idx * 4;
alloclen = proglen + FUNCTION_DESCR_SIZE;
image = module_alloc(max_t(unsigned int, alloclen,
sizeof(struct work_struct)));
if (!image)
goto out;
code_base = image + (FUNCTION_DESCR_SIZE/4);
/* Code generation passes 1-2 */
for (pass = 1; pass < 3; pass++) {
/* Now build the prologue, body code & epilogue for real. */
cgctx.idx = 0;
bpf_jit_build_prologue(fp, code_base, &cgctx);
bpf_jit_build_body(fp, code_base, &cgctx, addrs);
bpf_jit_build_epilogue(code_base, &cgctx);
if (bpf_jit_enable > 1)
pr_info("Pass %d: shrink = %d, seen = 0x%x\n", pass,
proglen - (cgctx.idx * 4), cgctx.seen);
}
if (bpf_jit_enable > 1)
pr_info("flen=%d proglen=%u pass=%d image=%p\n",
flen, proglen, pass, image);
if (image) {
if (bpf_jit_enable > 1)
print_hex_dump(KERN_ERR, "JIT code: ",
DUMP_PREFIX_ADDRESS,
16, 1, code_base,
proglen, false);
bpf_flush_icache(code_base, code_base + (proglen/4));
/* Function descriptor nastiness: Address + TOC */
((u64 *)image)[0] = (u64)code_base;
((u64 *)image)[1] = local_paca->kernel_toc;
fp->bpf_func = (void *)image;
}
out:
kfree(addrs);
return;
}
static void jit_free_defer(struct work_struct *arg)
{
module_free(NULL, arg);
}
/* run from softirq, we must use a work_struct to call
* module_free() from process context
*/
void bpf_jit_free(struct sk_filter *fp)
{
if (fp->bpf_func != sk_run_filter) {
struct work_struct *work = (struct work_struct *)fp->bpf_func;
INIT_WORK(work, jit_free_defer);
schedule_work(work);
}
}

View File

@ -36,6 +36,7 @@
#include <asm/bootparam.h>
#include <asm/pgtable.h>
#include <asm/pgalloc.h>
#include <asm/swiotlb.h>
#include <asm/fixmap.h>
#include <asm/proto.h>
#include <asm/setup.h>

View File

@ -21,6 +21,7 @@
*/
#include <linux/async_tx.h>
#include <linux/gfp.h>
#include <linux/mm.h>
#include <linux/random.h>
#undef pr

View File

@ -94,8 +94,6 @@ source "drivers/memstick/Kconfig"
source "drivers/leds/Kconfig"
source "drivers/nfc/Kconfig"
source "drivers/accessibility/Kconfig"
source "drivers/infiniband/Kconfig"

View File

@ -122,3 +122,4 @@ obj-y += ieee802154/
obj-y += clk/
obj-$(CONFIG_HWSPINLOCK) += hwspinlock/
obj-$(CONFIG_NFC) += nfc/

View File

@ -813,7 +813,7 @@ static void fill_rx_pool (amb_dev * dev, unsigned char pool,
return;
}
// top up all RX pools (can also be called as a bottom half)
// top up all RX pools
static void fill_rx_pools (amb_dev * dev) {
unsigned char pool;
@ -872,11 +872,7 @@ static irqreturn_t interrupt_handler(int irq, void *dev_id) {
++irq_work;
if (irq_work) {
#ifdef FILL_RX_POOLS_IN_BH
schedule_work (&dev->bh);
#else
fill_rx_pools (dev);
#endif
PRINTD (DBG_IRQ, "work done: %u", irq_work);
} else {
@ -2154,11 +2150,6 @@ static void setup_dev(amb_dev *dev, struct pci_dev *pci_dev)
dev->tx_avail = ATM_OC3_PCR;
dev->rx_avail = ATM_OC3_PCR;
#ifdef FILL_RX_POOLS_IN_BH
// initialise bottom half
INIT_WORK(&dev->bh, (void (*)(void *)) fill_rx_pools, dev);
#endif
// semaphore for txer/rxer modifications - we cannot use a
// spinlock as the critical region needs to switch processes
mutex_init(&dev->vcc_sf);

View File

@ -630,10 +630,6 @@ struct amb_dev {
u32 iobase;
u32 * membase;
#ifdef FILL_RX_POOLS_IN_BH
struct work_struct bh;
#endif
amb_cq cq;
amb_txq txq;
amb_rxq rxq[NUM_RX_POOLS];

View File

@ -8,6 +8,7 @@
#include <linux/atm.h>
#include <linux/atmdev.h>
#include <linux/interrupt.h>
#include <linux/sonet.h>
#include <linux/skbuff.h>
#include <linux/time.h>

View File

@ -44,6 +44,7 @@
#include <linux/ioport.h> /* for request_region */
#include <linux/uio.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/capability.h>
#include <linux/bitops.h>
#include <linux/slab.h>

View File

@ -38,6 +38,7 @@
#include <linux/delay.h>
#include <linux/uio.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/ioport.h>
#include <linux/wait.h>
#include <linux/slab.h>

View File

@ -37,6 +37,7 @@
#include <linux/atm.h>
#include <linux/delay.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/bitops.h>
#include <linux/wait.h>
#include <linux/jiffies.h>

View File

@ -53,6 +53,7 @@
#include <linux/delay.h>
#include <linux/uio.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/wait.h>
#include <linux/slab.h>
#include <asm/system.h>

View File

@ -1947,7 +1947,6 @@ static int __devinit lanai_pci_start(struct lanai_dev *lanai)
{
struct pci_dev *pci = lanai->pci;
int result;
u16 w;
if (pci_enable_device(pci) != 0) {
printk(KERN_ERR DEV_LABEL "(itf %d): can't enable "
@ -1965,13 +1964,7 @@ static int __devinit lanai_pci_start(struct lanai_dev *lanai)
"(itf %d): No suitable DMA available.\n", lanai->number);
return -EBUSY;
}
result = pci_read_config_word(pci, PCI_SUBSYSTEM_ID, &w);
if (result != PCIBIOS_SUCCESSFUL) {
printk(KERN_ERR DEV_LABEL "(itf %d): can't read "
"PCI_SUBSYSTEM_ID: %d\n", lanai->number, result);
return -EINVAL;
}
result = check_board_id_and_rev("PCI", w, NULL);
result = check_board_id_and_rev("PCI", pci->subsystem_device, NULL);
if (result != 0)
return result;
/* Set latency timer to zero as per lanai docs */

View File

@ -16,6 +16,7 @@
#include <linux/delay.h>
#include <linux/uio.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/dma-mapping.h>
#include <linux/atm_zatm.h>
#include <linux/capability.h>

View File

@ -13,6 +13,11 @@ config BCMA
Bus driver for Broadcom specific Advanced Microcontroller Bus
Architecture.
# Support for Block-I/O. SELECT this from the driver that needs it.
config BCMA_BLOCKIO
bool
depends on BCMA
config BCMA_HOST_PCI_POSSIBLE
bool
depends on BCMA && PCI = y
@ -22,6 +27,12 @@ config BCMA_HOST_PCI
bool "Support for BCMA on PCI-host bus"
depends on BCMA_HOST_PCI_POSSIBLE
config BCMA_DRIVER_PCI_HOSTMODE
bool "Driver for PCI core working in hostmode"
depends on BCMA && MIPS
help
PCI core hostmode operation (external PCI bus).
config BCMA_DEBUG
bool "BCMA debugging"
depends on BCMA

View File

@ -1,6 +1,7 @@
bcma-y += main.o scan.o core.o
bcma-y += main.o scan.o core.o sprom.o
bcma-y += driver_chipcommon.o driver_chipcommon_pmu.o
bcma-y += driver_pci.o
bcma-$(CONFIG_BCMA_DRIVER_PCI_HOSTMODE) += driver_pci_host.o
bcma-$(CONFIG_BCMA_HOST_PCI) += host_pci.o
obj-$(CONFIG_BCMA) += bcma.o

View File

@ -13,16 +13,23 @@
struct bcma_bus;
/* main.c */
extern int bcma_bus_register(struct bcma_bus *bus);
extern void bcma_bus_unregister(struct bcma_bus *bus);
int bcma_bus_register(struct bcma_bus *bus);
void bcma_bus_unregister(struct bcma_bus *bus);
/* scan.c */
int bcma_bus_scan(struct bcma_bus *bus);
/* sprom.c */
int bcma_sprom_get(struct bcma_bus *bus);
#ifdef CONFIG_BCMA_HOST_PCI
/* host_pci.c */
extern int __init bcma_host_pci_init(void);
extern void __exit bcma_host_pci_exit(void);
#endif /* CONFIG_BCMA_HOST_PCI */
#ifdef CONFIG_BCMA_DRIVER_PCI_HOSTMODE
void bcma_core_pci_hostmode_init(struct bcma_drv_pci *pc);
#endif /* CONFIG_BCMA_DRIVER_PCI_HOSTMODE */
#endif

View File

@ -19,7 +19,7 @@ bool bcma_core_is_enabled(struct bcma_device *core)
}
EXPORT_SYMBOL_GPL(bcma_core_is_enabled);
static void bcma_core_disable(struct bcma_device *core, u32 flags)
void bcma_core_disable(struct bcma_device *core, u32 flags)
{
if (bcma_aread32(core, BCMA_RESET_CTL) & BCMA_RESET_CTL_RESET)
return;
@ -31,6 +31,7 @@ static void bcma_core_disable(struct bcma_device *core, u32 flags)
bcma_awrite32(core, BCMA_RESET_CTL, BCMA_RESET_CTL_RESET);
udelay(1);
}
EXPORT_SYMBOL_GPL(bcma_core_disable);
int bcma_core_enable(struct bcma_device *core, u32 flags)
{

View File

@ -53,6 +53,7 @@ static void bcma_pmu_resources_init(struct bcma_drv_cc *cc)
max_msk = 0xFFFF;
break;
case 43224:
case 43225:
break;
default:
pr_err("PMU resource config unknown for device 0x%04X\n",
@ -74,6 +75,7 @@ void bcma_pmu_swreg_init(struct bcma_drv_cc *cc)
case 0x4313:
case 0x4331:
case 43224:
case 43225:
break;
default:
pr_err("PMU switch/regulators init unknown for device "
@ -96,11 +98,13 @@ void bcma_pmu_workarounds(struct bcma_drv_cc *cc)
if (bus->chipinfo.rev == 0) {
pr_err("Workarounds for 43224 rev 0 not fully "
"implemented\n");
bcma_chipco_chipctl_maskset(cc, 0, ~0, 0xF0);
bcma_chipco_chipctl_maskset(cc, 0, ~0, 0x00F000F0);
} else {
bcma_chipco_chipctl_maskset(cc, 0, ~0, 0xF0);
}
break;
case 43225:
break;
default:
pr_err("Workarounds unknown for device 0x%04X\n",
bus->chipinfo.id);

View File

@ -157,7 +157,67 @@ static void bcma_pcicore_serdes_workaround(struct bcma_drv_pci *pc)
* Init.
**************************************************/
void bcma_core_pci_init(struct bcma_drv_pci *pc)
static void bcma_core_pci_clientmode_init(struct bcma_drv_pci *pc)
{
bcma_pcicore_serdes_workaround(pc);
}
static bool bcma_core_pci_is_in_hostmode(struct bcma_drv_pci *pc)
{
struct bcma_bus *bus = pc->core->bus;
u16 chipid_top;
chipid_top = (bus->chipinfo.id & 0xFF00);
if (chipid_top != 0x4700 &&
chipid_top != 0x5300)
return false;
if (bus->sprom.boardflags_lo & SSB_PCICORE_BFL_NOPCI)
return false;
#if 0
/* TODO: on BCMA we use address from EROM instead of magic formula */
u32 tmp;
return !mips_busprobe32(tmp, (bus->mmio +
(pc->core->core_index * BCMA_CORE_SIZE)));
#endif
return true;
}
void bcma_core_pci_init(struct bcma_drv_pci *pc)
{
if (bcma_core_pci_is_in_hostmode(pc)) {
#ifdef CONFIG_BCMA_DRIVER_PCI_HOSTMODE
bcma_core_pci_hostmode_init(pc);
#else
pr_err("Driver compiled without support for hostmode PCI\n");
#endif /* CONFIG_BCMA_DRIVER_PCI_HOSTMODE */
} else {
bcma_core_pci_clientmode_init(pc);
}
}
int bcma_core_pci_irq_ctl(struct bcma_drv_pci *pc, struct bcma_device *core,
bool enable)
{
struct pci_dev *pdev = pc->core->bus->host_pci;
u32 coremask, tmp;
int err;
err = pci_read_config_dword(pdev, BCMA_PCI_IRQMASK, &tmp);
if (err)
goto out;
coremask = BIT(core->core_index) << 8;
if (enable)
tmp |= coremask;
else
tmp &= ~coremask;
err = pci_write_config_dword(pdev, BCMA_PCI_IRQMASK, tmp);
out:
return err;
}
EXPORT_SYMBOL_GPL(bcma_core_pci_irq_ctl);

View File

@ -0,0 +1,14 @@
/*
* Broadcom specific AMBA
* PCI Core in hostmode
*
* Licensed under the GNU/GPL. See COPYING for details.
*/
#include "bcma_private.h"
#include <linux/bcma/bcma.h>
void bcma_core_pci_hostmode_init(struct bcma_drv_pci *pc)
{
pr_err("No support for PCI core in hostmode yet\n");
}

View File

@ -65,6 +65,54 @@ static void bcma_host_pci_write32(struct bcma_device *core, u16 offset,
iowrite32(value, core->bus->mmio + offset);
}
#ifdef CONFIG_BCMA_BLOCKIO
void bcma_host_pci_block_read(struct bcma_device *core, void *buffer,
size_t count, u16 offset, u8 reg_width)
{
void __iomem *addr = core->bus->mmio + offset;
if (core->bus->mapped_core != core)
bcma_host_pci_switch_core(core);
switch (reg_width) {
case sizeof(u8):
ioread8_rep(addr, buffer, count);
break;
case sizeof(u16):
WARN_ON(count & 1);
ioread16_rep(addr, buffer, count >> 1);
break;
case sizeof(u32):
WARN_ON(count & 3);
ioread32_rep(addr, buffer, count >> 2);
break;
default:
WARN_ON(1);
}
}
void bcma_host_pci_block_write(struct bcma_device *core, const void *buffer,
size_t count, u16 offset, u8 reg_width)
{
void __iomem *addr = core->bus->mmio + offset;
if (core->bus->mapped_core != core)
bcma_host_pci_switch_core(core);
switch (reg_width) {
case sizeof(u8):
iowrite8_rep(addr, buffer, count);
break;
case sizeof(u16):
WARN_ON(count & 1);
iowrite16_rep(addr, buffer, count >> 1);
break;
case sizeof(u32):
WARN_ON(count & 3);
iowrite32_rep(addr, buffer, count >> 2);
break;
default:
WARN_ON(1);
}
}
#endif
static u32 bcma_host_pci_aread32(struct bcma_device *core, u16 offset)
{
if (core->bus->mapped_core != core)
@ -87,6 +135,10 @@ const struct bcma_host_ops bcma_host_pci_ops = {
.write8 = bcma_host_pci_write8,
.write16 = bcma_host_pci_write16,
.write32 = bcma_host_pci_write32,
#ifdef CONFIG_BCMA_BLOCKIO
.block_read = bcma_host_pci_block_read,
.block_write = bcma_host_pci_block_write,
#endif
.aread32 = bcma_host_pci_aread32,
.awrite32 = bcma_host_pci_awrite32,
};
@ -175,6 +227,7 @@ static DEFINE_PCI_DEVICE_TABLE(bcma_pci_bridge_tbl) = {
{ PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x0576) },
{ PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4331) },
{ PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4353) },
{ PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4357) },
{ PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4727) },
{ 0, },
};

View File

@ -7,6 +7,7 @@
#include "bcma_private.h"
#include <linux/bcma/bcma.h>
#include <linux/slab.h>
MODULE_DESCRIPTION("Broadcom's specific AMBA driver");
MODULE_LICENSE("GPL");
@ -89,6 +90,8 @@ static int bcma_register_cores(struct bcma_bus *bus)
switch (bus->hosttype) {
case BCMA_HOSTTYPE_PCI:
core->dev.parent = &bus->host_pci->dev;
core->dma_dev = &bus->host_pci->dev;
core->irq = bus->host_pci->irq;
break;
case BCMA_HOSTTYPE_NONE:
case BCMA_HOSTTYPE_SDIO:
@ -144,6 +147,15 @@ int bcma_bus_register(struct bcma_bus *bus)
bcma_core_pci_init(&bus->drv_pci);
}
/* Try to get SPROM */
err = bcma_sprom_get(bus);
if (err == -ENOENT) {
pr_err("No SPROM available\n");
} else if (err) {
pr_err("Failed to get SPROM: %d\n", err);
return -ENOENT;
}
/* Register found cores */
bcma_register_cores(bus);
@ -151,13 +163,11 @@ int bcma_bus_register(struct bcma_bus *bus)
return 0;
}
EXPORT_SYMBOL_GPL(bcma_bus_register);
void bcma_bus_unregister(struct bcma_bus *bus)
{
bcma_unregister_cores(bus);
}
EXPORT_SYMBOL_GPL(bcma_bus_unregister);
int __bcma_driver_register(struct bcma_driver *drv, struct module *owner)
{

165
drivers/bcma/sprom.c Normal file
View File

@ -0,0 +1,165 @@
/*
* Broadcom specific AMBA
* SPROM reading
*
* Licensed under the GNU/GPL. See COPYING for details.
*/
#include "bcma_private.h"
#include <linux/bcma/bcma.h>
#include <linux/bcma/bcma_regs.h>
#include <linux/pci.h>
#include <linux/io.h>
#include <linux/dma-mapping.h>
#include <linux/slab.h>
#define SPOFF(offset) ((offset) / sizeof(u16))
/**************************************************
* R/W ops.
**************************************************/
static void bcma_sprom_read(struct bcma_bus *bus, u16 *sprom)
{
int i;
for (i = 0; i < SSB_SPROMSIZE_WORDS_R4; i++)
sprom[i] = bcma_read16(bus->drv_cc.core,
BCMA_CC_SPROM + (i * 2));
}
/**************************************************
* Validation.
**************************************************/
static inline u8 bcma_crc8(u8 crc, u8 data)
{
/* Polynomial: x^8 + x^7 + x^6 + x^4 + x^2 + 1 */
static const u8 t[] = {
0x00, 0xF7, 0xB9, 0x4E, 0x25, 0xD2, 0x9C, 0x6B,
0x4A, 0xBD, 0xF3, 0x04, 0x6F, 0x98, 0xD6, 0x21,
0x94, 0x63, 0x2D, 0xDA, 0xB1, 0x46, 0x08, 0xFF,
0xDE, 0x29, 0x67, 0x90, 0xFB, 0x0C, 0x42, 0xB5,
0x7F, 0x88, 0xC6, 0x31, 0x5A, 0xAD, 0xE3, 0x14,
0x35, 0xC2, 0x8C, 0x7B, 0x10, 0xE7, 0xA9, 0x5E,
0xEB, 0x1C, 0x52, 0xA5, 0xCE, 0x39, 0x77, 0x80,
0xA1, 0x56, 0x18, 0xEF, 0x84, 0x73, 0x3D, 0xCA,
0xFE, 0x09, 0x47, 0xB0, 0xDB, 0x2C, 0x62, 0x95,
0xB4, 0x43, 0x0D, 0xFA, 0x91, 0x66, 0x28, 0xDF,
0x6A, 0x9D, 0xD3, 0x24, 0x4F, 0xB8, 0xF6, 0x01,
0x20, 0xD7, 0x99, 0x6E, 0x05, 0xF2, 0xBC, 0x4B,
0x81, 0x76, 0x38, 0xCF, 0xA4, 0x53, 0x1D, 0xEA,
0xCB, 0x3C, 0x72, 0x85, 0xEE, 0x19, 0x57, 0xA0,
0x15, 0xE2, 0xAC, 0x5B, 0x30, 0xC7, 0x89, 0x7E,
0x5F, 0xA8, 0xE6, 0x11, 0x7A, 0x8D, 0xC3, 0x34,
0xAB, 0x5C, 0x12, 0xE5, 0x8E, 0x79, 0x37, 0xC0,
0xE1, 0x16, 0x58, 0xAF, 0xC4, 0x33, 0x7D, 0x8A,
0x3F, 0xC8, 0x86, 0x71, 0x1A, 0xED, 0xA3, 0x54,
0x75, 0x82, 0xCC, 0x3B, 0x50, 0xA7, 0xE9, 0x1E,
0xD4, 0x23, 0x6D, 0x9A, 0xF1, 0x06, 0x48, 0xBF,
0x9E, 0x69, 0x27, 0xD0, 0xBB, 0x4C, 0x02, 0xF5,
0x40, 0xB7, 0xF9, 0x0E, 0x65, 0x92, 0xDC, 0x2B,
0x0A, 0xFD, 0xB3, 0x44, 0x2F, 0xD8, 0x96, 0x61,
0x55, 0xA2, 0xEC, 0x1B, 0x70, 0x87, 0xC9, 0x3E,
0x1F, 0xE8, 0xA6, 0x51, 0x3A, 0xCD, 0x83, 0x74,
0xC1, 0x36, 0x78, 0x8F, 0xE4, 0x13, 0x5D, 0xAA,
0x8B, 0x7C, 0x32, 0xC5, 0xAE, 0x59, 0x17, 0xE0,
0x2A, 0xDD, 0x93, 0x64, 0x0F, 0xF8, 0xB6, 0x41,
0x60, 0x97, 0xD9, 0x2E, 0x45, 0xB2, 0xFC, 0x0B,
0xBE, 0x49, 0x07, 0xF0, 0x9B, 0x6C, 0x22, 0xD5,
0xF4, 0x03, 0x4D, 0xBA, 0xD1, 0x26, 0x68, 0x9F,
};
return t[crc ^ data];
}
static u8 bcma_sprom_crc(const u16 *sprom)
{
int word;
u8 crc = 0xFF;
for (word = 0; word < SSB_SPROMSIZE_WORDS_R4 - 1; word++) {
crc = bcma_crc8(crc, sprom[word] & 0x00FF);
crc = bcma_crc8(crc, (sprom[word] & 0xFF00) >> 8);
}
crc = bcma_crc8(crc, sprom[SSB_SPROMSIZE_WORDS_R4 - 1] & 0x00FF);
crc ^= 0xFF;
return crc;
}
static int bcma_sprom_check_crc(const u16 *sprom)
{
u8 crc;
u8 expected_crc;
u16 tmp;
crc = bcma_sprom_crc(sprom);
tmp = sprom[SSB_SPROMSIZE_WORDS_R4 - 1] & SSB_SPROM_REVISION_CRC;
expected_crc = tmp >> SSB_SPROM_REVISION_CRC_SHIFT;
if (crc != expected_crc)
return -EPROTO;
return 0;
}
static int bcma_sprom_valid(const u16 *sprom)
{
u16 revision;
int err;
err = bcma_sprom_check_crc(sprom);
if (err)
return err;
revision = sprom[SSB_SPROMSIZE_WORDS_R4 - 1] & SSB_SPROM_REVISION_REV;
if (revision != 8) {
pr_err("Unsupported SPROM revision: %d\n", revision);
return -ENOENT;
}
return 0;
}
/**************************************************
* SPROM extraction.
**************************************************/
static void bcma_sprom_extract_r8(struct bcma_bus *bus, const u16 *sprom)
{
u16 v;
int i;
for (i = 0; i < 3; i++) {
v = sprom[SPOFF(SSB_SPROM8_IL0MAC) + i];
*(((__be16 *)bus->sprom.il0mac) + i) = cpu_to_be16(v);
}
}
int bcma_sprom_get(struct bcma_bus *bus)
{
u16 *sprom;
int err = 0;
if (!bus->drv_cc.core)
return -EOPNOTSUPP;
if (!(bus->drv_cc.capabilities & BCMA_CC_CAP_SPROM))
return -ENOENT;
sprom = kcalloc(SSB_SPROMSIZE_WORDS_R4, sizeof(u16),
GFP_KERNEL);
if (!sprom)
return -ENOMEM;
bcma_sprom_read(bus, sprom);
err = bcma_sprom_valid(sprom);
if (err)
goto out;
bcma_sprom_extract_r8(bus, sprom);
out:
kfree(sprom);
return err;
}

View File

@ -375,6 +375,11 @@ static int ath3k_probe(struct usb_interface *intf,
/* load patch and sysconfig files for AR3012 */
if (id->driver_info & BTUSB_ATH3012) {
/* New firmware with patch and sysconfig files already loaded */
if (le16_to_cpu(udev->descriptor.bcdDevice) > 0x0001)
return -ENODEV;
ret = ath3k_load_patch(udev);
if (ret < 0) {
BT_ERR("Loading patch file failed");

View File

@ -54,6 +54,7 @@ static struct usb_driver btusb_driver;
#define BTUSB_BCM92035 0x10
#define BTUSB_BROKEN_ISOC 0x20
#define BTUSB_WRONG_SCO_MTU 0x40
#define BTUSB_ATH3012 0x80
static struct usb_device_id btusb_table[] = {
/* Generic Bluetooth USB device */
@ -110,7 +111,7 @@ static struct usb_device_id blacklist_table[] = {
{ USB_DEVICE(0x03f0, 0x311d), .driver_info = BTUSB_IGNORE },
/* Atheros 3012 with sflash firmware */
{ USB_DEVICE(0x0cf3, 0x3004), .driver_info = BTUSB_IGNORE },
{ USB_DEVICE(0x0cf3, 0x3004), .driver_info = BTUSB_ATH3012 },
/* Atheros AR5BBU12 with sflash firmware */
{ USB_DEVICE(0x0489, 0xe02c), .driver_info = BTUSB_IGNORE },
@ -914,6 +915,15 @@ static int btusb_probe(struct usb_interface *intf,
if (ignore_sniffer && id->driver_info & BTUSB_SNIFFER)
return -ENODEV;
if (id->driver_info & BTUSB_ATH3012) {
struct usb_device *udev = interface_to_usbdev(intf);
/* Old firmware would otherwise let ath3k driver load
* patch and sysconfig files */
if (le16_to_cpu(udev->descriptor.bcdDevice) <= 0x0001)
return -ENODEV;
}
data = kzalloc(sizeof(*data), GFP_KERNEL);
if (!data)
return -ENOMEM;

View File

@ -1523,6 +1523,21 @@ __u32 secure_ip_id(__be32 daddr)
return half_md4_transform(hash, keyptr->secret);
}
__u32 secure_ipv6_id(const __be32 daddr[4])
{
const struct keydata *keyptr;
__u32 hash[4];
keyptr = get_keyptr();
hash[0] = (__force __u32)daddr[0];
hash[1] = (__force __u32)daddr[1];
hash[2] = (__force __u32)daddr[2];
hash[3] = (__force __u32)daddr[3];
return half_md4_transform(hash, keyptr->secret);
}
#ifdef CONFIG_INET
__u32 secure_tcp_sequence_number(__be32 saddr, __be32 daddr,

View File

@ -11,6 +11,7 @@
#include <linux/module.h>
#include <linux/kernel.h> /* printk() */
#include <linux/fs.h> /* everything... */
#include <linux/scatterlist.h>
#include <linux/slab.h> /* kmalloc() */
#include <linux/dmaengine.h>
#include <linux/platform_device.h>

View File

@ -45,6 +45,7 @@
* See Documentation/dmaengine.txt for more details
*/
#include <linux/dma-mapping.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/mm.h>

View File

@ -8,6 +8,7 @@
* published by the Free Software Foundation.
*/
#include <linux/delay.h>
#include <linux/dma-mapping.h>
#include <linux/dmaengine.h>
#include <linux/init.h>
#include <linux/kthread.h>

View File

@ -9,6 +9,7 @@
* published by the Free Software Foundation.
*/
#include <linux/dma-mapping.h>
#include <linux/init.h>
#include <linux/platform_device.h>
#include <linux/err.h>

View File

@ -6,6 +6,7 @@
* License terms: GNU General Public License (GPL) version 2
*/
#include <linux/dma-mapping.h>
#include <linux/kernel.h>
#include <linux/slab.h>
#include <linux/dmaengine.h>

View File

@ -261,16 +261,16 @@ static int fwnet_header_rebuild(struct sk_buff *skb)
}
static int fwnet_header_cache(const struct neighbour *neigh,
struct hh_cache *hh)
struct hh_cache *hh, __be16 type)
{
struct net_device *net;
struct fwnet_header *h;
if (hh->hh_type == cpu_to_be16(ETH_P_802_3))
if (type == cpu_to_be16(ETH_P_802_3))
return -1;
net = neigh->dev;
h = (struct fwnet_header *)((u8 *)hh->hh_data + 16 - sizeof(*h));
h->h_proto = hh->hh_type;
h->h_proto = type;
memcpy(h->h_dest, neigh->ha, net->addr_len);
hh->hh_len = FWNET_HLEN;

View File

@ -1,3 +1 @@
obj-$(CONFIG_IEEE802154_FAKEHARD) += fakehard.o
ccflags-y := -DDEBUG -DCONFIG_FFD

View File

@ -370,8 +370,6 @@ static int __devinit ieee802154fake_probe(struct platform_device *pdev)
return -ENOMEM;
}
phy->dev.platform_data = dev;
memcpy(dev->dev_addr, "\xba\xbe\xca\xfe\xde\xad\xbe\xef",
dev->addr_len);
memcpy(dev->perm_addr, dev->dev_addr, dev->addr_len);

View File

@ -215,7 +215,7 @@ static int addr4_resolve(struct sockaddr_in *src_in,
neigh = neigh_lookup(&arp_tbl, &rt->rt_gateway, rt->dst.dev);
if (!neigh || !(neigh->nud_state & NUD_VALID)) {
neigh_event_send(rt->dst.neighbour, NULL);
neigh_event_send(dst_get_neighbour(&rt->dst), NULL);
ret = -ENODATA;
if (neigh)
goto release;
@ -273,9 +273,10 @@ static int addr6_resolve(struct sockaddr_in6 *src_in,
goto put;
}
neigh = dst->neighbour;
neigh = dst_get_neighbour(dst);
if (!neigh || !(neigh->nud_state & NUD_VALID)) {
neigh_event_send(dst->neighbour, NULL);
if (neigh)
neigh_event_send(neigh, NULL);
ret = -ENODATA;
goto put;
}

View File

@ -148,7 +148,7 @@ static int ibnl_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
return -EINVAL;
return netlink_dump_start(nls, skb, nlh,
client->cb_table[op].dump,
NULL);
NULL, 0);
}
}

View File

@ -36,6 +36,7 @@
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
#include <linux/inetdevice.h>
#include <linux/interrupt.h>
#include <linux/delay.h>
#include <linux/ethtool.h>
#include <linux/mii.h>

View File

@ -1328,6 +1328,7 @@ static int pass_accept_req(struct t3cdev *tdev, struct sk_buff *skb, void *ctx)
struct iwch_ep *child_ep, *parent_ep = ctx;
struct cpl_pass_accept_req *req = cplhdr(skb);
unsigned int hwtid = GET_TID(req);
struct neighbour *neigh;
struct dst_entry *dst;
struct l2t_entry *l2t;
struct rtable *rt;
@ -1364,7 +1365,8 @@ static int pass_accept_req(struct t3cdev *tdev, struct sk_buff *skb, void *ctx)
goto reject;
}
dst = &rt->dst;
l2t = t3_l2t_get(tdev, dst->neighbour, dst->neighbour->dev);
neigh = dst_get_neighbour(dst);
l2t = t3_l2t_get(tdev, neigh, neigh->dev);
if (!l2t) {
printk(KERN_ERR MOD "%s - failed to allocate l2t entry!\n",
__func__);
@ -1874,10 +1876,11 @@ static int is_loopback_dst(struct iw_cm_id *cm_id)
int iwch_connect(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param)
{
int err = 0;
struct iwch_dev *h = to_iwch_dev(cm_id->device);
struct neighbour *neigh;
struct iwch_ep *ep;
struct rtable *rt;
int err = 0;
if (is_loopback_dst(cm_id)) {
err = -ENOSYS;
@ -1933,9 +1936,10 @@ int iwch_connect(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param)
}
ep->dst = &rt->dst;
neigh = dst_get_neighbour(ep->dst);
/* get a l2t entry */
ep->l2t = t3_l2t_get(ep->com.tdev, ep->dst->neighbour,
ep->dst->neighbour->dev);
ep->l2t = t3_l2t_get(ep->com.tdev, neigh, neigh->dev);
if (!ep->l2t) {
printk(KERN_ERR MOD "%s - cannot alloc l2e.\n", __func__);
err = -ENOMEM;

View File

@ -1325,6 +1325,7 @@ static int pass_accept_req(struct c4iw_dev *dev, struct sk_buff *skb)
unsigned int stid = GET_POPEN_TID(ntohl(req->tos_stid));
struct tid_info *t = dev->rdev.lldi.tids;
unsigned int hwtid = GET_TID(req);
struct neighbour *neigh;
struct dst_entry *dst;
struct l2t_entry *l2t;
struct rtable *rt;
@ -1357,11 +1358,11 @@ static int pass_accept_req(struct c4iw_dev *dev, struct sk_buff *skb)
goto reject;
}
dst = &rt->dst;
if (dst->neighbour->dev->flags & IFF_LOOPBACK) {
neigh = dst_get_neighbour(dst);
if (neigh->dev->flags & IFF_LOOPBACK) {
pdev = ip_dev_find(&init_net, peer_ip);
BUG_ON(!pdev);
l2t = cxgb4_l2t_get(dev->rdev.lldi.l2t, dst->neighbour,
pdev, 0);
l2t = cxgb4_l2t_get(dev->rdev.lldi.l2t, neigh, pdev, 0);
mtu = pdev->mtu;
tx_chan = cxgb4_port_chan(pdev);
smac_idx = (cxgb4_port_viid(pdev) & 0x7F) << 1;
@ -1372,17 +1373,16 @@ static int pass_accept_req(struct c4iw_dev *dev, struct sk_buff *skb)
rss_qid = dev->rdev.lldi.rxq_ids[cxgb4_port_idx(pdev) * step];
dev_put(pdev);
} else {
l2t = cxgb4_l2t_get(dev->rdev.lldi.l2t, dst->neighbour,
dst->neighbour->dev, 0);
l2t = cxgb4_l2t_get(dev->rdev.lldi.l2t, neigh, neigh->dev, 0);
mtu = dst_mtu(dst);
tx_chan = cxgb4_port_chan(dst->neighbour->dev);
smac_idx = (cxgb4_port_viid(dst->neighbour->dev) & 0x7F) << 1;
tx_chan = cxgb4_port_chan(neigh->dev);
smac_idx = (cxgb4_port_viid(neigh->dev) & 0x7F) << 1;
step = dev->rdev.lldi.ntxq / dev->rdev.lldi.nchan;
txq_idx = cxgb4_port_idx(dst->neighbour->dev) * step;
ctrlq_idx = cxgb4_port_idx(dst->neighbour->dev);
txq_idx = cxgb4_port_idx(neigh->dev) * step;
ctrlq_idx = cxgb4_port_idx(neigh->dev);
step = dev->rdev.lldi.nrxq / dev->rdev.lldi.nchan;
rss_qid = dev->rdev.lldi.rxq_ids[
cxgb4_port_idx(dst->neighbour->dev) * step];
cxgb4_port_idx(neigh->dev) * step];
}
if (!l2t) {
printk(KERN_ERR MOD "%s - failed to allocate l2t entry!\n",
@ -1847,6 +1847,7 @@ int c4iw_connect(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param)
struct c4iw_ep *ep;
struct rtable *rt;
struct net_device *pdev;
struct neighbour *neigh;
int step;
if ((conn_param->ord > c4iw_max_read_depth) ||
@ -1908,14 +1909,15 @@ int c4iw_connect(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param)
}
ep->dst = &rt->dst;
neigh = dst_get_neighbour(ep->dst);
/* get a l2t entry */
if (ep->dst->neighbour->dev->flags & IFF_LOOPBACK) {
if (neigh->dev->flags & IFF_LOOPBACK) {
PDBG("%s LOOPBACK\n", __func__);
pdev = ip_dev_find(&init_net,
cm_id->remote_addr.sin_addr.s_addr);
ep->l2t = cxgb4_l2t_get(ep->com.dev->rdev.lldi.l2t,
ep->dst->neighbour,
pdev, 0);
neigh, pdev, 0);
ep->mtu = pdev->mtu;
ep->tx_chan = cxgb4_port_chan(pdev);
ep->smac_idx = (cxgb4_port_viid(pdev) & 0x7F) << 1;
@ -1930,20 +1932,18 @@ int c4iw_connect(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param)
dev_put(pdev);
} else {
ep->l2t = cxgb4_l2t_get(ep->com.dev->rdev.lldi.l2t,
ep->dst->neighbour,
ep->dst->neighbour->dev, 0);
neigh, neigh->dev, 0);
ep->mtu = dst_mtu(ep->dst);
ep->tx_chan = cxgb4_port_chan(ep->dst->neighbour->dev);
ep->smac_idx = (cxgb4_port_viid(ep->dst->neighbour->dev) &
0x7F) << 1;
ep->tx_chan = cxgb4_port_chan(neigh->dev);
ep->smac_idx = (cxgb4_port_viid(neigh->dev) & 0x7F) << 1;
step = ep->com.dev->rdev.lldi.ntxq /
ep->com.dev->rdev.lldi.nchan;
ep->txq_idx = cxgb4_port_idx(ep->dst->neighbour->dev) * step;
ep->ctrlq_idx = cxgb4_port_idx(ep->dst->neighbour->dev);
ep->txq_idx = cxgb4_port_idx(neigh->dev) * step;
ep->ctrlq_idx = cxgb4_port_idx(neigh->dev);
step = ep->com.dev->rdev.lldi.nrxq /
ep->com.dev->rdev.lldi.nchan;
ep->rss_qid = ep->com.dev->rdev.lldi.rxq_ids[
cxgb4_port_idx(ep->dst->neighbour->dev) * step];
cxgb4_port_idx(neigh->dev) * step];
}
if (!ep->l2t) {
printk(KERN_ERR MOD "%s - cannot alloc l2e.\n", __func__);

View File

@ -1151,7 +1151,7 @@ static int nes_addr_resolve_neigh(struct nes_vnic *nesvnic, u32 dst_ip, int arpi
}
if ((neigh == NULL) || (!(neigh->nud_state & NUD_VALID)))
neigh_event_send(rt->dst.neighbour, NULL);
neigh_event_send(dst_get_neighbour(&rt->dst), NULL);
ip_rt_put(rt);
return rc;

View File

@ -2917,24 +2917,19 @@ void nes_nic_ce_handler(struct nes_device *nesdev, struct nes_hw_nic_cq *cq)
goto skip_rx_indicate0;
if ((cqe_misc & NES_NIC_CQE_TAG_VALID) &&
(nesvnic->vlan_grp != NULL)) {
if (cqe_misc & NES_NIC_CQE_TAG_VALID) {
vlan_tag = (u16)(le32_to_cpu(
cq->cq_vbase[head].cqe_words[NES_NIC_CQE_TAG_PKT_TYPE_IDX])
>> 16);
nes_debug(NES_DBG_CQ, "%s: Reporting stripped VLAN packet. Tag = 0x%04X\n",
nesvnic->netdev->name, vlan_tag);
if (nes_use_lro)
lro_vlan_hwaccel_receive_skb(&nesvnic->lro_mgr, rx_skb,
nesvnic->vlan_grp, vlan_tag, NULL);
else
nes_vlan_rx(rx_skb, nesvnic->vlan_grp, vlan_tag);
} else {
if (nes_use_lro)
lro_receive_skb(&nesvnic->lro_mgr, rx_skb, NULL);
else
nes_netif_rx(rx_skb);
__vlan_hwaccel_put_tag(rx_skb, vlan_tag);
}
if (nes_use_lro)
lro_receive_skb(&nesvnic->lro_mgr, rx_skb, NULL);
else
netif_receive_skb(rx_skb);
skip_rx_indicate0:
;

View File

@ -1211,7 +1211,6 @@ struct nes_vnic {
/* void *mem; */
struct nes_device *nesdev;
struct net_device *netdev;
struct vlan_group *vlan_grp;
atomic_t rx_skbs_needed;
atomic_t rx_skb_timer_running;
int budget;
@ -1357,7 +1356,4 @@ struct nes_terminate_hdr {
#define NES_LINK_RECHECK_DELAY msecs_to_jiffies(50)
#define NES_LINK_RECHECK_MAX 60
#define nes_vlan_rx vlan_hwaccel_receive_skb
#define nes_netif_rx netif_receive_skb
#endif /* __NES_HW_H */

View File

@ -1584,23 +1584,19 @@ static const struct ethtool_ops nes_ethtool_ops = {
.set_pauseparam = nes_netdev_set_pauseparam,
};
static void nes_netdev_vlan_rx_register(struct net_device *netdev, struct vlan_group *grp)
static void nes_vlan_mode(struct net_device *netdev, struct nes_device *nesdev, u32 features)
{
struct nes_vnic *nesvnic = netdev_priv(netdev);
struct nes_device *nesdev = nesvnic->nesdev;
struct nes_adapter *nesadapter = nesdev->nesadapter;
u32 u32temp;
unsigned long flags;
spin_lock_irqsave(&nesadapter->phy_lock, flags);
nesvnic->vlan_grp = grp;
nes_debug(NES_DBG_NETDEV, "%s: %s\n", __func__, netdev->name);
/* Enable/Disable VLAN Stripping */
u32temp = nes_read_indexed(nesdev, NES_IDX_PCIX_DIAG);
if (grp)
if (features & NETIF_F_HW_VLAN_RX)
u32temp &= 0xfdffffff;
else
u32temp |= 0x02000000;
@ -1609,17 +1605,44 @@ static void nes_netdev_vlan_rx_register(struct net_device *netdev, struct vlan_g
spin_unlock_irqrestore(&nesadapter->phy_lock, flags);
}
static u32 nes_fix_features(struct net_device *netdev, u32 features)
{
/*
* Since there is no support for separate rx/tx vlan accel
* enable/disable make sure tx flag is always in same state as rx.
*/
if (features & NETIF_F_HW_VLAN_RX)
features |= NETIF_F_HW_VLAN_TX;
else
features &= ~NETIF_F_HW_VLAN_TX;
return features;
}
static int nes_set_features(struct net_device *netdev, u32 features)
{
struct nes_vnic *nesvnic = netdev_priv(netdev);
struct nes_device *nesdev = nesvnic->nesdev;
u32 changed = netdev->features ^ features;
if (changed & NETIF_F_HW_VLAN_RX)
nes_vlan_mode(netdev, nesdev, features);
return 0;
}
static const struct net_device_ops nes_netdev_ops = {
.ndo_open = nes_netdev_open,
.ndo_open = nes_netdev_open,
.ndo_stop = nes_netdev_stop,
.ndo_start_xmit = nes_netdev_start_xmit,
.ndo_start_xmit = nes_netdev_start_xmit,
.ndo_get_stats = nes_netdev_get_stats,
.ndo_tx_timeout = nes_netdev_tx_timeout,
.ndo_tx_timeout = nes_netdev_tx_timeout,
.ndo_set_mac_address = nes_netdev_set_mac_address,
.ndo_set_multicast_list = nes_netdev_set_multicast_list,
.ndo_change_mtu = nes_netdev_change_mtu,
.ndo_validate_addr = eth_validate_addr,
.ndo_vlan_rx_register = nes_netdev_vlan_rx_register,
.ndo_fix_features = nes_fix_features,
.ndo_set_features = nes_set_features,
};
/**
@ -1656,7 +1679,7 @@ struct net_device *nes_netdev_init(struct nes_device *nesdev,
netdev->ethtool_ops = &nes_ethtool_ops;
netif_napi_add(netdev, &nesvnic->napi, nes_netdev_poll, 128);
nes_debug(NES_DBG_INIT, "Enabling VLAN Insert/Delete.\n");
netdev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX;
netdev->features |= NETIF_F_HW_VLAN_TX;
/* Fill in the port structure */
nesvnic->netdev = netdev;
@ -1683,7 +1706,8 @@ struct net_device *nes_netdev_init(struct nes_device *nesdev,
netdev->dev_addr[5] = (u8)u64temp;
memcpy(netdev->perm_addr, netdev->dev_addr, 6);
netdev->hw_features = NETIF_F_RXCSUM | NETIF_F_SG | NETIF_F_IP_CSUM;
netdev->hw_features = NETIF_F_RXCSUM | NETIF_F_SG | NETIF_F_IP_CSUM |
NETIF_F_HW_VLAN_RX;
if ((nesvnic->logical_port < 2) || (nesdev->nesadapter->hw_rev != NE020_REV))
netdev->hw_features |= NETIF_F_TSO;
netdev->features |= netdev->hw_features;
@ -1815,6 +1839,8 @@ struct net_device *nes_netdev_init(struct nes_device *nesdev,
nes_init_phy(nesdev);
}
nes_vlan_mode(netdev, nesdev, netdev->features);
return netdev;
}

View File

@ -560,9 +560,11 @@ static void neigh_add_path(struct sk_buff *skb, struct net_device *dev)
struct ipoib_dev_priv *priv = netdev_priv(dev);
struct ipoib_path *path;
struct ipoib_neigh *neigh;
struct neighbour *n;
unsigned long flags;
neigh = ipoib_neigh_alloc(skb_dst(skb)->neighbour, skb->dev);
n = dst_get_neighbour(skb_dst(skb));
neigh = ipoib_neigh_alloc(n, skb->dev);
if (!neigh) {
++dev->stats.tx_dropped;
dev_kfree_skb_any(skb);
@ -571,9 +573,9 @@ static void neigh_add_path(struct sk_buff *skb, struct net_device *dev)
spin_lock_irqsave(&priv->lock, flags);
path = __path_find(dev, skb_dst(skb)->neighbour->ha + 4);
path = __path_find(dev, n->ha + 4);
if (!path) {
path = path_rec_create(dev, skb_dst(skb)->neighbour->ha + 4);
path = path_rec_create(dev, n->ha + 4);
if (!path)
goto err_path;
@ -607,7 +609,7 @@ static void neigh_add_path(struct sk_buff *skb, struct net_device *dev)
}
} else {
spin_unlock_irqrestore(&priv->lock, flags);
ipoib_send(dev, skb, path->ah, IPOIB_QPN(skb_dst(skb)->neighbour->ha));
ipoib_send(dev, skb, path->ah, IPOIB_QPN(n->ha));
return;
}
} else {
@ -637,17 +639,20 @@ err_drop:
static void ipoib_path_lookup(struct sk_buff *skb, struct net_device *dev)
{
struct ipoib_dev_priv *priv = netdev_priv(skb->dev);
struct dst_entry *dst = skb_dst(skb);
struct neighbour *n;
/* Look up path record for unicasts */
if (skb_dst(skb)->neighbour->ha[4] != 0xff) {
n = dst_get_neighbour(dst);
if (n->ha[4] != 0xff) {
neigh_add_path(skb, dev);
return;
}
/* Add in the P_Key for multicasts */
skb_dst(skb)->neighbour->ha[8] = (priv->pkey >> 8) & 0xff;
skb_dst(skb)->neighbour->ha[9] = priv->pkey & 0xff;
ipoib_mcast_send(dev, skb_dst(skb)->neighbour->ha + 4, skb);
n->ha[8] = (priv->pkey >> 8) & 0xff;
n->ha[9] = priv->pkey & 0xff;
ipoib_mcast_send(dev, n->ha + 4, skb);
}
static void unicast_arp_send(struct sk_buff *skb, struct net_device *dev,
@ -712,18 +717,20 @@ static int ipoib_start_xmit(struct sk_buff *skb, struct net_device *dev)
{
struct ipoib_dev_priv *priv = netdev_priv(dev);
struct ipoib_neigh *neigh;
struct neighbour *n;
unsigned long flags;
if (likely(skb_dst(skb) && skb_dst(skb)->neighbour)) {
if (unlikely(!*to_ipoib_neigh(skb_dst(skb)->neighbour))) {
n = dst_get_neighbour(skb_dst(skb));
if (likely(skb_dst(skb) && n)) {
if (unlikely(!*to_ipoib_neigh(n))) {
ipoib_path_lookup(skb, dev);
return NETDEV_TX_OK;
}
neigh = *to_ipoib_neigh(skb_dst(skb)->neighbour);
neigh = *to_ipoib_neigh(n);
if (unlikely((memcmp(&neigh->dgid.raw,
skb_dst(skb)->neighbour->ha + 4,
n->ha + 4,
sizeof(union ib_gid))) ||
(neigh->dev != dev))) {
spin_lock_irqsave(&priv->lock, flags);
@ -749,7 +756,7 @@ static int ipoib_start_xmit(struct sk_buff *skb, struct net_device *dev)
return NETDEV_TX_OK;
}
} else if (neigh->ah) {
ipoib_send(dev, skb, neigh->ah, IPOIB_QPN(skb_dst(skb)->neighbour->ha));
ipoib_send(dev, skb, neigh->ah, IPOIB_QPN(n->ha));
return NETDEV_TX_OK;
}
@ -812,6 +819,8 @@ static int ipoib_hard_header(struct sk_buff *skb,
const void *daddr, const void *saddr, unsigned len)
{
struct ipoib_header *header;
struct dst_entry *dst;
struct neighbour *n;
header = (struct ipoib_header *) skb_push(skb, sizeof *header);
@ -823,7 +832,11 @@ static int ipoib_hard_header(struct sk_buff *skb,
* destination address onto the front of the skb so we can
* figure out where to send the packet later.
*/
if ((!skb_dst(skb) || !skb_dst(skb)->neighbour) && daddr) {
dst = skb_dst(skb);
n = NULL;
if (dst)
n = dst_get_neighbour(dst);
if ((!dst || !n) && daddr) {
struct ipoib_pseudoheader *phdr =
(struct ipoib_pseudoheader *) skb_push(skb, sizeof *phdr);
memcpy(phdr->hwaddr, daddr, INFINIBAND_ALEN);

View File

@ -258,11 +258,15 @@ static int ipoib_mcast_join_finish(struct ipoib_mcast *mcast,
netif_tx_lock_bh(dev);
while (!skb_queue_empty(&mcast->pkt_queue)) {
struct sk_buff *skb = skb_dequeue(&mcast->pkt_queue);
struct dst_entry *dst = skb_dst(skb);
struct neighbour *n = NULL;
netif_tx_unlock_bh(dev);
skb->dev = dev;
if (!skb_dst(skb) || !skb_dst(skb)->neighbour) {
if (dst)
n = dst_get_neighbour(dst);
if (!dst || !n) {
/* put pseudoheader back on for next time */
skb_push(skb, sizeof (struct ipoib_pseudoheader));
}
@ -715,11 +719,13 @@ void ipoib_mcast_send(struct net_device *dev, void *mgid, struct sk_buff *skb)
out:
if (mcast && mcast->ah) {
if (skb_dst(skb) &&
skb_dst(skb)->neighbour &&
!*to_ipoib_neigh(skb_dst(skb)->neighbour)) {
struct ipoib_neigh *neigh = ipoib_neigh_alloc(skb_dst(skb)->neighbour,
skb->dev);
struct dst_entry *dst = skb_dst(skb);
struct neighbour *n = NULL;
if (dst)
n = dst_get_neighbour(dst);
if (n && !*to_ipoib_neigh(n)) {
struct ipoib_neigh *neigh = ipoib_neigh_alloc(n,
skb->dev);
if (neigh) {
kref_get(&mcast->ah->ref);

View File

@ -45,6 +45,7 @@
#include <scsi/libiscsi.h>
#include <scsi/scsi_transport_iscsi.h>
#include <linux/interrupt.h>
#include <linux/wait.h>
#include <linux/sched.h>
#include <linux/list.h>

View File

@ -20,6 +20,7 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
*/
#include <linux/interrupt.h>
#include <linux/module.h>
#include <linux/pci.h>
#include <linux/delay.h>

View File

@ -152,6 +152,7 @@
#define HFC_MULTI_VERSION "2.03"
#include <linux/interrupt.h>
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/pci.h>

View File

@ -44,6 +44,7 @@
*
*/
#include <linux/interrupt.h>
#include <linux/module.h>
#include <linux/pci.h>
#include <linux/delay.h>

View File

@ -38,6 +38,7 @@
*
*/
#include <linux/interrupt.h>
#include <linux/module.h>
#include <linux/pci.h>
#include <linux/delay.h>

View File

@ -20,6 +20,7 @@
*
*/
#include <linux/irqreturn.h>
#include <linux/slab.h>
#include <linux/module.h>
#include <linux/mISDNhw.h>

View File

@ -20,6 +20,7 @@
*
*/
#include <linux/interrupt.h>
#include <linux/module.h>
#include <linux/pci.h>
#include <linux/delay.h>

View File

@ -22,6 +22,7 @@
*
*/
#include <linux/interrupt.h>
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/pci.h>

View File

@ -21,6 +21,7 @@
*
*/
#include <linux/interrupt.h>
#include <linux/module.h>
#include <linux/pci.h>
#include <linux/delay.h>

View File

@ -16,6 +16,7 @@
#include <linux/slab.h>
#include <linux/mm.h>
#include <linux/mman.h>
#include <linux/interrupt.h>
#include <linux/ioport.h>
#include <linux/timer.h>
#include <linux/wait.h>

View File

@ -25,6 +25,7 @@
#include <linux/module.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/pci.h>
#include <linux/isapnp.h>
#include <linux/kmod.h>

View File

@ -1983,13 +1983,14 @@ isdn_net_rebuild_header(struct sk_buff *skb)
return ret;
}
static int isdn_header_cache(const struct neighbour *neigh, struct hh_cache *hh)
static int isdn_header_cache(const struct neighbour *neigh, struct hh_cache *hh,
__be16 type)
{
const struct net_device *dev = neigh->dev;
isdn_net_local *lp = netdev_priv(dev);
if (lp->p_encap == ISDN_NET_ENCAP_ETHER)
return eth_header_cache(neigh, hh);
return eth_header_cache(neigh, hh, type);
return -1;
}

View File

@ -6,6 +6,7 @@
#ifndef __FLEXCOP_COMMON_H__
#define __FLEXCOP_COMMON_H__
#include <linux/interrupt.h>
#include <linux/pci.h>
#include <linux/mutex.h>

View File

@ -22,6 +22,7 @@
#include <linux/i2c.h>
#include <linux/i2c-algo-bit.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/proc_fs.h>

View File

@ -22,6 +22,7 @@
#include <linux/slab.h>
#include <linux/sched.h>
#include <linux/interrupt.h>
#include <asm/io.h>
#include "dmxdev.h"
#include "dvbdev.h"

View File

@ -21,6 +21,7 @@
#ifndef __MANTIS_COMMON_H
#define __MANTIS_COMMON_H
#include <linux/interrupt.h>
#include <linux/mutex.h>
#include <linux/workqueue.h>

View File

@ -23,6 +23,7 @@
#include <linux/signal.h>
#include <linux/sched.h>
#include <linux/interrupt.h>
#include <asm/io.h>
#include "dmxdev.h"
#include "dvbdev.h"

View File

@ -23,6 +23,7 @@
#include <linux/sched.h>
#include <linux/interrupt.h>
#include <asm/io.h>
#include "dmxdev.h"
#include "dvbdev.h"

View File

@ -24,6 +24,7 @@
#include <linux/signal.h>
#include <linux/sched.h>
#include <linux/interrupt.h>
#include <asm/io.h>
#include "dmxdev.h"
#include "dvbdev.h"

View File

@ -23,6 +23,7 @@
#include <linux/signal.h>
#include <linux/sched.h>
#include <linux/interrupt.h>
#include <asm/io.h>
#include "dmxdev.h"
#include "dvbdev.h"

View File

@ -20,6 +20,7 @@
#include <linux/kernel.h>
#include <linux/spinlock.h>
#include <asm/io.h>
#include <linux/signal.h>
#include <linux/sched.h>

View File

@ -21,6 +21,7 @@
#include <linux/signal.h>
#include <linux/sched.h>
#include <linux/interrupt.h>
#include <asm/io.h>
#include "dmxdev.h"
#include "dvbdev.h"

View File

@ -26,6 +26,7 @@
#include <linux/i2c.h>
#include <linux/i2c-algo-bit.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/pci.h>

View File

@ -11,6 +11,7 @@
*/
#include <linux/device.h>
#include <linux/dma-mapping.h>
#include <linux/dmaengine.h>
#include <linux/mfd/tmio.h>
#include <linux/mmc/host.h>

Some files were not shown because too many files have changed in this diff Show More