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

Pull networking updates from David Miller:

 1) Support ipv6 checksum offload in sunvnet driver, from Shannon
    Nelson.

 2) Move to RB-tree instead of custom AVL code in inetpeer, from Eric
    Dumazet.

 3) Allow generic XDP to work on virtual devices, from John Fastabend.

 4) Add bpf device maps and XDP_REDIRECT, which can be used to build
    arbitrary switching frameworks using XDP. From John Fastabend.

 5) Remove UFO offloads from the tree, gave us little other than bugs.

 6) Remove the IPSEC flow cache, from Florian Westphal.

 7) Support ipv6 route offload in mlxsw driver.

 8) Support VF representors in bnxt_en, from Sathya Perla.

 9) Add support for forward error correction modes to ethtool, from
    Vidya Sagar Ravipati.

10) Add time filter for packet scheduler action dumping, from Jamal Hadi
    Salim.

11) Extend the zerocopy sendmsg() used by virtio and tap to regular
    sockets via MSG_ZEROCOPY. From Willem de Bruijn.

12) Significantly rework value tracking in the BPF verifier, from Edward
    Cree.

13) Add new jump instructions to eBPF, from Daniel Borkmann.

14) Rework rtnetlink plumbing so that operations can be run without
    taking the RTNL semaphore. From Florian Westphal.

15) Support XDP in tap driver, from Jason Wang.

16) Add 32-bit eBPF JIT for ARM, from Shubham Bansal.

17) Add Huawei hinic ethernet driver.

18) Allow to report MD5 keys in TCP inet_diag dumps, from Ivan
    Delalande.

* git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next: (1780 commits)
  i40e: point wb_desc at the nvm_wb_desc during i40e_read_nvm_aq
  i40e: avoid NVM acquire deadlock during NVM update
  drivers: net: xgene: Remove return statement from void function
  drivers: net: xgene: Configure tx/rx delay for ACPI
  drivers: net: xgene: Read tx/rx delay for ACPI
  rocker: fix kcalloc parameter order
  rds: Fix non-atomic operation on shared flag variable
  net: sched: don't use GFP_KERNEL under spin lock
  vhost_net: correctly check tx avail during rx busy polling
  net: mdio-mux: add mdio_mux parameter to mdio_mux_init()
  rxrpc: Make service connection lookup always check for retry
  net: stmmac: Delete dead code for MDIO registration
  gianfar: Fix Tx flow control deactivation
  cxgb4: Ignore MPS_TX_INT_CAUSE[Bubble] for T6
  cxgb4: Fix pause frame count in t4_get_port_stats
  cxgb4: fix memory leak
  tun: rename generic_xdp to skb_xdp
  tun: reserve extra headroom only when XDP is set
  net: dsa: bcm_sf2: Configure IMP port TC2QOS mapping
  net: dsa: bcm_sf2: Advertise number of egress queues
  ...
This commit is contained in:
Linus Torvalds 2017-09-06 14:45:08 -07:00
commit aae3dbb477
1592 changed files with 99386 additions and 30614 deletions

View File

@ -0,0 +1,25 @@
* Adaptrum Anarion ethernet controller
This device is a platform glue layer for stmmac.
Please see stmmac.txt for the other unchanged properties.
Required properties:
- compatible: Should be "adaptrum,anarion-gmac", "snps,dwmac"
- phy-mode: Should be "rgmii". Other modes are not currently supported.
Examples:
gmac1: ethernet@f2014000 {
compatible = "adaptrum,anarion-gmac", "snps,dwmac";
reg = <0xf2014000 0x4000>, <0xf2018100 8>;
interrupt-parent = <&core_intc>;
interrupts = <21>;
interrupt-names = "macirq";
clocks = <&core_clk>;
clock-names = "stmmaceth";
phy-mode = "rgmii";
};

View File

@ -0,0 +1,35 @@
Broadcom Bluetooth Chips
---------------------
This documents the binding structure and common properties for serial
attached Broadcom devices.
Serial attached Broadcom devices shall be a child node of the host UART
device the slave device is attached to.
Required properties:
- compatible: should contain one of the following:
* "brcm,bcm43438-bt"
Optional properties:
- max-speed: see Documentation/devicetree/bindings/serial/slave-device.txt
- shutdown-gpios: GPIO specifier, used to enable the BT module
- device-wakeup-gpios: GPIO specifier, used to wakeup the controller
- host-wakeup-gpios: GPIO specifier, used to wakeup the host processor
- clocks: clock specifier if external clock provided to the controller
- clock-names: should be "extclk"
Example:
&uart2 {
pinctrl-names = "default";
pinctrl-0 = <&uart2_pins>;
bluetooth {
compatible = "brcm,bcm43438-bt";
max-speed = <921600>;
};
};

View File

@ -41,6 +41,11 @@ Optional properties (port):
- marvell,loopback: port is loopback mode
- phy: a phandle to a phy node defining the PHY address (as the reg
property, a single integer).
- interrupt-names: if more than a single interrupt for rx is given, must
be the name associated to the interrupts listed. Valid
names are: "tx-cpu0", "tx-cpu1", "tx-cpu2", "tx-cpu3",
"rx-shared", "link".
- marvell,system-controller: a phandle to the system controller.
Example for marvell,armada-375-pp2:
@ -80,19 +85,37 @@ cpm_ethernet: ethernet@0 {
clock-names = "pp_clk", "gop_clk", "gp_clk";
eth0: eth0 {
interrupts = <GIC_SPI 37 IRQ_TYPE_LEVEL_HIGH>;
interrupts = <ICU_GRP_NSR 39 IRQ_TYPE_LEVEL_HIGH>,
<ICU_GRP_NSR 43 IRQ_TYPE_LEVEL_HIGH>,
<ICU_GRP_NSR 47 IRQ_TYPE_LEVEL_HIGH>,
<ICU_GRP_NSR 51 IRQ_TYPE_LEVEL_HIGH>,
<ICU_GRP_NSR 55 IRQ_TYPE_LEVEL_HIGH>;
interrupt-names = "tx-cpu0", "tx-cpu1", "tx-cpu2",
"tx-cpu3", "rx-shared";
port-id = <0>;
gop-port-id = <0>;
};
eth1: eth1 {
interrupts = <GIC_SPI 38 IRQ_TYPE_LEVEL_HIGH>;
interrupts = <ICU_GRP_NSR 40 IRQ_TYPE_LEVEL_HIGH>,
<ICU_GRP_NSR 44 IRQ_TYPE_LEVEL_HIGH>,
<ICU_GRP_NSR 48 IRQ_TYPE_LEVEL_HIGH>,
<ICU_GRP_NSR 52 IRQ_TYPE_LEVEL_HIGH>,
<ICU_GRP_NSR 56 IRQ_TYPE_LEVEL_HIGH>;
interrupt-names = "tx-cpu0", "tx-cpu1", "tx-cpu2",
"tx-cpu3", "rx-shared";
port-id = <1>;
gop-port-id = <2>;
};
eth2: eth2 {
interrupts = <GIC_SPI 39 IRQ_TYPE_LEVEL_HIGH>;
interrupts = <ICU_GRP_NSR 41 IRQ_TYPE_LEVEL_HIGH>,
<ICU_GRP_NSR 45 IRQ_TYPE_LEVEL_HIGH>,
<ICU_GRP_NSR 49 IRQ_TYPE_LEVEL_HIGH>,
<ICU_GRP_NSR 53 IRQ_TYPE_LEVEL_HIGH>,
<ICU_GRP_NSR 57 IRQ_TYPE_LEVEL_HIGH>;
interrupt-names = "tx-cpu0", "tx-cpu1", "tx-cpu2",
"tx-cpu3", "rx-shared";
port-id = <2>;
gop-port-id = <3>;
};

View File

@ -7,24 +7,30 @@ have dual GMAC each represented by a child node..
* Ethernet controller node
Required properties:
- compatible: Should be "mediatek,mt2701-eth"
- compatible: Should be
"mediatek,mt2701-eth": for MT2701 SoC
"mediatek,mt7623-eth", "mediatek,mt2701-eth": for MT7623 SoC
"mediatek,mt7622-eth": for MT7622 SoC
- reg: Address and length of the register set for the device
- interrupts: Should contain the three frame engines interrupts in numeric
order. These are fe_int0, fe_int1 and fe_int2.
- clocks: the clock used by the core
- clock-names: the names of the clock listed in the clocks property. These are
"ethif", "esw", "gp2", "gp1"
"ethif", "esw", "gp2", "gp1" : For MT2701 and MT7623 SoC
"ethif", "esw", "gp0", "gp1", "gp2", "sgmii_tx250m", "sgmii_rx250m",
"sgmii_cdr_ref", "sgmii_cdr_fb", "sgmii_ck", "eth2pll" : For MT7622 SoC
- power-domains: phandle to the power domain that the ethernet is part of
- resets: Should contain a phandle to the ethsys reset signal
- reset-names: Should contain the reset signal name "eth"
- mediatek,ethsys: phandle to the syscon node that handles the port setup
- mediatek,sgmiisys: phandle to the syscon node that handles the SGMII setup
which is required for those SoCs equipped with SGMII such as MT7622 SoC.
- mediatek,pctl: phandle to the syscon node that handles the ports slew rate
and driver current
Optional properties:
- interrupt-parent: Should be the phandle for the interrupt controller
that services interrupts for this device
* Ethernet MAC node
Required properties:

View File

@ -52,6 +52,11 @@ Optional Properties:
Mark the corresponding energy efficient ethernet mode as broken and
request the ethernet to stop advertising it.
- phy-is-integrated: If set, indicates that the PHY is integrated into the same
physical package as the Ethernet MAC. If needed, muxers should be configured
to ensure the integrated PHY is used. The absence of this property indicates
the muxers should be configured so that the external PHY is used.
Example:
ethernet-phy@0 {

View File

@ -4,19 +4,25 @@ This file provides information on what the device node for the Ethernet AVB
interface contains.
Required properties:
- compatible: "renesas,etheravb-r8a7790" if the device is a part of R8A7790 SoC.
"renesas,etheravb-r8a7791" if the device is a part of R8A7791 SoC.
"renesas,etheravb-r8a7792" if the device is a part of R8A7792 SoC.
"renesas,etheravb-r8a7793" if the device is a part of R8A7793 SoC.
"renesas,etheravb-r8a7794" if the device is a part of R8A7794 SoC.
"renesas,etheravb-r8a7795" if the device is a part of R8A7795 SoC.
"renesas,etheravb-r8a7796" if the device is a part of R8A7796 SoC.
"renesas,etheravb-rcar-gen2" for generic R-Car Gen 2 compatible interface.
"renesas,etheravb-rcar-gen3" for generic R-Car Gen 3 compatible interface.
- compatible: Must contain one or more of the following:
- "renesas,etheravb-r8a7743" for the R8A7743 SoC.
- "renesas,etheravb-r8a7745" for the R8A7745 SoC.
- "renesas,etheravb-r8a7790" for the R8A7790 SoC.
- "renesas,etheravb-r8a7791" for the R8A7791 SoC.
- "renesas,etheravb-r8a7792" for the R8A7792 SoC.
- "renesas,etheravb-r8a7793" for the R8A7793 SoC.
- "renesas,etheravb-r8a7794" for the R8A7794 SoC.
- "renesas,etheravb-rcar-gen2" as a fallback for the above
R-Car Gen2 and RZ/G1 devices.
When compatible with the generic version, nodes must list the
SoC-specific version corresponding to the platform first
followed by the generic version.
- "renesas,etheravb-r8a7795" for the R8A7795 SoC.
- "renesas,etheravb-r8a7796" for the R8A7796 SoC.
- "renesas,etheravb-rcar-gen3" as a fallback for the above
R-Car Gen3 devices.
When compatible with the generic version, nodes must list the
SoC-specific version corresponding to the platform first followed by
the generic version.
- reg: offset and length of (1) the register block and (2) the stream buffer.
- interrupts: A list of interrupt-specifiers, one for each entry in

View File

@ -10,6 +10,7 @@ Required properties:
"rockchip,rk3366-gmac": found on RK3366 SoCs
"rockchip,rk3368-gmac": found on RK3368 SoCs
"rockchip,rk3399-gmac": found on RK3399 SoCs
"rockchip,rv1108-gmac": found on RV1108 SoCs
- reg: addresses and length of the register sets for the device.
- interrupts: Should contain the GMAC interrupts.
- interrupt-names: Should contain the interrupt names "macirq".

View File

@ -0,0 +1,55 @@
XILINX AXI ETHERNET Device Tree Bindings
--------------------------------------------------------
Also called AXI 1G/2.5G Ethernet Subsystem, the xilinx axi ethernet IP core
provides connectivity to an external ethernet PHY supporting different
interfaces: MII, GMII, RGMII, SGMII, 1000BaseX. It also includes two
segments of memory for buffering TX and RX, as well as the capability of
offloading TX/RX checksum calculation off the processor.
Management configuration is done through the AXI interface, while payload is
sent and received through means of an AXI DMA controller. This driver
includes the DMA driver code, so this driver is incompatible with AXI DMA
driver.
For more details about mdio please refer phy.txt file in the same directory.
Required properties:
- compatible : Must be one of "xlnx,axi-ethernet-1.00.a",
"xlnx,axi-ethernet-1.01.a", "xlnx,axi-ethernet-2.01.a"
- reg : Address and length of the IO space.
- interrupts : Should be a list of two interrupt, TX and RX.
- phy-handle : Should point to the external phy device.
See ethernet.txt file in the same directory.
- xlnx,rxmem : Set to allocated memory buffer for Rx/Tx in the hardware
Optional properties:
- phy-mode : See ethernet.txt
- xlnx,phy-type : Deprecated, do not use, but still accepted in preference
to phy-mode.
- xlnx,txcsum : 0 or empty for disabling TX checksum offload,
1 to enable partial TX checksum offload,
2 to enable full TX checksum offload
- xlnx,rxcsum : Same values as xlnx,txcsum but for RX checksum offload
Example:
axi_ethernet_eth: ethernet@40c00000 {
compatible = "xlnx,axi-ethernet-1.00.a";
device_type = "network";
interrupt-parent = <&microblaze_0_axi_intc>;
interrupts = <2 0>;
phy-mode = "mii";
reg = <0x40c00000 0x40000>;
xlnx,rxcsum = <0x2>;
xlnx,rxmem = <0x800>;
xlnx,txcsum = <0x2>;
phy-handle = <&phy0>;
axi_ethernetlite_0_mdio: mdio {
#address-cells = <1>;
#size-cells = <0>;
phy0: phy@0 {
device_type = "ethernet-phy";
reg = <1>;
};
};
};

View File

@ -0,0 +1,43 @@
mvebu comphy driver
-------------------
A comphy controller can be found on Marvell Armada 7k/8k on the CP110. It
provides a number of shared PHYs used by various interfaces (network, sata,
usb, PCIe...).
Required properties:
- compatible: should be "marvell,comphy-cp110"
- reg: should contain the comphy register location and length.
- marvell,system-controller: should contain a phandle to the
system controller node.
- #address-cells: should be 1.
- #size-cells: should be 0.
A sub-node is required for each comphy lane provided by the comphy.
Required properties (child nodes):
- reg: comphy lane number.
- #phy-cells : from the generic phy bindings, must be 1. Defines the
input port to use for a given comphy lane.
Example:
cpm_comphy: phy@120000 {
compatible = "marvell,comphy-cp110";
reg = <0x120000 0x6000>;
marvell,system-controller = <&cpm_syscon0>;
#address-cells = <1>;
#size-cells = <0>;
cpm_comphy0: phy@0 {
reg = <0>;
#phy-cells = <1>;
};
cpm_comphy1: phy@1 {
reg = <1>;
#phy-cells = <1>;
};
};

View File

@ -30,8 +30,6 @@ atm.txt
- info on where to get ATM programs and support for Linux.
ax25.txt
- info on using AX.25 and NET/ROM code for Linux
batman-adv.txt
- B.A.T.M.A.N routing protocol on top of layer 2 Ethernet Frames.
baycom.txt
- info on the driver for Baycom style amateur radio modems
bonding.txt

View File

@ -0,0 +1,220 @@
==========
batman-adv
==========
Batman advanced is a new approach to wireless networking which does no longer
operate on the IP basis. Unlike the batman daemon, which exchanges information
using UDP packets and sets routing tables, batman-advanced operates on ISO/OSI
Layer 2 only and uses and routes (or better: bridges) Ethernet Frames. It
emulates a virtual network switch of all nodes participating. Therefore all
nodes appear to be link local, thus all higher operating protocols won't be
affected by any changes within the network. You can run almost any protocol
above batman advanced, prominent examples are: IPv4, IPv6, DHCP, IPX.
Batman advanced was implemented as a Linux kernel driver to reduce the overhead
to a minimum. It does not depend on any (other) network driver, and can be used
on wifi as well as ethernet lan, vpn, etc ... (anything with ethernet-style
layer 2).
Configuration
=============
Load the batman-adv module into your kernel::
$ insmod batman-adv.ko
The module is now waiting for activation. You must add some interfaces on which
batman can operate. After loading the module batman advanced will scan your
systems interfaces to search for compatible interfaces. Once found, it will
create subfolders in the ``/sys`` directories of each supported interface,
e.g.::
$ ls /sys/class/net/eth0/batman_adv/
elp_interval iface_status mesh_iface throughput_override
If an interface does not have the ``batman_adv`` subfolder, it probably is not
supported. Not supported interfaces are: loopback, non-ethernet and batman's
own interfaces.
Note: After the module was loaded it will continuously watch for new
interfaces to verify the compatibility. There is no need to reload the module
if you plug your USB wifi adapter into your machine after batman advanced was
initially loaded.
The batman-adv soft-interface can be created using the iproute2 tool ``ip``::
$ ip link add name bat0 type batadv
To activate a given interface simply attach it to the ``bat0`` interface::
$ ip link set dev eth0 master bat0
Repeat this step for all interfaces you wish to add. Now batman starts
using/broadcasting on this/these interface(s).
By reading the "iface_status" file you can check its status::
$ cat /sys/class/net/eth0/batman_adv/iface_status
active
To deactivate an interface you have to detach it from the "bat0" interface::
$ ip link set dev eth0 nomaster
All mesh wide settings can be found in batman's own interface folder::
$ ls /sys/class/net/bat0/mesh/
aggregated_ogms fragmentation isolation_mark routing_algo
ap_isolation gw_bandwidth log_level vlan0
bonding gw_mode multicast_mode
bridge_loop_avoidance gw_sel_class network_coding
distributed_arp_table hop_penalty orig_interval
There is a special folder for debugging information::
$ ls /sys/kernel/debug/batman_adv/bat0/
bla_backbone_table log neighbors transtable_local
bla_claim_table mcast_flags originators
dat_cache nc socket
gateways nc_nodes transtable_global
Some of the files contain all sort of status information regarding the mesh
network. For example, you can view the table of originators (mesh
participants) with::
$ cat /sys/kernel/debug/batman_adv/bat0/originators
Other files allow to change batman's behaviour to better fit your requirements.
For instance, you can check the current originator interval (value in
milliseconds which determines how often batman sends its broadcast packets)::
$ cat /sys/class/net/bat0/mesh/orig_interval
1000
and also change its value::
$ echo 3000 > /sys/class/net/bat0/mesh/orig_interval
In very mobile scenarios, you might want to adjust the originator interval to a
lower value. This will make the mesh more responsive to topology changes, but
will also increase the overhead.
Usage
=====
To make use of your newly created mesh, batman advanced provides a new
interface "bat0" which you should use from this point on. All interfaces added
to batman advanced are not relevant any longer because batman handles them for
you. Basically, one "hands over" the data by using the batman interface and
batman will make sure it reaches its destination.
The "bat0" interface can be used like any other regular interface. It needs an
IP address which can be either statically configured or dynamically (by using
DHCP or similar services)::
NodeA: ip link set up dev bat0
NodeA: ip addr add 192.168.0.1/24 dev bat0
NodeB: ip link set up dev bat0
NodeB: ip addr add 192.168.0.2/24 dev bat0
NodeB: ping 192.168.0.1
Note: In order to avoid problems remove all IP addresses previously assigned to
interfaces now used by batman advanced, e.g.::
$ ip addr flush dev eth0
Logging/Debugging
=================
All error messages, warnings and information messages are sent to the kernel
log. Depending on your operating system distribution this can be read in one of
a number of ways. Try using the commands: ``dmesg``, ``logread``, or looking in
the files ``/var/log/kern.log`` or ``/var/log/syslog``. All batman-adv messages
are prefixed with "batman-adv:" So to see just these messages try::
$ dmesg | grep batman-adv
When investigating problems with your mesh network, it is sometimes necessary to
see more detail debug messages. This must be enabled when compiling the
batman-adv module. When building batman-adv as part of kernel, use "make
menuconfig" and enable the option ``B.A.T.M.A.N. debugging``
(``CONFIG_BATMAN_ADV_DEBUG=y``).
Those additional debug messages can be accessed using a special file in
debugfs::
$ cat /sys/kernel/debug/batman_adv/bat0/log
The additional debug output is by default disabled. It can be enabled during
run time. Following log_levels are defined:
.. flat-table::
* - 0
- All debug output disabled
* - 1
- Enable messages related to routing / flooding / broadcasting
* - 2
- Enable messages related to route added / changed / deleted
* - 4
- Enable messages related to translation table operations
* - 8
- Enable messages related to bridge loop avoidance
* - 16
- Enable messages related to DAT, ARP snooping and parsing
* - 32
- Enable messages related to network coding
* - 64
- Enable messages related to multicast
* - 128
- Enable messages related to throughput meter
* - 255
- Enable all messages
The debug output can be changed at runtime using the file
``/sys/class/net/bat0/mesh/log_level``. e.g.::
$ echo 6 > /sys/class/net/bat0/mesh/log_level
will enable debug messages for when routes change.
Counters for different types of packets entering and leaving the batman-adv
module are available through ethtool::
$ ethtool --statistics bat0
batctl
======
As batman advanced operates on layer 2, all hosts participating in the virtual
switch are completely transparent for all protocols above layer 2. Therefore
the common diagnosis tools do not work as expected. To overcome these problems,
batctl was created. At the moment the batctl contains ping, traceroute, tcpdump
and interfaces to the kernel module settings.
For more information, please see the manpage (``man batctl``).
batctl is available on https://www.open-mesh.org/
Contact
=======
Please send us comments, experiences, questions, anything :)
IRC:
#batman on irc.freenode.org
Mailing-list:
b.a.t.m.a.n@open-mesh.org (optional subscription at
https://lists.open-mesh.org/mm/listinfo/b.a.t.m.a.n)
You can also contact the Authors:
* Marek Lindner <mareklindner@neomailbox.ch>
* Simon Wunderlich <sw@simonwunderlich.de>

View File

@ -1,215 +0,0 @@
BATMAN-ADV
----------
Batman advanced is a new approach to wireless networking which
does no longer operate on the IP basis. Unlike the batman daemon,
which exchanges information using UDP packets and sets routing
tables, batman-advanced operates on ISO/OSI Layer 2 only and uses
and routes (or better: bridges) Ethernet Frames. It emulates a
virtual network switch of all nodes participating. Therefore all
nodes appear to be link local, thus all higher operating proto-
cols won't be affected by any changes within the network. You can
run almost any protocol above batman advanced, prominent examples
are: IPv4, IPv6, DHCP, IPX.
Batman advanced was implemented as a Linux kernel driver to re-
duce the overhead to a minimum. It does not depend on any (other)
network driver, and can be used on wifi as well as ethernet lan,
vpn, etc ... (anything with ethernet-style layer 2).
CONFIGURATION
-------------
Load the batman-adv module into your kernel:
# insmod batman-adv.ko
The module is now waiting for activation. You must add some in-
terfaces on which batman can operate. After loading the module
batman advanced will scan your systems interfaces to search for
compatible interfaces. Once found, it will create subfolders in
the /sys directories of each supported interface, e.g.
# ls /sys/class/net/eth0/batman_adv/
# elp_interval iface_status mesh_iface throughput_override
If an interface does not have the "batman_adv" subfolder it prob-
ably is not supported. Not supported interfaces are: loopback,
non-ethernet and batman's own interfaces.
Note: After the module was loaded it will continuously watch for
new interfaces to verify the compatibility. There is no need to
reload the module if you plug your USB wifi adapter into your ma-
chine after batman advanced was initially loaded.
The batman-adv soft-interface can be created using the iproute2
tool "ip"
# ip link add name bat0 type batadv
To activate a given interface simply attach it to the "bat0"
interface
# ip link set dev eth0 master bat0
Repeat this step for all interfaces you wish to add. Now batman
starts using/broadcasting on this/these interface(s).
By reading the "iface_status" file you can check its status:
# cat /sys/class/net/eth0/batman_adv/iface_status
# active
To deactivate an interface you have to detach it from the
"bat0" interface:
# ip link set dev eth0 nomaster
All mesh wide settings can be found in batman's own interface
folder:
# ls /sys/class/net/bat0/mesh/
# aggregated_ogms fragmentation isolation_mark routing_algo
# ap_isolation gw_bandwidth log_level vlan0
# bonding gw_mode multicast_mode
# bridge_loop_avoidance gw_sel_class network_coding
# distributed_arp_table hop_penalty orig_interval
There is a special folder for debugging information:
# ls /sys/kernel/debug/batman_adv/bat0/
# bla_backbone_table log neighbors transtable_local
# bla_claim_table mcast_flags originators
# dat_cache nc socket
# gateways nc_nodes transtable_global
Some of the files contain all sort of status information regard-
ing the mesh network. For example, you can view the table of
originators (mesh participants) with:
# cat /sys/kernel/debug/batman_adv/bat0/originators
Other files allow to change batman's behaviour to better fit your
requirements. For instance, you can check the current originator
interval (value in milliseconds which determines how often batman
sends its broadcast packets):
# cat /sys/class/net/bat0/mesh/orig_interval
# 1000
and also change its value:
# echo 3000 > /sys/class/net/bat0/mesh/orig_interval
In very mobile scenarios, you might want to adjust the originator
interval to a lower value. This will make the mesh more respon-
sive to topology changes, but will also increase the overhead.
USAGE
-----
To make use of your newly created mesh, batman advanced provides
a new interface "bat0" which you should use from this point on.
All interfaces added to batman advanced are not relevant any
longer because batman handles them for you. Basically, one "hands
over" the data by using the batman interface and batman will make
sure it reaches its destination.
The "bat0" interface can be used like any other regular inter-
face. It needs an IP address which can be either statically con-
figured or dynamically (by using DHCP or similar services):
# NodeA: ip link set up dev bat0
# NodeA: ip addr add 192.168.0.1/24 dev bat0
# NodeB: ip link set up dev bat0
# NodeB: ip addr add 192.168.0.2/24 dev bat0
# NodeB: ping 192.168.0.1
Note: In order to avoid problems remove all IP addresses previ-
ously assigned to interfaces now used by batman advanced, e.g.
# ip addr flush dev eth0
LOGGING/DEBUGGING
-----------------
All error messages, warnings and information messages are sent to
the kernel log. Depending on your operating system distribution
this can be read in one of a number of ways. Try using the com-
mands: dmesg, logread, or looking in the files /var/log/kern.log
or /var/log/syslog. All batman-adv messages are prefixed with
"batman-adv:" So to see just these messages try
# dmesg | grep batman-adv
When investigating problems with your mesh network it is some-
times necessary to see more detail debug messages. This must be
enabled when compiling the batman-adv module. When building bat-
man-adv as part of kernel, use "make menuconfig" and enable the
option "B.A.T.M.A.N. debugging".
Those additional debug messages can be accessed using a special
file in debugfs
# cat /sys/kernel/debug/batman_adv/bat0/log
The additional debug output is by default disabled. It can be en-
abled during run time. Following log_levels are defined:
0 - All debug output disabled
1 - Enable messages related to routing / flooding / broadcasting
2 - Enable messages related to route added / changed / deleted
4 - Enable messages related to translation table operations
8 - Enable messages related to bridge loop avoidance
16 - Enable messages related to DAT, ARP snooping and parsing
32 - Enable messages related to network coding
64 - Enable messages related to multicast
128 - Enable messages related to throughput meter
255 - Enable all messages
The debug output can be changed at runtime using the file
/sys/class/net/bat0/mesh/log_level. e.g.
# echo 6 > /sys/class/net/bat0/mesh/log_level
will enable debug messages for when routes change.
Counters for different types of packets entering and leaving the
batman-adv module are available through ethtool:
# ethtool --statistics bat0
BATCTL
------
As batman advanced operates on layer 2 all hosts participating in
the virtual switch are completely transparent for all protocols
above layer 2. Therefore the common diagnosis tools do not work
as expected. To overcome these problems batctl was created. At
the moment the batctl contains ping, traceroute, tcpdump and
interfaces to the kernel module settings.
For more information, please see the manpage (man batctl).
batctl is available on https://www.open-mesh.org/
CONTACT
-------
Please send us comments, experiences, questions, anything :)
IRC: #batman on irc.freenode.org
Mailing-list: b.a.t.m.a.n@open-mesh.org (optional subscription
at https://lists.open-mesh.org/mm/listinfo/b.a.t.m.a.n)
You can also contact the Authors:
Marek Lindner <mareklindner@neomailbox.ch>
Simon Wunderlich <sw@simonwunderlich.de>

View File

@ -13,6 +13,7 @@ Contents
- Configuring DPAA Ethernet in your kernel
- DPAA Ethernet Frame Processing
- DPAA Ethernet Features
- DPAA IRQ Affinity and Receive Side Scaling
- Debugging
DPAA Ethernet Overview
@ -147,7 +148,10 @@ gradually.
The driver has Rx and Tx checksum offloading for UDP and TCP. Currently the Rx
checksum offload feature is enabled by default and cannot be controlled through
ethtool.
ethtool. Also, rx-flow-hash and rx-hashing was added. The addition of RSS
provides a big performance boost for the forwarding scenarios, allowing
different traffic flows received by one interface to be processed by different
CPUs in parallel.
The driver has support for multiple prioritized Tx traffic classes. Priorities
range from 0 (lowest) to 3 (highest). These are mapped to HW workqueues with
@ -166,6 +170,68 @@ classes as follows:
tc qdisc add dev <int> root handle 1: \
mqprio num_tc 4 map 0 0 0 0 1 1 1 1 2 2 2 2 3 3 3 3 hw 1
DPAA IRQ Affinity and Receive Side Scaling
==========================================
Traffic coming on the DPAA Rx queues or on the DPAA Tx confirmation
queues is seen by the CPU as ingress traffic on a certain portal.
The DPAA QMan portal interrupts are affined each to a certain CPU.
The same portal interrupt services all the QMan portal consumers.
By default the DPAA Ethernet driver enables RSS, making use of the
DPAA FMan Parser and Keygen blocks to distribute traffic on 128
hardware frame queues using a hash on IP v4/v6 source and destination
and L4 source and destination ports, in present in the received frame.
When RSS is disabled, all traffic received by a certain interface is
received on the default Rx frame queue. The default DPAA Rx frame
queues are configured to put the received traffic into a pool channel
that allows any available CPU portal to dequeue the ingress traffic.
The default frame queues have the HOLDACTIVE option set, ensuring that
traffic bursts from a certain queue are serviced by the same CPU.
This ensures a very low rate of frame reordering. A drawback of this
is that only one CPU at a time can service the traffic received by a
certain interface when RSS is not enabled.
To implement RSS, the DPAA Ethernet driver allocates an extra set of
128 Rx frame queues that are configured to dedicated channels, in a
round-robin manner. The mapping of the frame queues to CPUs is now
hardcoded, there is no indirection table to move traffic for a certain
FQ (hash result) to another CPU. The ingress traffic arriving on one
of these frame queues will arrive at the same portal and will always
be processed by the same CPU. This ensures intra-flow order preservation
and workload distribution for multiple traffic flows.
RSS can be turned off for a certain interface using ethtool, i.e.
# ethtool -N fm1-mac9 rx-flow-hash tcp4 ""
To turn it back on, one needs to set rx-flow-hash for tcp4/6 or udp4/6:
# ethtool -N fm1-mac9 rx-flow-hash udp4 sfdn
There is no independent control for individual protocols, any command
run for one of tcp4|udp4|ah4|esp4|sctp4|tcp6|udp6|ah6|esp6|sctp6 is
going to control the rx-flow-hashing for all protocols on that interface.
Besides using the FMan Keygen computed hash for spreading traffic on the
128 Rx FQs, the DPAA Ethernet driver also sets the skb hash value when
the NETIF_F_RXHASH feature is on (active by default). This can be turned
on or off through ethtool, i.e.:
# ethtool -K fm1-mac9 rx-hashing off
# ethtool -k fm1-mac9 | grep hash
receive-hashing: off
# ethtool -K fm1-mac9 rx-hashing on
Actual changes:
receive-hashing: on
# ethtool -k fm1-mac9 | grep hash
receive-hashing: on
Please note that Rx hashing depends upon the rx-flow-hashing being on
for that interface - turning off rx-flow-hashing will also disable the
rx-hashing (without ethtool reporting it as off as that depends on the
NETIF_F_RXHASH feature flag).
Debugging
=========

View File

@ -596,8 +596,8 @@ skb pointer). All constraints and restrictions from bpf_check_classic() apply
before a conversion to the new layout is being done behind the scenes!
Currently, the classic BPF format is being used for JITing on most 32-bit
architectures, whereas x86-64, aarch64, s390x, powerpc64, sparc64 perform JIT
compilation from eBPF instruction set.
architectures, whereas x86-64, aarch64, s390x, powerpc64, sparc64, arm32 perform
JIT compilation from eBPF instruction set.
Some core changes of the new internal format:
@ -793,7 +793,7 @@ Some core changes of the new internal format:
bpf_exit
After the call the registers R1-R5 contain junk values and cannot be read.
In the future an eBPF verifier can be used to validate internal BPF programs.
An in-kernel eBPF verifier is used to validate internal BPF programs.
Also in the new design, eBPF is limited to 4096 insns, which means that any
program will terminate quickly and will only call a fixed number of kernel
@ -906,6 +906,10 @@ If BPF_CLASS(code) == BPF_JMP, BPF_OP(code) is one of:
BPF_JSGE 0x70 /* eBPF only: signed '>=' */
BPF_CALL 0x80 /* eBPF only: function call */
BPF_EXIT 0x90 /* eBPF only: function return */
BPF_JLT 0xa0 /* eBPF only: unsigned '<' */
BPF_JLE 0xb0 /* eBPF only: unsigned '<=' */
BPF_JSLT 0xc0 /* eBPF only: signed '<' */
BPF_JSLE 0xd0 /* eBPF only: signed '<=' */
So BPF_ADD | BPF_X | BPF_ALU means 32-bit addition in both classic BPF
and eBPF. There are only two registers in classic BPF, so it means A += X.
@ -1017,7 +1021,7 @@ At the start of the program the register R1 contains a pointer to context
and has type PTR_TO_CTX.
If verifier sees an insn that does R2=R1, then R2 has now type
PTR_TO_CTX as well and can be used on the right hand side of expression.
If R1=PTR_TO_CTX and insn is R2=R1+R1, then R2=UNKNOWN_VALUE,
If R1=PTR_TO_CTX and insn is R2=R1+R1, then R2=SCALAR_VALUE,
since addition of two valid pointers makes invalid pointer.
(In 'secure' mode verifier will reject any type of pointer arithmetic to make
sure that kernel addresses don't leak to unprivileged users)
@ -1039,7 +1043,7 @@ is a correct program. If there was R1 instead of R6, it would have
been rejected.
load/store instructions are allowed only with registers of valid types, which
are PTR_TO_CTX, PTR_TO_MAP, FRAME_PTR. They are bounds and alignment checked.
are PTR_TO_CTX, PTR_TO_MAP, PTR_TO_STACK. They are bounds and alignment checked.
For example:
bpf_mov R1 = 1
bpf_mov R2 = 2
@ -1058,7 +1062,7 @@ intends to load a word from address R6 + 8 and store it into R0
If R6=PTR_TO_CTX, via is_valid_access() callback the verifier will know
that offset 8 of size 4 bytes can be accessed for reading, otherwise
the verifier will reject the program.
If R6=FRAME_PTR, then access should be aligned and be within
If R6=PTR_TO_STACK, then access should be aligned and be within
stack bounds, which are [-MAX_BPF_STACK, 0). In this example offset is 8,
so it will fail verification, since it's out of bounds.
@ -1069,7 +1073,7 @@ For example:
bpf_ld R0 = *(u32 *)(R10 - 4)
bpf_exit
is invalid program.
Though R10 is correct read-only register and has type FRAME_PTR
Though R10 is correct read-only register and has type PTR_TO_STACK
and R10 - 4 is within stack bounds, there were no stores into that location.
Pointer register spill/fill is tracked as well, since four (R6-R9)
@ -1094,6 +1098,71 @@ all use cases.
See details of eBPF verifier in kernel/bpf/verifier.c
Register value tracking
-----------------------
In order to determine the safety of an eBPF program, the verifier must track
the range of possible values in each register and also in each stack slot.
This is done with 'struct bpf_reg_state', defined in include/linux/
bpf_verifier.h, which unifies tracking of scalar and pointer values. Each
register state has a type, which is either NOT_INIT (the register has not been
written to), SCALAR_VALUE (some value which is not usable as a pointer), or a
pointer type. The types of pointers describe their base, as follows:
PTR_TO_CTX Pointer to bpf_context.
CONST_PTR_TO_MAP Pointer to struct bpf_map. "Const" because arithmetic
on these pointers is forbidden.
PTR_TO_MAP_VALUE Pointer to the value stored in a map element.
PTR_TO_MAP_VALUE_OR_NULL
Either a pointer to a map value, or NULL; map accesses
(see section 'eBPF maps', below) return this type,
which becomes a PTR_TO_MAP_VALUE when checked != NULL.
Arithmetic on these pointers is forbidden.
PTR_TO_STACK Frame pointer.
PTR_TO_PACKET skb->data.
PTR_TO_PACKET_END skb->data + headlen; arithmetic forbidden.
However, a pointer may be offset from this base (as a result of pointer
arithmetic), and this is tracked in two parts: the 'fixed offset' and 'variable
offset'. The former is used when an exactly-known value (e.g. an immediate
operand) is added to a pointer, while the latter is used for values which are
not exactly known. The variable offset is also used in SCALAR_VALUEs, to track
the range of possible values in the register.
The verifier's knowledge about the variable offset consists of:
* minimum and maximum values as unsigned
* minimum and maximum values as signed
* knowledge of the values of individual bits, in the form of a 'tnum': a u64
'mask' and a u64 'value'. 1s in the mask represent bits whose value is unknown;
1s in the value represent bits known to be 1. Bits known to be 0 have 0 in both
mask and value; no bit should ever be 1 in both. For example, if a byte is read
into a register from memory, the register's top 56 bits are known zero, while
the low 8 are unknown - which is represented as the tnum (0x0; 0xff). If we
then OR this with 0x40, we get (0x40; 0xcf), then if we add 1 we get (0x0;
0x1ff), because of potential carries.
Besides arithmetic, the register state can also be updated by conditional
branches. For instance, if a SCALAR_VALUE is compared > 8, in the 'true' branch
it will have a umin_value (unsigned minimum value) of 9, whereas in the 'false'
branch it will have a umax_value of 8. A signed compare (with BPF_JSGT or
BPF_JSGE) would instead update the signed minimum/maximum values. Information
from the signed and unsigned bounds can be combined; for instance if a value is
first tested < 8 and then tested s> 4, the verifier will conclude that the value
is also > 4 and s< 8, since the bounds prevent crossing the sign boundary.
PTR_TO_PACKETs with a variable offset part have an 'id', which is common to all
pointers sharing that same variable offset. This is important for packet range
checks: after adding some variable to a packet pointer, if you then copy it to
another register and (say) add a constant 4, both registers will share the same
'id' but one will have a fixed offset of +4. Then if it is bounds-checked and
found to be less than a PTR_TO_PACKET_END, the other register is now known to
have a safe range of at least 4 bytes. See 'Direct packet access', below, for
more on PTR_TO_PACKET ranges.
The 'id' field is also used on PTR_TO_MAP_VALUE_OR_NULL, common to all copies of
the pointer returned from a map lookup. This means that when one copy is
checked and found to be non-NULL, all copies can become PTR_TO_MAP_VALUEs.
As well as range-checking, the tracked information is also used for enforcing
alignment of pointer accesses. For instance, on most systems the packet pointer
is 2 bytes after a 4-byte alignment. If a program adds 14 bytes to that to jump
over the Ethernet header, then reads IHL and addes (IHL * 4), the resulting
pointer will have a variable offset known to be 4n+2 for some n, so adding the 2
bytes (NET_IP_ALIGN) gives a 4-byte alignment and so word-sized accesses through
that pointer are safe.
Direct packet access
--------------------
In cls_bpf and act_bpf programs the verifier allows direct access to the packet
@ -1121,7 +1190,7 @@ it now points to 'skb->data + 14' and accessible range is [R5, R5 + 14 - 14)
which is zero bytes.
More complex packet access may look like:
R0=imm1 R1=ctx R3=pkt(id=0,off=0,r=14) R4=pkt_end R5=pkt(id=0,off=14,r=14) R10=fp
R0=inv1 R1=ctx R3=pkt(id=0,off=0,r=14) R4=pkt_end R5=pkt(id=0,off=14,r=14) R10=fp
6: r0 = *(u8 *)(r3 +7) /* load 7th byte from the packet */
7: r4 = *(u8 *)(r3 +12)
8: r4 *= 14
@ -1135,26 +1204,31 @@ More complex packet access may look like:
16: r2 += 8
17: r1 = *(u32 *)(r1 +80) /* load skb->data_end */
18: if r2 > r1 goto pc+2
R0=inv56 R1=pkt_end R2=pkt(id=2,off=8,r=8) R3=pkt(id=2,off=0,r=8) R4=inv52 R5=pkt(id=0,off=14,r=14) R10=fp
R0=inv(id=0,umax_value=255,var_off=(0x0; 0xff)) R1=pkt_end R2=pkt(id=2,off=8,r=8) R3=pkt(id=2,off=0,r=8) R4=inv(id=0,umax_value=3570,var_off=(0x0; 0xfffe)) R5=pkt(id=0,off=14,r=14) R10=fp
19: r1 = *(u8 *)(r3 +4)
The state of the register R3 is R3=pkt(id=2,off=0,r=8)
id=2 means that two 'r3 += rX' instructions were seen, so r3 points to some
offset within a packet and since the program author did
'if (r3 + 8 > r1) goto err' at insn #18, the safe range is [R3, R3 + 8).
The verifier only allows 'add' operation on packet registers. Any other
operation will set the register state to 'unknown_value' and it won't be
The verifier only allows 'add'/'sub' operations on packet registers. Any other
operation will set the register state to 'SCALAR_VALUE' and it won't be
available for direct packet access.
Operation 'r3 += rX' may overflow and become less than original skb->data,
therefore the verifier has to prevent that. So it tracks the number of
upper zero bits in all 'uknown_value' registers, so when it sees
'r3 += rX' instruction and rX is more than 16-bit value, it will error as:
"cannot add integer value with N upper zero bits to ptr_to_packet"
therefore the verifier has to prevent that. So when it sees 'r3 += rX'
instruction and rX is more than 16-bit value, any subsequent bounds-check of r3
against skb->data_end will not give us 'range' information, so attempts to read
through the pointer will give "invalid access to packet" error.
Ex. after insn 'r4 = *(u8 *)(r3 +12)' (insn #7 above) the state of r4 is
R4=inv56 which means that upper 56 bits on the register are guaranteed
to be zero. After insn 'r4 *= 14' the state becomes R4=inv52, since
multiplying 8-bit value by constant 14 will keep upper 52 bits as zero.
Similarly 'r2 >>= 48' will make R2=inv48, since the shift is not sign
extending. This logic is implemented in evaluate_reg_alu() function.
R4=inv(id=0,umax_value=255,var_off=(0x0; 0xff)) which means that upper 56 bits
of the register are guaranteed to be zero, and nothing is known about the lower
8 bits. After insn 'r4 *= 14' the state becomes
R4=inv(id=0,umax_value=3570,var_off=(0x0; 0xfffe)), since multiplying an 8-bit
value by constant 14 will keep upper 52 bits as zero, also the least significant
bit will be zero as 14 is even. Similarly 'r2 >>= 48' will make
R2=inv(id=0,umax_value=65535,var_off=(0x0; 0xffff)), since the shift is not sign
extending. This logic is implemented in adjust_reg_min_max_vals() function,
which calls adjust_ptr_min_max_vals() for adding pointer to scalar (or vice
versa) and adjust_scalar_min_max_vals() for operations on two scalars.
The end result is that bpf program author can access packet directly
using normal C code as:
@ -1214,6 +1288,22 @@ The map is defined by:
. key size in bytes
. value size in bytes
Pruning
-------
The verifier does not actually walk all possible paths through the program. For
each new branch to analyse, the verifier looks at all the states it's previously
been in when at this instruction. If any of them contain the current state as a
subset, the branch is 'pruned' - that is, the fact that the previous state was
accepted implies the current state would be as well. For instance, if in the
previous state, r1 held a packet-pointer, and in the current state, r1 holds a
packet-pointer with a range as long or longer and at least as strict an
alignment, then r1 is safe. Similarly, if r2 was NOT_INIT before then it can't
have been used by any path from that point, so any value in r2 (including
another NOT_INIT) is safe. The implementation is in the function regsafe().
Pruning considers not only the registers but also the stack (and any spilled
registers it may hold). They must all be safe for the branch to be pruned.
This is implemented in states_equal().
Understanding eBPF verifier messages
------------------------------------

View File

@ -0,0 +1,125 @@
Linux Kernel Driver for Huawei Intelligent NIC(HiNIC) family
============================================================
Overview:
=========
HiNIC is a network interface card for the Data Center Area.
The driver supports a range of link-speed devices (10GbE, 25GbE, 40GbE, etc.).
The driver supports also a negotiated and extendable feature set.
Some HiNIC devices support SR-IOV. This driver is used for Physical Function
(PF).
HiNIC devices support MSI-X interrupt vector for each Tx/Rx queue and
adaptive interrupt moderation.
HiNIC devices support also various offload features such as checksum offload,
TCP Transmit Segmentation Offload(TSO), Receive-Side Scaling(RSS) and
LRO(Large Receive Offload).
Supported PCI vendor ID/device IDs:
===================================
19e5:1822 - HiNIC PF
Driver Architecture and Source Code:
====================================
hinic_dev - Implement a Logical Network device that is independent from
specific HW details about HW data structure formats.
hinic_hwdev - Implement the HW details of the device and include the components
for accessing the PCI NIC.
hinic_hwdev contains the following components:
===============================================
HW Interface:
=============
The interface for accessing the pci device (DMA memory and PCI BARs).
(hinic_hw_if.c, hinic_hw_if.h)
Configuration Status Registers Area that describes the HW Registers on the
configuration and status BAR0. (hinic_hw_csr.h)
MGMT components:
================
Asynchronous Event Queues(AEQs) - The event queues for receiving messages from
the MGMT modules on the cards. (hinic_hw_eqs.c, hinic_hw_eqs.h)
Application Programmable Interface commands(API CMD) - Interface for sending
MGMT commands to the card. (hinic_hw_api_cmd.c, hinic_hw_api_cmd.h)
Management (MGMT) - the PF to MGMT channel that uses API CMD for sending MGMT
commands to the card and receives notifications from the MGMT modules on the
card by AEQs. Also set the addresses of the IO CMDQs in HW.
(hinic_hw_mgmt.c, hinic_hw_mgmt.h)
IO components:
==============
Completion Event Queues(CEQs) - The completion Event Queues that describe IO
tasks that are finished. (hinic_hw_eqs.c, hinic_hw_eqs.h)
Work Queues(WQ) - Contain the memory and operations for use by CMD queues and
the Queue Pairs. The WQ is a Memory Block in a Page. The Block contains
pointers to Memory Areas that are the Memory for the Work Queue Elements(WQEs).
(hinic_hw_wq.c, hinic_hw_wq.h)
Command Queues(CMDQ) - The queues for sending commands for IO management and is
used to set the QPs addresses in HW. The commands completion events are
accumulated on the CEQ that is configured to receive the CMDQ completion events.
(hinic_hw_cmdq.c, hinic_hw_cmdq.h)
Queue Pairs(QPs) - The HW Receive and Send queues for Receiving and Transmitting
Data. (hinic_hw_qp.c, hinic_hw_qp.h, hinic_hw_qp_ctxt.h)
IO - de/constructs all the IO components. (hinic_hw_io.c, hinic_hw_io.h)
HW device:
==========
HW device - de/constructs the HW Interface, the MGMT components on the
initialization of the driver and the IO components on the case of Interface
UP/DOWN Events. (hinic_hw_dev.c, hinic_hw_dev.h)
hinic_dev contains the following components:
===============================================
PCI ID table - Contains the supported PCI Vendor/Device IDs.
(hinic_pci_tbl.h)
Port Commands - Send commands to the HW device for port management
(MAC, Vlan, MTU, ...). (hinic_port.c, hinic_port.h)
Tx Queues - Logical Tx Queues that use the HW Send Queues for transmit.
The Logical Tx queue is not dependent on the format of the HW Send Queue.
(hinic_tx.c, hinic_tx.h)
Rx Queues - Logical Rx Queues that use the HW Receive Queues for receive.
The Logical Rx queue is not dependent on the format of the HW Receive Queue.
(hinic_rx.c, hinic_rx.h)
hinic_dev - de/constructs the Logical Tx and Rx Queues.
(hinic_main.c, hinic_dev.h)
Miscellaneous:
=============
Common functions that are used by HW and Logical Device.
(hinic_common.c, hinic_common.h)
Support
=======
If an issue is identified with the released source code on the supported kernel
with a supported adapter, email the specific information related to the issue to
aviad.krawczyk@huawei.com.

View File

@ -6,6 +6,7 @@ Contents:
.. toctree::
:maxdepth: 2
batman-adv
kapi
z8530book

View File

@ -109,7 +109,10 @@ neigh/default/unres_qlen_bytes - INTEGER
queued for each unresolved address by other network layers.
(added in linux 3.3)
Setting negative value is meaningless and will return error.
Default: 65536 Bytes(64KB)
Default: SK_WMEM_MAX, (same as net.core.wmem_default).
Exact value depends on architecture and kernel options,
but should be enough to allow queuing 256 packets
of medium size.
neigh/default/unres_qlen - INTEGER
The maximum number of packets which may be queued for each
@ -119,7 +122,7 @@ neigh/default/unres_qlen - INTEGER
unexpected packet loss. The current default value is calculated
according to default value of unres_qlen_bytes and true size of
packet.
Default: 31
Default: 101
mtu_expires - INTEGER
Time, in seconds, that cached PMTU information is kept.
@ -353,12 +356,7 @@ tcp_l3mdev_accept - BOOLEAN
compiled with CONFIG_NET_L3_MASTER_DEV.
tcp_low_latency - BOOLEAN
If set, the TCP stack makes decisions that prefer lower
latency as opposed to higher throughput. By default, this
option is not set meaning that higher throughput is preferred.
An example of an application where this default should be
changed would be a Beowulf compute cluster.
Default: 0
This is a legacy option, it has no effect anymore.
tcp_max_orphans - INTEGER
Maximal number of TCP sockets not attached to any user file handle,
@ -1291,8 +1289,7 @@ tag - INTEGER
xfrm4_gc_thresh - INTEGER
The threshold at which we will start garbage collecting for IPv4
destination cache entries. At twice this value the system will
refuse new allocations. The value must be set below the flowcache
limit (4096 * number of online cpus) to take effect.
refuse new allocations.
igmp_link_local_mcast_reports - BOOLEAN
Enable IGMP reports for link local multicast groups in the
@ -1356,6 +1353,15 @@ flowlabel_state_ranges - BOOLEAN
FALSE: disabled
Default: true
flowlabel_reflect - BOOLEAN
Automatically reflect the flow label. Needed for Path MTU
Discovery to work with Equal Cost Multipath Routing in anycast
environments. See RFC 7690 and:
https://tools.ietf.org/html/draft-wang-6man-flow-label-reflection-01
TRUE: enabled
FALSE: disabled
Default: FALSE
anycast_src_echo_reply - BOOLEAN
Controls the use of anycast addresses as source addresses for ICMPv6
echo reply
@ -1778,8 +1784,7 @@ ratelimit - INTEGER
xfrm6_gc_thresh - INTEGER
The threshold at which we will start garbage collecting for IPv6
destination cache entries. At twice this value the system will
refuse new allocations. The value must be set below the flowcache
limit (4096 * number of online cpus) to take effect.
refuse new allocations.
IPv6 Update by:

View File

@ -0,0 +1,257 @@
============
MSG_ZEROCOPY
============
Intro
=====
The MSG_ZEROCOPY flag enables copy avoidance for socket send calls.
The feature is currently implemented for TCP sockets.
Opportunity and Caveats
-----------------------
Copying large buffers between user process and kernel can be
expensive. Linux supports various interfaces that eschew copying,
such as sendpage and splice. The MSG_ZEROCOPY flag extends the
underlying copy avoidance mechanism to common socket send calls.
Copy avoidance is not a free lunch. As implemented, with page pinning,
it replaces per byte copy cost with page accounting and completion
notification overhead. As a result, MSG_ZEROCOPY is generally only
effective at writes over around 10 KB.
Page pinning also changes system call semantics. It temporarily shares
the buffer between process and network stack. Unlike with copying, the
process cannot immediately overwrite the buffer after system call
return without possibly modifying the data in flight. Kernel integrity
is not affected, but a buggy program can possibly corrupt its own data
stream.
The kernel returns a notification when it is safe to modify data.
Converting an existing application to MSG_ZEROCOPY is not always as
trivial as just passing the flag, then.
More Info
---------
Much of this document was derived from a longer paper presented at
netdev 2.1. For more in-depth information see that paper and talk,
the excellent reporting over at LWN.net or read the original code.
paper, slides, video
https://netdevconf.org/2.1/session.html?debruijn
LWN article
https://lwn.net/Articles/726917/
patchset
[PATCH net-next v4 0/9] socket sendmsg MSG_ZEROCOPY
http://lkml.kernel.org/r/20170803202945.70750-1-willemdebruijn.kernel@gmail.com
Interface
=========
Passing the MSG_ZEROCOPY flag is the most obvious step to enable copy
avoidance, but not the only one.
Socket Setup
------------
The kernel is permissive when applications pass undefined flags to the
send system call. By default it simply ignores these. To avoid enabling
copy avoidance mode for legacy processes that accidentally already pass
this flag, a process must first signal intent by setting a socket option:
::
if (setsockopt(fd, SOL_SOCKET, SO_ZEROCOPY, &one, sizeof(one)))
error(1, errno, "setsockopt zerocopy");
Transmission
------------
The change to send (or sendto, sendmsg, sendmmsg) itself is trivial.
Pass the new flag.
::
ret = send(fd, buf, sizeof(buf), MSG_ZEROCOPY);
A zerocopy failure will return -1 with errno ENOBUFS. This happens if
the socket option was not set, the socket exceeds its optmem limit or
the user exceeds its ulimit on locked pages.
Mixing copy avoidance and copying
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Many workloads have a mixture of large and small buffers. Because copy
avoidance is more expensive than copying for small packets, the
feature is implemented as a flag. It is safe to mix calls with the flag
with those without.
Notifications
-------------
The kernel has to notify the process when it is safe to reuse a
previously passed buffer. It queues completion notifications on the
socket error queue, akin to the transmit timestamping interface.
The notification itself is a simple scalar value. Each socket
maintains an internal unsigned 32-bit counter. Each send call with
MSG_ZEROCOPY that successfully sends data increments the counter. The
counter is not incremented on failure or if called with length zero.
The counter counts system call invocations, not bytes. It wraps after
UINT_MAX calls.
Notification Reception
~~~~~~~~~~~~~~~~~~~~~~
The below snippet demonstrates the API. In the simplest case, each
send syscall is followed by a poll and recvmsg on the error queue.
Reading from the error queue is always a non-blocking operation. The
poll call is there to block until an error is outstanding. It will set
POLLERR in its output flags. That flag does not have to be set in the
events field. Errors are signaled unconditionally.
::
pfd.fd = fd;
pfd.events = 0;
if (poll(&pfd, 1, -1) != 1 || pfd.revents & POLLERR == 0)
error(1, errno, "poll");
ret = recvmsg(fd, &msg, MSG_ERRQUEUE);
if (ret == -1)
error(1, errno, "recvmsg");
read_notification(msg);
The example is for demonstration purpose only. In practice, it is more
efficient to not wait for notifications, but read without blocking
every couple of send calls.
Notifications can be processed out of order with other operations on
the socket. A socket that has an error queued would normally block
other operations until the error is read. Zerocopy notifications have
a zero error code, however, to not block send and recv calls.
Notification Batching
~~~~~~~~~~~~~~~~~~~~~
Multiple outstanding packets can be read at once using the recvmmsg
call. This is often not needed. In each message the kernel returns not
a single value, but a range. It coalesces consecutive notifications
while one is outstanding for reception on the error queue.
When a new notification is about to be queued, it checks whether the
new value extends the range of the notification at the tail of the
queue. If so, it drops the new notification packet and instead increases
the range upper value of the outstanding notification.
For protocols that acknowledge data in-order, like TCP, each
notification can be squashed into the previous one, so that no more
than one notification is outstanding at any one point.
Ordered delivery is the common case, but not guaranteed. Notifications
may arrive out of order on retransmission and socket teardown.
Notification Parsing
~~~~~~~~~~~~~~~~~~~~
The below snippet demonstrates how to parse the control message: the
read_notification() call in the previous snippet. A notification
is encoded in the standard error format, sock_extended_err.
The level and type fields in the control data are protocol family
specific, IP_RECVERR or IPV6_RECVERR.
Error origin is the new type SO_EE_ORIGIN_ZEROCOPY. ee_errno is zero,
as explained before, to avoid blocking read and write system calls on
the socket.
The 32-bit notification range is encoded as [ee_info, ee_data]. This
range is inclusive. Other fields in the struct must be treated as
undefined, bar for ee_code, as discussed below.
::
struct sock_extended_err *serr;
struct cmsghdr *cm;
cm = CMSG_FIRSTHDR(msg);
if (cm->cmsg_level != SOL_IP &&
cm->cmsg_type != IP_RECVERR)
error(1, 0, "cmsg");
serr = (void *) CMSG_DATA(cm);
if (serr->ee_errno != 0 ||
serr->ee_origin != SO_EE_ORIGIN_ZEROCOPY)
error(1, 0, "serr");
printf("completed: %u..%u\n", serr->ee_info, serr->ee_data);
Deferred copies
~~~~~~~~~~~~~~~
Passing flag MSG_ZEROCOPY is a hint to the kernel to apply copy
avoidance, and a contract that the kernel will queue a completion
notification. It is not a guarantee that the copy is elided.
Copy avoidance is not always feasible. Devices that do not support
scatter-gather I/O cannot send packets made up of kernel generated
protocol headers plus zerocopy user data. A packet may need to be
converted to a private copy of data deep in the stack, say to compute
a checksum.
In all these cases, the kernel returns a completion notification when
it releases its hold on the shared pages. That notification may arrive
before the (copied) data is fully transmitted. A zerocopy completion
notification is not a transmit completion notification, therefore.
Deferred copies can be more expensive than a copy immediately in the
system call, if the data is no longer warm in the cache. The process
also incurs notification processing cost for no benefit. For this
reason, the kernel signals if data was completed with a copy, by
setting flag SO_EE_CODE_ZEROCOPY_COPIED in field ee_code on return.
A process may use this signal to stop passing flag MSG_ZEROCOPY on
subsequent requests on the same socket.
Implementation
==============
Loopback
--------
Data sent to local sockets can be queued indefinitely if the receive
process does not read its socket. Unbound notification latency is not
acceptable. For this reason all packets generated with MSG_ZEROCOPY
that are looped to a local socket will incur a deferred copy. This
includes looping onto packet sockets (e.g., tcpdump) and tun devices.
Testing
=======
More realistic example code can be found in the kernel source under
tools/testing/selftests/net/msg_zerocopy.c.
Be cognizant of the loopback constraint. The test can be run between
a pair of hosts. But if run between a local pair of processes, for
instance when run with msg_zerocopy.sh between a veth pair across
namespaces, the test will not show any improvement. For testing, the
loopback restriction can be temporarily relaxed by making
skb_orphan_frags_rx identical to skb_orphan_frags.

View File

@ -111,6 +111,14 @@ A: Generally speaking, the patches get triaged quickly (in less than 48h).
patch is a good way to ensure your patch is ignored or pushed to
the bottom of the priority list.
Q: I submitted multiple versions of the patch series, should I directly update
patchwork for the previous versions of these patch series?
A: No, please don't interfere with the patch status on patchwork, leave it to
the maintainer to figure out what is the most recent and current version that
should be applied. If there is any doubt, the maintainer will reply and ask
what should be done.
Q: How can I tell what patches are queued up for backporting to the
various stable releases?

View File

@ -0,0 +1,75 @@
Hyper-V network driver
======================
Compatibility
=============
This driver is compatible with Windows Server 2012 R2, 2016 and
Windows 10.
Features
========
Checksum offload
----------------
The netvsc driver supports checksum offload as long as the
Hyper-V host version does. Windows Server 2016 and Azure
support checksum offload for TCP and UDP for both IPv4 and
IPv6. Windows Server 2012 only supports checksum offload for TCP.
Receive Side Scaling
--------------------
Hyper-V supports receive side scaling. For TCP, packets are
distributed among available queues based on IP address and port
number.
For UDP, we can switch UDP hash level between L3 and L4 by ethtool
command. UDP over IPv4 and v6 can be set differently. The default
hash level is L4. We currently only allow switching TX hash level
from within the guests.
On Azure, fragmented UDP packets have high loss rate with L4
hashing. Using L3 hashing is recommended in this case.
For example, for UDP over IPv4 on eth0:
To include UDP port numbers in hashing:
ethtool -N eth0 rx-flow-hash udp4 sdfn
To exclude UDP port numbers in hashing:
ethtool -N eth0 rx-flow-hash udp4 sd
To show UDP hash level:
ethtool -n eth0 rx-flow-hash udp4
Generic Receive Offload, aka GRO
--------------------------------
The driver supports GRO and it is enabled by default. GRO coalesces
like packets and significantly reduces CPU usage under heavy Rx
load.
SR-IOV support
--------------
Hyper-V supports SR-IOV as a hardware acceleration option. If SR-IOV
is enabled in both the vSwitch and the guest configuration, then the
Virtual Function (VF) device is passed to the guest as a PCI
device. In this case, both a synthetic (netvsc) and VF device are
visible in the guest OS and both NIC's have the same MAC address.
The VF is enslaved by netvsc device. The netvsc driver will transparently
switch the data path to the VF when it is available and up.
Network state (addresses, firewall, etc) should be applied only to the
netvsc device; the slave device should not be accessed directly in
most cases. The exceptions are if some special queue discipline or
flow direction is desired, these should be applied directly to the
VF slave device.
Receive Buffer
--------------
Packets are received into a receive area which is created when device
is probed. The receive area is broken into MTU sized chunks and each may
contain one or more packets. The number of receive sections may be changed
via ethtool Rx ring parameters.
There is a similar send buffer which is used to aggregate packets for sending.
The send area is broken into chunks of 6144 bytes, each of section may
contain one or more packets. The send buffer is an optimization, the driver
will use slower method to handle very large packets or if the send buffer
area is exhausted.

View File

@ -96,17 +96,6 @@ nf_conntrack_max - INTEGER
Size of connection tracking table. Default value is
nf_conntrack_buckets value * 4.
nf_conntrack_default_on - BOOLEAN
0 - don't register conntrack in new net namespaces
1 - register conntrack in new net namespaces (default)
This controls wheter newly created network namespaces have connection
tracking enabled by default. It will be enabled automatically
regardless of this setting if the new net namespace requires
connection tracking, e.g. when NAT rules are created.
This setting is only visible in initial user namespace, it has no
effect on existing namespaces.
nf_conntrack_tcp_be_liberal - BOOLEAN
0 - disabled (default)
not 0 - enabled

View File

@ -0,0 +1,82 @@
1. Introduction
rmnet driver is used for supporting the Multiplexing and aggregation
Protocol (MAP). This protocol is used by all recent chipsets using Qualcomm
Technologies, Inc. modems.
This driver can be used to register onto any physical network device in
IP mode. Physical transports include USB, HSIC, PCIe and IP accelerator.
Multiplexing allows for creation of logical netdevices (rmnet devices) to
handle multiple private data networks (PDN) like a default internet, tethering,
multimedia messaging service (MMS) or IP media subsystem (IMS). Hardware sends
packets with MAP headers to rmnet. Based on the multiplexer id, rmnet
routes to the appropriate PDN after removing the MAP header.
Aggregation is required to achieve high data rates. This involves hardware
sending aggregated bunch of MAP frames. rmnet driver will de-aggregate
these MAP frames and send them to appropriate PDN's.
2. Packet format
a. MAP packet (data / control)
MAP header has the same endianness of the IP packet.
Packet format -
Bit 0 1 2-7 8 - 15 16 - 31
Function Command / Data Reserved Pad Multiplexer ID Payload length
Bit 32 - x
Function Raw Bytes
Command (1)/ Data (0) bit value is to indicate if the packet is a MAP command
or data packet. Control packet is used for transport level flow control. Data
packets are standard IP packets.
Reserved bits are usually zeroed out and to be ignored by receiver.
Padding is number of bytes to be added for 4 byte alignment if required by
hardware.
Multiplexer ID is to indicate the PDN on which data has to be sent.
Payload length includes the padding length but does not include MAP header
length.
b. MAP packet (command specific)
Bit 0 1 2-7 8 - 15 16 - 31
Function Command Reserved Pad Multiplexer ID Payload length
Bit 32 - 39 40 - 45 46 - 47 48 - 63
Function Command name Reserved Command Type Reserved
Bit 64 - 95
Function Transaction ID
Bit 96 - 127
Function Command data
Command 1 indicates disabling flow while 2 is enabling flow
Command types -
0 for MAP command request
1 is to acknowledge the receipt of a command
2 is for unsupported commands
3 is for error during processing of commands
c. Aggregation
Aggregation is multiple MAP packets (can be data or command) delivered to
rmnet in a single linear skb. rmnet will process the individual
packets and either ACK the MAP command or deliver the IP packet to the
network stack as needed
MAP header|IP Packet|Optional padding|MAP header|IP Packet|Optional padding....
MAP header|IP Packet|Optional padding|MAP header|Command Packet|Optional pad...
3. Userspace configuration
rmnet userspace configuration is done through netlink library librmnetctl
and command line utility rmnetcli. Utility is hosted in codeaurora forum git.
The driver uses rtnl_link_ops for communication.
https://source.codeaurora.org/quic/la/platform/vendor/qcom-opensource/dataservices/tree/rmnetctl

View File

@ -818,10 +818,15 @@ The kernel interface functions are as follows:
(*) Send data through a call.
typedef void (*rxrpc_notify_end_tx_t)(struct sock *sk,
unsigned long user_call_ID,
struct sk_buff *skb);
int rxrpc_kernel_send_data(struct socket *sock,
struct rxrpc_call *call,
struct msghdr *msg,
size_t len);
size_t len,
rxrpc_notify_end_tx_t notify_end_rx);
This is used to supply either the request part of a client call or the
reply part of a server call. msg.msg_iovlen and msg.msg_iov specify the
@ -832,6 +837,11 @@ The kernel interface functions are as follows:
The msg must not specify a destination address, control data or any flags
other than MSG_MORE. len is the total amount of data to transmit.
notify_end_rx can be NULL or it can be used to specify a function to be
called when the call changes state to end the Tx phase. This function is
called with the call-state spinlock held to prevent any reply or final ACK
from being delivered first.
(*) Receive data from a call.
int rxrpc_kernel_recv_data(struct socket *sock,
@ -965,6 +975,51 @@ The kernel interface functions are as follows:
size should be set when the call is begun. tx_total_len may not be less
than zero.
(*) Check to see the completion state of a call so that the caller can assess
whether it needs to be retried.
enum rxrpc_call_completion {
RXRPC_CALL_SUCCEEDED,
RXRPC_CALL_REMOTELY_ABORTED,
RXRPC_CALL_LOCALLY_ABORTED,
RXRPC_CALL_LOCAL_ERROR,
RXRPC_CALL_NETWORK_ERROR,
};
int rxrpc_kernel_check_call(struct socket *sock, struct rxrpc_call *call,
enum rxrpc_call_completion *_compl,
u32 *_abort_code);
On return, -EINPROGRESS will be returned if the call is still ongoing; if
it is finished, *_compl will be set to indicate the manner of completion,
*_abort_code will be set to any abort code that occurred. 0 will be
returned on a successful completion, -ECONNABORTED will be returned if the
client failed due to a remote abort and anything else will return an
appropriate error code.
The caller should look at this information to decide if it's worth
retrying the call.
(*) Retry a client call.
int rxrpc_kernel_retry_call(struct socket *sock,
struct rxrpc_call *call,
struct sockaddr_rxrpc *srx,
struct key *key);
This attempts to partially reinitialise a call and submit it again whilst
reusing the original call's Tx queue to avoid the need to repackage and
re-encrypt the data to be sent. call indicates the call to retry, srx the
new address to send it to and key the encryption key to use for signing or
encrypting the packets.
For this to work, the first Tx data packet must still be in the transmit
queue, and currently this is only permitted for local and network errors
and the call must not have been aborted. Any partially constructed Tx
packet is left as is and can continue being filled afterwards.
It returns 0 if the call was requeued and an error otherwise.
=======================
CONFIGURABLE PARAMETERS

View File

@ -1,45 +1,107 @@
Stream Parser
-------------
Stream Parser (strparser)
Introduction
============
The stream parser (strparser) is a utility that parses messages of an
application layer protocol running over a TCP connection. The stream
application layer protocol running over a data stream. The stream
parser works in conjunction with an upper layer in the kernel to provide
kernel support for application layer messages. For instance, Kernel
Connection Multiplexor (KCM) uses the Stream Parser to parse messages
using a BPF program.
The strparser works in one of two modes: receive callback or general
mode.
In receive callback mode, the strparser is called from the data_ready
callback of a TCP socket. Messages are parsed and delivered as they are
received on the socket.
In general mode, a sequence of skbs are fed to strparser from an
outside source. Message are parsed and delivered as the sequence is
processed. This modes allows strparser to be applied to arbitrary
streams of data.
Interface
---------
=========
The API includes a context structure, a set of callbacks, utility
functions, and a data_ready function. The callbacks include
a parse_msg function that is called to perform parsing (e.g.
BPF parsing in case of KCM), and a rcv_msg function that is called
when a full message has been completed.
functions, and a data_ready function for receive callback mode. The
callbacks include a parse_msg function that is called to perform
parsing (e.g. BPF parsing in case of KCM), and a rcv_msg function
that is called when a full message has been completed.
A stream parser can be instantiated for a TCP connection. This is done
by:
Functions
=========
strp_init(struct strparser *strp, struct sock *csk,
struct strp_callbacks *cb)
strp_init(struct strparser *strp, struct sock *sk,
const struct strp_callbacks *cb)
strp is a struct of type strparser that is allocated by the upper layer.
csk is the TCP socket associated with the stream parser. Callbacks are
called by the stream parser.
Called to initialize a stream parser. strp is a struct of type
strparser that is allocated by the upper layer. sk is the TCP
socket associated with the stream parser for use with receive
callback mode; in general mode this is set to NULL. Callbacks
are called by the stream parser (the callbacks are listed below).
void strp_pause(struct strparser *strp)
Temporarily pause a stream parser. Message parsing is suspended
and no new messages are delivered to the upper layer.
void strp_pause(struct strparser *strp)
Unpause a paused stream parser.
void strp_stop(struct strparser *strp);
strp_stop is called to completely stop stream parser operations.
This is called internally when the stream parser encounters an
error, and it is called from the upper layer to stop parsing
operations.
void strp_done(struct strparser *strp);
strp_done is called to release any resources held by the stream
parser instance. This must be called after the stream processor
has been stopped.
int strp_process(struct strparser *strp, struct sk_buff *orig_skb,
unsigned int orig_offset, size_t orig_len,
size_t max_msg_size, long timeo)
strp_process is called in general mode for a stream parser to
parse an sk_buff. The number of bytes processed or a negative
error number is returned. Note that strp_process does not
consume the sk_buff. max_msg_size is maximum size the stream
parser will parse. timeo is timeout for completing a message.
void strp_data_ready(struct strparser *strp);
The upper layer calls strp_tcp_data_ready when data is ready on
the lower socket for strparser to process. This should be called
from a data_ready callback that is set on the socket. Note that
maximum messages size is the limit of the receive socket
buffer and message timeout is the receive timeout for the socket.
void strp_check_rcv(struct strparser *strp);
strp_check_rcv is called to check for new messages on the socket.
This is normally called at initialization of a stream parser
instance or after strp_unpause.
Callbacks
---------
=========
There are four callbacks:
There are six callbacks:
int (*parse_msg)(struct strparser *strp, struct sk_buff *skb);
parse_msg is called to determine the length of the next message
in the stream. The upper layer must implement this function. It
should parse the sk_buff as containing the headers for the
next application layer messages in the stream.
next application layer message in the stream.
The skb->cb in the input skb is a struct strp_rx_msg. Only
The skb->cb in the input skb is a struct strp_msg. Only
the offset field is relevant in parse_msg and gives the offset
where the message starts in the skb.
@ -50,26 +112,41 @@ int (*parse_msg)(struct strparser *strp, struct sk_buff *skb);
-ESTRPIPE : current message should not be processed by the
kernel, return control of the socket to userspace which
can proceed to read the messages itself
other < 0 : Error is parsing, give control back to userspace
other < 0 : Error in parsing, give control back to userspace
assuming that synchronization is lost and the stream
is unrecoverable (application expected to close TCP socket)
In the case that an error is returned (return value is less than
zero) the stream parser will set the error on TCP socket and wake
it up. If parse_msg returned -ESTRPIPE and the stream parser had
previously read some bytes for the current message, then the error
set on the attached socket is ENODATA since the stream is
unrecoverable in that case.
zero) and the parser is in receive callback mode, then it will set
the error on TCP socket and wake it up. If parse_msg returned
-ESTRPIPE and the stream parser had previously read some bytes for
the current message, then the error set on the attached socket is
ENODATA since the stream is unrecoverable in that case.
void (*lock)(struct strparser *strp)
The lock callback is called to lock the strp structure when
the strparser is performing an asynchronous operation (such as
processing a timeout). In receive callback mode the default
function is to lock_sock for the associated socket. In general
mode the callback must be set appropriately.
void (*unlock)(struct strparser *strp)
The unlock callback is called to release the lock obtained
by the lock callback. In receive callback mode the default
function is release_sock for the associated socket. In general
mode the callback must be set appropriately.
void (*rcv_msg)(struct strparser *strp, struct sk_buff *skb);
rcv_msg is called when a full message has been received and
is queued. The callee must consume the sk_buff; it can
call strp_pause to prevent any further messages from being
received in rcv_msg (see strp_pause below). This callback
received in rcv_msg (see strp_pause above). This callback
must be set.
The skb->cb in the input skb is a struct strp_rx_msg. This
The skb->cb in the input skb is a struct strp_msg. This
struct contains two fields: offset and full_len. Offset is
where the message starts in the skb, and full_len is the
the length of the message. skb->len - offset may be greater
@ -78,59 +155,53 @@ void (*rcv_msg)(struct strparser *strp, struct sk_buff *skb);
int (*read_sock_done)(struct strparser *strp, int err);
read_sock_done is called when the stream parser is done reading
the TCP socket. The stream parser may read multiple messages
in a loop and this function allows cleanup to occur when existing
the loop. If the callback is not set (NULL in strp_init) a
default function is used.
the TCP socket in receive callback mode. The stream parser may
read multiple messages in a loop and this function allows cleanup
to occur when exiting the loop. If the callback is not set (NULL
in strp_init) a default function is used.
void (*abort_parser)(struct strparser *strp, int err);
This function is called when stream parser encounters an error
in parsing. The default function stops the stream parser for the
TCP socket and sets the error in the socket. The default function
can be changed by setting the callback to non-NULL in strp_init.
Functions
---------
The upper layer calls strp_tcp_data_ready when data is ready on the lower
socket for strparser to process. This should be called from a data_ready
callback that is set on the socket.
strp_stop is called to completely stop stream parser operations. This
is called internally when the stream parser encounters an error, and
it is called from the upper layer when unattaching a TCP socket.
strp_done is called to unattach the stream parser from the TCP socket.
This must be called after the stream processor has be stopped.
strp_check_rcv is called to check for new messages on the socket. This
is normally called at initialization of the a stream parser instance
of after strp_unpause.
in parsing. The default function stops the stream parser and
sets the error in the socket if the parser is in receive callback
mode. The default function can be changed by setting the callback
to non-NULL in strp_init.
Statistics
----------
==========
Various counters are kept for each stream parser for a TCP socket.
These are in the strp_stats structure. strp_aggr_stats is a convenience
structure for accumulating statistics for multiple stream parser
instances. save_strp_stats and aggregate_strp_stats are helper functions
to save and aggregate statistics.
Various counters are kept for each stream parser instance. These are in
the strp_stats structure. strp_aggr_stats is a convenience structure for
accumulating statistics for multiple stream parser instances.
save_strp_stats and aggregate_strp_stats are helper functions to save
and aggregate statistics.
Message assembly limits
-----------------------
=======================
The stream parser provide mechanisms to limit the resources consumed by
message assembly.
A timer is set when assembly starts for a new message. The message
timeout is taken from rcvtime for the associated TCP socket. If the
timer fires before assembly completes the stream parser is aborted
and the ETIMEDOUT error is set on the TCP socket.
A timer is set when assembly starts for a new message. In receive
callback mode the message timeout is taken from rcvtime for the
associated TCP socket. In general mode, the timeout is passed as an
argument in strp_process. If the timer fires before assembly completes
the stream parser is aborted and the ETIMEDOUT error is set on the TCP
socket if in receive callback mode.
In receive callback mode, message length is limited to the receive
buffer size of the associated TCP socket. If the length returned by
parse_msg is greater than the socket buffer size then the stream parser
is aborted with EMSGSIZE error set on the TCP socket. Note that this
makes the maximum size of receive skbuffs for a socket with a stream
parser to be 2*sk_rcvbuf of the TCP socket.
In general mode the message length limit is passed in as an argument
to strp_process.
Author
======
Tom Herbert (tom@quantonium.net)
Message length is limited to the receive buffer size of the associated
TCP socket. If the length returned by parse_msg is greater than
the socket buffer size then the stream parser is aborted with
EMSGSIZE error set on the TCP socket. Note that this makes the
maximum size of receive skbuffs for a socket with a stream parser
to be 2*sk_rcvbuf of the TCP socket.

View File

@ -46,13 +46,13 @@ translate these BPF proglets into native CPU instructions. There are
two flavors of JITs, the newer eBPF JIT currently supported on:
- x86_64
- arm64
- arm32
- ppc64
- sparc64
- mips64
- s390x
And the older cBPF JIT supported on the following archs:
- arm
- mips
- ppc
- sparc

View File

@ -2492,7 +2492,7 @@ Q: https://patchwork.open-mesh.org/project/batman/list/
S: Maintained
F: Documentation/ABI/testing/sysfs-class-net-batman-adv
F: Documentation/ABI/testing/sysfs-class-net-mesh
F: Documentation/networking/batman-adv.txt
F: Documentation/networking/batman-adv.rst
F: include/uapi/linux/batman_adv.h
F: net/batman-adv/
@ -5136,6 +5136,7 @@ F: include/linux/of_net.h
F: include/linux/phy.h
F: include/linux/phy_fixed.h
F: include/linux/platform_data/mdio-gpio.h
F: include/linux/platform_data/mdio-bcm-unimac.h
F: include/trace/events/mdio.h
F: include/uapi/linux/mdio.h
F: include/uapi/linux/mii.h
@ -6183,6 +6184,14 @@ S: Maintained
F: drivers/net/ethernet/hisilicon/
F: Documentation/devicetree/bindings/net/hisilicon*.txt
HISILICON NETWORK SUBSYSTEM 3 DRIVER (HNS3)
M: Yisen Zhuang <yisen.zhuang@huawei.com>
M: Salil Mehta <salil.mehta@huawei.com>
L: netdev@vger.kernel.org
W: http://www.hisilicon.com
S: Maintained
F: drivers/net/ethernet/hisilicon/hns3/
HISILICON ROCE DRIVER
M: Lijun Ou <oulijun@huawei.com>
M: Wei Hu(Xavier) <xavier.huwei@huawei.com>
@ -6267,6 +6276,13 @@ L: linux-input@vger.kernel.org
S: Maintained
F: drivers/input/touchscreen/htcpen.c
HUAWEI ETHERNET DRIVER
M: Aviad Krawczyk <aviad.krawczyk@huawei.com>
L: netdev@vger.kernel.org
S: Supported
F: Documentation/networking/hinic.txt
F: drivers/net/ethernet/huawei/hinic/
HUGETLB FILESYSTEM
M: Nadia Yvette Chambers <nyc@holomorphy.com>
S: Maintained
@ -6293,6 +6309,7 @@ M: Haiyang Zhang <haiyangz@microsoft.com>
M: Stephen Hemminger <sthemmin@microsoft.com>
L: devel@linuxdriverproject.org
S: Maintained
F: Documentation/networking/netvsc.txt
F: arch/x86/include/asm/mshyperv.h
F: arch/x86/include/uapi/asm/hyperv.h
F: arch/x86/kernel/cpu/mshyperv.c
@ -6305,6 +6322,7 @@ F: drivers/net/hyperv/
F: drivers/scsi/storvsc_drv.c
F: drivers/uio/uio_hv_generic.c
F: drivers/video/fbdev/hyperv_fb.c
F: net/vmw_vsock/hyperv_transport.c
F: include/linux/hyperv.h
F: tools/hv/
F: Documentation/ABI/stable/sysfs-bus-vmbus
@ -7120,9 +7138,7 @@ W: http://irda.sourceforge.net/
S: Maintained
T: git git://git.kernel.org/pub/scm/linux/kernel/git/sameo/irda-2.6.git
F: Documentation/networking/irda.txt
F: drivers/net/irda/
F: include/net/irda/
F: net/irda/
F: drivers/staging/irda/
IRQ DOMAINS (IRQ NUMBER MAPPING LIBRARY)
M: Marc Zyngier <marc.zyngier@arm.com>
@ -8449,7 +8465,9 @@ F: include/uapi/linux/uvcvideo.h
MEDIATEK ETHERNET DRIVER
M: Felix Fietkau <nbd@openwrt.org>
M: John Crispin <blogic@openwrt.org>
M: John Crispin <john@phrozen.org>
M: Sean Wang <sean.wang@mediatek.com>
M: Nelson Chang <nelson.chang@mediatek.com>
L: netdev@vger.kernel.org
S: Maintained
F: drivers/net/ethernet/mediatek/

View File

@ -109,4 +109,6 @@
#define SO_PEERGROUPS 59
#define SO_ZEROCOPY 60
#endif /* _UAPI_ASM_SOCKET_H */

View File

@ -50,7 +50,7 @@ config ARM
select HAVE_ARCH_SECCOMP_FILTER if (AEABI && !OABI_COMPAT)
select HAVE_ARCH_TRACEHOOK
select HAVE_ARM_SMCCC if CPU_V7
select HAVE_CBPF_JIT
select HAVE_EBPF_JIT if !CPU_ENDIAN_BE32
select HAVE_CC_STACKPROTECTOR
select HAVE_CONTEXT_TRACKING
select HAVE_C_RECORDMCOUNT

View File

@ -50,6 +50,16 @@
device_type = "memory";
reg = <0x60000000 0x40000000>;
};
vcc_phy: vcc-phy-regulator {
compatible = "regulator-fixed";
enable-active-high;
regulator-name = "vcc_phy";
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <1800000>;
regulator-always-on;
regulator-boot-on;
};
};
&emmc {
@ -60,6 +70,30 @@
status = "okay";
};
&gmac {
assigned-clocks = <&cru SCLK_MAC_SRC>;
assigned-clock-rates = <50000000>;
clock_in_out = "output";
phy-supply = <&vcc_phy>;
phy-mode = "rmii";
phy-handle = <&phy>;
status = "okay";
mdio {
compatible = "snps,dwmac-mdio";
#address-cells = <1>;
#size-cells = <0>;
phy: phy@0 {
compatible = "ethernet-phy-id1234.d400", "ethernet-phy-ieee802.3-c22";
reg = <0>;
clocks = <&cru SCLK_MAC_PHY>;
resets = <&cru SRST_MACPHY>;
phy-is-integrated;
};
};
};
&tsadc {
status = "okay";

View File

@ -270,6 +270,7 @@ CONFIG_ICPLUS_PHY=y
CONFIG_REALTEK_PHY=y
CONFIG_MICREL_PHY=y
CONFIG_FIXED_PHY=y
CONFIG_ROCKCHIP_PHY=y
CONFIG_USB_PEGASUS=y
CONFIG_USB_RTL8152=m
CONFIG_USB_USBNET=y

File diff suppressed because it is too large Load Diff

View File

@ -11,6 +11,7 @@
#ifndef PFILTER_OPCODES_ARM_H
#define PFILTER_OPCODES_ARM_H
/* ARM 32bit Registers */
#define ARM_R0 0
#define ARM_R1 1
#define ARM_R2 2
@ -22,38 +23,43 @@
#define ARM_R8 8
#define ARM_R9 9
#define ARM_R10 10
#define ARM_FP 11
#define ARM_IP 12
#define ARM_SP 13
#define ARM_LR 14
#define ARM_PC 15
#define ARM_FP 11 /* Frame Pointer */
#define ARM_IP 12 /* Intra-procedure scratch register */
#define ARM_SP 13 /* Stack pointer: as load/store base reg */
#define ARM_LR 14 /* Link Register */
#define ARM_PC 15 /* Program counter */
#define ARM_COND_EQ 0x0
#define ARM_COND_NE 0x1
#define ARM_COND_CS 0x2
#define ARM_COND_EQ 0x0 /* == */
#define ARM_COND_NE 0x1 /* != */
#define ARM_COND_CS 0x2 /* unsigned >= */
#define ARM_COND_HS ARM_COND_CS
#define ARM_COND_CC 0x3
#define ARM_COND_CC 0x3 /* unsigned < */
#define ARM_COND_LO ARM_COND_CC
#define ARM_COND_MI 0x4
#define ARM_COND_PL 0x5
#define ARM_COND_VS 0x6
#define ARM_COND_VC 0x7
#define ARM_COND_HI 0x8
#define ARM_COND_LS 0x9
#define ARM_COND_GE 0xa
#define ARM_COND_LT 0xb
#define ARM_COND_GT 0xc
#define ARM_COND_LE 0xd
#define ARM_COND_AL 0xe
#define ARM_COND_MI 0x4 /* < 0 */
#define ARM_COND_PL 0x5 /* >= 0 */
#define ARM_COND_VS 0x6 /* Signed Overflow */
#define ARM_COND_VC 0x7 /* No Signed Overflow */
#define ARM_COND_HI 0x8 /* unsigned > */
#define ARM_COND_LS 0x9 /* unsigned <= */
#define ARM_COND_GE 0xa /* Signed >= */
#define ARM_COND_LT 0xb /* Signed < */
#define ARM_COND_GT 0xc /* Signed > */
#define ARM_COND_LE 0xd /* Signed <= */
#define ARM_COND_AL 0xe /* None */
/* register shift types */
#define SRTYPE_LSL 0
#define SRTYPE_LSR 1
#define SRTYPE_ASR 2
#define SRTYPE_ROR 3
#define SRTYPE_ASL (SRTYPE_LSL)
#define ARM_INST_ADD_R 0x00800000
#define ARM_INST_ADDS_R 0x00900000
#define ARM_INST_ADC_R 0x00a00000
#define ARM_INST_ADC_I 0x02a00000
#define ARM_INST_ADD_I 0x02800000
#define ARM_INST_ADDS_I 0x02900000
#define ARM_INST_AND_R 0x00000000
#define ARM_INST_AND_I 0x02000000
@ -76,8 +82,10 @@
#define ARM_INST_LDRH_I 0x01d000b0
#define ARM_INST_LDRH_R 0x019000b0
#define ARM_INST_LDR_I 0x05900000
#define ARM_INST_LDR_R 0x07900000
#define ARM_INST_LDM 0x08900000
#define ARM_INST_LDM_IA 0x08b00000
#define ARM_INST_LSL_I 0x01a00000
#define ARM_INST_LSL_R 0x01a00010
@ -86,6 +94,7 @@
#define ARM_INST_LSR_R 0x01a00030
#define ARM_INST_MOV_R 0x01a00000
#define ARM_INST_MOVS_R 0x01b00000
#define ARM_INST_MOV_I 0x03a00000
#define ARM_INST_MOVW 0x03000000
#define ARM_INST_MOVT 0x03400000
@ -96,17 +105,28 @@
#define ARM_INST_PUSH 0x092d0000
#define ARM_INST_ORR_R 0x01800000
#define ARM_INST_ORRS_R 0x01900000
#define ARM_INST_ORR_I 0x03800000
#define ARM_INST_REV 0x06bf0f30
#define ARM_INST_REV16 0x06bf0fb0
#define ARM_INST_RSB_I 0x02600000
#define ARM_INST_RSBS_I 0x02700000
#define ARM_INST_RSC_I 0x02e00000
#define ARM_INST_SUB_R 0x00400000
#define ARM_INST_SUBS_R 0x00500000
#define ARM_INST_RSB_R 0x00600000
#define ARM_INST_SUB_I 0x02400000
#define ARM_INST_SUBS_I 0x02500000
#define ARM_INST_SBC_I 0x02c00000
#define ARM_INST_SBC_R 0x00c00000
#define ARM_INST_SBCS_R 0x00d00000
#define ARM_INST_STR_I 0x05800000
#define ARM_INST_STRB_I 0x05c00000
#define ARM_INST_STRH_I 0x01c000b0
#define ARM_INST_TST_R 0x01100000
#define ARM_INST_TST_I 0x03100000
@ -117,6 +137,8 @@
#define ARM_INST_MLS 0x00600090
#define ARM_INST_UXTH 0x06ff0070
/*
* Use a suitable undefined instruction to use for ARM/Thumb2 faulting.
* We need to be careful not to conflict with those used by other modules
@ -135,9 +157,15 @@
#define _AL3_R(op, rd, rn, rm) ((op ## _R) | (rd) << 12 | (rn) << 16 | (rm))
/* immediate */
#define _AL3_I(op, rd, rn, imm) ((op ## _I) | (rd) << 12 | (rn) << 16 | (imm))
/* register with register-shift */
#define _AL3_SR(inst) (inst | (1 << 4))
#define ARM_ADD_R(rd, rn, rm) _AL3_R(ARM_INST_ADD, rd, rn, rm)
#define ARM_ADDS_R(rd, rn, rm) _AL3_R(ARM_INST_ADDS, rd, rn, rm)
#define ARM_ADD_I(rd, rn, imm) _AL3_I(ARM_INST_ADD, rd, rn, imm)
#define ARM_ADDS_I(rd, rn, imm) _AL3_I(ARM_INST_ADDS, rd, rn, imm)
#define ARM_ADC_R(rd, rn, rm) _AL3_R(ARM_INST_ADC, rd, rn, rm)
#define ARM_ADC_I(rd, rn, imm) _AL3_I(ARM_INST_ADC, rd, rn, imm)
#define ARM_AND_R(rd, rn, rm) _AL3_R(ARM_INST_AND, rd, rn, rm)
#define ARM_AND_I(rd, rn, imm) _AL3_I(ARM_INST_AND, rd, rn, imm)
@ -156,7 +184,9 @@
#define ARM_EOR_I(rd, rn, imm) _AL3_I(ARM_INST_EOR, rd, rn, imm)
#define ARM_LDR_I(rt, rn, off) (ARM_INST_LDR_I | (rt) << 12 | (rn) << 16 \
| (off))
| ((off) & 0xfff))
#define ARM_LDR_R(rt, rn, rm) (ARM_INST_LDR_R | (rt) << 12 | (rn) << 16 \
| (rm))
#define ARM_LDRB_I(rt, rn, off) (ARM_INST_LDRB_I | (rt) << 12 | (rn) << 16 \
| (off))
#define ARM_LDRB_R(rt, rn, rm) (ARM_INST_LDRB_R | (rt) << 12 | (rn) << 16 \
@ -167,15 +197,23 @@
| (rm))
#define ARM_LDM(rn, regs) (ARM_INST_LDM | (rn) << 16 | (regs))
#define ARM_LDM_IA(rn, regs) (ARM_INST_LDM_IA | (rn) << 16 | (regs))
#define ARM_LSL_R(rd, rn, rm) (_AL3_R(ARM_INST_LSL, rd, 0, rn) | (rm) << 8)
#define ARM_LSL_I(rd, rn, imm) (_AL3_I(ARM_INST_LSL, rd, 0, rn) | (imm) << 7)
#define ARM_LSR_R(rd, rn, rm) (_AL3_R(ARM_INST_LSR, rd, 0, rn) | (rm) << 8)
#define ARM_LSR_I(rd, rn, imm) (_AL3_I(ARM_INST_LSR, rd, 0, rn) | (imm) << 7)
#define ARM_ASR_R(rd, rn, rm) (_AL3_R(ARM_INST_ASR, rd, 0, rn) | (rm) << 8)
#define ARM_ASR_I(rd, rn, imm) (_AL3_I(ARM_INST_ASR, rd, 0, rn) | (imm) << 7)
#define ARM_MOV_R(rd, rm) _AL3_R(ARM_INST_MOV, rd, 0, rm)
#define ARM_MOVS_R(rd, rm) _AL3_R(ARM_INST_MOVS, rd, 0, rm)
#define ARM_MOV_I(rd, imm) _AL3_I(ARM_INST_MOV, rd, 0, imm)
#define ARM_MOV_SR(rd, rm, type, rs) \
(_AL3_SR(ARM_MOV_R(rd, rm)) | (type) << 5 | (rs) << 8)
#define ARM_MOV_SI(rd, rm, type, imm6) \
(ARM_MOV_R(rd, rm) | (type) << 5 | (imm6) << 7)
#define ARM_MOVW(rd, imm) \
(ARM_INST_MOVW | ((imm) >> 12) << 16 | (rd) << 12 | ((imm) & 0x0fff))
@ -190,19 +228,38 @@
#define ARM_ORR_R(rd, rn, rm) _AL3_R(ARM_INST_ORR, rd, rn, rm)
#define ARM_ORR_I(rd, rn, imm) _AL3_I(ARM_INST_ORR, rd, rn, imm)
#define ARM_ORR_S(rd, rn, rm, type, rs) \
(ARM_ORR_R(rd, rn, rm) | (type) << 5 | (rs) << 7)
#define ARM_ORR_SR(rd, rn, rm, type, rs) \
(_AL3_SR(ARM_ORR_R(rd, rn, rm)) | (type) << 5 | (rs) << 8)
#define ARM_ORRS_R(rd, rn, rm) _AL3_R(ARM_INST_ORRS, rd, rn, rm)
#define ARM_ORRS_SR(rd, rn, rm, type, rs) \
(_AL3_SR(ARM_ORRS_R(rd, rn, rm)) | (type) << 5 | (rs) << 8)
#define ARM_ORR_SI(rd, rn, rm, type, imm6) \
(ARM_ORR_R(rd, rn, rm) | (type) << 5 | (imm6) << 7)
#define ARM_ORRS_SI(rd, rn, rm, type, imm6) \
(ARM_ORRS_R(rd, rn, rm) | (type) << 5 | (imm6) << 7)
#define ARM_REV(rd, rm) (ARM_INST_REV | (rd) << 12 | (rm))
#define ARM_REV16(rd, rm) (ARM_INST_REV16 | (rd) << 12 | (rm))
#define ARM_RSB_I(rd, rn, imm) _AL3_I(ARM_INST_RSB, rd, rn, imm)
#define ARM_RSBS_I(rd, rn, imm) _AL3_I(ARM_INST_RSBS, rd, rn, imm)
#define ARM_RSC_I(rd, rn, imm) _AL3_I(ARM_INST_RSC, rd, rn, imm)
#define ARM_SUB_R(rd, rn, rm) _AL3_R(ARM_INST_SUB, rd, rn, rm)
#define ARM_SUBS_R(rd, rn, rm) _AL3_R(ARM_INST_SUBS, rd, rn, rm)
#define ARM_RSB_R(rd, rn, rm) _AL3_R(ARM_INST_RSB, rd, rn, rm)
#define ARM_SBC_R(rd, rn, rm) _AL3_R(ARM_INST_SBC, rd, rn, rm)
#define ARM_SBCS_R(rd, rn, rm) _AL3_R(ARM_INST_SBCS, rd, rn, rm)
#define ARM_SUB_I(rd, rn, imm) _AL3_I(ARM_INST_SUB, rd, rn, imm)
#define ARM_SUBS_I(rd, rn, imm) _AL3_I(ARM_INST_SUBS, rd, rn, imm)
#define ARM_SBC_I(rd, rn, imm) _AL3_I(ARM_INST_SBC, rd, rn, imm)
#define ARM_STR_I(rt, rn, off) (ARM_INST_STR_I | (rt) << 12 | (rn) << 16 \
| (off))
| ((off) & 0xfff))
#define ARM_STRH_I(rt, rn, off) (ARM_INST_STRH_I | (rt) << 12 | (rn) << 16 \
| (((off) & 0xf0) << 4) | ((off) & 0xf))
#define ARM_STRB_I(rt, rn, off) (ARM_INST_STRB_I | (rt) << 12 | (rn) << 16 \
| (((off) & 0xf0) << 4) | ((off) & 0xf))
#define ARM_TST_R(rn, rm) _AL3_R(ARM_INST_TST, 0, rn, rm)
#define ARM_TST_I(rn, imm) _AL3_I(ARM_INST_TST, 0, rn, imm)
@ -214,5 +271,6 @@
#define ARM_MLS(rd, rn, rm, ra) (ARM_INST_MLS | (rd) << 16 | (rn) | (rm) << 8 \
| (ra) << 12)
#define ARM_UXTH(rd, rm) (ARM_INST_UXTH | (rd) << 12 | (rm))
#endif /* PFILTER_OPCODES_ARM_H */

View File

@ -50,6 +50,23 @@
chosen {
stdout-path = "serial2:1500000n8";
};
vcc_phy: vcc-phy-regulator {
compatible = "regulator-fixed";
regulator-name = "vcc_phy";
regulator-always-on;
regulator-boot-on;
};
};
&gmac2phy {
phy-supply = <&vcc_phy>;
clock_in_out = "output";
assigned-clocks = <&cru SCLK_MAC2PHY_SRC>;
assigned-clock-rate = <50000000>;
assigned-clocks = <&cru SCLK_MAC2PHY>;
assigned-clock-parents = <&cru SCLK_MAC2PHY_SRC>;
status = "okay";
};
&uart2 {

View File

@ -63,6 +63,8 @@
i2c1 = &i2c1;
i2c2 = &i2c2;
i2c3 = &i2c3;
ethernet0 = &gmac2io;
ethernet1 = &gmac2phy;
};
cpus {
@ -424,6 +426,43 @@
status = "disabled";
};
gmac2phy: ethernet@ff550000 {
compatible = "rockchip,rk3328-gmac";
reg = <0x0 0xff550000 0x0 0x10000>;
rockchip,grf = <&grf>;
interrupts = <GIC_SPI 21 IRQ_TYPE_LEVEL_HIGH>;
interrupt-names = "macirq";
clocks = <&cru SCLK_MAC2PHY_SRC>, <&cru SCLK_MAC2PHY_RXTX>,
<&cru SCLK_MAC2PHY_RXTX>, <&cru SCLK_MAC2PHY_REF>,
<&cru ACLK_MAC2PHY>, <&cru PCLK_MAC2PHY>,
<&cru SCLK_MAC2PHY_OUT>;
clock-names = "stmmaceth", "mac_clk_rx",
"mac_clk_tx", "clk_mac_ref",
"aclk_mac", "pclk_mac",
"clk_macphy";
resets = <&cru SRST_GMAC2PHY_A>, <&cru SRST_MACPHY>;
reset-names = "stmmaceth", "mac-phy";
phy-mode = "rmii";
phy-handle = <&phy>;
status = "disabled";
mdio {
compatible = "snps,dwmac-mdio";
#address-cells = <1>;
#size-cells = <0>;
phy: phy@0 {
compatible = "ethernet-phy-id1234.d400", "ethernet-phy-ieee802.3-c22";
reg = <0>;
clocks = <&cru SCLK_MAC2PHY_OUT>;
resets = <&cru SRST_MACPHY>;
pinctrl-names = "default";
pinctrl-0 = <&fephyled_rxm1 &fephyled_linkm1>;
phy-is-integrated;
};
};
};
gic: interrupt-controller@ff811000 {
compatible = "arm,gic-400";
#interrupt-cells = <3>;

View File

@ -203,6 +203,7 @@ CONFIG_MARVELL_PHY=m
CONFIG_MESON_GXL_PHY=m
CONFIG_MICREL_PHY=y
CONFIG_REALTEK_PHY=m
CONFIG_ROCKCHIP_PHY=y
CONFIG_USB_PEGASUS=m
CONFIG_USB_RTL8150=m
CONFIG_USB_RTL8152=m

View File

@ -44,8 +44,12 @@
#define A64_COND_NE AARCH64_INSN_COND_NE /* != */
#define A64_COND_CS AARCH64_INSN_COND_CS /* unsigned >= */
#define A64_COND_HI AARCH64_INSN_COND_HI /* unsigned > */
#define A64_COND_LS AARCH64_INSN_COND_LS /* unsigned <= */
#define A64_COND_CC AARCH64_INSN_COND_CC /* unsigned < */
#define A64_COND_GE AARCH64_INSN_COND_GE /* signed >= */
#define A64_COND_GT AARCH64_INSN_COND_GT /* signed > */
#define A64_COND_LE AARCH64_INSN_COND_LE /* signed <= */
#define A64_COND_LT AARCH64_INSN_COND_LT /* signed < */
#define A64_B_(cond, imm19) A64_COND_BRANCH(cond, (imm19) << 2)
/* Unconditional branch (immediate) */

View File

@ -527,10 +527,14 @@ emit_bswap_uxt:
/* IF (dst COND src) JUMP off */
case BPF_JMP | BPF_JEQ | BPF_X:
case BPF_JMP | BPF_JGT | BPF_X:
case BPF_JMP | BPF_JLT | BPF_X:
case BPF_JMP | BPF_JGE | BPF_X:
case BPF_JMP | BPF_JLE | BPF_X:
case BPF_JMP | BPF_JNE | BPF_X:
case BPF_JMP | BPF_JSGT | BPF_X:
case BPF_JMP | BPF_JSLT | BPF_X:
case BPF_JMP | BPF_JSGE | BPF_X:
case BPF_JMP | BPF_JSLE | BPF_X:
emit(A64_CMP(1, dst, src), ctx);
emit_cond_jmp:
jmp_offset = bpf2a64_offset(i + off, i, ctx);
@ -542,9 +546,15 @@ emit_cond_jmp:
case BPF_JGT:
jmp_cond = A64_COND_HI;
break;
case BPF_JLT:
jmp_cond = A64_COND_CC;
break;
case BPF_JGE:
jmp_cond = A64_COND_CS;
break;
case BPF_JLE:
jmp_cond = A64_COND_LS;
break;
case BPF_JSET:
case BPF_JNE:
jmp_cond = A64_COND_NE;
@ -552,9 +562,15 @@ emit_cond_jmp:
case BPF_JSGT:
jmp_cond = A64_COND_GT;
break;
case BPF_JSLT:
jmp_cond = A64_COND_LT;
break;
case BPF_JSGE:
jmp_cond = A64_COND_GE;
break;
case BPF_JSLE:
jmp_cond = A64_COND_LE;
break;
default:
return -EFAULT;
}
@ -566,10 +582,14 @@ emit_cond_jmp:
/* IF (dst COND imm) JUMP off */
case BPF_JMP | BPF_JEQ | BPF_K:
case BPF_JMP | BPF_JGT | BPF_K:
case BPF_JMP | BPF_JLT | BPF_K:
case BPF_JMP | BPF_JGE | BPF_K:
case BPF_JMP | BPF_JLE | BPF_K:
case BPF_JMP | BPF_JNE | BPF_K:
case BPF_JMP | BPF_JSGT | BPF_K:
case BPF_JMP | BPF_JSLT | BPF_K:
case BPF_JMP | BPF_JSGE | BPF_K:
case BPF_JMP | BPF_JSLE | BPF_K:
emit_a64_mov_i(1, tmp, imm, ctx);
emit(A64_CMP(1, dst, tmp), ctx);
goto emit_cond_jmp;

View File

@ -102,5 +102,7 @@
#define SO_PEERGROUPS 59
#define SO_ZEROCOPY 60
#endif /* _ASM_SOCKET_H */

View File

@ -111,4 +111,6 @@
#define SO_PEERGROUPS 59
#define SO_ZEROCOPY 60
#endif /* _ASM_IA64_SOCKET_H */

View File

@ -102,4 +102,6 @@
#define SO_PEERGROUPS 59
#define SO_ZEROCOPY 60
#endif /* _ASM_M32R_SOCKET_H */

View File

@ -120,4 +120,6 @@
#define SO_PEERGROUPS 59
#define SO_ZEROCOPY 60
#endif /* _UAPI_ASM_SOCKET_H */

View File

@ -113,6 +113,7 @@ struct jit_ctx {
u64 *reg_val_types;
unsigned int long_b_conversion:1;
unsigned int gen_b_offsets:1;
unsigned int use_bbit_insns:1;
};
static void set_reg_val_type(u64 *rvt, int reg, enum reg_val_type type)
@ -655,19 +656,6 @@ static int emit_bpf_tail_call(struct jit_ctx *ctx, int this_idx)
return build_int_epilogue(ctx, MIPS_R_T9);
}
static bool use_bbit_insns(void)
{
switch (current_cpu_type()) {
case CPU_CAVIUM_OCTEON:
case CPU_CAVIUM_OCTEON_PLUS:
case CPU_CAVIUM_OCTEON2:
case CPU_CAVIUM_OCTEON3:
return true;
default:
return false;
}
}
static bool is_bad_offset(int b_off)
{
return b_off > 0x1ffff || b_off < -0x20000;
@ -682,6 +670,7 @@ static int build_one_insn(const struct bpf_insn *insn, struct jit_ctx *ctx,
unsigned int target;
u64 t64;
s64 t64s;
int bpf_op = BPF_OP(insn->code);
switch (insn->code) {
case BPF_ALU64 | BPF_ADD | BPF_K: /* ALU64_IMM */
@ -770,13 +759,13 @@ static int build_one_insn(const struct bpf_insn *insn, struct jit_ctx *ctx,
emit_instr(ctx, sll, dst, dst, 0);
if (insn->imm == 1) {
/* div by 1 is a nop, mod by 1 is zero */
if (BPF_OP(insn->code) == BPF_MOD)
if (bpf_op == BPF_MOD)
emit_instr(ctx, addu, dst, MIPS_R_ZERO, MIPS_R_ZERO);
break;
}
gen_imm_to_reg(insn, MIPS_R_AT, ctx);
emit_instr(ctx, divu, dst, MIPS_R_AT);
if (BPF_OP(insn->code) == BPF_DIV)
if (bpf_op == BPF_DIV)
emit_instr(ctx, mflo, dst);
else
emit_instr(ctx, mfhi, dst);
@ -798,13 +787,13 @@ static int build_one_insn(const struct bpf_insn *insn, struct jit_ctx *ctx,
if (insn->imm == 1) {
/* div by 1 is a nop, mod by 1 is zero */
if (BPF_OP(insn->code) == BPF_MOD)
if (bpf_op == BPF_MOD)
emit_instr(ctx, addu, dst, MIPS_R_ZERO, MIPS_R_ZERO);
break;
}
gen_imm_to_reg(insn, MIPS_R_AT, ctx);
emit_instr(ctx, ddivu, dst, MIPS_R_AT);
if (BPF_OP(insn->code) == BPF_DIV)
if (bpf_op == BPF_DIV)
emit_instr(ctx, mflo, dst);
else
emit_instr(ctx, mfhi, dst);
@ -829,7 +818,7 @@ static int build_one_insn(const struct bpf_insn *insn, struct jit_ctx *ctx,
emit_instr(ctx, dinsu, dst, MIPS_R_ZERO, 32, 32);
did_move = false;
if (insn->src_reg == BPF_REG_10) {
if (BPF_OP(insn->code) == BPF_MOV) {
if (bpf_op == BPF_MOV) {
emit_instr(ctx, daddiu, dst, MIPS_R_SP, MAX_BPF_STACK);
did_move = true;
} else {
@ -839,7 +828,7 @@ static int build_one_insn(const struct bpf_insn *insn, struct jit_ctx *ctx,
} else if (get_reg_val_type(ctx, this_idx, insn->src_reg) == REG_32BIT) {
int tmp_reg = MIPS_R_AT;
if (BPF_OP(insn->code) == BPF_MOV) {
if (bpf_op == BPF_MOV) {
tmp_reg = dst;
did_move = true;
}
@ -847,7 +836,7 @@ static int build_one_insn(const struct bpf_insn *insn, struct jit_ctx *ctx,
emit_instr(ctx, dinsu, tmp_reg, MIPS_R_ZERO, 32, 32);
src = MIPS_R_AT;
}
switch (BPF_OP(insn->code)) {
switch (bpf_op) {
case BPF_MOV:
if (!did_move)
emit_instr(ctx, daddu, dst, src, MIPS_R_ZERO);
@ -879,7 +868,7 @@ static int build_one_insn(const struct bpf_insn *insn, struct jit_ctx *ctx,
emit_instr(ctx, beq, src, MIPS_R_ZERO, b_off);
emit_instr(ctx, movz, MIPS_R_V0, MIPS_R_ZERO, src);
emit_instr(ctx, ddivu, dst, src);
if (BPF_OP(insn->code) == BPF_DIV)
if (bpf_op == BPF_DIV)
emit_instr(ctx, mflo, dst);
else
emit_instr(ctx, mfhi, dst);
@ -923,7 +912,7 @@ static int build_one_insn(const struct bpf_insn *insn, struct jit_ctx *ctx,
if (ts == REG_64BIT || ts == REG_32BIT_ZERO_EX) {
int tmp_reg = MIPS_R_AT;
if (BPF_OP(insn->code) == BPF_MOV) {
if (bpf_op == BPF_MOV) {
tmp_reg = dst;
did_move = true;
}
@ -931,7 +920,7 @@ static int build_one_insn(const struct bpf_insn *insn, struct jit_ctx *ctx,
emit_instr(ctx, sll, tmp_reg, src, 0);
src = MIPS_R_AT;
}
switch (BPF_OP(insn->code)) {
switch (bpf_op) {
case BPF_MOV:
if (!did_move)
emit_instr(ctx, addu, dst, src, MIPS_R_ZERO);
@ -962,7 +951,7 @@ static int build_one_insn(const struct bpf_insn *insn, struct jit_ctx *ctx,
emit_instr(ctx, beq, src, MIPS_R_ZERO, b_off);
emit_instr(ctx, movz, MIPS_R_V0, MIPS_R_ZERO, src);
emit_instr(ctx, divu, dst, src);
if (BPF_OP(insn->code) == BPF_DIV)
if (bpf_op == BPF_DIV)
emit_instr(ctx, mflo, dst);
else
emit_instr(ctx, mfhi, dst);
@ -989,7 +978,7 @@ static int build_one_insn(const struct bpf_insn *insn, struct jit_ctx *ctx,
break;
case BPF_JMP | BPF_JEQ | BPF_K: /* JMP_IMM */
case BPF_JMP | BPF_JNE | BPF_K: /* JMP_IMM */
cmp_eq = (BPF_OP(insn->code) == BPF_JEQ);
cmp_eq = (bpf_op == BPF_JEQ);
dst = ebpf_to_mips_reg(ctx, insn, dst_reg_fp_ok);
if (dst < 0)
return dst;
@ -1002,8 +991,12 @@ static int build_one_insn(const struct bpf_insn *insn, struct jit_ctx *ctx,
goto jeq_common;
case BPF_JMP | BPF_JEQ | BPF_X: /* JMP_REG */
case BPF_JMP | BPF_JNE | BPF_X:
case BPF_JMP | BPF_JSLT | BPF_X:
case BPF_JMP | BPF_JSLE | BPF_X:
case BPF_JMP | BPF_JSGT | BPF_X:
case BPF_JMP | BPF_JSGE | BPF_X:
case BPF_JMP | BPF_JLT | BPF_X:
case BPF_JMP | BPF_JLE | BPF_X:
case BPF_JMP | BPF_JGT | BPF_X:
case BPF_JMP | BPF_JGE | BPF_X:
case BPF_JMP | BPF_JSET | BPF_X:
@ -1020,33 +1013,39 @@ static int build_one_insn(const struct bpf_insn *insn, struct jit_ctx *ctx,
emit_instr(ctx, sll, MIPS_R_AT, dst, 0);
dst = MIPS_R_AT;
}
if (BPF_OP(insn->code) == BPF_JSET) {
if (bpf_op == BPF_JSET) {
emit_instr(ctx, and, MIPS_R_AT, dst, src);
cmp_eq = false;
dst = MIPS_R_AT;
src = MIPS_R_ZERO;
} else if (BPF_OP(insn->code) == BPF_JSGT) {
} else if (bpf_op == BPF_JSGT || bpf_op == BPF_JSLE) {
emit_instr(ctx, dsubu, MIPS_R_AT, dst, src);
if ((insn + 1)->code == (BPF_JMP | BPF_EXIT) && insn->off == 1) {
b_off = b_imm(exit_idx, ctx);
if (is_bad_offset(b_off))
return -E2BIG;
emit_instr(ctx, blez, MIPS_R_AT, b_off);
if (bpf_op == BPF_JSGT)
emit_instr(ctx, blez, MIPS_R_AT, b_off);
else
emit_instr(ctx, bgtz, MIPS_R_AT, b_off);
emit_instr(ctx, nop);
return 2; /* We consumed the exit. */
}
b_off = b_imm(this_idx + insn->off + 1, ctx);
if (is_bad_offset(b_off))
return -E2BIG;
emit_instr(ctx, bgtz, MIPS_R_AT, b_off);
if (bpf_op == BPF_JSGT)
emit_instr(ctx, bgtz, MIPS_R_AT, b_off);
else
emit_instr(ctx, blez, MIPS_R_AT, b_off);
emit_instr(ctx, nop);
break;
} else if (BPF_OP(insn->code) == BPF_JSGE) {
} else if (bpf_op == BPF_JSGE || bpf_op == BPF_JSLT) {
emit_instr(ctx, slt, MIPS_R_AT, dst, src);
cmp_eq = true;
cmp_eq = bpf_op == BPF_JSGE;
dst = MIPS_R_AT;
src = MIPS_R_ZERO;
} else if (BPF_OP(insn->code) == BPF_JGT) {
} else if (bpf_op == BPF_JGT || bpf_op == BPF_JLE) {
/* dst or src could be AT */
emit_instr(ctx, dsubu, MIPS_R_T8, dst, src);
emit_instr(ctx, sltu, MIPS_R_AT, dst, src);
@ -1054,16 +1053,16 @@ static int build_one_insn(const struct bpf_insn *insn, struct jit_ctx *ctx,
emit_instr(ctx, movz, MIPS_R_T9, MIPS_R_SP, MIPS_R_T8);
emit_instr(ctx, movn, MIPS_R_T9, MIPS_R_ZERO, MIPS_R_T8);
emit_instr(ctx, or, MIPS_R_AT, MIPS_R_T9, MIPS_R_AT);
cmp_eq = true;
cmp_eq = bpf_op == BPF_JGT;
dst = MIPS_R_AT;
src = MIPS_R_ZERO;
} else if (BPF_OP(insn->code) == BPF_JGE) {
} else if (bpf_op == BPF_JGE || bpf_op == BPF_JLT) {
emit_instr(ctx, sltu, MIPS_R_AT, dst, src);
cmp_eq = true;
cmp_eq = bpf_op == BPF_JGE;
dst = MIPS_R_AT;
src = MIPS_R_ZERO;
} else { /* JNE/JEQ case */
cmp_eq = (BPF_OP(insn->code) == BPF_JEQ);
cmp_eq = (bpf_op == BPF_JEQ);
}
jeq_common:
/*
@ -1122,7 +1121,9 @@ jeq_common:
break;
case BPF_JMP | BPF_JSGT | BPF_K: /* JMP_IMM */
case BPF_JMP | BPF_JSGE | BPF_K: /* JMP_IMM */
cmp_eq = (BPF_OP(insn->code) == BPF_JSGE);
case BPF_JMP | BPF_JSLT | BPF_K: /* JMP_IMM */
case BPF_JMP | BPF_JSLE | BPF_K: /* JMP_IMM */
cmp_eq = (bpf_op == BPF_JSGE);
dst = ebpf_to_mips_reg(ctx, insn, dst_reg_fp_ok);
if (dst < 0)
return dst;
@ -1132,65 +1133,92 @@ jeq_common:
b_off = b_imm(exit_idx, ctx);
if (is_bad_offset(b_off))
return -E2BIG;
if (cmp_eq)
emit_instr(ctx, bltz, dst, b_off);
else
switch (bpf_op) {
case BPF_JSGT:
emit_instr(ctx, blez, dst, b_off);
break;
case BPF_JSGE:
emit_instr(ctx, bltz, dst, b_off);
break;
case BPF_JSLT:
emit_instr(ctx, bgez, dst, b_off);
break;
case BPF_JSLE:
emit_instr(ctx, bgtz, dst, b_off);
break;
}
emit_instr(ctx, nop);
return 2; /* We consumed the exit. */
}
b_off = b_imm(this_idx + insn->off + 1, ctx);
if (is_bad_offset(b_off))
return -E2BIG;
if (cmp_eq)
emit_instr(ctx, bgez, dst, b_off);
else
switch (bpf_op) {
case BPF_JSGT:
emit_instr(ctx, bgtz, dst, b_off);
break;
case BPF_JSGE:
emit_instr(ctx, bgez, dst, b_off);
break;
case BPF_JSLT:
emit_instr(ctx, bltz, dst, b_off);
break;
case BPF_JSLE:
emit_instr(ctx, blez, dst, b_off);
break;
}
emit_instr(ctx, nop);
break;
}
/*
* only "LT" compare available, so we must use imm + 1
* to generate "GT"
* to generate "GT" and imm -1 to generate LE
*/
t64s = insn->imm + (cmp_eq ? 0 : 1);
if (bpf_op == BPF_JSGT)
t64s = insn->imm + 1;
else if (bpf_op == BPF_JSLE)
t64s = insn->imm + 1;
else
t64s = insn->imm;
cmp_eq = bpf_op == BPF_JSGT || bpf_op == BPF_JSGE;
if (t64s >= S16_MIN && t64s <= S16_MAX) {
emit_instr(ctx, slti, MIPS_R_AT, dst, (int)t64s);
src = MIPS_R_AT;
dst = MIPS_R_ZERO;
cmp_eq = true;
goto jeq_common;
}
emit_const_to_reg(ctx, MIPS_R_AT, (u64)t64s);
emit_instr(ctx, slt, MIPS_R_AT, dst, MIPS_R_AT);
src = MIPS_R_AT;
dst = MIPS_R_ZERO;
cmp_eq = true;
goto jeq_common;
case BPF_JMP | BPF_JGT | BPF_K:
case BPF_JMP | BPF_JGE | BPF_K:
cmp_eq = (BPF_OP(insn->code) == BPF_JGE);
case BPF_JMP | BPF_JLT | BPF_K:
case BPF_JMP | BPF_JLE | BPF_K:
cmp_eq = (bpf_op == BPF_JGE);
dst = ebpf_to_mips_reg(ctx, insn, dst_reg_fp_ok);
if (dst < 0)
return dst;
/*
* only "LT" compare available, so we must use imm + 1
* to generate "GT"
* to generate "GT" and imm -1 to generate LE
*/
t64s = (u64)(u32)(insn->imm) + (cmp_eq ? 0 : 1);
if (t64s >= 0 && t64s <= S16_MAX) {
emit_instr(ctx, sltiu, MIPS_R_AT, dst, (int)t64s);
src = MIPS_R_AT;
dst = MIPS_R_ZERO;
cmp_eq = true;
goto jeq_common;
}
if (bpf_op == BPF_JGT)
t64s = (u64)(u32)(insn->imm) + 1;
else if (bpf_op == BPF_JLE)
t64s = (u64)(u32)(insn->imm) + 1;
else
t64s = (u64)(u32)(insn->imm);
cmp_eq = bpf_op == BPF_JGT || bpf_op == BPF_JGE;
emit_const_to_reg(ctx, MIPS_R_AT, (u64)t64s);
emit_instr(ctx, sltu, MIPS_R_AT, dst, MIPS_R_AT);
src = MIPS_R_AT;
dst = MIPS_R_ZERO;
cmp_eq = true;
goto jeq_common;
case BPF_JMP | BPF_JSET | BPF_K: /* JMP_IMM */
@ -1198,7 +1226,7 @@ jeq_common:
if (dst < 0)
return dst;
if (use_bbit_insns() && hweight32((u32)insn->imm) == 1) {
if (ctx->use_bbit_insns && hweight32((u32)insn->imm) == 1) {
if ((insn + 1)->code == (BPF_JMP | BPF_EXIT) && insn->off == 1) {
b_off = b_imm(exit_idx, ctx);
if (is_bad_offset(b_off))
@ -1724,10 +1752,14 @@ static int reg_val_propagate_range(struct jit_ctx *ctx, u64 initial_rvt,
case BPF_JEQ:
case BPF_JGT:
case BPF_JGE:
case BPF_JLT:
case BPF_JLE:
case BPF_JSET:
case BPF_JNE:
case BPF_JSGT:
case BPF_JSGE:
case BPF_JSLT:
case BPF_JSLE:
if (follow_taken) {
rvt[idx] |= RVT_BRANCH_TAKEN;
idx += insn->off;
@ -1853,6 +1885,19 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *prog)
memset(&ctx, 0, sizeof(ctx));
preempt_disable();
switch (current_cpu_type()) {
case CPU_CAVIUM_OCTEON:
case CPU_CAVIUM_OCTEON_PLUS:
case CPU_CAVIUM_OCTEON2:
case CPU_CAVIUM_OCTEON3:
ctx.use_bbit_insns = 1;
break;
default:
ctx.use_bbit_insns = 0;
}
preempt_enable();
ctx.offsets = kcalloc(prog->len + 1, sizeof(*ctx.offsets), GFP_KERNEL);
if (ctx.offsets == NULL)
goto out_err;

View File

@ -102,4 +102,6 @@
#define SO_PEERGROUPS 59
#define SO_ZEROCOPY 60
#endif /* _ASM_SOCKET_H */

View File

@ -31,7 +31,6 @@ CONFIG_IP_PNP_BOOTP=y
CONFIG_INET6_IPCOMP=m
CONFIG_IPV6_TUNNEL=m
CONFIG_NETFILTER=y
CONFIG_NETFILTER_DEBUG=y
CONFIG_NET_PKTGEN=m
CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
CONFIG_DEVTMPFS=y

View File

@ -101,4 +101,6 @@
#define SO_PEERGROUPS 0x4034
#define SO_ZEROCOPY 0x4035
#endif /* _UAPI_ASM_SOCKET_H */

View File

@ -263,6 +263,7 @@ static inline bool is_nearbranch(int offset)
#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 COND_LE (CR0_GT | COND_CMP_FALSE)
#endif

View File

@ -795,12 +795,24 @@ emit_clear:
case BPF_JMP | BPF_JSGT | BPF_X:
true_cond = COND_GT;
goto cond_branch;
case BPF_JMP | BPF_JLT | BPF_K:
case BPF_JMP | BPF_JLT | BPF_X:
case BPF_JMP | BPF_JSLT | BPF_K:
case BPF_JMP | BPF_JSLT | BPF_X:
true_cond = COND_LT;
goto cond_branch;
case BPF_JMP | BPF_JGE | BPF_K:
case BPF_JMP | BPF_JGE | BPF_X:
case BPF_JMP | BPF_JSGE | BPF_K:
case BPF_JMP | BPF_JSGE | BPF_X:
true_cond = COND_GE;
goto cond_branch;
case BPF_JMP | BPF_JLE | BPF_K:
case BPF_JMP | BPF_JLE | BPF_X:
case BPF_JMP | BPF_JSLE | BPF_K:
case BPF_JMP | BPF_JSLE | BPF_X:
true_cond = COND_LE;
goto cond_branch;
case BPF_JMP | BPF_JEQ | BPF_K:
case BPF_JMP | BPF_JEQ | BPF_X:
true_cond = COND_EQ;
@ -817,14 +829,18 @@ emit_clear:
cond_branch:
switch (code) {
case BPF_JMP | BPF_JGT | BPF_X:
case BPF_JMP | BPF_JLT | BPF_X:
case BPF_JMP | BPF_JGE | BPF_X:
case BPF_JMP | BPF_JLE | BPF_X:
case BPF_JMP | BPF_JEQ | BPF_X:
case BPF_JMP | BPF_JNE | BPF_X:
/* unsigned comparison */
PPC_CMPLD(dst_reg, src_reg);
break;
case BPF_JMP | BPF_JSGT | BPF_X:
case BPF_JMP | BPF_JSLT | BPF_X:
case BPF_JMP | BPF_JSGE | BPF_X:
case BPF_JMP | BPF_JSLE | BPF_X:
/* signed comparison */
PPC_CMPD(dst_reg, src_reg);
break;
@ -834,7 +850,9 @@ cond_branch:
case BPF_JMP | BPF_JNE | BPF_K:
case BPF_JMP | BPF_JEQ | BPF_K:
case BPF_JMP | BPF_JGT | BPF_K:
case BPF_JMP | BPF_JLT | BPF_K:
case BPF_JMP | BPF_JGE | BPF_K:
case BPF_JMP | BPF_JLE | BPF_K:
/*
* Need sign-extended load, so only positive
* values can be used as imm in cmpldi
@ -849,7 +867,9 @@ cond_branch:
}
break;
case BPF_JMP | BPF_JSGT | BPF_K:
case BPF_JMP | BPF_JSLT | BPF_K:
case BPF_JMP | BPF_JSGE | BPF_K:
case BPF_JMP | BPF_JSLE | BPF_K:
/*
* signed comparison, so any 16-bit value
* can be used in cmpdi

View File

@ -108,4 +108,6 @@
#define SO_PEERGROUPS 59
#define SO_ZEROCOPY 60
#endif /* _ASM_SOCKET_H */

View File

@ -1093,15 +1093,27 @@ static noinline int bpf_jit_insn(struct bpf_jit *jit, struct bpf_prog *fp, int i
case BPF_JMP | BPF_JSGT | BPF_K: /* ((s64) dst > (s64) imm) */
mask = 0x2000; /* jh */
goto branch_ks;
case BPF_JMP | BPF_JSLT | BPF_K: /* ((s64) dst < (s64) imm) */
mask = 0x4000; /* jl */
goto branch_ks;
case BPF_JMP | BPF_JSGE | BPF_K: /* ((s64) dst >= (s64) imm) */
mask = 0xa000; /* jhe */
goto branch_ks;
case BPF_JMP | BPF_JSLE | BPF_K: /* ((s64) dst <= (s64) imm) */
mask = 0xc000; /* jle */
goto branch_ks;
case BPF_JMP | BPF_JGT | BPF_K: /* (dst_reg > imm) */
mask = 0x2000; /* jh */
goto branch_ku;
case BPF_JMP | BPF_JLT | BPF_K: /* (dst_reg < imm) */
mask = 0x4000; /* jl */
goto branch_ku;
case BPF_JMP | BPF_JGE | BPF_K: /* (dst_reg >= imm) */
mask = 0xa000; /* jhe */
goto branch_ku;
case BPF_JMP | BPF_JLE | BPF_K: /* (dst_reg <= imm) */
mask = 0xc000; /* jle */
goto branch_ku;
case BPF_JMP | BPF_JNE | BPF_K: /* (dst_reg != imm) */
mask = 0x7000; /* jne */
goto branch_ku;
@ -1119,15 +1131,27 @@ static noinline int bpf_jit_insn(struct bpf_jit *jit, struct bpf_prog *fp, int i
case BPF_JMP | BPF_JSGT | BPF_X: /* ((s64) dst > (s64) src) */
mask = 0x2000; /* jh */
goto branch_xs;
case BPF_JMP | BPF_JSLT | BPF_X: /* ((s64) dst < (s64) src) */
mask = 0x4000; /* jl */
goto branch_xs;
case BPF_JMP | BPF_JSGE | BPF_X: /* ((s64) dst >= (s64) src) */
mask = 0xa000; /* jhe */
goto branch_xs;
case BPF_JMP | BPF_JSLE | BPF_X: /* ((s64) dst <= (s64) src) */
mask = 0xc000; /* jle */
goto branch_xs;
case BPF_JMP | BPF_JGT | BPF_X: /* (dst > src) */
mask = 0x2000; /* jh */
goto branch_xu;
case BPF_JMP | BPF_JLT | BPF_X: /* (dst < src) */
mask = 0x4000; /* jl */
goto branch_xu;
case BPF_JMP | BPF_JGE | BPF_X: /* (dst >= src) */
mask = 0xa000; /* jhe */
goto branch_xu;
case BPF_JMP | BPF_JLE | BPF_X: /* (dst <= src) */
mask = 0xc000; /* jle */
goto branch_xu;
case BPF_JMP | BPF_JNE | BPF_X: /* (dst != src) */
mask = 0x7000; /* jne */
goto branch_xu;

View File

@ -28,7 +28,6 @@ CONFIG_IP_PNP_RARP=y
# CONFIG_INET_LRO is not set
# CONFIG_IPV6 is not set
CONFIG_NETFILTER=y
CONFIG_NETFILTER_DEBUG=y
CONFIG_IP_NF_QUEUE=y
CONFIG_MTD=y
CONFIG_MTD_PARTITIONS=y

View File

@ -98,6 +98,8 @@
#define SO_PEERGROUPS 0x003d
#define SO_ZEROCOPY 0x003e
/* Security levels - as per NRL IPv6 - don't actually do anything */
#define SO_SECURITY_AUTHENTICATION 0x5001
#define SO_SECURITY_ENCRYPTION_TRANSPORT 0x5002

View File

@ -128,6 +128,8 @@ static u32 WDISP10(u32 off)
#define BA (BRANCH | CONDA)
#define BG (BRANCH | CONDG)
#define BL (BRANCH | CONDL)
#define BLE (BRANCH | CONDLE)
#define BGU (BRANCH | CONDGU)
#define BLEU (BRANCH | CONDLEU)
#define BGE (BRANCH | CONDGE)
@ -715,9 +717,15 @@ static int emit_compare_and_branch(const u8 code, const u8 dst, u8 src,
case BPF_JGT:
br_opcode = BGU;
break;
case BPF_JLT:
br_opcode = BLU;
break;
case BPF_JGE:
br_opcode = BGEU;
break;
case BPF_JLE:
br_opcode = BLEU;
break;
case BPF_JSET:
case BPF_JNE:
br_opcode = BNE;
@ -725,9 +733,15 @@ static int emit_compare_and_branch(const u8 code, const u8 dst, u8 src,
case BPF_JSGT:
br_opcode = BG;
break;
case BPF_JSLT:
br_opcode = BL;
break;
case BPF_JSGE:
br_opcode = BGE;
break;
case BPF_JSLE:
br_opcode = BLE;
break;
default:
/* Make sure we dont leak kernel information to the
* user.
@ -746,18 +760,30 @@ static int emit_compare_and_branch(const u8 code, const u8 dst, u8 src,
case BPF_JGT:
cbcond_opcode = CBCONDGU;
break;
case BPF_JLT:
cbcond_opcode = CBCONDLU;
break;
case BPF_JGE:
cbcond_opcode = CBCONDGEU;
break;
case BPF_JLE:
cbcond_opcode = CBCONDLEU;
break;
case BPF_JNE:
cbcond_opcode = CBCONDNE;
break;
case BPF_JSGT:
cbcond_opcode = CBCONDG;
break;
case BPF_JSLT:
cbcond_opcode = CBCONDL;
break;
case BPF_JSGE:
cbcond_opcode = CBCONDGE;
break;
case BPF_JSLE:
cbcond_opcode = CBCONDLE;
break;
default:
/* Make sure we dont leak kernel information to the
* user.
@ -1176,10 +1202,14 @@ static int build_insn(const struct bpf_insn *insn, struct jit_ctx *ctx)
/* IF (dst COND src) JUMP off */
case BPF_JMP | BPF_JEQ | BPF_X:
case BPF_JMP | BPF_JGT | BPF_X:
case BPF_JMP | BPF_JLT | BPF_X:
case BPF_JMP | BPF_JGE | BPF_X:
case BPF_JMP | BPF_JLE | BPF_X:
case BPF_JMP | BPF_JNE | BPF_X:
case BPF_JMP | BPF_JSGT | BPF_X:
case BPF_JMP | BPF_JSLT | BPF_X:
case BPF_JMP | BPF_JSGE | BPF_X:
case BPF_JMP | BPF_JSLE | BPF_X:
case BPF_JMP | BPF_JSET | BPF_X: {
int err;
@ -1191,10 +1221,14 @@ static int build_insn(const struct bpf_insn *insn, struct jit_ctx *ctx)
/* IF (dst COND imm) JUMP off */
case BPF_JMP | BPF_JEQ | BPF_K:
case BPF_JMP | BPF_JGT | BPF_K:
case BPF_JMP | BPF_JLT | BPF_K:
case BPF_JMP | BPF_JGE | BPF_K:
case BPF_JMP | BPF_JLE | BPF_K:
case BPF_JMP | BPF_JNE | BPF_K:
case BPF_JMP | BPF_JSGT | BPF_K:
case BPF_JMP | BPF_JSLT | BPF_K:
case BPF_JMP | BPF_JSGE | BPF_K:
case BPF_JMP | BPF_JSLE | BPF_K:
case BPF_JMP | BPF_JSET | BPF_K: {
int err;

View File

@ -94,7 +94,9 @@ static int bpf_size_to_x86_bytes(int bpf_size)
#define X86_JNE 0x75
#define X86_JBE 0x76
#define X86_JA 0x77
#define X86_JL 0x7C
#define X86_JGE 0x7D
#define X86_JLE 0x7E
#define X86_JG 0x7F
static void bpf_flush_icache(void *start, void *end)
@ -285,7 +287,7 @@ static void emit_bpf_tail_call(u8 **pprog)
EMIT4(0x48, 0x8B, 0x46, /* mov rax, qword ptr [rsi + 16] */
offsetof(struct bpf_array, map.max_entries));
EMIT3(0x48, 0x39, 0xD0); /* cmp rax, rdx */
#define OFFSET1 47 /* number of bytes to jump */
#define OFFSET1 43 /* number of bytes to jump */
EMIT2(X86_JBE, OFFSET1); /* jbe out */
label1 = cnt;
@ -294,21 +296,20 @@ static void emit_bpf_tail_call(u8 **pprog)
*/
EMIT2_off32(0x8B, 0x85, 36); /* mov eax, dword ptr [rbp + 36] */
EMIT3(0x83, 0xF8, MAX_TAIL_CALL_CNT); /* cmp eax, MAX_TAIL_CALL_CNT */
#define OFFSET2 36
#define OFFSET2 32
EMIT2(X86_JA, OFFSET2); /* ja out */
label2 = cnt;
EMIT3(0x83, 0xC0, 0x01); /* add eax, 1 */
EMIT2_off32(0x89, 0x85, 36); /* mov dword ptr [rbp + 36], eax */
/* prog = array->ptrs[index]; */
EMIT4_off32(0x48, 0x8D, 0x84, 0xD6, /* lea rax, [rsi + rdx * 8 + offsetof(...)] */
EMIT4_off32(0x48, 0x8B, 0x84, 0xD6, /* mov rax, [rsi + rdx * 8 + offsetof(...)] */
offsetof(struct bpf_array, ptrs));
EMIT3(0x48, 0x8B, 0x00); /* mov rax, qword ptr [rax] */
/* if (prog == NULL)
* goto out;
*/
EMIT4(0x48, 0x83, 0xF8, 0x00); /* cmp rax, 0 */
EMIT3(0x48, 0x85, 0xC0); /* test rax,rax */
#define OFFSET3 10
EMIT2(X86_JE, OFFSET3); /* je out */
label3 = cnt;
@ -888,9 +889,13 @@ xadd: if (is_imm8(insn->off))
case BPF_JMP | BPF_JEQ | BPF_X:
case BPF_JMP | BPF_JNE | BPF_X:
case BPF_JMP | BPF_JGT | BPF_X:
case BPF_JMP | BPF_JLT | BPF_X:
case BPF_JMP | BPF_JGE | BPF_X:
case BPF_JMP | BPF_JLE | BPF_X:
case BPF_JMP | BPF_JSGT | BPF_X:
case BPF_JMP | BPF_JSLT | BPF_X:
case BPF_JMP | BPF_JSGE | BPF_X:
case BPF_JMP | BPF_JSLE | BPF_X:
/* cmp dst_reg, src_reg */
EMIT3(add_2mod(0x48, dst_reg, src_reg), 0x39,
add_2reg(0xC0, dst_reg, src_reg));
@ -911,9 +916,13 @@ xadd: if (is_imm8(insn->off))
case BPF_JMP | BPF_JEQ | BPF_K:
case BPF_JMP | BPF_JNE | BPF_K:
case BPF_JMP | BPF_JGT | BPF_K:
case BPF_JMP | BPF_JLT | BPF_K:
case BPF_JMP | BPF_JGE | BPF_K:
case BPF_JMP | BPF_JLE | BPF_K:
case BPF_JMP | BPF_JSGT | BPF_K:
case BPF_JMP | BPF_JSLT | BPF_K:
case BPF_JMP | BPF_JSGE | BPF_K:
case BPF_JMP | BPF_JSLE | BPF_K:
/* cmp dst_reg, imm8/32 */
EMIT1(add_1mod(0x48, dst_reg));
@ -935,18 +944,34 @@ emit_cond_jmp: /* convert BPF opcode to x86 */
/* GT is unsigned '>', JA in x86 */
jmp_cond = X86_JA;
break;
case BPF_JLT:
/* LT is unsigned '<', JB in x86 */
jmp_cond = X86_JB;
break;
case BPF_JGE:
/* GE is unsigned '>=', JAE in x86 */
jmp_cond = X86_JAE;
break;
case BPF_JLE:
/* LE is unsigned '<=', JBE in x86 */
jmp_cond = X86_JBE;
break;
case BPF_JSGT:
/* signed '>', GT in x86 */
jmp_cond = X86_JG;
break;
case BPF_JSLT:
/* signed '<', LT in x86 */
jmp_cond = X86_JL;
break;
case BPF_JSGE:
/* signed '>=', GE in x86 */
jmp_cond = X86_JGE;
break;
case BPF_JSLE:
/* signed '<=', LE in x86 */
jmp_cond = X86_JLE;
break;
default: /* to silence gcc warning */
return -EFAULT;
}

View File

@ -113,4 +113,6 @@
#define SO_PEERGROUPS 59
#define SO_ZEROCOPY 60
#endif /* _XTENSA_SOCKET_H */

View File

@ -71,7 +71,7 @@ static struct attribute *adummy_attrs[] = {
NULL
};
static struct attribute_group adummy_group_attrs = {
static const struct attribute_group adummy_group_attrs = {
.name = NULL, /* We want them in dev's root folder */
.attrs = adummy_attrs
};
@ -130,7 +130,7 @@ adummy_proc_read(struct atm_dev *dev, loff_t *pos, char *page)
return 0;
}
static struct atmdev_ops adummy_ops =
static const struct atmdev_ops adummy_ops =
{
.open = adummy_open,
.close = adummy_close,

View File

@ -2374,7 +2374,7 @@ MODULE_PARM_DESC(pci_lat, "PCI latency in bus cycles");
/********** module entry **********/
static struct pci_device_id amb_pci_tbl[] = {
static const struct pci_device_id amb_pci_tbl[] = {
{ PCI_VDEVICE(MADGE, PCI_DEVICE_ID_MADGE_AMBASSADOR), 0 },
{ PCI_VDEVICE(MADGE, PCI_DEVICE_ID_MADGE_AMBASSADOR_BAD), 0 },
{ 0, }

View File

@ -342,7 +342,7 @@ static struct atmdev_ops atmtcp_v_dev_ops = {
*/
static struct atmdev_ops atmtcp_c_dev_ops = {
static const struct atmdev_ops atmtcp_c_dev_ops = {
.close = atmtcp_c_close,
.send = atmtcp_c_send
};

View File

@ -2292,7 +2292,7 @@ err_disable:
}
static struct pci_device_id eni_pci_tbl[] = {
static const struct pci_device_id eni_pci_tbl[] = {
{ PCI_VDEVICE(EF, PCI_DEVICE_ID_EF_ATM_FPGA), 0 /* FPGA */ },
{ PCI_VDEVICE(EF, PCI_DEVICE_ID_EF_ATM_ASIC), 1 /* ASIC */ },
{ 0, }

View File

@ -2030,7 +2030,7 @@ static void firestream_remove_one(struct pci_dev *pdev)
func_exit ();
}
static struct pci_device_id firestream_pci_tbl[] = {
static const struct pci_device_id firestream_pci_tbl[] = {
{ PCI_VDEVICE(FUJITSU_ME, PCI_DEVICE_ID_FUJITSU_FS50), FS_IS50},
{ PCI_VDEVICE(FUJITSU_ME, PCI_DEVICE_ID_FUJITSU_FS155), FS_IS155},
{ 0, }

View File

@ -2757,7 +2757,7 @@ static void fore200e_pca_remove_one(struct pci_dev *pci_dev)
}
static struct pci_device_id fore200e_pca_tbl[] = {
static const struct pci_device_id fore200e_pca_tbl[] = {
{ PCI_VENDOR_ID_FORE, PCI_DEVICE_ID_FORE_PCA200E, PCI_ANY_ID, PCI_ANY_ID,
0, 0, (unsigned long) &fore200e_bus[0] },
{ 0, }

View File

@ -161,7 +161,7 @@ static unsigned int clocktab[] = {
CLK_LOW
};
static struct atmdev_ops he_ops =
static const struct atmdev_ops he_ops =
{
.open = he_open,
.close = he_close,
@ -2851,7 +2851,7 @@ MODULE_PARM_DESC(irq_coalesce, "use interrupt coalescing (default 1)");
module_param(sdh, bool, 0);
MODULE_PARM_DESC(sdh, "use SDH framing (default 0)");
static struct pci_device_id he_pci_tbl[] = {
static const struct pci_device_id he_pci_tbl[] = {
{ PCI_VDEVICE(FORE, PCI_DEVICE_ID_FORE_HE), 0 },
{ 0, }
};

View File

@ -2867,7 +2867,7 @@ MODULE_PARM_DESC(max_tx_size, "maximum size of TX AAL5 frames");
MODULE_PARM_DESC(max_rx_size, "maximum size of RX AAL5 frames");
MODULE_PARM_DESC(pci_lat, "PCI latency in bus cycles");
static struct pci_device_id hrz_pci_tbl[] = {
static const struct pci_device_id hrz_pci_tbl[] = {
{ PCI_VENDOR_ID_MADGE, PCI_DEVICE_ID_MADGE_HORIZON, PCI_ANY_ID, PCI_ANY_ID,
0, 0, 0 },
{ 0, }

View File

@ -134,7 +134,7 @@ static int idt77252_proc_read(struct atm_dev *dev, loff_t * pos,
static void idt77252_softint(struct work_struct *work);
static struct atmdev_ops idt77252_ops =
static const struct atmdev_ops idt77252_ops =
{
.dev_close = idt77252_dev_close,
.open = idt77252_open,
@ -3725,7 +3725,7 @@ err_out_disable_pdev:
return err;
}
static struct pci_device_id idt77252_pci_tbl[] =
static const struct pci_device_id idt77252_pci_tbl[] =
{
{ PCI_VDEVICE(IDT, PCI_DEVICE_ID_IDT_IDT77252), 0 },
{ 0, }

View File

@ -3266,7 +3266,7 @@ static void ia_remove_one(struct pci_dev *pdev)
kfree(iadev);
}
static struct pci_device_id ia_pci_tbl[] = {
static const struct pci_device_id ia_pci_tbl[] = {
{ PCI_VENDOR_ID_IPHASE, 0x0008, PCI_ANY_ID, PCI_ANY_ID, },
{ PCI_VENDOR_ID_IPHASE, 0x0009, PCI_ANY_ID, PCI_ANY_ID, },
{ 0,}

View File

@ -2589,7 +2589,7 @@ static int lanai_init_one(struct pci_dev *pci,
return result;
}
static struct pci_device_id lanai_pci_tbl[] = {
static const struct pci_device_id lanai_pci_tbl[] = {
{ PCI_VDEVICE(EF, PCI_DEVICE_ID_EF_ATM_LANAI2) },
{ PCI_VDEVICE(EF, PCI_DEVICE_ID_EF_ATM_LANAIHB) },
{ 0, } /* terminal entry */

View File

@ -154,7 +154,7 @@ static unsigned char ns_phy_get(struct atm_dev *dev, unsigned long addr);
static struct ns_dev *cards[NS_MAX_CARDS];
static unsigned num_cards;
static struct atmdev_ops atm_ops = {
static const struct atmdev_ops atm_ops = {
.open = ns_open,
.close = ns_close,
.ioctl = ns_ioctl,
@ -253,7 +253,7 @@ static void nicstar_remove_one(struct pci_dev *pcidev)
kfree(card);
}
static struct pci_device_id nicstar_pci_tbl[] = {
static const struct pci_device_id nicstar_pci_tbl[] = {
{ PCI_VDEVICE(IDT, PCI_DEVICE_ID_IDT_IDT77201), 0 },
{0,} /* terminate list */
};

View File

@ -611,7 +611,7 @@ static struct attribute *solos_attrs[] = {
NULL
};
static struct attribute_group solos_attr_group = {
static const struct attribute_group solos_attr_group = {
.attrs = solos_attrs,
.name = "parameters",
};
@ -628,7 +628,7 @@ static struct attribute *gpio_attrs[] = {
NULL
};
static struct attribute_group gpio_attr_group = {
static const struct attribute_group gpio_attr_group = {
.attrs = gpio_attrs,
.name = "gpio",
};
@ -1187,7 +1187,7 @@ static int psend(struct atm_vcc *vcc, struct sk_buff *skb)
return 0;
}
static struct atmdev_ops fpga_ops = {
static const struct atmdev_ops fpga_ops = {
.open = popen,
.close = pclose,
.ioctl = NULL,
@ -1476,7 +1476,7 @@ static void fpga_remove(struct pci_dev *dev)
kfree(card);
}
static struct pci_device_id fpga_pci_tbl[] = {
static const struct pci_device_id fpga_pci_tbl[] = {
{ 0x10ee, 0x0300, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
{ 0, }
};

View File

@ -1642,7 +1642,7 @@ out_free:
MODULE_LICENSE("GPL");
static struct pci_device_id zatm_pci_tbl[] = {
static const struct pci_device_id zatm_pci_tbl[] = {
{ PCI_VDEVICE(ZEITNET, PCI_DEVICE_ID_ZEITNET_1221), ZATM_COPPER },
{ PCI_VDEVICE(ZEITNET, PCI_DEVICE_ID_ZEITNET_1225), 0 },
{ 0, }

View File

@ -3,11 +3,8 @@ config BCMA_POSSIBLE
depends on HAS_IOMEM && HAS_DMA
default y
menu "Broadcom specific AMBA"
depends on BCMA_POSSIBLE
config BCMA
tristate "BCMA support"
menuconfig BCMA
tristate "Broadcom specific AMBA"
depends on BCMA_POSSIBLE
help
Bus driver for Broadcom specific Advanced Microcontroller Bus
@ -117,5 +114,3 @@ config BCMA_DEBUG
This turns on additional debugging messages.
If unsure, say N
endmenu

View File

@ -191,6 +191,7 @@ int bcma_gpio_init(struct bcma_drv_cc *cc)
case BCMA_CHIP_ID_BCM4707:
case BCMA_CHIP_ID_BCM5357:
case BCMA_CHIP_ID_BCM53572:
case BCMA_CHIP_ID_BCM53573:
case BCMA_CHIP_ID_BCM47094:
chip->ngpio = 32;
break;

View File

@ -98,6 +98,7 @@ config BT_HCIUART_NOKIA
depends on BT_HCIUART_SERDEV
depends on PM
select BT_HCIUART_H4
select BT_BCM
help
Nokia H4+ is serial protocol for communication between Bluetooth
device and host. This protocol is required for Bluetooth devices
@ -167,6 +168,7 @@ config BT_HCIUART_INTEL
config BT_HCIUART_BCM
bool "Broadcom protocol support"
depends on BT_HCIUART
depends on BT_HCIUART_SERDEV
select BT_HCIUART_H4
select BT_BCM
help

View File

@ -140,7 +140,8 @@ MODULE_DEVICE_TABLE(usb, ath3k_table);
#define BTUSB_ATH3012 0x80
/* This table is to load patch and sysconfig files
* for AR3012 */
* for AR3012
*/
static const struct usb_device_id ath3k_blist_tbl[] = {
/* Atheros AR3012 with sflash firmware*/

View File

@ -93,6 +93,7 @@ static void bluecard_detach(struct pcmcia_device *p_dev);
/* Hardware states */
#define CARD_READY 1
#define CARD_ACTIVITY 2
#define CARD_HAS_PCCARD_ID 4
#define CARD_HAS_POWER_LED 5
#define CARD_HAS_ACTIVITY_LED 6
@ -160,16 +161,14 @@ static void bluecard_activity_led_timeout(u_long arg)
struct bluecard_info *info = (struct bluecard_info *)arg;
unsigned int iobase = info->p_dev->resource[0]->start;
if (!test_bit(CARD_HAS_PCCARD_ID, &(info->hw_state)))
return;
if (test_bit(CARD_HAS_ACTIVITY_LED, &(info->hw_state))) {
/* Disable activity LED */
outb(0x08 | 0x20, iobase + 0x30);
} else {
/* Disable power LED */
outb(0x00, iobase + 0x30);
if (test_bit(CARD_ACTIVITY, &(info->hw_state))) {
/* leave LED in inactive state for HZ/10 for blink effect */
clear_bit(CARD_ACTIVITY, &(info->hw_state));
mod_timer(&(info->timer), jiffies + HZ / 10);
}
/* Disable activity LED, enable power LED */
outb(0x08 | 0x20, iobase + 0x30);
}
@ -177,22 +176,22 @@ static void bluecard_enable_activity_led(struct bluecard_info *info)
{
unsigned int iobase = info->p_dev->resource[0]->start;
if (!test_bit(CARD_HAS_PCCARD_ID, &(info->hw_state)))
/* don't disturb running blink timer */
if (timer_pending(&(info->timer)))
return;
set_bit(CARD_ACTIVITY, &(info->hw_state));
if (test_bit(CARD_HAS_ACTIVITY_LED, &(info->hw_state))) {
/* Enable activity LED */
outb(0x10 | 0x40, iobase + 0x30);
/* Stop the LED after HZ/4 */
mod_timer(&(info->timer), jiffies + HZ / 4);
/* Enable activity LED, keep power LED enabled */
outb(0x18 | 0x60, iobase + 0x30);
} else {
/* Enable power LED */
outb(0x08 | 0x20, iobase + 0x30);
/* Stop the LED after HZ/2 */
mod_timer(&(info->timer), jiffies + HZ / 2);
/* Disable power LED */
outb(0x00, iobase + 0x30);
}
/* Stop the LED after HZ/10 */
mod_timer(&(info->timer), jiffies + HZ / 10);
}
@ -625,16 +624,13 @@ static int bluecard_hci_flush(struct hci_dev *hdev)
static int bluecard_hci_open(struct hci_dev *hdev)
{
struct bluecard_info *info = hci_get_drvdata(hdev);
unsigned int iobase = info->p_dev->resource[0]->start;
if (test_bit(CARD_HAS_PCCARD_ID, &(info->hw_state)))
bluecard_hci_set_baud_rate(hdev, DEFAULT_BAUD_RATE);
if (test_bit(CARD_HAS_PCCARD_ID, &(info->hw_state))) {
unsigned int iobase = info->p_dev->resource[0]->start;
/* Enable LED */
outb(0x08 | 0x20, iobase + 0x30);
}
/* Enable power LED */
outb(0x08 | 0x20, iobase + 0x30);
return 0;
}
@ -643,15 +639,15 @@ static int bluecard_hci_open(struct hci_dev *hdev)
static int bluecard_hci_close(struct hci_dev *hdev)
{
struct bluecard_info *info = hci_get_drvdata(hdev);
unsigned int iobase = info->p_dev->resource[0]->start;
bluecard_hci_flush(hdev);
if (test_bit(CARD_HAS_PCCARD_ID, &(info->hw_state))) {
unsigned int iobase = info->p_dev->resource[0]->start;
/* Stop LED timer */
del_timer_sync(&(info->timer));
/* Disable LED */
outb(0x00, iobase + 0x30);
}
/* Disable power LED */
outb(0x00, iobase + 0x30);
return 0;
}

View File

@ -684,14 +684,16 @@ static int bt3c_config(struct pcmcia_device *link)
unsigned long try;
/* First pass: look for a config entry that looks normal.
Two tries: without IO aliases, then with aliases */
* Two tries: without IO aliases, then with aliases
*/
for (try = 0; try < 2; try++)
if (!pcmcia_loop_config(link, bt3c_check_config, (void *) try))
goto found_port;
/* Second pass: try to find an entry that isn't picky about
its base address, then try to grab any standard serial port
address, and finally try to get any free port. */
* its base address, then try to grab any standard serial port
* address, and finally try to get any free port.
*/
if (!pcmcia_loop_config(link, bt3c_check_config_notpicky, NULL))
goto found_port;

View File

@ -287,6 +287,37 @@ static struct sk_buff *btbcm_read_usb_product(struct hci_dev *hdev)
return skb;
}
static int btbcm_read_info(struct hci_dev *hdev)
{
struct sk_buff *skb;
/* Read Verbose Config Version Info */
skb = btbcm_read_verbose_config(hdev);
if (IS_ERR(skb))
return PTR_ERR(skb);
BT_INFO("%s: BCM: chip id %u", hdev->name, skb->data[1]);
kfree_skb(skb);
/* Read Controller Features */
skb = btbcm_read_controller_features(hdev);
if (IS_ERR(skb))
return PTR_ERR(skb);
BT_INFO("%s: BCM: features 0x%2.2x", hdev->name, skb->data[1]);
kfree_skb(skb);
/* Read Local Name */
skb = btbcm_read_local_name(hdev);
if (IS_ERR(skb))
return PTR_ERR(skb);
BT_INFO("%s: %s", hdev->name, (char *)(skb->data + 1));
kfree_skb(skb);
return 0;
}
static const struct {
u16 subver;
const char *name;
@ -322,13 +353,10 @@ int btbcm_initialize(struct hci_dev *hdev, char *fw_name, size_t len)
subver = le16_to_cpu(ver->lmp_subver);
kfree_skb(skb);
/* Read Verbose Config Version Info */
skb = btbcm_read_verbose_config(hdev);
if (IS_ERR(skb))
return PTR_ERR(skb);
BT_INFO("%s: BCM: chip id %u", hdev->name, skb->data[1]);
kfree_skb(skb);
/* Read controller information */
err = btbcm_read_info(hdev);
if (err)
return err;
switch ((rev & 0xf000) >> 12) {
case 0:
@ -431,29 +459,10 @@ int btbcm_setup_patchram(struct hci_dev *hdev)
subver = le16_to_cpu(ver->lmp_subver);
kfree_skb(skb);
/* Read Verbose Config Version Info */
skb = btbcm_read_verbose_config(hdev);
if (IS_ERR(skb))
return PTR_ERR(skb);
BT_INFO("%s: BCM: chip id %u", hdev->name, skb->data[1]);
kfree_skb(skb);
/* Read Controller Features */
skb = btbcm_read_controller_features(hdev);
if (IS_ERR(skb))
return PTR_ERR(skb);
BT_INFO("%s: BCM: features 0x%2.2x", hdev->name, skb->data[1]);
kfree_skb(skb);
/* Read Local Name */
skb = btbcm_read_local_name(hdev);
if (IS_ERR(skb))
return PTR_ERR(skb);
BT_INFO("%s: %s", hdev->name, (char *)(skb->data + 1));
kfree_skb(skb);
/* Read controller information */
err = btbcm_read_info(hdev);
if (err)
return err;
switch ((rev & 0xf000) >> 12) {
case 0:

View File

@ -1455,7 +1455,8 @@ done:
fw_dump_ptr = fw_dump_data;
/* Dump all the memory data into single file, a userspace script will
be used to split all the memory data to multiple files*/
* be used to split all the memory data to multiple files
*/
BT_INFO("== btmrvl firmware dump to /sys/class/devcoredump start");
for (idx = 0; idx < dump_num; idx++) {
struct memory_type_mapping *entry = &mem_type_mapping_tbl[idx];
@ -1482,7 +1483,8 @@ done:
}
/* fw_dump_data will be free in device coredump release function
after 5 min*/
* after 5 min
*/
dev_coredumpv(&card->func->dev, fw_dump_data, fw_dump_len, GFP_KERNEL);
BT_INFO("== btmrvl firmware dump to /sys/class/devcoredump end");
}

View File

@ -81,7 +81,7 @@ static int rome_patch_ver_req(struct hci_dev *hdev, u32 *rome_version)
* and lower 2 bytes from patch will be used.
*/
*rome_version = (le32_to_cpu(ver->soc_id) << 16) |
(le16_to_cpu(ver->rome_ver) & 0x0000ffff);
(le16_to_cpu(ver->rome_ver) & 0x0000ffff);
out:
kfree_skb(skb);

View File

@ -279,6 +279,8 @@ static int rtl_load_config(struct hci_dev *hdev, const char *name, u8 **buff)
return ret;
ret = fw->size;
*buff = kmemdup(fw->data, ret, GFP_KERNEL);
if (!*buff)
ret = -ENOMEM;
release_firmware(fw);

View File

@ -144,7 +144,8 @@ static int btsdio_rx_packet(struct btsdio_data *data)
if (!skb) {
/* Out of memory. Prepare a read retry and just
* return with the expectation that the next time
* we're called we'll have more memory. */
* we're called we'll have more memory.
*/
return -ENOMEM;
}

View File

@ -614,14 +614,16 @@ static int btuart_config(struct pcmcia_device *link)
int try;
/* First pass: look for a config entry that looks normal.
Two tries: without IO aliases, then with aliases */
* Two tries: without IO aliases, then with aliases
*/
for (try = 0; try < 2; try++)
if (!pcmcia_loop_config(link, btuart_check_config, &try))
goto found_port;
/* Second pass: try to find an entry that isn't picky about
its base address, then try to grab any standard serial port
address, and finally try to get any free port. */
* its base address, then try to grab any standard serial port
* address, and finally try to get any free port.
*/
if (!pcmcia_loop_config(link, btuart_check_config_notpicky, NULL))
goto found_port;

View File

@ -66,6 +66,7 @@ static struct usb_driver btusb_driver;
#define BTUSB_BCM2045 0x40000
#define BTUSB_IFNUM_2 0x80000
#define BTUSB_CW6622 0x100000
#define BTUSB_BCM_NO_PRODID 0x200000
static const struct usb_device_id btusb_table[] = {
/* Generic Bluetooth USB device */
@ -131,7 +132,8 @@ static const struct usb_device_id btusb_table[] = {
{ USB_DEVICE(0x19ff, 0x0239), .driver_info = BTUSB_BCM_PATCHRAM },
/* Broadcom BCM43142A0 (Foxconn/Lenovo) */
{ USB_DEVICE(0x105b, 0xe065), .driver_info = BTUSB_BCM_PATCHRAM },
{ USB_VENDOR_AND_INTERFACE_INFO(0x105b, 0xff, 0x01, 0x01),
.driver_info = BTUSB_BCM_PATCHRAM },
/* Broadcom BCM920703 (HTC Vive) */
{ USB_VENDOR_AND_INTERFACE_INFO(0x0bb4, 0xff, 0x01, 0x01),
@ -169,6 +171,10 @@ static const struct usb_device_id btusb_table[] = {
{ USB_VENDOR_AND_INTERFACE_INFO(0x0930, 0xff, 0x01, 0x01),
.driver_info = BTUSB_BCM_PATCHRAM },
/* Broadcom devices with missing product id */
{ USB_DEVICE_AND_INTERFACE_INFO(0x0000, 0x0000, 0xff, 0x01, 0x01),
.driver_info = BTUSB_BCM_PATCHRAM | BTUSB_BCM_NO_PRODID },
/* Intel Bluetooth USB Bootloader (RAM module) */
{ USB_DEVICE(0x8087, 0x0a5a),
.driver_info = BTUSB_INTEL_BOOT | BTUSB_BROKEN_ISOC },
@ -268,6 +274,7 @@ static const struct usb_device_id blacklist_table[] = {
{ USB_DEVICE(0x0489, 0xe092), .driver_info = BTUSB_QCA_ROME },
{ USB_DEVICE(0x0489, 0xe0a2), .driver_info = BTUSB_QCA_ROME },
{ USB_DEVICE(0x04ca, 0x3011), .driver_info = BTUSB_QCA_ROME },
{ USB_DEVICE(0x04ca, 0x3016), .driver_info = BTUSB_QCA_ROME },
/* Broadcom BCM2035 */
{ USB_DEVICE(0x0a5c, 0x2009), .driver_info = BTUSB_BCM92035 },
@ -357,6 +364,7 @@ static const struct usb_device_id blacklist_table[] = {
{ USB_DEVICE(0x13d3, 0x3410), .driver_info = BTUSB_REALTEK },
{ USB_DEVICE(0x13d3, 0x3416), .driver_info = BTUSB_REALTEK },
{ USB_DEVICE(0x13d3, 0x3459), .driver_info = BTUSB_REALTEK },
{ USB_DEVICE(0x13d3, 0x3494), .driver_info = BTUSB_REALTEK },
/* Additional Realtek 8821AE Bluetooth devices */
{ USB_DEVICE(0x0b05, 0x17dc), .driver_info = BTUSB_REALTEK },
@ -656,7 +664,8 @@ static void btusb_intr_complete(struct urb *urb)
err = usb_submit_urb(urb, GFP_ATOMIC);
if (err < 0) {
/* -EPERM: urb is being killed;
* -ENODEV: device got disconnected */
* -ENODEV: device got disconnected
*/
if (err != -EPERM && err != -ENODEV)
BT_ERR("%s urb %p failed to resubmit (%d)",
hdev->name, urb, -err);
@ -745,7 +754,8 @@ static void btusb_bulk_complete(struct urb *urb)
err = usb_submit_urb(urb, GFP_ATOMIC);
if (err < 0) {
/* -EPERM: urb is being killed;
* -ENODEV: device got disconnected */
* -ENODEV: device got disconnected
*/
if (err != -EPERM && err != -ENODEV)
BT_ERR("%s urb %p failed to resubmit (%d)",
hdev->name, urb, -err);
@ -840,7 +850,8 @@ static void btusb_isoc_complete(struct urb *urb)
err = usb_submit_urb(urb, GFP_ATOMIC);
if (err < 0) {
/* -EPERM: urb is being killed;
* -ENODEV: device got disconnected */
* -ENODEV: device got disconnected
*/
if (err != -EPERM && err != -ENODEV)
BT_ERR("%s urb %p failed to resubmit (%d)",
hdev->name, urb, -err);
@ -952,7 +963,8 @@ static void btusb_diag_complete(struct urb *urb)
err = usb_submit_urb(urb, GFP_ATOMIC);
if (err < 0) {
/* -EPERM: urb is being killed;
* -ENODEV: device got disconnected */
* -ENODEV: device got disconnected
*/
if (err != -EPERM && err != -ENODEV)
BT_ERR("%s urb %p failed to resubmit (%d)",
hdev->name, urb, -err);
@ -1076,6 +1088,10 @@ static int btusb_open(struct hci_dev *hdev)
}
data->intf->needs_remote_wakeup = 1;
/* device specific wakeup source enabled and required for USB
* remote wakeup while host is suspended
*/
device_wakeup_enable(&data->udev->dev);
if (test_and_set_bit(BTUSB_INTR_RUNNING, &data->flags))
goto done;
@ -1139,6 +1155,7 @@ static int btusb_close(struct hci_dev *hdev)
goto failed;
data->intf->needs_remote_wakeup = 0;
device_wakeup_disable(&data->udev->dev);
usb_autopm_put_interface(data->intf);
failed:
@ -2892,11 +2909,25 @@ static int btusb_probe(struct usb_interface *intf,
if (id->driver_info == BTUSB_IGNORE)
return -ENODEV;
if (id->driver_info & BTUSB_BCM_NO_PRODID) {
struct usb_device *udev = interface_to_usbdev(intf);
/* For the broken Broadcom devices that show 0000:0000
* as USB vendor and product information, check that the
* manufacturer string identifies them as Broadcom based
* devices.
*/
if (!udev->manufacturer ||
strcmp(udev->manufacturer, "Broadcom Corp"))
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 */
* patch and sysconfig files
*/
if (le16_to_cpu(udev->descriptor.bcdDevice) <= 0x0001)
return -ENODEV;
}
@ -3067,6 +3098,12 @@ static int btusb_probe(struct usb_interface *intf,
if (id->driver_info & BTUSB_QCA_ROME) {
data->setup_on_usb = btusb_setup_qca;
hdev->set_bdaddr = btusb_set_bdaddr_ath3012;
/* QCA Rome devices lose their updated firmware over suspend,
* but the USB hub doesn't notice any status change.
* Explicitly request a device reset on resume.
*/
set_bit(BTUSB_RESET_RESUME, &data->flags);
}
#ifdef CONFIG_BT_HCIBTUSB_RTL
@ -3259,13 +3296,28 @@ static void play_deferred(struct btusb_data *data)
int err;
while ((urb = usb_get_from_anchor(&data->deferred))) {
usb_anchor_urb(urb, &data->tx_anchor);
err = usb_submit_urb(urb, GFP_ATOMIC);
if (err < 0)
if (err < 0) {
if (err != -EPERM && err != -ENODEV)
BT_ERR("%s urb %p submission failed (%d)",
data->hdev->name, urb, -err);
kfree(urb->setup_packet);
usb_unanchor_urb(urb);
usb_free_urb(urb);
break;
}
data->tx_in_flight++;
usb_free_urb(urb);
}
/* Cleanup the rest deferred urbs. */
while ((urb = usb_get_from_anchor(&data->deferred))) {
kfree(urb->setup_packet);
usb_free_urb(urb);
}
usb_scuttle_anchored_urbs(&data->deferred);
}
static int btusb_resume(struct usb_interface *intf)

View File

@ -93,8 +93,7 @@ static void st_reg_completion_cb(void *priv_data, int data)
complete(&lhst->wait_reg_completion);
}
/* Called by Shared Transport layer when receive data is
* available */
/* Called by Shared Transport layer when receive data is available */
static long st_receive(void *priv_data, struct sk_buff *skb)
{
struct ti_st *lhst = priv_data;
@ -198,7 +197,8 @@ static int ti_st_open(struct hci_dev *hdev)
}
/* Is ST registration callback
* called with ERROR status? */
* called with ERROR status?
*/
if (hst->reg_status != 0) {
BT_ERR("ST registration completed with invalid "
"status %d", hst->reg_status);
@ -276,7 +276,7 @@ static int ti_st_send_frame(struct hci_dev *hdev, struct sk_buff *skb)
static int bt_ti_probe(struct platform_device *pdev)
{
static struct ti_st *hst;
struct ti_st *hst;
struct hci_dev *hdev;
int err;

View File

@ -27,6 +27,8 @@
#include <linux/firmware.h>
#include <linux/module.h>
#include <linux/acpi.h>
#include <linux/of.h>
#include <linux/property.h>
#include <linux/platform_device.h>
#include <linux/clk.h>
#include <linux/gpio/consumer.h>
@ -34,6 +36,7 @@
#include <linux/interrupt.h>
#include <linux/dmi.h>
#include <linux/pm_runtime.h>
#include <linux/serdev.h>
#include <net/bluetooth/bluetooth.h>
#include <net/bluetooth/hci_core.h>
@ -41,11 +44,15 @@
#include "btbcm.h"
#include "hci_uart.h"
#define BCM_NULL_PKT 0x00
#define BCM_NULL_SIZE 0
#define BCM_LM_DIAG_PKT 0x07
#define BCM_LM_DIAG_SIZE 63
#define BCM_AUTOSUSPEND_DELAY 5000 /* default autosleep delay */
/* platform device driver resources */
struct bcm_device {
struct list_head list;
@ -59,6 +66,7 @@ struct bcm_device {
bool clk_enabled;
u32 init_speed;
u32 oper_speed;
int irq;
u8 irq_polarity;
@ -68,6 +76,12 @@ struct bcm_device {
#endif
};
/* serdev driver resources */
struct bcm_serdev {
struct hci_uart hu;
};
/* generic bcm uart resources */
struct bcm_data {
struct sk_buff *rx_skb;
struct sk_buff_head txq;
@ -79,6 +93,14 @@ struct bcm_data {
static DEFINE_MUTEX(bcm_device_lock);
static LIST_HEAD(bcm_device_list);
static inline void host_set_baudrate(struct hci_uart *hu, unsigned int speed)
{
if (hu->serdev)
serdev_device_set_baudrate(hu->serdev, speed);
else
hci_uart_set_baudrate(hu, speed);
}
static int bcm_set_baudrate(struct hci_uart *hu, unsigned int speed)
{
struct hci_dev *hdev = hu->hdev;
@ -176,7 +198,7 @@ static irqreturn_t bcm_host_wake(int irq, void *data)
static int bcm_request_irq(struct bcm_data *bcm)
{
struct bcm_device *bdev = bcm->dev;
int err = 0;
int err;
/* If this is not a platform device, do not enable PM functionalities */
mutex_lock(&bcm_device_lock);
@ -185,22 +207,24 @@ static int bcm_request_irq(struct bcm_data *bcm)
goto unlock;
}
if (bdev->irq > 0) {
err = devm_request_irq(&bdev->pdev->dev, bdev->irq,
bcm_host_wake, IRQF_TRIGGER_RISING,
"host_wake", bdev);
if (err)
goto unlock;
device_init_wakeup(&bdev->pdev->dev, true);
pm_runtime_set_autosuspend_delay(&bdev->pdev->dev,
BCM_AUTOSUSPEND_DELAY);
pm_runtime_use_autosuspend(&bdev->pdev->dev);
pm_runtime_set_active(&bdev->pdev->dev);
pm_runtime_enable(&bdev->pdev->dev);
if (bdev->irq <= 0) {
err = -EOPNOTSUPP;
goto unlock;
}
err = devm_request_irq(&bdev->pdev->dev, bdev->irq, bcm_host_wake,
IRQF_TRIGGER_RISING, "host_wake", bdev);
if (err)
goto unlock;
device_init_wakeup(&bdev->pdev->dev, true);
pm_runtime_set_autosuspend_delay(&bdev->pdev->dev,
BCM_AUTOSUSPEND_DELAY);
pm_runtime_use_autosuspend(&bdev->pdev->dev);
pm_runtime_set_active(&bdev->pdev->dev);
pm_runtime_enable(&bdev->pdev->dev);
unlock:
mutex_unlock(&bcm_device_lock);
@ -287,6 +311,14 @@ static int bcm_open(struct hci_uart *hu)
hu->priv = bcm;
/* If this is a serdev defined device, then only use
* serdev open primitive and skip the rest.
*/
if (hu->serdev) {
serdev_device_open(hu->serdev);
goto out;
}
if (!hu->tty->dev)
goto out;
@ -301,6 +333,7 @@ static int bcm_open(struct hci_uart *hu)
if (hu->tty->dev->parent == dev->pdev->dev.parent) {
bcm->dev = dev;
hu->init_speed = dev->init_speed;
hu->oper_speed = dev->oper_speed;
#ifdef CONFIG_PM
dev->hu = hu;
#endif
@ -321,6 +354,12 @@ static int bcm_close(struct hci_uart *hu)
bt_dev_dbg(hu->hdev, "hu %p", hu);
/* If this is a serdev defined device, only use serdev
* close primitive and then continue as usual.
*/
if (hu->serdev)
serdev_device_close(hu->serdev);
/* Protect bcm->dev against removal of the device or driver */
mutex_lock(&bcm_device_lock);
if (bcm_device_exists(bdev)) {
@ -396,7 +435,7 @@ static int bcm_setup(struct hci_uart *hu)
speed = 0;
if (speed)
hci_uart_set_baudrate(hu, speed);
host_set_baudrate(hu, speed);
/* Operational speed if any */
if (hu->oper_speed)
@ -409,7 +448,7 @@ static int bcm_setup(struct hci_uart *hu)
if (speed) {
err = bcm_set_baudrate(hu, speed);
if (!err)
hci_uart_set_baudrate(hu, speed);
host_set_baudrate(hu, speed);
}
finalize:
@ -432,11 +471,19 @@ finalize:
.lsize = 0, \
.maxlen = BCM_LM_DIAG_SIZE
#define BCM_RECV_NULL \
.type = BCM_NULL_PKT, \
.hlen = BCM_NULL_SIZE, \
.loff = 0, \
.lsize = 0, \
.maxlen = BCM_NULL_SIZE
static const struct h4_recv_pkt bcm_recv_pkts[] = {
{ H4_RECV_ACL, .recv = hci_recv_frame },
{ H4_RECV_SCO, .recv = hci_recv_frame },
{ H4_RECV_EVENT, .recv = hci_recv_frame },
{ BCM_RECV_LM_DIAG, .recv = hci_recv_diag },
{ BCM_RECV_NULL, .recv = hci_recv_diag },
};
static int bcm_recv(struct hci_uart *hu, const void *data, int count)
@ -697,8 +744,10 @@ static int bcm_resource(struct acpi_resource *ares, void *data)
case ACPI_RESOURCE_TYPE_SERIAL_BUS:
sb = &ares->data.uart_serial_bus;
if (sb->type == ACPI_RESOURCE_SERIAL_TYPE_UART)
if (sb->type == ACPI_RESOURCE_SERIAL_TYPE_UART) {
dev->init_speed = sb->default_baud_rate;
dev->oper_speed = 4000000;
}
break;
default:
@ -851,7 +900,6 @@ static const struct hci_uart_proto bcm_proto = {
.name = "Broadcom",
.manufacturer = 15,
.init_speed = 115200,
.oper_speed = 4000000,
.open = bcm_open,
.close = bcm_close,
.flush = bcm_flush,
@ -901,9 +949,57 @@ static struct platform_driver bcm_driver = {
},
};
static int bcm_serdev_probe(struct serdev_device *serdev)
{
struct bcm_serdev *bcmdev;
u32 speed;
int err;
bcmdev = devm_kzalloc(&serdev->dev, sizeof(*bcmdev), GFP_KERNEL);
if (!bcmdev)
return -ENOMEM;
bcmdev->hu.serdev = serdev;
serdev_device_set_drvdata(serdev, bcmdev);
err = device_property_read_u32(&serdev->dev, "max-speed", &speed);
if (!err)
bcmdev->hu.oper_speed = speed;
return hci_uart_register_device(&bcmdev->hu, &bcm_proto);
}
static void bcm_serdev_remove(struct serdev_device *serdev)
{
struct bcm_serdev *bcmdev = serdev_device_get_drvdata(serdev);
hci_uart_unregister_device(&bcmdev->hu);
}
#ifdef CONFIG_OF
static const struct of_device_id bcm_bluetooth_of_match[] = {
{ .compatible = "brcm,bcm43438-bt" },
{ },
};
MODULE_DEVICE_TABLE(of, bcm_bluetooth_of_match);
#endif
static struct serdev_device_driver bcm_serdev_driver = {
.probe = bcm_serdev_probe,
.remove = bcm_serdev_remove,
.driver = {
.name = "hci_uart_bcm",
.of_match_table = of_match_ptr(bcm_bluetooth_of_match),
},
};
int __init bcm_init(void)
{
/* For now, we need to keep both platform device
* driver (ACPI generated) and serdev driver (DT).
*/
platform_driver_register(&bcm_driver);
serdev_device_driver_register(&bcm_serdev_driver);
return hci_uart_register_proto(&bcm_proto);
}
@ -911,6 +1007,7 @@ int __init bcm_init(void)
int __exit bcm_deinit(void)
{
platform_driver_unregister(&bcm_driver);
serdev_device_driver_unregister(&bcm_serdev_driver);
return hci_uart_unregister_proto(&bcm_proto);
}

View File

@ -172,7 +172,7 @@ struct sk_buff *h4_recv_buf(struct hci_dev *hdev, struct sk_buff *skb,
const struct h4_recv_pkt *pkts, int pkts_count)
{
struct hci_uart *hu = hci_get_drvdata(hdev);
u8 alignment = hu->alignment;
u8 alignment = hu->alignment ? hu->alignment : 1;
while (count) {
int i, len;

View File

@ -457,7 +457,8 @@ static int hci_uart_tty_open(struct tty_struct *tty)
BT_DBG("tty %p", tty);
/* Error if the tty has no write op instead of leaving an exploitable
hole */
* hole
*/
if (tty->ops->write == NULL)
return -EOPNOTSUPP;

View File

@ -622,7 +622,8 @@ static int download_firmware(struct ll_device *lldev)
cmd = (struct hci_command *)action_ptr;
if (cmd->opcode == 0xff36) {
/* ignore remote change
* baud rate HCI VS command */
* baud rate HCI VS command
*/
bt_dev_warn(lldev->hu.hdev, "change remote baud rate command in firmware");
break;
}
@ -742,14 +743,8 @@ static int hci_ti_probe(struct serdev_device *serdev)
static void hci_ti_remove(struct serdev_device *serdev)
{
struct ll_device *lldev = serdev_device_get_drvdata(serdev);
struct hci_uart *hu = &lldev->hu;
struct hci_dev *hdev = hu->hdev;
cancel_work_sync(&hu->write_work);
hci_unregister_dev(hdev);
hci_free_dev(hdev);
hu->proto->close(hu);
hci_uart_unregister_device(&lldev->hu);
}
static const struct of_device_id hci_ti_of_match[] = {

View File

@ -767,16 +767,8 @@ static int nokia_bluetooth_serdev_probe(struct serdev_device *serdev)
static void nokia_bluetooth_serdev_remove(struct serdev_device *serdev)
{
struct nokia_bt_dev *btdev = serdev_device_get_drvdata(serdev);
struct hci_uart *hu = &btdev->hu;
struct hci_dev *hdev = hu->hdev;
cancel_work_sync(&hu->write_work);
hci_unregister_dev(hdev);
hci_free_dev(hdev);
hu->proto->close(hu);
pm_runtime_disable(&btdev->serdev->dev);
hci_uart_unregister_device(&btdev->hu);
}
static int nokia_bluetooth_runtime_suspend(struct device *dev)

View File

@ -354,3 +354,16 @@ err_alloc:
return err;
}
EXPORT_SYMBOL_GPL(hci_uart_register_device);
void hci_uart_unregister_device(struct hci_uart *hu)
{
struct hci_dev *hdev = hu->hdev;
hci_unregister_dev(hdev);
hci_free_dev(hdev);
cancel_work_sync(&hu->write_work);
hu->proto->close(hu);
}
EXPORT_SYMBOL_GPL(hci_uart_unregister_device);

View File

@ -112,6 +112,7 @@ struct hci_uart {
int hci_uart_register_proto(const struct hci_uart_proto *p);
int hci_uart_unregister_proto(const struct hci_uart_proto *p);
int hci_uart_register_device(struct hci_uart *hu, const struct hci_uart_proto *p);
void hci_uart_unregister_device(struct hci_uart *hu);
int hci_uart_tx_wakeup(struct hci_uart *hu);
int hci_uart_init_ready(struct hci_uart *hu);

View File

@ -661,9 +661,23 @@ void vmbus_close(struct vmbus_channel *channel)
}
EXPORT_SYMBOL_GPL(vmbus_close);
int vmbus_sendpacket_ctl(struct vmbus_channel *channel, void *buffer,
u32 bufferlen, u64 requestid,
enum vmbus_packet_type type, u32 flags)
/**
* vmbus_sendpacket() - Send the specified buffer on the given channel
* @channel: Pointer to vmbus_channel structure.
* @buffer: Pointer to the buffer you want to receive the data into.
* @bufferlen: Maximum size of what the the buffer will hold
* @requestid: Identifier of the request
* @type: Type of packet that is being send e.g. negotiate, time
* packet etc.
*
* Sends data in @buffer directly to hyper-v via the vmbus
* This will send the data unparsed to hyper-v.
*
* Mainly used by Hyper-V drivers.
*/
int vmbus_sendpacket(struct vmbus_channel *channel, void *buffer,
u32 bufferlen, u64 requestid,
enum vmbus_packet_type type, u32 flags)
{
struct vmpacket_descriptor desc;
u32 packetlen = sizeof(struct vmpacket_descriptor) + bufferlen;
@ -690,42 +704,19 @@ int vmbus_sendpacket_ctl(struct vmbus_channel *channel, void *buffer,
return hv_ringbuffer_write(channel, bufferlist, num_vecs);
}
EXPORT_SYMBOL(vmbus_sendpacket_ctl);
/**
* vmbus_sendpacket() - Send the specified buffer on the given channel
* @channel: Pointer to vmbus_channel structure.
* @buffer: Pointer to the buffer you want to receive the data into.
* @bufferlen: Maximum size of what the the buffer will hold
* @requestid: Identifier of the request
* @type: Type of packet that is being send e.g. negotiate, time
* packet etc.
*
* Sends data in @buffer directly to hyper-v via the vmbus
* This will send the data unparsed to hyper-v.
*
* Mainly used by Hyper-V drivers.
*/
int vmbus_sendpacket(struct vmbus_channel *channel, void *buffer,
u32 bufferlen, u64 requestid,
enum vmbus_packet_type type, u32 flags)
{
return vmbus_sendpacket_ctl(channel, buffer, bufferlen, requestid,
type, flags);
}
EXPORT_SYMBOL(vmbus_sendpacket);
/*
* vmbus_sendpacket_pagebuffer_ctl - Send a range of single-page buffer
* vmbus_sendpacket_pagebuffer - Send a range of single-page buffer
* packets using a GPADL Direct packet type. This interface allows you
* to control notifying the host. This will be useful for sending
* batched data. Also the sender can control the send flags
* explicitly.
*/
int vmbus_sendpacket_pagebuffer_ctl(struct vmbus_channel *channel,
struct hv_page_buffer pagebuffers[],
u32 pagecount, void *buffer, u32 bufferlen,
u64 requestid, u32 flags)
int vmbus_sendpacket_pagebuffer(struct vmbus_channel *channel,
struct hv_page_buffer pagebuffers[],
u32 pagecount, void *buffer, u32 bufferlen,
u64 requestid)
{
int i;
struct vmbus_channel_packet_page_buffer desc;
@ -750,7 +741,7 @@ int vmbus_sendpacket_pagebuffer_ctl(struct vmbus_channel *channel,
/* Setup the descriptor */
desc.type = VM_PKT_DATA_USING_GPA_DIRECT;
desc.flags = flags;
desc.flags = VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED;
desc.dataoffset8 = descsize >> 3; /* in 8-bytes granularity */
desc.length8 = (u16)(packetlen_aligned >> 3);
desc.transactionid = requestid;
@ -771,24 +762,6 @@ int vmbus_sendpacket_pagebuffer_ctl(struct vmbus_channel *channel,
return hv_ringbuffer_write(channel, bufferlist, 3);
}
EXPORT_SYMBOL_GPL(vmbus_sendpacket_pagebuffer_ctl);
/*
* vmbus_sendpacket_pagebuffer - Send a range of single-page buffer
* packets using a GPADL Direct packet type.
*/
int vmbus_sendpacket_pagebuffer(struct vmbus_channel *channel,
struct hv_page_buffer pagebuffers[],
u32 pagecount, void *buffer, u32 bufferlen,
u64 requestid)
{
u32 flags = VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED;
return vmbus_sendpacket_pagebuffer_ctl(channel, pagebuffers, pagecount,
buffer, bufferlen,
requestid, flags);
}
EXPORT_SYMBOL_GPL(vmbus_sendpacket_pagebuffer);
/*
@ -828,62 +801,6 @@ int vmbus_sendpacket_mpb_desc(struct vmbus_channel *channel,
}
EXPORT_SYMBOL_GPL(vmbus_sendpacket_mpb_desc);
/*
* vmbus_sendpacket_multipagebuffer - Send a multi-page buffer packet
* using a GPADL Direct packet type.
*/
int vmbus_sendpacket_multipagebuffer(struct vmbus_channel *channel,
struct hv_multipage_buffer *multi_pagebuffer,
void *buffer, u32 bufferlen, u64 requestid)
{
struct vmbus_channel_packet_multipage_buffer desc;
u32 descsize;
u32 packetlen;
u32 packetlen_aligned;
struct kvec bufferlist[3];
u64 aligned_data = 0;
u32 pfncount = NUM_PAGES_SPANNED(multi_pagebuffer->offset,
multi_pagebuffer->len);
if (pfncount > MAX_MULTIPAGE_BUFFER_COUNT)
return -EINVAL;
/*
* Adjust the size down since vmbus_channel_packet_multipage_buffer is
* the largest size we support
*/
descsize = sizeof(struct vmbus_channel_packet_multipage_buffer) -
((MAX_MULTIPAGE_BUFFER_COUNT - pfncount) *
sizeof(u64));
packetlen = descsize + bufferlen;
packetlen_aligned = ALIGN(packetlen, sizeof(u64));
/* Setup the descriptor */
desc.type = VM_PKT_DATA_USING_GPA_DIRECT;
desc.flags = VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED;
desc.dataoffset8 = descsize >> 3; /* in 8-bytes granularity */
desc.length8 = (u16)(packetlen_aligned >> 3);
desc.transactionid = requestid;
desc.rangecount = 1;
desc.range.len = multi_pagebuffer->len;
desc.range.offset = multi_pagebuffer->offset;
memcpy(desc.range.pfn_array, multi_pagebuffer->pfn_array,
pfncount * sizeof(u64));
bufferlist[0].iov_base = &desc;
bufferlist[0].iov_len = descsize;
bufferlist[1].iov_base = buffer;
bufferlist[1].iov_len = bufferlen;
bufferlist[2].iov_base = &aligned_data;
bufferlist[2].iov_len = (packetlen_aligned - packetlen);
return hv_ringbuffer_write(channel, bufferlist, 3);
}
EXPORT_SYMBOL_GPL(vmbus_sendpacket_multipagebuffer);
/**
* vmbus_recvpacket() - Retrieve the user packet on the specified channel
* @channel: Pointer to vmbus_channel structure.

View File

@ -1,6 +1,7 @@
config INFINIBAND_BNXT_RE
tristate "Broadcom Netxtreme HCA support"
depends on ETHERNET && NETDEVICES && PCI && INET && DCB
depends on MAY_USE_DEVLINK
select NET_VENDOR_BROADCOM
select BNXT
---help---

View File

@ -150,8 +150,8 @@ static int is_sqp(struct mlx4_ib_dev *dev, struct mlx4_ib_qp *qp)
/* VF or PF -- proxy SQP */
if (mlx4_is_mfunc(dev->dev)) {
for (i = 0; i < dev->dev->caps.num_ports; i++) {
if (qp->mqp.qpn == dev->dev->caps.qp0_proxy[i] ||
qp->mqp.qpn == dev->dev->caps.qp1_proxy[i]) {
if (qp->mqp.qpn == dev->dev->caps.spec_qps[i].qp0_proxy ||
qp->mqp.qpn == dev->dev->caps.spec_qps[i].qp1_proxy) {
proxy_sqp = 1;
break;
}
@ -178,7 +178,7 @@ static int is_qp0(struct mlx4_ib_dev *dev, struct mlx4_ib_qp *qp)
/* VF or PF -- proxy QP0 */
if (mlx4_is_mfunc(dev->dev)) {
for (i = 0; i < dev->dev->caps.num_ports; i++) {
if (qp->mqp.qpn == dev->dev->caps.qp0_proxy[i]) {
if (qp->mqp.qpn == dev->dev->caps.spec_qps[i].qp0_proxy) {
proxy_qp0 = 1;
break;
}
@ -632,8 +632,8 @@ static int qp0_enabled_vf(struct mlx4_dev *dev, int qpn)
{
int i;
for (i = 0; i < dev->caps.num_ports; i++) {
if (qpn == dev->caps.qp0_proxy[i])
return !!dev->caps.qp0_qkey[i];
if (qpn == dev->caps.spec_qps[i].qp0_proxy)
return !!dev->caps.spec_qps[i].qp0_qkey;
}
return 0;
}
@ -1521,9 +1521,9 @@ static u32 get_sqp_num(struct mlx4_ib_dev *dev, struct ib_qp_init_attr *attr)
}
/* PF or VF -- creating proxies */
if (attr->qp_type == IB_QPT_SMI)
return dev->dev->caps.qp0_proxy[attr->port_num - 1];
return dev->dev->caps.spec_qps[attr->port_num - 1].qp0_proxy;
else
return dev->dev->caps.qp1_proxy[attr->port_num - 1];
return dev->dev->caps.spec_qps[attr->port_num - 1].qp1_proxy;
}
static struct ib_qp *_mlx4_ib_create_qp(struct ib_pd *pd,
@ -2880,9 +2880,9 @@ static int vf_get_qp0_qkey(struct mlx4_dev *dev, int qpn, u32 *qkey)
{
int i;
for (i = 0; i < dev->caps.num_ports; i++) {
if (qpn == dev->caps.qp0_proxy[i] ||
qpn == dev->caps.qp0_tunnel[i]) {
*qkey = dev->caps.qp0_qkey[i];
if (qpn == dev->caps.spec_qps[i].qp0_proxy ||
qpn == dev->caps.spec_qps[i].qp0_tunnel) {
*qkey = dev->caps.spec_qps[i].qp0_qkey;
return 0;
}
}
@ -2943,7 +2943,7 @@ static int build_sriov_qp0_header(struct mlx4_ib_sqp *sqp,
sqp->ud_header.bth.destination_qpn = cpu_to_be32(wr->remote_qpn);
else
sqp->ud_header.bth.destination_qpn =
cpu_to_be32(mdev->dev->caps.qp0_tunnel[sqp->qp.port - 1]);
cpu_to_be32(mdev->dev->caps.spec_qps[sqp->qp.port - 1].qp0_tunnel);
sqp->ud_header.bth.psn = cpu_to_be32((sqp->send_psn++) & ((1 << 24) - 1));
if (mlx4_is_master(mdev->dev)) {
@ -3403,9 +3403,9 @@ static void set_tunnel_datagram_seg(struct mlx4_ib_dev *dev,
memcpy(dseg->av, &sqp_av, sizeof (struct mlx4_av));
if (qpt == MLX4_IB_QPT_PROXY_GSI)
dseg->dqpn = cpu_to_be32(dev->dev->caps.qp1_tunnel[port - 1]);
dseg->dqpn = cpu_to_be32(dev->dev->caps.spec_qps[port - 1].qp1_tunnel);
else
dseg->dqpn = cpu_to_be32(dev->dev->caps.qp0_tunnel[port - 1]);
dseg->dqpn = cpu_to_be32(dev->dev->caps.spec_qps[port - 1].qp0_tunnel);
/* Use QKEY from the QP context, which is set by master */
dseg->qkey = cpu_to_be32(IB_QP_SET_QKEY);
}

View File

@ -55,7 +55,7 @@ struct capictr_event {
/* ------------------------------------------------------------- */
static struct capi_version driver_version = {2, 0, 1, 1 << 4};
static const struct capi_version driver_version = {2, 0, 1, 1 << 4};
static char driver_serial[CAPI_SERIAL_LEN] = "0004711";
static char capi_manufakturer[64] = "AVM Berlin";

View File

@ -26,15 +26,7 @@
/*#define DEBUG */
#include <linux/types.h>
#define IMPLEMENT_DTMF 1
#define IMPLEMENT_LINE_INTERCONNECT2 1
@ -82,8 +74,6 @@
#define CODEC_PERMANENT 0x02
#define ADV_VOICE 0x03
#define MAX_CIP_TYPES 5 /* kind of CIP types for group optimization */
#define C_IND_MASK_DWORDS ((MAX_APPL + 32) >> 5)
#define FAX_CONNECT_INFO_BUFFER_SIZE 256
#define NCPI_BUFFER_SIZE 256
@ -265,8 +255,8 @@ struct _PLCI {
word ncci_ring_list;
byte inc_dis_ncci_table[MAX_CHANNELS_PER_PLCI];
t_std_internal_command internal_command_queue[MAX_INTERNAL_COMMAND_LEVELS];
dword c_ind_mask_table[C_IND_MASK_DWORDS];
dword group_optimization_mask_table[C_IND_MASK_DWORDS];
DECLARE_BITMAP(c_ind_mask_table, MAX_APPL);
DECLARE_BITMAP(group_optimization_mask_table, MAX_APPL);
byte RBuffer[200];
dword msg_in_queue[MSG_IN_QUEUE_SIZE/sizeof(dword)];
API_SAVE saved_msg;

View File

@ -23,9 +23,7 @@
*
*/
#include <linux/bitmap.h>
#include "platform.h"
#include "di_defs.h"
@ -35,19 +33,9 @@
#include "mdm_msg.h"
#include "divasync.h"
#define FILE_ "MESSAGE.C"
#define dprintf
/*------------------------------------------------------------------*/
/* This is options supported for all adapters that are server by */
/* XDI driver. Allo it is not necessary to ask it from every adapter*/
@ -72,9 +60,6 @@ static dword diva_xdi_extended_features = 0;
/*------------------------------------------------------------------*/
static void group_optimization(DIVA_CAPI_ADAPTER *a, PLCI *plci);
static void set_group_ind_mask(PLCI *plci);
static void clear_group_ind_mask_bit(PLCI *plci, word b);
static byte test_group_ind_mask_bit(PLCI *plci, word b);
void AutomaticLaw(DIVA_CAPI_ADAPTER *);
word CapiRelease(word);
word CapiRegister(word);
@ -1086,106 +1071,6 @@ static void plci_remove(PLCI *plci)
plci->State = OUTG_DIS_PENDING;
}
/*------------------------------------------------------------------*/
/* Application Group function helpers */
/*------------------------------------------------------------------*/
static void set_group_ind_mask(PLCI *plci)
{
word i;
for (i = 0; i < C_IND_MASK_DWORDS; i++)
plci->group_optimization_mask_table[i] = 0xffffffffL;
}
static void clear_group_ind_mask_bit(PLCI *plci, word b)
{
plci->group_optimization_mask_table[b >> 5] &= ~(1L << (b & 0x1f));
}
static byte test_group_ind_mask_bit(PLCI *plci, word b)
{
return ((plci->group_optimization_mask_table[b >> 5] & (1L << (b & 0x1f))) != 0);
}
/*------------------------------------------------------------------*/
/* c_ind_mask operations for arbitrary MAX_APPL */
/*------------------------------------------------------------------*/
static void clear_c_ind_mask(PLCI *plci)
{
word i;
for (i = 0; i < C_IND_MASK_DWORDS; i++)
plci->c_ind_mask_table[i] = 0;
}
static byte c_ind_mask_empty(PLCI *plci)
{
word i;
i = 0;
while ((i < C_IND_MASK_DWORDS) && (plci->c_ind_mask_table[i] == 0))
i++;
return (i == C_IND_MASK_DWORDS);
}
static void set_c_ind_mask_bit(PLCI *plci, word b)
{
plci->c_ind_mask_table[b >> 5] |= (1L << (b & 0x1f));
}
static void clear_c_ind_mask_bit(PLCI *plci, word b)
{
plci->c_ind_mask_table[b >> 5] &= ~(1L << (b & 0x1f));
}
static byte test_c_ind_mask_bit(PLCI *plci, word b)
{
return ((plci->c_ind_mask_table[b >> 5] & (1L << (b & 0x1f))) != 0);
}
static void dump_c_ind_mask(PLCI *plci)
{
word i, j, k;
dword d;
char *p;
char buf[40];
for (i = 0; i < C_IND_MASK_DWORDS; i += 4)
{
p = buf + 36;
*p = '\0';
for (j = 0; j < 4; j++)
{
if (i + j < C_IND_MASK_DWORDS)
{
d = plci->c_ind_mask_table[i + j];
for (k = 0; k < 8; k++)
{
*(--p) = hex_asc_lo(d);
d >>= 4;
}
}
else if (i != 0)
{
for (k = 0; k < 8; k++)
*(--p) = ' ';
}
*(--p) = ' ';
}
dbug(1, dprintf("c_ind_mask =%s", (char *) p));
}
}
#define dump_plcis(a)
/*------------------------------------------------------------------*/
/* translation function for each message */
/*------------------------------------------------------------------*/
@ -1457,13 +1342,13 @@ static byte connect_res(dword Id, word Number, DIVA_CAPI_ADAPTER *a,
return 1;
}
else if (plci->State == INC_CON_PENDING || plci->State == INC_CON_ALERT) {
clear_c_ind_mask_bit(plci, (word)(appl->Id - 1));
dump_c_ind_mask(plci);
__clear_bit(appl->Id - 1, plci->c_ind_mask_table);
dbug(1, dprintf("c_ind_mask =%*pb", MAX_APPL, plci->c_ind_mask_table));
Reject = GET_WORD(parms[0].info);
dbug(1, dprintf("Reject=0x%x", Reject));
if (Reject)
{
if (c_ind_mask_empty(plci))
if (bitmap_empty(plci->c_ind_mask_table, MAX_APPL))
{
if ((Reject & 0xff00) == 0x3400)
{
@ -1553,11 +1438,8 @@ static byte connect_res(dword Id, word Number, DIVA_CAPI_ADAPTER *a,
sig_req(plci, CALL_RES, 0);
}
for (i = 0; i < max_appl; i++) {
if (test_c_ind_mask_bit(plci, i)) {
sendf(&application[i], _DISCONNECT_I, Id, 0, "w", _OTHER_APPL_CONNECTED);
}
}
for_each_set_bit(i, plci->c_ind_mask_table, max_appl)
sendf(&application[i], _DISCONNECT_I, Id, 0, "w", _OTHER_APPL_CONNECTED);
}
}
return 1;
@ -1584,13 +1466,10 @@ static byte disconnect_req(dword Id, word Number, DIVA_CAPI_ADAPTER *a,
{
if (plci->State == INC_CON_PENDING || plci->State == INC_CON_ALERT)
{
clear_c_ind_mask_bit(plci, (word)(appl->Id - 1));
__clear_bit(appl->Id - 1, plci->c_ind_mask_table);
plci->appl = appl;
for (i = 0; i < max_appl; i++)
{
if (test_c_ind_mask_bit(plci, i))
sendf(&application[i], _DISCONNECT_I, Id, 0, "w", 0);
}
for_each_set_bit(i, plci->c_ind_mask_table, max_appl)
sendf(&application[i], _DISCONNECT_I, Id, 0, "w", 0);
plci->State = OUTG_DIS_PENDING;
}
if (plci->Sig.Id && plci->appl)
@ -1634,7 +1513,7 @@ static byte disconnect_res(dword Id, word Number, DIVA_CAPI_ADAPTER *a,
{
/* clear ind mask bit, just in case of collsion of */
/* DISCONNECT_IND and CONNECT_RES */
clear_c_ind_mask_bit(plci, (word)(appl->Id - 1));
__clear_bit(appl->Id - 1, plci->c_ind_mask_table);
ncci_free_receive_buffers(plci, 0);
if (plci_remove_check(plci))
{
@ -1642,7 +1521,7 @@ static byte disconnect_res(dword Id, word Number, DIVA_CAPI_ADAPTER *a,
}
if (plci->State == INC_DIS_PENDING
|| plci->State == SUSPENDING) {
if (c_ind_mask_empty(plci)) {
if (bitmap_empty(plci->c_ind_mask_table, MAX_APPL)) {
if (plci->State != SUSPENDING) plci->State = IDLE;
dbug(1, dprintf("chs=%d", plci->channels));
if (!plci->channels) {
@ -3351,13 +3230,11 @@ static byte select_b_req(dword Id, word Number, DIVA_CAPI_ADAPTER *a,
}
plci->State = INC_CON_CONNECTED_ALERT;
plci->appl = appl;
clear_c_ind_mask_bit(plci, (word)(appl->Id - 1));
dump_c_ind_mask(plci);
for (i = 0; i < max_appl; i++) /* disconnect the other appls */
{ /* its quasi a connect */
if (test_c_ind_mask_bit(plci, i))
sendf(&application[i], _DISCONNECT_I, Id, 0, "w", _OTHER_APPL_CONNECTED);
}
__clear_bit(appl->Id - 1, plci->c_ind_mask_table);
dbug(1, dprintf("c_ind_mask =%*pb", MAX_APPL, plci->c_ind_mask_table));
/* disconnect the other appls its quasi a connect */
for_each_set_bit(i, plci->c_ind_mask_table, max_appl)
sendf(&application[i], _DISCONNECT_I, Id, 0, "w", _OTHER_APPL_CONNECTED);
}
api_save_msg(msg, "s", &plci->saved_msg);
@ -5692,19 +5569,17 @@ static void sig_ind(PLCI *plci)
cip = find_cip(a, parms[4], parms[6]);
cip_mask = 1L << cip;
dbug(1, dprintf("cip=%d,cip_mask=%lx", cip, cip_mask));
clear_c_ind_mask(plci);
bitmap_zero(plci->c_ind_mask_table, MAX_APPL);
if (!remove_started && !a->adapter_disabled)
{
set_c_ind_mask_bit(plci, MAX_APPL);
group_optimization(a, plci);
for (i = 0; i < max_appl; i++) {
for_each_set_bit(i, plci->group_optimization_mask_table, max_appl) {
if (application[i].Id
&& (a->CIP_Mask[i] & 1 || a->CIP_Mask[i] & cip_mask)
&& CPN_filter_ok(parms[0], a, i)
&& test_group_ind_mask_bit(plci, i)) {
&& CPN_filter_ok(parms[0], a, i)) {
dbug(1, dprintf("storedcip_mask[%d]=0x%lx", i, a->CIP_Mask[i]));
set_c_ind_mask_bit(plci, i);
dump_c_ind_mask(plci);
__set_bit(i, plci->c_ind_mask_table);
dbug(1, dprintf("c_ind_mask =%*pb", MAX_APPL, plci->c_ind_mask_table));
plci->State = INC_CON_PENDING;
plci->call_dir = (plci->call_dir & ~(CALL_DIR_OUT | CALL_DIR_ORIGINATE)) |
CALL_DIR_IN | CALL_DIR_ANSWER;
@ -5750,10 +5625,9 @@ static void sig_ind(PLCI *plci)
SendMultiIE(plci, Id, multi_pi_parms, PI, 0x210, true));
}
}
clear_c_ind_mask_bit(plci, MAX_APPL);
dump_c_ind_mask(plci);
dbug(1, dprintf("c_ind_mask =%*pb", MAX_APPL, plci->c_ind_mask_table));
}
if (c_ind_mask_empty(plci)) {
if (bitmap_empty(plci->c_ind_mask_table, MAX_APPL)) {
sig_req(plci, HANGUP, 0);
send_req(plci);
plci->State = IDLE;
@ -5994,13 +5868,13 @@ static void sig_ind(PLCI *plci)
break;
case RESUME:
clear_c_ind_mask_bit(plci, (word)(plci->appl->Id - 1));
__clear_bit(plci->appl->Id - 1, plci->c_ind_mask_table);
PUT_WORD(&resume_cau[4], GOOD);
sendf(plci->appl, _FACILITY_I, Id, 0, "ws", (word)3, resume_cau);
break;
case SUSPEND:
clear_c_ind_mask(plci);
bitmap_zero(plci->c_ind_mask_table, MAX_APPL);
if (plci->NL.Id && !plci->nl_remove_id) {
mixer_remove(plci);
@ -6037,15 +5911,12 @@ static void sig_ind(PLCI *plci)
if (plci->State == INC_CON_PENDING || plci->State == INC_CON_ALERT)
{
for (i = 0; i < max_appl; i++)
{
if (test_c_ind_mask_bit(plci, i))
sendf(&application[i], _DISCONNECT_I, Id, 0, "w", 0);
}
for_each_set_bit(i, plci->c_ind_mask_table, max_appl)
sendf(&application[i], _DISCONNECT_I, Id, 0, "w", 0);
}
else
{
clear_c_ind_mask(plci);
bitmap_zero(plci->c_ind_mask_table, MAX_APPL);
}
if (!plci->appl)
{
@ -6055,7 +5926,7 @@ static void sig_ind(PLCI *plci)
a->listen_active--;
}
plci->State = INC_DIS_PENDING;
if (c_ind_mask_empty(plci))
if (bitmap_empty(plci->c_ind_mask_table, MAX_APPL))
{
plci->State = IDLE;
if (plci->NL.Id && !plci->nl_remove_id)
@ -6341,14 +6212,10 @@ static void SendInfo(PLCI *plci, dword Id, byte **parms, byte iesent)
|| Info_Number == DSP
|| Info_Number == UUI)
{
for (j = 0; j < max_appl; j++)
{
if (test_c_ind_mask_bit(plci, j))
{
dbug(1, dprintf("Ovl_Ind"));
iesent = true;
sendf(&application[j], _INFO_I, Id, 0, "wS", Info_Number, Info_Element);
}
for_each_set_bit(j, plci->c_ind_mask_table, max_appl) {
dbug(1, dprintf("Ovl_Ind"));
iesent = true;
sendf(&application[j], _INFO_I, Id, 0, "wS", Info_Number, Info_Element);
}
}
} /* all other signalling states */
@ -6416,14 +6283,10 @@ static byte SendMultiIE(PLCI *plci, dword Id, byte **parms, byte ie_type,
}
else if (!plci->appl && Info_Number)
{ /* overlap receiving broadcast */
for (j = 0; j < max_appl; j++)
{
if (test_c_ind_mask_bit(plci, j))
{
iesent = true;
dbug(1, dprintf("Mlt_Ovl_Ind"));
sendf(&application[j] , _INFO_I, Id, 0, "wS", Info_Number, Info_Element);
}
for_each_set_bit(j, plci->c_ind_mask_table, max_appl) {
iesent = true;
dbug(1, dprintf("Mlt_Ovl_Ind"));
sendf(&application[j] , _INFO_I, Id, 0, "wS", Info_Number, Info_Element);
}
} /* all other signalling states */
else if (Info_Number
@ -7270,7 +7133,6 @@ static word get_plci(DIVA_CAPI_ADAPTER *a)
word i, j;
PLCI *plci;
dump_plcis(a);
for (i = 0; i < a->max_plci && a->plci[i].Id; i++);
if (i == a->max_plci) {
dbug(1, dprintf("get_plci: out of PLCIs"));
@ -7321,8 +7183,8 @@ static word get_plci(DIVA_CAPI_ADAPTER *a)
plci->ncci_ring_list = 0;
for (j = 0; j < MAX_CHANNELS_PER_PLCI; j++) plci->inc_dis_ncci_table[j] = 0;
clear_c_ind_mask(plci);
set_group_ind_mask(plci);
bitmap_zero(plci->c_ind_mask_table, MAX_APPL);
bitmap_fill(plci->group_optimization_mask_table, MAX_APPL);
plci->fax_connect_info_length = 0;
plci->nsf_control_bits = 0;
plci->ncpi_state = 0x00;
@ -9373,10 +9235,10 @@ word CapiRelease(word Id)
if (plci->State == INC_CON_PENDING
|| plci->State == INC_CON_ALERT)
{
if (test_c_ind_mask_bit(plci, (word)(Id - 1)))
if (test_bit(Id - 1, plci->c_ind_mask_table))
{
clear_c_ind_mask_bit(plci, (word)(Id - 1));
if (c_ind_mask_empty(plci))
__clear_bit(Id - 1, plci->c_ind_mask_table);
if (bitmap_empty(plci->c_ind_mask_table, MAX_APPL))
{
sig_req(plci, HANGUP, 0);
send_req(plci);
@ -9384,10 +9246,10 @@ word CapiRelease(word Id)
}
}
}
if (test_c_ind_mask_bit(plci, (word)(Id - 1)))
if (test_bit(Id - 1, plci->c_ind_mask_table))
{
clear_c_ind_mask_bit(plci, (word)(Id - 1));
if (c_ind_mask_empty(plci))
__clear_bit(Id - 1, plci->c_ind_mask_table);
if (bitmap_empty(plci->c_ind_mask_table, MAX_APPL))
{
if (!plci->appl)
{
@ -9452,7 +9314,7 @@ word CapiRelease(word Id)
static word plci_remove_check(PLCI *plci)
{
if (!plci) return true;
if (!plci->NL.Id && c_ind_mask_empty(plci))
if (!plci->NL.Id && bitmap_empty(plci->c_ind_mask_table, MAX_APPL))
{
if (plci->Sig.Id == 0xff)
plci->Sig.Id = 0;
@ -14735,7 +14597,8 @@ static void group_optimization(DIVA_CAPI_ADAPTER *a, PLCI *plci)
word appl_number_group_type[MAX_APPL];
PLCI *auxplci;
set_group_ind_mask(plci); /* all APPLs within this inc. call are allowed to dial in */
/* all APPLs within this inc. call are allowed to dial in */
bitmap_fill(plci->group_optimization_mask_table, MAX_APPL);
if (!a->group_optimization_enabled)
{
@ -14771,13 +14634,12 @@ static void group_optimization(DIVA_CAPI_ADAPTER *a, PLCI *plci)
if (a->plci[k].Id)
{
auxplci = &a->plci[k];
if (auxplci->appl == &application[i]) /* application has a busy PLCI */
{
if (auxplci->appl == &application[i]) {
/* application has a busy PLCI */
busy = true;
dbug(1, dprintf("Appl 0x%x is busy", i + 1));
}
else if (test_c_ind_mask_bit(auxplci, i)) /* application has an incoming call pending */
{
} else if (test_bit(i, plci->c_ind_mask_table)) {
/* application has an incoming call pending */
busy = true;
dbug(1, dprintf("Appl 0x%x has inc. call pending", i + 1));
}
@ -14826,7 +14688,8 @@ static void group_optimization(DIVA_CAPI_ADAPTER *a, PLCI *plci)
if (appl_number_group_type[i] == appl_number_group_type[j])
{
dbug(1, dprintf("Appl 0x%x is member of group 0x%x, no call", j + 1, appl_number_group_type[j]));
clear_group_ind_mask_bit(plci, j); /* disable call on other group members */
/* disable call on other group members */
__clear_bit(j, plci->group_optimization_mask_table);
appl_number_group_type[j] = 0; /* remove disabled group member from group list */
}
}
@ -14834,7 +14697,7 @@ static void group_optimization(DIVA_CAPI_ADAPTER *a, PLCI *plci)
}
else /* application should not get a call */
{
clear_group_ind_mask_bit(plci, i);
__clear_bit(i, plci->group_optimization_mask_table);
}
}

View File

@ -337,7 +337,7 @@ static const char *HFC_NT_LAYER1_STATES[HFC_MAX_NT_LAYER1_STATE + 1] = {
};
/* supported devices */
static struct usb_device_id hfcsusb_idtab[] = {
static const struct usb_device_id hfcsusb_idtab[] = {
{
USB_DEVICE(0x0959, 0x2bd0),
.driver_info = (unsigned long) &((struct hfcsusb_vdata)

View File

@ -65,7 +65,7 @@ typedef struct {
} hfcsusb_vdata;
/* VID/PID device list */
static struct usb_device_id hfcusb_idtab[] = {
static const struct usb_device_id hfcusb_idtab[] = {
{
USB_DEVICE(0x0959, 0x2bd0),
.driver_info = (unsigned long) &((hfcsusb_vdata)

View File

@ -45,7 +45,6 @@ obj-$(CONFIG_ETHERNET) += ethernet/
obj-$(CONFIG_FDDI) += fddi/
obj-$(CONFIG_HIPPI) += hippi/
obj-$(CONFIG_HAMRADIO) += hamradio/
obj-$(CONFIG_IRDA) += irda/
obj-$(CONFIG_PLIP) += plip/
obj-$(CONFIG_PPP) += ppp/
obj-$(CONFIG_PPP_ASYNC) += ppp/

View File

@ -311,9 +311,7 @@ module_param(ipddp_mode, int, 0);
static int __init ipddp_init_module(void)
{
dev_ipddp = ipddp_init();
if (IS_ERR(dev_ipddp))
return PTR_ERR(dev_ipddp);
return 0;
return PTR_ERR_OR_ZERO(dev_ipddp);
}
static void __exit ipddp_cleanup_module(void)

View File

@ -20,7 +20,7 @@
#include <linux/if_arcnet.h>
#ifdef __KERNEL__
#include <linux/irqreturn.h>
#include <linux/interrupt.h>
/*
* RECON_THRESHOLD is the maximum number of RECON messages to receive

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