Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next
Pull networking updates from David Miller: "Some highlights from this development cycle: 1) Big refactoring of ipv6 route and neigh handling to support nexthop objects configurable as units from userspace. From David Ahern. 2) Convert explored_states in BPF verifier into a hash table, significantly decreased state held for programs with bpf2bpf calls, from Alexei Starovoitov. 3) Implement bpf_send_signal() helper, from Yonghong Song. 4) Various classifier enhancements to mvpp2 driver, from Maxime Chevallier. 5) Add aRFS support to hns3 driver, from Jian Shen. 6) Fix use after free in inet frags by allocating fqdirs dynamically and reworking how rhashtable dismantle occurs, from Eric Dumazet. 7) Add act_ctinfo packet classifier action, from Kevin Darbyshire-Bryant. 8) Add TFO key backup infrastructure, from Jason Baron. 9) Remove several old and unused ISDN drivers, from Arnd Bergmann. 10) Add devlink notifications for flash update status to mlxsw driver, from Jiri Pirko. 11) Lots of kTLS offload infrastructure fixes, from Jakub Kicinski. 12) Add support for mv88e6250 DSA chips, from Rasmus Villemoes. 13) Various enhancements to ipv6 flow label handling, from Eric Dumazet and Willem de Bruijn. 14) Support TLS offload in nfp driver, from Jakub Kicinski, Dirk van der Merwe, and others. 15) Various improvements to axienet driver including converting it to phylink, from Robert Hancock. 16) Add PTP support to sja1105 DSA driver, from Vladimir Oltean. 17) Add mqprio qdisc offload support to dpaa2-eth, from Ioana Radulescu. 18) Add devlink health reporting to mlx5, from Moshe Shemesh. 19) Convert stmmac over to phylink, from Jose Abreu. 20) Add PTP PHC (Physical Hardware Clock) support to mlxsw, from Shalom Toledo. 21) Add nftables SYNPROXY support, from Fernando Fernandez Mancera. 22) Convert tcp_fastopen over to use SipHash, from Ard Biesheuvel. 23) Track spill/fill of constants in BPF verifier, from Alexei Starovoitov. 24) Support bounded loops in BPF, from Alexei Starovoitov. 25) Various page_pool API fixes and improvements, from Jesper Dangaard Brouer. 26) Just like ipv4, support ref-countless ipv6 route handling. From Wei Wang. 27) Support VLAN offloading in aquantia driver, from Igor Russkikh. 28) Add AF_XDP zero-copy support to mlx5, from Maxim Mikityanskiy. 29) Add flower GRE encap/decap support to nfp driver, from Pieter Jansen van Vuuren. 30) Protect against stack overflow when using act_mirred, from John Hurley. 31) Allow devmap map lookups from eBPF, from Toke Høiland-Jørgensen. 32) Use page_pool API in netsec driver, Ilias Apalodimas. 33) Add Google gve network driver, from Catherine Sullivan. 34) More indirect call avoidance, from Paolo Abeni. 35) Add kTLS TX HW offload support to mlx5, from Tariq Toukan. 36) Add XDP_REDIRECT support to bnxt_en, from Andy Gospodarek. 37) Add MPLS manipulation actions to TC, from John Hurley. 38) Add sending a packet to connection tracking from TC actions, and then allow flower classifier matching on conntrack state. From Paul Blakey. 39) Netfilter hw offload support, from Pablo Neira Ayuso" * git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next: (2080 commits) net/mlx5e: Return in default case statement in tx_post_resync_params mlx5: Return -EINVAL when WARN_ON_ONCE triggers in mlx5e_tls_resync(). net: dsa: add support for BRIDGE_MROUTER attribute pkt_sched: Include const.h net: netsec: remove static declaration for netsec_set_tx_de() net: netsec: remove superfluous if statement netfilter: nf_tables: add hardware offload support net: flow_offload: rename tc_cls_flower_offload to flow_cls_offload net: flow_offload: add flow_block_cb_is_busy() and use it net: sched: remove tcf block API drivers: net: use flow block API net: sched: use flow block API net: flow_offload: add flow_block_cb_{priv, incref, decref}() net: flow_offload: add list handling functions net: flow_offload: add flow_block_cb_alloc() and flow_block_cb_free() net: flow_offload: rename TCF_BLOCK_BINDER_TYPE_* to FLOW_BLOCK_BINDER_TYPE_* net: flow_offload: rename TC_BLOCK_{UN}BIND to FLOW_BLOCK_{UN}BIND net: flow_offload: add flow_block_cb_setup_simple() net: hisilicon: Add an tx_desc to adapt HI13X1_GMAC net: hisilicon: Add an rx_desc to adapt HI13X1_GMAC ...
This commit is contained in:
commit
237f83dfbe
2
CREDITS
2
CREDITS
|
@ -1800,7 +1800,7 @@ S: 2300 Copenhagen S.
|
|||
S: Denmark
|
||||
|
||||
N: Jozsef Kadlecsik
|
||||
E: kadlec@blackhole.kfki.hu
|
||||
E: kadlec@netfilter.org
|
||||
P: 1024D/470DB964 4CB3 1A05 713E 9BF7 FAC5 5809 DD8C B7B1 470D B964
|
||||
D: netfilter: TCP window tracking code
|
||||
D: netfilter: raw table
|
||||
|
|
|
@ -41,3 +41,11 @@ Description:
|
|||
xgmii, moca, qsgmii, trgmii, 1000base-x, 2500base-x, rxaui,
|
||||
xaui, 10gbase-kr, unknown
|
||||
|
||||
What: /sys/class/mdio_bus/<bus>/<device>/phy_standalone
|
||||
Date: May 2019
|
||||
KernelVersion: 5.3
|
||||
Contact: netdev@vger.kernel.org
|
||||
Description:
|
||||
Boolean value indicating whether the PHY device is used in
|
||||
standalone mode, without a net_device associated, by PHYLINK.
|
||||
Attribute created only when this is the case.
|
||||
|
|
|
@ -172,11 +172,31 @@ registers which makes BPF inefficient virtual machine for 32-bit
|
|||
CPU architectures and 32-bit HW accelerators. Can true 32-bit registers
|
||||
be added to BPF in the future?
|
||||
|
||||
A: NO. The first thing to improve performance on 32-bit archs is to teach
|
||||
LLVM to generate code that uses 32-bit subregisters. Then second step
|
||||
is to teach verifier to mark operations where zero-ing upper bits
|
||||
is unnecessary. Then JITs can take advantage of those markings and
|
||||
drastically reduce size of generated code and improve performance.
|
||||
A: NO.
|
||||
|
||||
But some optimizations on zero-ing the upper 32 bits for BPF registers are
|
||||
available, and can be leveraged to improve the performance of JITed BPF
|
||||
programs for 32-bit architectures.
|
||||
|
||||
Starting with version 7, LLVM is able to generate instructions that operate
|
||||
on 32-bit subregisters, provided the option -mattr=+alu32 is passed for
|
||||
compiling a program. Furthermore, the verifier can now mark the
|
||||
instructions for which zero-ing the upper bits of the destination register
|
||||
is required, and insert an explicit zero-extension (zext) instruction
|
||||
(a mov32 variant). This means that for architectures without zext hardware
|
||||
support, the JIT back-ends do not need to clear the upper bits for
|
||||
subregisters written by alu32 instructions or narrow loads. Instead, the
|
||||
back-ends simply need to support code generation for that mov32 variant,
|
||||
and to overwrite bpf_jit_needs_zext() to make it return "true" (in order to
|
||||
enable zext insertion in the verifier).
|
||||
|
||||
Note that it is possible for a JIT back-end to have partial hardware
|
||||
support for zext. In that case, if verifier zext insertion is enabled,
|
||||
it could lead to the insertion of unnecessary zext instructions. Such
|
||||
instructions could be removed by creating a simple peephole inside the JIT
|
||||
back-end: if one instruction has hardware support for zext and if the next
|
||||
instruction is an explicit zext, then the latter can be skipped when doing
|
||||
the code generation.
|
||||
|
||||
Q: Does BPF have a stable ABI?
|
||||
------------------------------
|
||||
|
|
|
@ -42,6 +42,7 @@ Program types
|
|||
.. toctree::
|
||||
:maxdepth: 1
|
||||
|
||||
prog_cgroup_sockopt
|
||||
prog_cgroup_sysctl
|
||||
prog_flow_dissector
|
||||
|
||||
|
|
|
@ -0,0 +1,93 @@
|
|||
.. SPDX-License-Identifier: GPL-2.0
|
||||
|
||||
============================
|
||||
BPF_PROG_TYPE_CGROUP_SOCKOPT
|
||||
============================
|
||||
|
||||
``BPF_PROG_TYPE_CGROUP_SOCKOPT`` program type can be attached to two
|
||||
cgroup hooks:
|
||||
|
||||
* ``BPF_CGROUP_GETSOCKOPT`` - called every time process executes ``getsockopt``
|
||||
system call.
|
||||
* ``BPF_CGROUP_SETSOCKOPT`` - called every time process executes ``setsockopt``
|
||||
system call.
|
||||
|
||||
The context (``struct bpf_sockopt``) has associated socket (``sk``) and
|
||||
all input arguments: ``level``, ``optname``, ``optval`` and ``optlen``.
|
||||
|
||||
BPF_CGROUP_SETSOCKOPT
|
||||
=====================
|
||||
|
||||
``BPF_CGROUP_SETSOCKOPT`` is triggered *before* the kernel handling of
|
||||
sockopt and it has writable context: it can modify the supplied arguments
|
||||
before passing them down to the kernel. This hook has access to the cgroup
|
||||
and socket local storage.
|
||||
|
||||
If BPF program sets ``optlen`` to -1, the control will be returned
|
||||
back to the userspace after all other BPF programs in the cgroup
|
||||
chain finish (i.e. kernel ``setsockopt`` handling will *not* be executed).
|
||||
|
||||
Note, that ``optlen`` can not be increased beyond the user-supplied
|
||||
value. It can only be decreased or set to -1. Any other value will
|
||||
trigger ``EFAULT``.
|
||||
|
||||
Return Type
|
||||
-----------
|
||||
|
||||
* ``0`` - reject the syscall, ``EPERM`` will be returned to the userspace.
|
||||
* ``1`` - success, continue with next BPF program in the cgroup chain.
|
||||
|
||||
BPF_CGROUP_GETSOCKOPT
|
||||
=====================
|
||||
|
||||
``BPF_CGROUP_GETSOCKOPT`` is triggered *after* the kernel handing of
|
||||
sockopt. The BPF hook can observe ``optval``, ``optlen`` and ``retval``
|
||||
if it's interested in whatever kernel has returned. BPF hook can override
|
||||
the values above, adjust ``optlen`` and reset ``retval`` to 0. If ``optlen``
|
||||
has been increased above initial ``getsockopt`` value (i.e. userspace
|
||||
buffer is too small), ``EFAULT`` is returned.
|
||||
|
||||
This hook has access to the cgroup and socket local storage.
|
||||
|
||||
Note, that the only acceptable value to set to ``retval`` is 0 and the
|
||||
original value that the kernel returned. Any other value will trigger
|
||||
``EFAULT``.
|
||||
|
||||
Return Type
|
||||
-----------
|
||||
|
||||
* ``0`` - reject the syscall, ``EPERM`` will be returned to the userspace.
|
||||
* ``1`` - success: copy ``optval`` and ``optlen`` to userspace, return
|
||||
``retval`` from the syscall (note that this can be overwritten by
|
||||
the BPF program from the parent cgroup).
|
||||
|
||||
Cgroup Inheritance
|
||||
==================
|
||||
|
||||
Suppose, there is the following cgroup hierarchy where each cgroup
|
||||
has ``BPF_CGROUP_GETSOCKOPT`` attached at each level with
|
||||
``BPF_F_ALLOW_MULTI`` flag::
|
||||
|
||||
A (root, parent)
|
||||
\
|
||||
B (child)
|
||||
|
||||
When the application calls ``getsockopt`` syscall from the cgroup B,
|
||||
the programs are executed from the bottom up: B, A. First program
|
||||
(B) sees the result of kernel's ``getsockopt``. It can optionally
|
||||
adjust ``optval``, ``optlen`` and reset ``retval`` to 0. After that
|
||||
control will be passed to the second (A) program which will see the
|
||||
same context as B including any potential modifications.
|
||||
|
||||
Same for ``BPF_CGROUP_SETSOCKOPT``: if the program is attached to
|
||||
A and B, the trigger order is B, then A. If B does any changes
|
||||
to the input arguments (``level``, ``optname``, ``optval``, ``optlen``),
|
||||
then the next program in the chain (A) will see those changes,
|
||||
*not* the original input ``setsockopt`` arguments. The potentially
|
||||
modified values will be then passed down to the kernel.
|
||||
|
||||
Example
|
||||
=======
|
||||
|
||||
See ``tools/testing/selftests/bpf/progs/sockopt_sk.c`` for an example
|
||||
of BPF program that handles socket options.
|
|
@ -9,6 +9,8 @@ Required Properties:
|
|||
- "mediatek,mt7622-sgmiisys", "syscon"
|
||||
- "mediatek,mt7629-sgmiisys", "syscon"
|
||||
- #clock-cells: Must be 1
|
||||
- mediatek,physpeed: Should be one of "auto", "1000" or "2500" to match up
|
||||
the capability of the target PHY.
|
||||
|
||||
The SGMIISYS controller uses the common clk binding from
|
||||
Documentation/devicetree/bindings/clock/clock-bindings.txt
|
||||
|
|
|
@ -16,6 +16,8 @@ Required properties:
|
|||
Optional properties:
|
||||
|
||||
- reset-gpios : Should be a gpio specifier for a reset line
|
||||
- microchip,synclko-125 : Set if the output SYNCLKO frequency should be set to
|
||||
125MHz instead of 25MHz.
|
||||
|
||||
See Documentation/devicetree/bindings/net/dsa/dsa.txt for a list of additional
|
||||
required and optional properties.
|
||||
|
|
|
@ -21,10 +21,13 @@ which is at a different MDIO base address in different switch families.
|
|||
6341, 6350, 6351, 6352
|
||||
- "marvell,mv88e6190" : Switch has base address 0x00. Use with models:
|
||||
6190, 6190X, 6191, 6290, 6390, 6390X
|
||||
- "marvell,mv88e6250" : Switch has base address 0x08 or 0x18. Use with model:
|
||||
6250
|
||||
|
||||
Required properties:
|
||||
- compatible : Should be one of "marvell,mv88e6085" or
|
||||
"marvell,mv88e6190" as indicated above
|
||||
- compatible : Should be one of "marvell,mv88e6085",
|
||||
"marvell,mv88e6190" or "marvell,mv88e6250" as
|
||||
indicated above
|
||||
- reg : Address on the MII bus for the switch.
|
||||
|
||||
Optional properties:
|
||||
|
|
|
@ -9,6 +9,10 @@ Required properties:
|
|||
- #size-cells: must be 0
|
||||
- #address-cells: must be 1
|
||||
|
||||
Optional properties:
|
||||
|
||||
- reset-gpios: GPIO to be used to reset the whole device
|
||||
|
||||
Subnodes:
|
||||
|
||||
The integrated switch subnode should be specified according to the binding
|
||||
|
@ -66,6 +70,7 @@ for the external mdio-bus configuration:
|
|||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
reset-gpios = <&gpio 42 GPIO_ACTIVE_LOW>;
|
||||
reg = <0x10>;
|
||||
|
||||
ports {
|
||||
|
@ -123,6 +128,7 @@ for the internal master mdio-bus configuration:
|
|||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
reset-gpios = <&gpio 42 GPIO_ACTIVE_LOW>;
|
||||
reg = <0x10>;
|
||||
|
||||
ports {
|
||||
|
|
|
@ -2,8 +2,8 @@ Vitesse VSC73xx Switches
|
|||
========================
|
||||
|
||||
This defines device tree bindings for the Vitesse VSC73xx switch chips.
|
||||
The Vitesse company has been acquired by Microsemi and Microsemi in turn
|
||||
acquired by Microchip but retains this vendor branding.
|
||||
The Vitesse company has been acquired by Microsemi and Microsemi has
|
||||
been acquired Microchip but retains this vendor branding.
|
||||
|
||||
The currently supported switch chips are:
|
||||
Vitesse VSC7385 SparX-G5 5+1-port Integrated Gigabit Ethernet Switch
|
||||
|
@ -11,8 +11,14 @@ Vitesse VSC7388 SparX-G8 8-port Integrated Gigabit Ethernet Switch
|
|||
Vitesse VSC7395 SparX-G5e 5+1-port Integrated Gigabit Ethernet Switch
|
||||
Vitesse VSC7398 SparX-G8e 8-port Integrated Gigabit Ethernet Switch
|
||||
|
||||
The device tree node is an SPI device so it must reside inside a SPI bus
|
||||
device tree node, see spi/spi-bus.txt
|
||||
This switch could have two different management interface.
|
||||
|
||||
If SPI interface is used, the device tree node is an SPI device so it must
|
||||
reside inside a SPI bus device tree node, see spi/spi-bus.txt
|
||||
|
||||
When the chip is connected to a parallel memory bus and work in memory-mapped
|
||||
I/O mode, a platform device is used to represent the vsc73xx. In this case it
|
||||
must reside inside a platform bus device tree node.
|
||||
|
||||
Required properties:
|
||||
|
||||
|
@ -38,6 +44,7 @@ and subnodes of DSA switches.
|
|||
|
||||
Examples:
|
||||
|
||||
SPI:
|
||||
switch@0 {
|
||||
compatible = "vitesse,vsc7395";
|
||||
reg = <0>;
|
||||
|
@ -79,3 +86,46 @@ switch@0 {
|
|||
};
|
||||
};
|
||||
};
|
||||
|
||||
Platform:
|
||||
switch@2,0 {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
compatible = "vitesse,vsc7385";
|
||||
reg = <0x2 0x0 0x20000>;
|
||||
reset-gpios = <&gpio0 12 GPIO_ACTIVE_LOW>;
|
||||
|
||||
ports {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
port@0 {
|
||||
reg = <0>;
|
||||
label = "lan1";
|
||||
};
|
||||
port@1 {
|
||||
reg = <1>;
|
||||
label = "lan2";
|
||||
};
|
||||
port@2 {
|
||||
reg = <2>;
|
||||
label = "lan3";
|
||||
};
|
||||
port@3 {
|
||||
reg = <3>;
|
||||
label = "lan4";
|
||||
};
|
||||
vsc: port@6 {
|
||||
reg = <6>;
|
||||
label = "cpu";
|
||||
ethernet = <&enet0>;
|
||||
phy-mode = "rgmii";
|
||||
fixed-link {
|
||||
speed = <1000>;
|
||||
full-duplex;
|
||||
pause;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
};
|
||||
|
|
|
@ -43,6 +43,7 @@ Documentation/devicetree/bindings/phy/phy-bindings.txt.
|
|||
* "rxaui"
|
||||
* "xaui"
|
||||
* "10gbase-kr" (10GBASE-KR, XFI, SFI)
|
||||
* "usxgmii"
|
||||
- phy-connection-type: the same as "phy-mode" property but described in the
|
||||
Devicetree Specification;
|
||||
- phy-handle: phandle, specifies a reference to a node representing a PHY
|
||||
|
|
|
@ -10,6 +10,7 @@ Required properties:
|
|||
phandle, specifies a reference to the syscon ppe node
|
||||
port, port number connected to the controller
|
||||
channel, recv channel start from channel * number (RX_DESC_NUM)
|
||||
group, field in the pkg desc, in general, it is the same as the port.
|
||||
- phy-mode: see ethernet.txt [1].
|
||||
|
||||
Optional properties:
|
||||
|
@ -66,7 +67,7 @@ Example:
|
|||
reg = <0x28b0000 0x10000>;
|
||||
interrupts = <0 413 4>;
|
||||
phy-mode = "mii";
|
||||
port-handle = <&ppe 31 0>;
|
||||
port-handle = <&ppe 31 0 31>;
|
||||
};
|
||||
|
||||
ge0: ethernet@2800000 {
|
||||
|
@ -74,7 +75,7 @@ Example:
|
|||
reg = <0x2800000 0x10000>;
|
||||
interrupts = <0 402 4>;
|
||||
phy-mode = "sgmii";
|
||||
port-handle = <&ppe 0 1>;
|
||||
port-handle = <&ppe 0 1 0>;
|
||||
phy-handle = <&phy0>;
|
||||
};
|
||||
|
||||
|
@ -83,6 +84,6 @@ Example:
|
|||
reg = <0x2880000 0x10000>;
|
||||
interrupts = <0 410 4>;
|
||||
phy-mode = "sgmii";
|
||||
port-handle = <&ppe 8 2>;
|
||||
port-handle = <&ppe 8 2 8>;
|
||||
phy-handle = <&phy1>;
|
||||
};
|
||||
|
|
|
@ -104,6 +104,23 @@ Required properties:
|
|||
- 10Gb mac<->mac forced mode : 11
|
||||
----phy-handle: phandle to PHY device
|
||||
|
||||
- cpts: sub-node time synchronization (CPTS) submodule configuration
|
||||
-- clocks: CPTS reference clock. Should point on cpts-refclk-mux clock.
|
||||
-- clock-names: should be "cpts"
|
||||
-- cpts-refclk-mux: multiplexer clock definition sub-node for CPTS reference (RFTCLK) clock
|
||||
--- #clock-cells: should be 0
|
||||
--- clocks: list of CPTS reference (RFTCLK) clock's parents as defined in Data manual
|
||||
--- ti,mux-tbl: array of multiplexer indexes as defined in Data manual
|
||||
--- assigned-clocks: should point on cpts-refclk-mux clock
|
||||
--- assigned-clock-parents: should point on required RFTCLK clock parent to be selected
|
||||
-- cpts_clock_mult: (optional) Numerator to convert input clock ticks
|
||||
into nanoseconds
|
||||
-- cpts_clock_shift: (optional) Denominator to convert input clock ticks into
|
||||
nanoseconds.
|
||||
Mult and shift will be calculated basing on CPTS
|
||||
rftclk frequency if both cpts_clock_shift and
|
||||
cpts_clock_mult properties are not provided.
|
||||
|
||||
Optional properties:
|
||||
- enable-ale: NetCP driver keeps the address learning feature in the ethernet
|
||||
switch module disabled. This attribute is to enable the address
|
||||
|
@ -168,6 +185,23 @@ netcp: netcp@2000000 {
|
|||
tx-queue = <648>;
|
||||
tx-channel = <8>;
|
||||
|
||||
cpts {
|
||||
clocks = <&cpts_refclk_mux>;
|
||||
clock-names = "cpts";
|
||||
|
||||
cpts_refclk_mux: cpts-refclk-mux {
|
||||
#clock-cells = <0>;
|
||||
clocks = <&chipclk12>, <&chipclk13>,
|
||||
<&timi0>, <&timi1>,
|
||||
<&tsipclka>, <&tsrefclk>,
|
||||
<&tsipclkb>;
|
||||
ti,mux-tbl = <0x0>, <0x1>, <0x2>,
|
||||
<0x3>, <0x4>, <0x8>, <0xC>;
|
||||
assigned-clocks = <&cpts_refclk_mux>;
|
||||
assigned-clock-parents = <&chipclk12>;
|
||||
};
|
||||
};
|
||||
|
||||
interfaces {
|
||||
gbe0: interface-0 {
|
||||
slave-port = <0>;
|
||||
|
@ -219,3 +253,13 @@ netcp: netcp@2000000 {
|
|||
};
|
||||
};
|
||||
};
|
||||
|
||||
CPTS board configuration - select external CPTS RFTCLK:
|
||||
|
||||
&tsrefclk{
|
||||
clock-frequency = <500000000>;
|
||||
};
|
||||
|
||||
&cpts_refclk_mux {
|
||||
assigned-clock-parents = <&tsrefclk>;
|
||||
};
|
||||
|
|
|
@ -15,8 +15,11 @@ Required properties:
|
|||
Use "atmel,sama5d4-gem" for the GEM IP (10/100) available on Atmel sama5d4 SoCs.
|
||||
Use "cdns,zynq-gem" Xilinx Zynq-7xxx SoC.
|
||||
Use "cdns,zynqmp-gem" for Zynq Ultrascale+ MPSoC.
|
||||
Use "sifive,fu540-macb" for SiFive FU540-C000 SoC.
|
||||
Or the generic form: "cdns,emac".
|
||||
- reg: Address and length of the register set for the device
|
||||
For "sifive,fu540-macb", second range is required to specify the
|
||||
address and length of the registers for GEMGXL Management block.
|
||||
- interrupts: Should contain macb interrupt
|
||||
- phy-mode: See ethernet.txt file in the same directory.
|
||||
- clock-names: Tuple listing input clock names.
|
||||
|
|
|
@ -0,0 +1,25 @@
|
|||
Marvell Bluetooth Chips
|
||||
-----------------------
|
||||
|
||||
This documents the binding structure and common properties for serial
|
||||
attached Marvell Bluetooth devices. The following chips are included in
|
||||
this binding:
|
||||
|
||||
* Marvell 88W8897 Bluetooth devices
|
||||
|
||||
Required properties:
|
||||
- compatible: should be:
|
||||
"mrvl,88w8897"
|
||||
|
||||
Optional properties:
|
||||
None so far
|
||||
|
||||
Example:
|
||||
|
||||
&serial0 {
|
||||
compatible = "ns16550a";
|
||||
...
|
||||
bluetooth {
|
||||
compatible = "mrvl,88w8897";
|
||||
};
|
||||
};
|
|
@ -16,7 +16,7 @@ Required properties:
|
|||
|
||||
Optional properties:
|
||||
- interrupts: interrupt line number for the SMI error/done interrupt
|
||||
- clocks: phandle for up to three required clocks for the MDIO instance
|
||||
- clocks: phandle for up to four required clocks for the MDIO instance
|
||||
|
||||
The child nodes of the MDIO driver are the individual PHY devices
|
||||
connected to this MDIO bus. They must have a "reg" property given the
|
||||
|
|
|
@ -50,16 +50,33 @@ Required properties:
|
|||
"mediatek,mt7663u-bluetooth": for MT7663U device
|
||||
"mediatek,mt7668u-bluetooth": for MT7668U device
|
||||
- vcc-supply: Main voltage regulator
|
||||
|
||||
If the pin controller on the platform can support both pinmux and GPIO
|
||||
control such as the most of MediaTek platform. Please use below properties.
|
||||
|
||||
- pinctrl-names: Should be "default", "runtime"
|
||||
- pinctrl-0: Should contain UART RXD low when the device is powered up to
|
||||
enter proper bootstrap mode.
|
||||
- pinctrl-1: Should contain UART mode pin ctrl
|
||||
|
||||
Else, the pin controller on the platform only can support pinmux control and
|
||||
the GPIO control still has to rely on the dedicated GPIO controller such as
|
||||
a legacy MediaTek SoC, MT7621. Please use the below properties.
|
||||
|
||||
- boot-gpios: GPIO same to the pin as UART RXD and used to keep LOW when
|
||||
the device is powered up to enter proper bootstrap mode when
|
||||
- pinctrl-names: Should be "default"
|
||||
- pinctrl-0: Should contain UART mode pin ctrl
|
||||
|
||||
Optional properties:
|
||||
|
||||
- reset-gpios: GPIO used to reset the device whose initial state keeps low,
|
||||
if the GPIO is missing, then board-level design should be
|
||||
guaranteed.
|
||||
- clocks: Should be the clock specifiers corresponding to the entry in
|
||||
clock-names property. If the clock is missing, then board-level
|
||||
design should be guaranteed.
|
||||
- clock-names: Should contain "osc" entry for the external oscillator.
|
||||
- current-speed: Current baud rate of the device whose defaults to 921600
|
||||
|
||||
Example:
|
||||
|
|
|
@ -11,6 +11,7 @@ Required properties:
|
|||
"mediatek,mt2701-eth": for MT2701 SoC
|
||||
"mediatek,mt7623-eth", "mediatek,mt2701-eth": for MT7623 SoC
|
||||
"mediatek,mt7622-eth": for MT7622 SoC
|
||||
"mediatek,mt7629-eth": for MT7629 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.
|
||||
|
@ -19,14 +20,23 @@ Required properties:
|
|||
"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
|
||||
"ethif", "sgmiitop", "esw", "gp0", "gp1", "gp2", "fe", "sgmii_tx250m",
|
||||
"sgmii_rx250m", "sgmii_cdr_ref", "sgmii_cdr_fb", "sgmii2_tx250m",
|
||||
"sgmii2_rx250m", "sgmii2_cdr_ref", "sgmii2_cdr_fb", "sgmii_ck",
|
||||
"eth2pll" : For MT7629 SoC.
|
||||
- power-domains: phandle to the power domain that the ethernet is part of
|
||||
- resets: Should contain phandles to the ethsys reset signals
|
||||
- reset-names: Should contain the names of reset signal listed in the resets
|
||||
property
|
||||
These are "fe", "gmac" and "ppe"
|
||||
- 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,infracfg: phandle to the syscon node that handles the path from
|
||||
GMAC to PHY variants, which is required for MT7629 SoC.
|
||||
- mediatek,sgmiisys: a list of phandles to the syscon node that handles the
|
||||
SGMII setup which is required for those SoCs equipped with SGMII such
|
||||
as MT7622 and MT7629 SoC. And MT7622 have only one set of SGMII shared
|
||||
by GMAC1 and GMAC2; MT7629 have two independent sets of SGMII directed
|
||||
to GMAC1 and GMAC2, respectively.
|
||||
- mediatek,pctl: phandle to the syscon node that handles the ports slew rate
|
||||
and driver current: only for MT2701 and MT7623 SoC
|
||||
|
||||
|
|
|
@ -0,0 +1,45 @@
|
|||
Required properties:
|
||||
- compatible: Should be "qca,<soc>-eth". Currently support compatibles are:
|
||||
qca,ar7100-eth - Atheros AR7100
|
||||
qca,ar7240-eth - Atheros AR7240
|
||||
qca,ar7241-eth - Atheros AR7241
|
||||
qca,ar7242-eth - Atheros AR7242
|
||||
qca,ar9130-eth - Atheros AR9130
|
||||
qca,ar9330-eth - Atheros AR9330
|
||||
qca,ar9340-eth - Atheros AR9340
|
||||
qca,qca9530-eth - Qualcomm Atheros QCA9530
|
||||
qca,qca9550-eth - Qualcomm Atheros QCA9550
|
||||
qca,qca9560-eth - Qualcomm Atheros QCA9560
|
||||
|
||||
- reg : Address and length of the register set for the device
|
||||
- interrupts : Should contain eth interrupt
|
||||
- phy-mode : See ethernet.txt file in the same directory
|
||||
- clocks: the clock used by the core
|
||||
- clock-names: the names of the clock listed in the clocks property. These are
|
||||
"eth" and "mdio".
|
||||
- resets: Should contain phandles to the reset signals
|
||||
- reset-names: Should contain the names of reset signal listed in the resets
|
||||
property. These are "mac" and "mdio"
|
||||
|
||||
Optional properties:
|
||||
- phy-handle : phandle to the PHY device connected to this device.
|
||||
- fixed-link : Assume a fixed link. See fixed-link.txt in the same directory.
|
||||
Use instead of phy-handle.
|
||||
|
||||
Optional subnodes:
|
||||
- mdio : specifies the mdio bus, used as a container for phy nodes
|
||||
according to phy.txt in the same directory
|
||||
|
||||
Example:
|
||||
|
||||
ethernet@1a000000 {
|
||||
compatible = "qca,ar9330-eth";
|
||||
reg = <0x1a000000 0x200>;
|
||||
interrupts = <5>;
|
||||
resets = <&rst 13>, <&rst 23>;
|
||||
reset-names = "mac", "mdio";
|
||||
clocks = <&pll ATH79_CLK_AHB>, <&pll ATH79_CLK_MDIO>;
|
||||
clock-names = "eth", "mdio";
|
||||
|
||||
phy-mode = "gmii";
|
||||
};
|
|
@ -17,6 +17,7 @@ Optional properties for compatible string qcom,qca6174-bt:
|
|||
|
||||
- enable-gpios: gpio specifier used to enable chip
|
||||
- clocks: clock provided to the controller (SUSCLK_32KHZ)
|
||||
- firmware-name: specify the name of nvm firmware to load
|
||||
|
||||
Required properties for compatible string qcom,wcn399x-bt:
|
||||
|
||||
|
@ -28,6 +29,7 @@ Required properties for compatible string qcom,wcn399x-bt:
|
|||
Optional properties for compatible string qcom,wcn399x-bt:
|
||||
|
||||
- max-speed: see Documentation/devicetree/bindings/serial/slave-device.txt
|
||||
- firmware-name: specify the name of nvm firmware to load
|
||||
|
||||
Examples:
|
||||
|
||||
|
@ -40,6 +42,7 @@ serial@7570000 {
|
|||
|
||||
enable-gpios = <&pm8994_gpios 19 GPIO_ACTIVE_HIGH>;
|
||||
clocks = <&divclk4>;
|
||||
firmware-name = "nvm_00440302.bin";
|
||||
};
|
||||
};
|
||||
|
||||
|
@ -52,5 +55,6 @@ serial@898000 {
|
|||
vddrf-supply = <&vreg_l17a_1p3>;
|
||||
vddch0-supply = <&vreg_l25a_3p3>;
|
||||
max-speed = <3200000>;
|
||||
firmware-name = "crnv21.bin";
|
||||
};
|
||||
};
|
||||
|
|
|
@ -6,11 +6,17 @@ present in Documentation/devicetree/bindings/net/stmmac.txt.
|
|||
The device node has additional properties:
|
||||
|
||||
Required properties:
|
||||
- compatible : Should contain "altr,socfpga-stmmac" along with
|
||||
"snps,dwmac" and any applicable more detailed
|
||||
- compatible : For Cyclone5/Arria5 SoCs it should contain
|
||||
"altr,socfpga-stmmac". For Arria10/Agilex/Stratix10 SoCs
|
||||
"altr,socfpga-stmmac-a10-s10".
|
||||
Along with "snps,dwmac" and any applicable more detailed
|
||||
designware version numbers documented in stmmac.txt
|
||||
- altr,sysmgr-syscon : Should be the phandle to the system manager node that
|
||||
encompasses the glue register, the register offset, and the register shift.
|
||||
On Cyclone5/Arria5, the register shift represents the PHY mode bits, while
|
||||
on the Arria10/Stratix10/Agilex platforms, the register shift represents
|
||||
bit for each emac to enable/disable signals from the FPGA fabric to the
|
||||
EMAC modules.
|
||||
- altr,f2h_ptp_ref_clk use f2h_ptp_ref_clk instead of default eosc1 clock
|
||||
for ptp ref clk. This affects all emacs as the clock is common.
|
||||
|
||||
|
|
|
@ -11,6 +11,14 @@ Required properties:
|
|||
- ti,fifo-depth - Transmitt FIFO depth- see dt-bindings/net/ti-dp83867.h
|
||||
for applicable values
|
||||
|
||||
Note: If the interface type is PHY_INTERFACE_MODE_RGMII the TX/RX clock delays
|
||||
will be left at their default values, as set by the PHY's pin strapping.
|
||||
The default strapping will use a delay of 2.00 ns. Thus
|
||||
PHY_INTERFACE_MODE_RGMII, by default, does not behave as RGMII with no
|
||||
internal delay, but as PHY_INTERFACE_MODE_RGMII_ID. The device tree
|
||||
should use "rgmii-id" if internal delays are desired as this may be
|
||||
changed in future to cause "rgmii" mode to disable delays.
|
||||
|
||||
Optional property:
|
||||
- ti,min-output-impedance - MAC Interface Impedance control to set
|
||||
the programmable output impedance to
|
||||
|
@ -25,8 +33,10 @@ Optional property:
|
|||
software needs to take when this pin is
|
||||
strapped in these modes. See data manual
|
||||
for details.
|
||||
- ti,clk-output-sel - Muxing option for CLK_OUT pin - see dt-bindings/net/ti-dp83867.h
|
||||
for applicable values.
|
||||
- ti,clk-output-sel - Muxing option for CLK_OUT pin. See dt-bindings/net/ti-dp83867.h
|
||||
for applicable values. The CLK_OUT pin can also
|
||||
be disabled by this property. When omitted, the
|
||||
PHY's default will be left as is.
|
||||
|
||||
Note: ti,min-output-impedance and ti,max-output-impedance are mutually
|
||||
exclusive. When both properties are present ti,max-output-impedance
|
||||
|
|
|
@ -0,0 +1,50 @@
|
|||
* Wiznet w5x00
|
||||
|
||||
This is a standalone 10/100 MBit Ethernet controller with SPI interface.
|
||||
|
||||
For each device connected to a SPI bus, define a child node within
|
||||
the SPI master node.
|
||||
|
||||
Required properties:
|
||||
- compatible: Should be one of the following strings:
|
||||
"wiznet,w5100"
|
||||
"wiznet,w5200"
|
||||
"wiznet,w5500"
|
||||
- reg: Specify the SPI chip select the chip is wired to.
|
||||
- interrupts: Specify the interrupt index within the interrupt controller (referred
|
||||
to above in interrupt-parent) and interrupt type. w5x00 natively
|
||||
generates falling edge interrupts, however, additional board logic
|
||||
might invert the signal.
|
||||
- pinctrl-names: List of assigned state names, see pinctrl binding documentation.
|
||||
- pinctrl-0: List of phandles to configure the GPIO pin used as interrupt line,
|
||||
see also generic and your platform specific pinctrl binding
|
||||
documentation.
|
||||
|
||||
Optional properties:
|
||||
- spi-max-frequency: Maximum frequency of the SPI bus when accessing the w5500.
|
||||
According to the w5500 datasheet, the chip allows a maximum of 80 MHz, however,
|
||||
board designs may need to limit this value.
|
||||
- local-mac-address: See ethernet.txt in the same directory.
|
||||
|
||||
|
||||
Example (for Raspberry Pi with pin control stuff for GPIO irq):
|
||||
|
||||
&spi {
|
||||
ethernet@0: w5500@0 {
|
||||
compatible = "wiznet,w5500";
|
||||
reg = <0>;
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <ð1_pins>;
|
||||
interrupt-parent = <&gpio>;
|
||||
interrupts = <25 IRQ_TYPE_EDGE_FALLING>;
|
||||
spi-max-frequency = <30000000>;
|
||||
};
|
||||
};
|
||||
|
||||
&gpio {
|
||||
eth1_pins: eth1_pins {
|
||||
brcm,pins = <25>;
|
||||
brcm,function = <0>; /* in */
|
||||
brcm,pull = <0>; /* none */
|
||||
};
|
||||
};
|
|
@ -17,8 +17,15 @@ 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.
|
||||
- reg : Address and length of the IO space, as well as the address
|
||||
and length of the AXI DMA controller IO space, unless
|
||||
axistream-connected is specified, in which case the reg
|
||||
attribute of the node referenced by it is used.
|
||||
- interrupts : Should be a list of 2 or 3 interrupts: TX DMA, RX DMA,
|
||||
and optionally Ethernet core. If axistream-connected is
|
||||
specified, the TX/RX DMA interrupts should be on that node
|
||||
instead, and only the Ethernet core interrupt is optionally
|
||||
specified here.
|
||||
- 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
|
||||
|
@ -31,15 +38,29 @@ Optional properties:
|
|||
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
|
||||
- clocks : AXI bus clock for the device. Refer to common clock bindings.
|
||||
Used to calculate MDIO clock divisor. If not specified, it is
|
||||
auto-detected from the CPU clock (but only on platforms where
|
||||
this is possible). New device trees should specify this - the
|
||||
auto detection is only for backward compatibility.
|
||||
- axistream-connected: Reference to another node which contains the resources
|
||||
for the AXI DMA controller used by this device.
|
||||
If this is specified, the DMA-related resources from that
|
||||
device (DMA registers and DMA TX/RX interrupts) rather
|
||||
than this one will be used.
|
||||
- mdio : Child node for MDIO bus. Must be defined if PHY access is
|
||||
required through the core's MDIO interface (i.e. always,
|
||||
unless the PHY is accessed through a different bus).
|
||||
|
||||
Example:
|
||||
axi_ethernet_eth: ethernet@40c00000 {
|
||||
compatible = "xlnx,axi-ethernet-1.00.a";
|
||||
device_type = "network";
|
||||
interrupt-parent = <µblaze_0_axi_intc>;
|
||||
interrupts = <2 0>;
|
||||
interrupts = <2 0 1>;
|
||||
clocks = <&axi_clk>;
|
||||
phy-mode = "mii";
|
||||
reg = <0x40c00000 0x40000>;
|
||||
reg = <0x40c00000 0x40000 0x50c00000 0x40000>;
|
||||
xlnx,rxcsum = <0x2>;
|
||||
xlnx,rxmem = <0x800>;
|
||||
xlnx,txcsum = <0x2>;
|
||||
|
|
|
@ -4,6 +4,8 @@ General Properties:
|
|||
|
||||
- compatible Should be "fsl,etsec-ptp" for eTSEC
|
||||
Should be "fsl,fman-ptp-timer" for DPAA FMan
|
||||
Should be "fsl,dpaa2-ptp" for DPAA2
|
||||
Should be "fsl,enetc-ptp" for ENETC
|
||||
- reg Offset and length of the register set for the device
|
||||
- interrupts There should be at least two interrupts. Some devices
|
||||
have as many as four PTP related interrupts.
|
||||
|
|
|
@ -226,9 +226,6 @@ TBD
|
|||
.. kernel-doc:: include/net/mac80211.h
|
||||
:functions: ieee80211_tx_rate_control
|
||||
|
||||
.. kernel-doc:: include/net/mac80211.h
|
||||
:functions: rate_control_send_low
|
||||
|
||||
TBD
|
||||
|
||||
This part of the book describes mac80211 internals.
|
||||
|
|
|
@ -1,96 +0,0 @@
|
|||
-----BEGIN PGP SIGNED MESSAGE-----
|
||||
|
||||
First:
|
||||
|
||||
HiSax is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
However, if you wish to modify the HiSax sources, please note the following:
|
||||
|
||||
HiSax has passed the ITU approval test suite with ELSA Quickstep ISDN cards
|
||||
and Eicon Technology Diva 2.01 PCI card.
|
||||
The certification is only valid for the combination of the tested software
|
||||
version and the tested hardware. Any changes to the HiSax source code may
|
||||
therefore affect the certification.
|
||||
|
||||
Additional ITU approval tests have been carried out for all generic cards
|
||||
using Colognechip single chip solutions HFC-S PCI A for PCI cards as well
|
||||
as HFC-S USB based USB ISDN ta adapters.
|
||||
These tests included all layers 1-3 and as well all functional tests for
|
||||
the layer 1. Because all hardware based on these chips are complete ISDN
|
||||
solutions in one chip all cards and USB-TAs using these chips are to be
|
||||
regarded as approved for those tests. Some additional electrical tests
|
||||
of the layer 1 which are independent of the driver and related to a
|
||||
special hardware used will be regarded as approved if at least one
|
||||
solution has been tested including those electrical tests. So if cards
|
||||
or tas have been completely approved for any other os, the approval
|
||||
for those electrical tests is valid for linux, too.
|
||||
Please send any questions regarding this drivers or approval abouts to
|
||||
werner@isdn-development.de
|
||||
Additional information and the type approval documents will be found
|
||||
shortly on the Colognechip website www.colognechip.com
|
||||
|
||||
If you change the main files of the HiSax ISDN stack, the certification will
|
||||
become invalid. Because in most countries it is illegal to connect
|
||||
unapproved ISDN equipment to the public network, I have to guarantee that
|
||||
changes in HiSax do not affect the certification.
|
||||
|
||||
In order to make a valid certification apparent to the user, I have built in
|
||||
some validation checks that are made during the make process. The HiSax main
|
||||
files are protected by md5 checksums and the md5sum file is pgp signed by
|
||||
myself:
|
||||
|
||||
KeyID 1024/FF992F6D 1997/01/16 Karsten Keil <kkeil@suse.de>
|
||||
Key fingerprint = 92 6B F7 58 EE 86 28 C8 C4 1A E6 DC 39 89 F2 AA
|
||||
|
||||
Only if the checksums are OK, and the signature of the file
|
||||
"drivers/isdn/hisax/md5sums.asc" match, is the certification valid; a
|
||||
message confirming this is then displayed during the hisax init process.
|
||||
|
||||
The affected files are:
|
||||
|
||||
drivers/isdn/hisax/isac.c
|
||||
drivers/isdn/hisax/isdnl1.c
|
||||
drivers/isdn/hisax/isdnl2.c
|
||||
drivers/isdn/hisax/isdnl3.c
|
||||
drivers/isdn/hisax/tei.c
|
||||
drivers/isdn/hisax/callc.c
|
||||
drivers/isdn/hisax/l3dss1.c
|
||||
drivers/isdn/hisax/l3_1tr6.c
|
||||
drivers/isdn/hisax/cert.c
|
||||
drivers/isdn/hisax/elsa.c
|
||||
drivers/isdn/hisax/diva.c
|
||||
drivers/isdn/hisax/hfc_pci.c
|
||||
|
||||
Please send any changes, bugfixes and patches to me rather than implementing
|
||||
them directly into the HiSax sources.
|
||||
|
||||
This does not reduce your rights granted by the GNU General Public License.
|
||||
If you wish to change the sources, go ahead; but note that then the
|
||||
certification is invalid even if you use one of the approved cards.
|
||||
|
||||
Here are the certification registration numbers for ELSA Quickstep cards:
|
||||
German D133361J CETECOM ICT Services GmbH 0682
|
||||
European D133362J CETECOM ICT Services GmbH 0682
|
||||
|
||||
|
||||
Karsten Keil
|
||||
keil@isdn4linux.de
|
||||
|
||||
-----BEGIN PGP SIGNATURE-----
|
||||
Version: 2.6.3i
|
||||
Charset: noconv
|
||||
|
||||
iQCVAwUBOFAwqTpxHvX/mS9tAQFI2QP9GLDK2iy/KBhwReE3F7LeO+tVhffTVZ3a
|
||||
20q5/z/WcIg/pnH0uTkl2UgDXBFXYl45zJyDGNpAposIFmT+Edd14o7Vj1w/BBdn
|
||||
Y+5rBmJf+gyBu61da5d6bv0lpymwRa/um+ri+ilYnZ/XPfg5JKhdjGSBCJuJAElM
|
||||
d2jFbTrsMYw=
|
||||
=LNf9
|
||||
-----END PGP SIGNATURE-----
|
|
@ -1,759 +0,0 @@
|
|||
$Id: INTERFACE,v 1.15.8.2 2001/03/13 16:17:07 kai Exp $
|
||||
|
||||
Description of the Interface between Linklevel and Hardwarelevel
|
||||
of isdn4linux:
|
||||
|
||||
|
||||
The Communication between Linklevel (LL) and Hardwarelevel (HL)
|
||||
is based on the struct isdn_if (defined in isdnif.h).
|
||||
|
||||
An HL-driver can register itself at LL by calling the function
|
||||
register_isdn() with a pointer to that struct. Prior to that, it has
|
||||
to preset some of the fields of isdn_if. The LL sets the rest of
|
||||
the fields. All further communication is done via callbacks using
|
||||
the function-pointers defined in isdn_if.
|
||||
|
||||
Changes/Version numbering:
|
||||
|
||||
During development of the ISDN subsystem, several changes have been
|
||||
made to the interface. Before it went into kernel, the package
|
||||
had a unique version number. The last version, distributed separately
|
||||
was 0.7.4. When the subsystem went into kernel, every functional unit
|
||||
got a separate version number. These numbers are shown at initialization,
|
||||
separated by slashes:
|
||||
|
||||
c.c/t.t/n.n/p.p/a.a/v.v
|
||||
|
||||
where
|
||||
|
||||
c.c is the revision of the common code.
|
||||
t.t is the revision of the tty related code.
|
||||
n.n is the revision of the network related code.
|
||||
p.p is the revision of the ppp related code.
|
||||
a.a is the revision of the audio related code.
|
||||
v.v is the revision of the V.110 related code.
|
||||
|
||||
Changes in this document are marked with '***CHANGEx' where x representing
|
||||
the version number. If that number starts with 0, it refers to the old,
|
||||
separately distributed package. If it starts with one of the letters
|
||||
above, it refers to the revision of the corresponding module.
|
||||
***CHANGEIx refers to the revision number of the isdnif.h
|
||||
|
||||
1. Description of the fields of isdn_if:
|
||||
|
||||
int channels;
|
||||
|
||||
This field has to be set by the HL-driver to the number of channels
|
||||
supported prior to calling register_isdn(). Upon return of the call,
|
||||
the LL puts an id there, which has to be used by the HL-driver when
|
||||
invoking the other callbacks.
|
||||
|
||||
int maxbufsize;
|
||||
|
||||
***CHANGE0.6: New since this version.
|
||||
|
||||
Also to be preset by the HL-driver. With this value the HL-driver
|
||||
tells the LL the maximum size of a data-packet it will accept.
|
||||
|
||||
unsigned long features;
|
||||
|
||||
To be preset by the HL-driver. Using this field, the HL-driver
|
||||
announces the features supported. At the moment this is limited to
|
||||
report the supported layer2 and layer3-protocols. For setting this
|
||||
field the constants ISDN_FEATURE..., declared in isdnif.h have to be
|
||||
used.
|
||||
|
||||
***CHANGE0.7.1: The line type (1TR6, EDSS1) has to be set.
|
||||
|
||||
unsigned short hl_hdrlen;
|
||||
|
||||
***CHANGE0.7.4: New field.
|
||||
|
||||
To be preset by the HL-driver, if it supports sk_buff's. The driver
|
||||
should put here the amount of additional space needed in sk_buff's for
|
||||
its internal purposes. Drivers not supporting sk_buff's should
|
||||
initialize this field to 0.
|
||||
|
||||
void (*rcvcallb_skb)(int, int, struct sk_buff *)
|
||||
|
||||
***CHANGE0.7.4: New field.
|
||||
|
||||
This field will be set by LL. The HL-driver delivers received data-
|
||||
packets by calling this function. Upon calling, the HL-driver must
|
||||
already have its private data pulled off the head of the sk_buff.
|
||||
|
||||
Parameter:
|
||||
int driver-Id
|
||||
int Channel-number locally to the driver. (starting with 0)
|
||||
struct sk_buff * Pointer to sk_buff, containing received data.
|
||||
|
||||
int (*statcallb)(isdn_ctrl*);
|
||||
|
||||
This field will be set by LL. This function has to be called by the
|
||||
HL-driver for signaling status-changes or other events to the LL.
|
||||
|
||||
Parameter:
|
||||
isdn_ctrl*
|
||||
|
||||
The struct isdn_ctrl also defined in isdn_if. The exact meanings of its
|
||||
fields are described together with the descriptions of the possible
|
||||
events. Here is only a short description of the fields:
|
||||
|
||||
driver = driver Id.
|
||||
command = event-type. (one of the constants ISDN_STAT_...)
|
||||
arg = depends on event-type.
|
||||
num = depends on event-type.
|
||||
|
||||
Returnvalue:
|
||||
0 on success, else -1
|
||||
|
||||
int (*command)(isdn_ctrl*);
|
||||
|
||||
This field has to be preset by the HL-driver. It points to a function,
|
||||
to be called by LL to perform functions like dialing, B-channel
|
||||
setup, etc. The exact meaning of the parameters is described with the
|
||||
descriptions of the possible commands.
|
||||
|
||||
Parameter:
|
||||
isdn_ctrl*
|
||||
driver = driver-Id
|
||||
command = command to perform. (one of the constants ISDN_CMD_...)
|
||||
arg = depends on command.
|
||||
num = depends on command.
|
||||
|
||||
Returnvalue:
|
||||
>=0 on success, else error-code (-ENODEV etc.)
|
||||
|
||||
int (*writebuf_skb)(int, int, int, struct sk_buff *)
|
||||
|
||||
***CHANGE0.7.4: New field.
|
||||
***CHANGEI.1.21: New field.
|
||||
|
||||
This field has to be preset by the HL-driver. The given function will
|
||||
be called by the LL for delivering data to be send via B-Channel.
|
||||
|
||||
|
||||
Parameter:
|
||||
int driver-Id ***CHANGE0.7.4: New parameter.
|
||||
int channel-number locally to the HL-driver. (starts with 0)
|
||||
int ack ***ChangeI1.21: New parameter
|
||||
If this is !0, the driver has to signal the delivery
|
||||
by sending an ISDN_STAT_BSENT. If this is 0, the driver
|
||||
MUST NOT send an ISDN_STAT_BSENT.
|
||||
struct sk_buff * Pointer to sk_buff containing data to be send via
|
||||
B-channel.
|
||||
|
||||
Returnvalue:
|
||||
Length of data accepted on success, else error-code (-EINVAL on
|
||||
oversized packets etc.)
|
||||
|
||||
int (*writecmd)(u_char*, int, int, int, int);
|
||||
|
||||
This field has to be preset by the HL-driver. The given function will be
|
||||
called to perform write-requests on /dev/isdnctrl (i.e. sending commands
|
||||
to the card) The data-format is hardware-specific. This function is
|
||||
intended for debugging only. It is not necessary for normal operation
|
||||
and never will be called by the tty-emulation- or network-code. If
|
||||
this function is not supported, the driver has to set NULL here.
|
||||
|
||||
Parameter:
|
||||
u_char* pointer to data.
|
||||
int length of data.
|
||||
int flag: 0 = call from within kernel-space. (HL-driver must use
|
||||
memcpy, may NOT use schedule())
|
||||
1 = call from user-space. (HL-driver must use
|
||||
memcpy_fromfs, use of schedule() allowed)
|
||||
int driver-Id.
|
||||
int channel-number locally to the HL-driver. (starts with 0)
|
||||
|
||||
***CHANGEI1.14: The driver-Id and channel-number are new since this revision.
|
||||
|
||||
Returnvalue:
|
||||
Length of data accepted on success, else error-code (-EINVAL etc.)
|
||||
|
||||
int (*readstat)(u_char*, int, int, int, int);
|
||||
|
||||
This field has to be preset by the HL-driver. The given function will be
|
||||
called to perform read-requests on /dev/isdnctrl (i.e. reading replies
|
||||
from the card) The data-format is hardware-specific. This function is
|
||||
intended for debugging only. It is not necessary for normal operation
|
||||
and never will be called by the tty-emulation- or network-code. If
|
||||
this function is not supported, the driver has to set NULL here.
|
||||
|
||||
Parameter:
|
||||
u_char* pointer to data.
|
||||
int length of data.
|
||||
int flag: 0 = call from within kernel-space. (HL-driver must use
|
||||
memcpy, may NOT use schedule())
|
||||
1 = call from user-space. (HL-driver must use
|
||||
memcpy_fromfs, use of schedule() allowed)
|
||||
int driver-Id.
|
||||
int channel-number locally to the HL-driver. (starts with 0)
|
||||
|
||||
***CHANGEI1.14: The driver-Id and channel-number are new since this revision.
|
||||
|
||||
Returnvalue:
|
||||
Length of data on success, else error-code (-EINVAL etc.)
|
||||
|
||||
char id[20];
|
||||
***CHANGE0.7: New since this version.
|
||||
|
||||
This string has to be preset by the HL-driver. Its purpose is for
|
||||
identification of the driver by the user. Eg.: it is shown in the
|
||||
status-info of /dev/isdninfo. Furthermore it is used as Id for binding
|
||||
net-interfaces to a specific channel. If a string of length zero is
|
||||
given, upon return, isdn4linux will replace it by a generic name. (line0,
|
||||
line1 etc.) It is recommended to make this string configurable during
|
||||
module-load-time. (copy a global variable to this string.) For doing that,
|
||||
modules 1.2.8 or newer are necessary.
|
||||
|
||||
2. Description of the commands, a HL-driver has to support:
|
||||
|
||||
All commands will be performed by calling the function command() described
|
||||
above from within the LL. The field command of the struct-parameter will
|
||||
contain the desired command, the field driver is always set to the
|
||||
appropriate driver-Id.
|
||||
|
||||
Until now, the following commands are defined:
|
||||
|
||||
***CHANGEI1.34: The parameter "num" has been replaced by a union "parm" containing
|
||||
the old "num" and a new setup_type struct used for ISDN_CMD_DIAL
|
||||
and ISDN_STAT_ICALL callback.
|
||||
|
||||
ISDN_CMD_IOCTL:
|
||||
|
||||
This command is intended for performing ioctl-calls for configuring
|
||||
hardware or similar purposes (setting port-addresses, loading firmware
|
||||
etc.) For this purpose, in the LL all ioctl-calls with an argument
|
||||
>= IIOCDRVCTL (0x100) will be handed transparently to this
|
||||
function after subtracting 0x100 and placing the result in arg.
|
||||
Example:
|
||||
If a userlevel-program calls ioctl(0x101,...) the function gets
|
||||
called with the field command set to 1.
|
||||
|
||||
Parameter:
|
||||
driver = driver-Id.
|
||||
command = ISDN_CMD_IOCTL
|
||||
arg = Original ioctl-cmd - IIOCDRVCTL
|
||||
parm.num = first bytes filled with (unsigned long)arg
|
||||
|
||||
Returnvalue:
|
||||
Depending on driver.
|
||||
|
||||
|
||||
ISDN_CMD_DIAL:
|
||||
|
||||
This command is used to tell the HL-driver it should dial a given
|
||||
number.
|
||||
|
||||
Parameter:
|
||||
driver = driver-Id.
|
||||
command = ISDN_CMD_DIAL
|
||||
arg = channel-number locally to the driver. (starting with 0)
|
||||
|
||||
parm.setup.phone = An ASCII-String containing the number to dial.
|
||||
parm.setup.eazmsn = An ASCII-Sting containing the own EAZ or MSN.
|
||||
parm.setup.si1 = The Service-Indicator.
|
||||
parm.setup.si2 = Additional Service-Indicator.
|
||||
|
||||
If the Line has been designed as SPV (a special german
|
||||
feature, meaning semi-leased-line) the phone has to
|
||||
start with an "S".
|
||||
***CHANGE0.6: In previous versions the EAZ has been given in the
|
||||
highbyte of arg.
|
||||
***CHANGE0.7.1: New since this version: ServiceIndicator and AddInfo.
|
||||
|
||||
ISDN_CMD_ACCEPTD:
|
||||
|
||||
With this command, the HL-driver is told to accept a D-Channel-setup.
|
||||
(Response to an incoming call)
|
||||
|
||||
Parameter:
|
||||
driver = driver-Id.
|
||||
command = ISDN_CMD_ACCEPTD
|
||||
arg = channel-number locally to the driver. (starting with 0)
|
||||
parm = unused.
|
||||
|
||||
ISDN_CMD_ACCEPTB:
|
||||
|
||||
With this command, the HL-driver is told to perform a B-Channel-setup.
|
||||
(after establishing D-Channel-Connection)
|
||||
|
||||
Parameter:
|
||||
driver = driver-Id.
|
||||
command = ISDN_CMD_ACCEPTB
|
||||
arg = channel-number locally to the driver. (starting with 0)
|
||||
parm = unused.
|
||||
|
||||
ISDN_CMD_HANGUP:
|
||||
|
||||
With this command, the HL-driver is told to hangup (B-Channel if
|
||||
established first, then D-Channel). This command is also used for
|
||||
actively rejecting an incoming call.
|
||||
|
||||
Parameter:
|
||||
driver = driver-Id.
|
||||
command = ISDN_CMD_HANGUP
|
||||
arg = channel-number locally to the driver. (starting with 0)
|
||||
parm = unused.
|
||||
|
||||
ISDN_CMD_CLREAZ:
|
||||
|
||||
With this command, the HL-driver is told not to signal incoming
|
||||
calls to the LL.
|
||||
|
||||
Parameter:
|
||||
driver = driver-Id.
|
||||
command = ISDN_CMD_CLREAZ
|
||||
arg = channel-number locally to the driver. (starting with 0)
|
||||
parm = unused.
|
||||
|
||||
ISDN_CMD_SETEAZ:
|
||||
|
||||
With this command, the HL-driver is told to signal incoming calls for
|
||||
the given EAZs/MSNs to the LL.
|
||||
|
||||
Parameter:
|
||||
driver = driver-Id.
|
||||
command = ISDN_CMD_SETEAZ
|
||||
arg = channel-number locally to the driver. (starting with 0)
|
||||
parm.num = ASCII-String, containing the desired EAZ's/MSN's
|
||||
(comma-separated). If an empty String is given, the
|
||||
HL-driver should respond to ALL incoming calls,
|
||||
regardless of the destination-address.
|
||||
***CHANGE0.6: New since this version the "empty-string"-feature.
|
||||
|
||||
ISDN_CMD_GETEAZ: (currently unused)
|
||||
|
||||
With this command, the HL-driver is told to report the current setting
|
||||
given with ISDN_CMD_SETEAZ.
|
||||
|
||||
Parameter:
|
||||
driver = driver-Id.
|
||||
command = ISDN_CMD_GETEAZ
|
||||
arg = channel-number locally to the driver. (starting with 0)
|
||||
parm.num = ASCII-String, containing the current EAZ's/MSN's
|
||||
|
||||
ISDN_CMD_SETSIL: (currently unused)
|
||||
|
||||
With this command, the HL-driver is told to signal only incoming
|
||||
calls with the given Service-Indicators.
|
||||
|
||||
Parameter:
|
||||
driver = driver-Id.
|
||||
command = ISDN_CMD_SETSIL
|
||||
arg = channel-number locally to the driver. (starting with 0)
|
||||
parm.num = ASCII-String, containing the desired Service-Indicators.
|
||||
|
||||
ISDN_CMD_GETSIL: (currently unused)
|
||||
|
||||
With this command, the HL-driver is told to return the current
|
||||
Service-Indicators it will respond to.
|
||||
|
||||
Parameter:
|
||||
driver = driver-Id.
|
||||
command = ISDN_CMD_SETSIL
|
||||
arg = channel-number locally to the driver. (starting with 0)
|
||||
parm.num = ASCII-String, containing the current Service-Indicators.
|
||||
|
||||
ISDN_CMD_SETL2:
|
||||
|
||||
With this command, the HL-driver is told to select the given Layer-2-
|
||||
protocol. This command is issued by the LL prior to ISDN_CMD_DIAL or
|
||||
ISDN_CMD_ACCEPTD.
|
||||
|
||||
|
||||
Parameter:
|
||||
driver = driver-Id.
|
||||
command = ISDN_CMD_SETL2
|
||||
arg = channel-number locally to the driver. (starting with 0)
|
||||
logical or'ed with (protocol-Id << 8)
|
||||
protocol-Id is one of the constants ISDN_PROTO_L2...
|
||||
parm = unused.
|
||||
|
||||
ISDN_CMD_GETL2: (currently unused)
|
||||
|
||||
With this command, the HL-driver is told to return the current
|
||||
setting of the Layer-2-protocol.
|
||||
|
||||
Parameter:
|
||||
driver = driver-Id.
|
||||
command = ISDN_CMD_GETL2
|
||||
arg = channel-number locally to the driver. (starting with 0)
|
||||
parm = unused.
|
||||
Returnvalue:
|
||||
current protocol-Id (one of the constants ISDN_L2_PROTO)
|
||||
|
||||
ISDN_CMD_SETL3:
|
||||
|
||||
With this command, the HL-driver is told to select the given Layer-3-
|
||||
protocol. This command is issued by the LL prior to ISDN_CMD_DIAL or
|
||||
ISDN_CMD_ACCEPTD.
|
||||
|
||||
|
||||
Parameter:
|
||||
driver = driver-Id.
|
||||
command = ISDN_CMD_SETL3
|
||||
arg = channel-number locally to the driver. (starting with 0)
|
||||
logical or'ed with (protocol-Id << 8)
|
||||
protocol-Id is one of the constants ISDN_PROTO_L3...
|
||||
parm.fax = Pointer to T30_s fax struct. (fax usage only)
|
||||
|
||||
ISDN_CMD_GETL2: (currently unused)
|
||||
|
||||
With this command, the HL-driver is told to return the current
|
||||
setting of the Layer-3-protocol.
|
||||
|
||||
Parameter:
|
||||
driver = driver-Id.
|
||||
command = ISDN_CMD_GETL3
|
||||
arg = channel-number locally to the driver. (starting with 0)
|
||||
parm = unused.
|
||||
Returnvalue:
|
||||
current protocol-Id (one of the constants ISDN_L3_PROTO)
|
||||
|
||||
ISDN_CMD_PROCEED:
|
||||
|
||||
With this command, the HL-driver is told to proceed with a incoming call.
|
||||
|
||||
Parameter:
|
||||
driver = driver-Id.
|
||||
command = ISDN_CMD_PROCEED
|
||||
arg = channel-number locally to the driver. (starting with 0)
|
||||
setup.eazmsn= empty string or string send as uus1 in DSS1 with
|
||||
PROCEED message
|
||||
|
||||
ISDN_CMD_ALERT:
|
||||
|
||||
With this command, the HL-driver is told to alert a proceeding call.
|
||||
|
||||
Parameter:
|
||||
driver = driver-Id.
|
||||
command = ISDN_CMD_ALERT
|
||||
arg = channel-number locally to the driver. (starting with 0)
|
||||
setup.eazmsn= empty string or string send as uus1 in DSS1 with
|
||||
ALERT message
|
||||
|
||||
ISDN_CMD_REDIR:
|
||||
|
||||
With this command, the HL-driver is told to redirect a call in proceeding
|
||||
or alerting state.
|
||||
|
||||
Parameter:
|
||||
driver = driver-Id.
|
||||
command = ISDN_CMD_REDIR
|
||||
arg = channel-number locally to the driver. (starting with 0)
|
||||
setup.eazmsn= empty string or string send as uus1 in DSS1 protocol
|
||||
setup.screen= screening indicator
|
||||
setup.phone = redirected to party number
|
||||
|
||||
ISDN_CMD_PROT_IO:
|
||||
|
||||
With this call, the LL-driver invokes protocol specific features through
|
||||
the LL.
|
||||
The call is not implicitely bound to a connection.
|
||||
|
||||
Parameter:
|
||||
driver = driver-Id
|
||||
command = ISDN_CMD_PROT_IO
|
||||
arg = The lower 8 Bits define the addressed protocol as defined
|
||||
in ISDN_PTYPE..., the upper bits are used to differentiate
|
||||
the protocol specific CMD.
|
||||
|
||||
para = protocol and function specific. See isdnif.h for detail.
|
||||
|
||||
|
||||
ISDN_CMD_FAXCMD:
|
||||
|
||||
With this command the HL-driver receives a fax sub-command.
|
||||
For details refer to INTERFACE.fax
|
||||
|
||||
Parameter:
|
||||
driver = driver-Id.
|
||||
command = ISDN_CMD_FAXCMD
|
||||
arg = channel-number locally to the driver. (starting with 0)
|
||||
parm = unused.
|
||||
|
||||
|
||||
3. Description of the events to be signaled by the HL-driver to the LL.
|
||||
|
||||
All status-changes are signaled via calling the previously described
|
||||
function statcallb(). The field command of the struct isdn_cmd has
|
||||
to be set by the HL-driver with the appropriate Status-Id (event-number).
|
||||
The field arg has to be set to the channel-number (locally to the driver,
|
||||
starting with 0) to which this event applies. (Exception: STAVAIL-event)
|
||||
|
||||
Until now, the following Status-Ids are defined:
|
||||
|
||||
ISDN_STAT_AVAIL:
|
||||
|
||||
With this call, the HL-driver signals the availability of new data
|
||||
for readstat(). Used only for debugging-purposes, see description
|
||||
of readstat().
|
||||
|
||||
Parameter:
|
||||
driver = driver-Id
|
||||
command = ISDN_STAT_STAVAIL
|
||||
arg = length of available data.
|
||||
parm = unused.
|
||||
|
||||
ISDN_STAT_ICALL:
|
||||
ISDN_STAT_ICALLW:
|
||||
|
||||
With this call, the HL-driver signals an incoming call to the LL.
|
||||
If ICALLW is signalled the incoming call is a waiting call without
|
||||
a available B-chan.
|
||||
|
||||
Parameter:
|
||||
driver = driver-Id
|
||||
command = ISDN_STAT_ICALL
|
||||
arg = channel-number, locally to the driver. (starting with 0)
|
||||
para.setup.phone = Callernumber.
|
||||
para.setup.eazmsn = CalledNumber.
|
||||
para.setup.si1 = Service Indicator.
|
||||
para.setup.si2 = Additional Service Indicator.
|
||||
para.setup.plan = octet 3 from Calling party number Information Element.
|
||||
para.setup.screen = octet 3a from Calling party number Information Element.
|
||||
|
||||
Return:
|
||||
0 = No device matching this call.
|
||||
1 = At least one device matching this call (RING on ttyI).
|
||||
HL-driver may send ALERTING on the D-channel in this case.
|
||||
2 = Call will be rejected.
|
||||
3 = Incoming called party number is currently incomplete.
|
||||
Additional digits are required.
|
||||
Used for signalling with PtP connections.
|
||||
4 = Call will be held in a proceeding state
|
||||
(HL driver sends PROCEEDING)
|
||||
Used when a user space prog needs time to interpret a call
|
||||
para.setup.eazmsn may be filled with an uus1 message of
|
||||
30 octets maximum. Empty string if no uus.
|
||||
5 = Call will be actively deflected to another party
|
||||
Only available in DSS1/EURO protocol
|
||||
para.setup.phone must be set to destination party number
|
||||
para.setup.eazmsn may be filled with an uus1 message of
|
||||
30 octets maximum. Empty string if no uus.
|
||||
-1 = An error happened. (Invalid parameters for example.)
|
||||
The keypad support now is included in the dial command.
|
||||
|
||||
|
||||
ISDN_STAT_RUN:
|
||||
|
||||
With this call, the HL-driver signals availability of the ISDN-card.
|
||||
(after initializing, loading firmware)
|
||||
|
||||
Parameter:
|
||||
driver = driver-Id
|
||||
command = ISDN_STAT_RUN
|
||||
arg = unused.
|
||||
parm = unused.
|
||||
|
||||
ISDN_STAT_STOP:
|
||||
|
||||
With this call, the HL-driver signals unavailability of the ISDN-card.
|
||||
(before unloading, while resetting/reconfiguring the card)
|
||||
|
||||
Parameter:
|
||||
driver = driver-Id
|
||||
command = ISDN_STAT_STOP
|
||||
arg = unused.
|
||||
parm = unused.
|
||||
|
||||
ISDN_STAT_DCONN:
|
||||
|
||||
With this call, the HL-driver signals the successful establishment of
|
||||
a D-Channel-connection. (Response to ISDN_CMD_ACCEPTD or ISDN_CMD_DIAL)
|
||||
|
||||
Parameter:
|
||||
driver = driver-Id
|
||||
command = ISDN_STAT_DCONN
|
||||
arg = channel-number, locally to the driver. (starting with 0)
|
||||
parm = unused.
|
||||
|
||||
ISDN_STAT_BCONN:
|
||||
|
||||
With this call, the HL-driver signals the successful establishment of
|
||||
a B-Channel-connection. (Response to ISDN_CMD_ACCEPTB or because the
|
||||
remote-station has initiated establishment)
|
||||
|
||||
The HL driver should call this when the logical l2/l3 protocol
|
||||
connection on top of the physical B-channel is established.
|
||||
|
||||
Parameter:
|
||||
driver = driver-Id
|
||||
command = ISDN_STAT_BCONN
|
||||
arg = channel-number, locally to the driver. (starting with 0)
|
||||
parm.num = ASCII-String, containing type of connection (for analog
|
||||
modem only). This will be appended to the CONNECT message
|
||||
e.g. 14400/V.32bis
|
||||
|
||||
ISDN_STAT_DHUP:
|
||||
|
||||
With this call, the HL-driver signals the shutdown of a
|
||||
D-Channel-connection. This could be a response to a prior ISDN_CMD_HANGUP,
|
||||
or caused by a remote-hangup or if the remote-station has actively
|
||||
rejected a call.
|
||||
|
||||
Parameter:
|
||||
driver = driver-Id
|
||||
command = ISDN_STAT_DHUP
|
||||
arg = channel-number, locally to the driver. (starting with 0)
|
||||
parm = unused.
|
||||
|
||||
ISDN_STAT_BHUP:
|
||||
|
||||
With this call, the HL-driver signals the shutdown of a
|
||||
B-Channel-connection. This could be a response to a prior ISDN_CMD_HANGUP,
|
||||
or caused by a remote-hangup.
|
||||
|
||||
The HL driver should call this as soon as the logical l2/l3 protocol
|
||||
connection on top of the physical B-channel is released.
|
||||
|
||||
Parameter:
|
||||
driver = driver-Id
|
||||
command = ISDN_STAT_BHUP
|
||||
arg = channel-number, locally to the driver. (starting with 0)
|
||||
parm = unused.
|
||||
|
||||
ISDN_STAT_CINF:
|
||||
|
||||
With this call, the HL-driver delivers charge-unit information to the
|
||||
LL.
|
||||
|
||||
Parameter:
|
||||
driver = driver-Id
|
||||
command = ISDN_STAT_CINF
|
||||
arg = channel-number, locally to the driver. (starting with 0)
|
||||
parm.num = ASCII string containing charge-units (digits only).
|
||||
|
||||
ISDN_STAT_LOAD: (currently unused)
|
||||
|
||||
ISDN_STAT_UNLOAD:
|
||||
|
||||
With this call, the HL-driver signals that it will be unloaded now. This
|
||||
tells the LL to release all corresponding data-structures.
|
||||
|
||||
Parameter:
|
||||
driver = driver-Id
|
||||
command = ISDN_STAT_UNLOAD
|
||||
arg = unused.
|
||||
parm = unused.
|
||||
|
||||
ISDN_STAT_BSENT:
|
||||
|
||||
With this call the HL-driver signals the delivery of a data-packet.
|
||||
This callback is used by the network-interfaces only, tty-Emulation
|
||||
does not need this call.
|
||||
|
||||
Parameter:
|
||||
driver = driver-Id
|
||||
command = ISDN_STAT_BSENT
|
||||
arg = channel-number, locally to the driver. (starting with 0)
|
||||
parm.length = ***CHANGEI.1.21: New field.
|
||||
the driver has to set this to the original length
|
||||
of the skb at the time of receiving it from the linklevel.
|
||||
|
||||
ISDN_STAT_NODCH:
|
||||
|
||||
With this call, the driver has to respond to a prior ISDN_CMD_DIAL, if
|
||||
no D-Channel is available.
|
||||
|
||||
Parameter:
|
||||
driver = driver-Id
|
||||
command = ISDN_STAT_NODCH
|
||||
arg = channel-number, locally to the driver. (starting with 0)
|
||||
parm = unused.
|
||||
|
||||
ISDN_STAT_ADDCH:
|
||||
|
||||
This call is for HL-drivers, which are unable to check card-type
|
||||
or numbers of supported channels before they have loaded any firmware
|
||||
using ioctl. Those HL-driver simply set the channel-parameter to a
|
||||
minimum channel-number when registering, and later if they know
|
||||
the real amount, perform this call, allocating additional channels.
|
||||
|
||||
Parameter:
|
||||
driver = driver-Id
|
||||
command = ISDN_STAT_ADDCH
|
||||
arg = number of channels to be added.
|
||||
parm = unused.
|
||||
|
||||
ISDN_STAT_CAUSE:
|
||||
|
||||
With this call, the HL-driver delivers CAUSE-messages to the LL.
|
||||
Currently the LL does not use this messages. Their contents is simply
|
||||
logged via kernel-messages. Therefore, currently the format of the
|
||||
messages is completely free. However they should be printable.
|
||||
|
||||
Parameter:
|
||||
driver = driver-Id
|
||||
command = ISDN_STAT_NODCH
|
||||
arg = channel-number, locally to the driver. (starting with 0)
|
||||
parm.num = ASCII string containing CAUSE-message.
|
||||
|
||||
ISDN_STAT_DISPLAY:
|
||||
|
||||
With this call, the HL-driver delivers DISPLAY-messages to the LL.
|
||||
Currently the LL does not use this messages.
|
||||
|
||||
Parameter:
|
||||
driver = driver-Id
|
||||
command = ISDN_STAT_DISPLAY
|
||||
arg = channel-number, locally to the driver. (starting with 0)
|
||||
para.display= string containing DISPLAY-message.
|
||||
|
||||
ISDN_STAT_PROT:
|
||||
|
||||
With this call, the HL-driver delivers protocol specific infos to the LL.
|
||||
The call is not implicitely bound to a connection.
|
||||
|
||||
Parameter:
|
||||
driver = driver-Id
|
||||
command = ISDN_STAT_PROT
|
||||
arg = The lower 8 Bits define the addressed protocol as defined
|
||||
in ISDN_PTYPE..., the upper bits are used to differentiate
|
||||
the protocol specific STAT.
|
||||
|
||||
para = protocol and function specific. See isdnif.h for detail.
|
||||
|
||||
ISDN_STAT_DISCH:
|
||||
|
||||
With this call, the HL-driver signals the LL to disable or enable the
|
||||
use of supplied channel and driver.
|
||||
The call may be used to reduce the available number of B-channels after
|
||||
loading the driver. The LL has to ignore a disabled channel when searching
|
||||
for free channels. The HL driver itself never delivers STAT callbacks for
|
||||
disabled channels.
|
||||
The LL returns a nonzero code if the operation was not successful or the
|
||||
selected channel is actually regarded as busy.
|
||||
|
||||
Parameter:
|
||||
driver = driver-Id
|
||||
command = ISDN_STAT_DISCH
|
||||
arg = channel-number, locally to the driver. (starting with 0)
|
||||
parm.num[0] = 0 if channel shall be disabled, else enabled.
|
||||
|
||||
ISDN_STAT_L1ERR:
|
||||
|
||||
***CHANGEI1.21 new status message.
|
||||
A signal can be sent to the linklevel if an Layer1-error results in
|
||||
packet-loss on receive or send. The field errcode of the cmd.parm
|
||||
union describes the error more precisely.
|
||||
|
||||
Parameter:
|
||||
driver = driver-Id
|
||||
command = ISDN_STAT_L1ERR
|
||||
arg = channel-number, locally to the driver. (starting with 0)
|
||||
parm.errcode= ISDN_STAT_L1ERR_SEND: Packet lost while sending.
|
||||
ISDN_STAT_L1ERR_RECV: Packet lost while receiving.
|
||||
ISDN_STAT_FAXIND:
|
||||
|
||||
With this call the HL-driver signals a fax sub-command to the LL.
|
||||
For details refer to INTERFACE.fax
|
||||
|
||||
Parameter:
|
||||
driver = driver-Id.
|
||||
command = ISDN_STAT_FAXIND
|
||||
arg = channel-number, locally to the driver. (starting with 0)
|
||||
parm = unused.
|
||||
|
|
@ -1,163 +0,0 @@
|
|||
$Id: INTERFACE.fax,v 1.2 2000/08/06 09:22:50 armin Exp $
|
||||
|
||||
|
||||
Description of the fax-subinterface between linklevel and hardwarelevel of
|
||||
isdn4linux.
|
||||
|
||||
The communication between linklevel (LL) and hardwarelevel (HL) for fax
|
||||
is based on the struct T30_s (defined in isdnif.h).
|
||||
This struct is allocated in the LL.
|
||||
In order to use fax, the LL provides the pointer to this struct with the
|
||||
command ISDN_CMD_SETL3 (parm.fax). This pointer expires in case of hangup
|
||||
and when a new channel to a new connection is assigned.
|
||||
|
||||
|
||||
Data handling:
|
||||
In send-mode the HL-driver has to handle the <DLE> codes and the bit-order
|
||||
conversion by itself.
|
||||
In receive-mode the LL-driver takes care of the bit-order conversion
|
||||
(specified by +FBOR)
|
||||
|
||||
Structure T30_s description:
|
||||
|
||||
This structure stores the values (set by AT-commands), the remote-
|
||||
capability-values and the command-codes between LL and HL.
|
||||
|
||||
If the HL-driver receives ISDN_CMD_FAXCMD, all needed information
|
||||
is in this struct set by the LL.
|
||||
To signal information to the LL, the HL-driver has to set the
|
||||
parameters and use ISDN_STAT_FAXIND.
|
||||
(Please refer to INTERFACE)
|
||||
|
||||
Structure T30_s:
|
||||
|
||||
All members are 8-bit unsigned (__u8)
|
||||
|
||||
- resolution
|
||||
- rate
|
||||
- width
|
||||
- length
|
||||
- compression
|
||||
- ecm
|
||||
- binary
|
||||
- scantime
|
||||
- id[]
|
||||
Local faxmachine's parameters, set by +FDIS, +FDCS, +FLID, ...
|
||||
|
||||
- r_resolution
|
||||
- r_rate
|
||||
- r_width
|
||||
- r_length
|
||||
- r_compression
|
||||
- r_ecm
|
||||
- r_binary
|
||||
- r_scantime
|
||||
- r_id[]
|
||||
Remote faxmachine's parameters. To be set by HL-driver.
|
||||
|
||||
- phase
|
||||
Defines the actual state of fax connection. Set by HL or LL
|
||||
depending on progress and type of connection.
|
||||
If the phase changes because of an AT command, the LL driver
|
||||
changes this value. Otherwise the HL-driver takes care of it, but
|
||||
only necessary on call establishment (from IDLE to PHASE_A).
|
||||
(one of the constants ISDN_FAX_PHASE_[IDLE,A,B,C,D,E])
|
||||
|
||||
- direction
|
||||
Defines outgoing/send or incoming/receive connection.
|
||||
(ISDN_TTY_FAX_CONN_[IN,OUT])
|
||||
|
||||
- code
|
||||
Commands from LL to HL; possible constants :
|
||||
ISDN_TTY_FAX_DR signals +FDR command to HL
|
||||
|
||||
ISDN_TTY_FAX_DT signals +FDT command to HL
|
||||
|
||||
ISDN_TTY_FAX_ET signals +FET command to HL
|
||||
|
||||
|
||||
Other than that the "code" is set with the hangup-code value at
|
||||
the end of connection for the +FHNG message.
|
||||
|
||||
- r_code
|
||||
Commands from HL to LL; possible constants :
|
||||
ISDN_TTY_FAX_CFR output of +FCFR message.
|
||||
|
||||
ISDN_TTY_FAX_RID output of remote ID set in r_id[]
|
||||
(+FCSI/+FTSI on send/receive)
|
||||
|
||||
ISDN_TTY_FAX_DCS output of +FDCS and CONNECT message,
|
||||
switching to phase C.
|
||||
|
||||
ISDN_TTY_FAX_ET signals end of data,
|
||||
switching to phase D.
|
||||
|
||||
ISDN_TTY_FAX_FCON signals the established, outgoing connection,
|
||||
switching to phase B.
|
||||
|
||||
ISDN_TTY_FAX_FCON_I signals the established, incoming connection,
|
||||
switching to phase B.
|
||||
|
||||
ISDN_TTY_FAX_DIS output of +FDIS message and values.
|
||||
|
||||
ISDN_TTY_FAX_SENT signals that all data has been sent
|
||||
and <DLE><ETX> is acknowledged,
|
||||
OK message will be sent.
|
||||
|
||||
ISDN_TTY_FAX_PTS signals a msg-confirmation (page sent successful),
|
||||
depending on fet value:
|
||||
0: output OK message (more pages follow)
|
||||
1: switching to phase B (next document)
|
||||
|
||||
ISDN_TTY_FAX_TRAIN_OK output of +FDCS and OK message (for receive mode).
|
||||
|
||||
ISDN_TTY_FAX_EOP signals end of data in receive mode,
|
||||
switching to phase D.
|
||||
|
||||
ISDN_TTY_FAX_HNG output of the +FHNG and value set by code and
|
||||
OK message, switching to phase E.
|
||||
|
||||
|
||||
- badlin
|
||||
Value of +FBADLIN
|
||||
|
||||
- badmul
|
||||
Value of +FBADMUL
|
||||
|
||||
- bor
|
||||
Value of +FBOR
|
||||
|
||||
- fet
|
||||
Value of +FET command in send-mode.
|
||||
Set by HL in receive-mode for +FET message.
|
||||
|
||||
- pollid[]
|
||||
ID-string, set by +FCIG
|
||||
|
||||
- cq
|
||||
Value of +FCQ
|
||||
|
||||
- cr
|
||||
Value of +FCR
|
||||
|
||||
- ctcrty
|
||||
Value of +FCTCRTY
|
||||
|
||||
- minsp
|
||||
Value of +FMINSP
|
||||
|
||||
- phcto
|
||||
Value of +FPHCTO
|
||||
|
||||
- rel
|
||||
Value of +FREL
|
||||
|
||||
- nbc
|
||||
Value of +FNBC (0,1)
|
||||
(+FNBC is not a known class 2 fax command, I added this to change the
|
||||
automatic "best capabilities" connection in the eicon HL-driver)
|
||||
|
||||
|
||||
Armin
|
||||
mac@melware.de
|
||||
|
|
@ -1,599 +0,0 @@
|
|||
README for the ISDN-subsystem
|
||||
|
||||
1. Preface
|
||||
|
||||
1.1 Introduction
|
||||
|
||||
This README describes how to set up and how to use the different parts
|
||||
of the ISDN-subsystem.
|
||||
|
||||
For using the ISDN-subsystem, some additional userlevel programs are
|
||||
necessary. Those programs and some contributed utilities are available
|
||||
at
|
||||
|
||||
ftp.isdn4linux.de
|
||||
|
||||
/pub/isdn4linux/isdn4k-utils-<VersionNumber>.tar.gz
|
||||
|
||||
|
||||
We also have set up a mailing-list:
|
||||
|
||||
The isdn4linux-project originates in Germany, and therefore by historical
|
||||
reasons, the mailing-list's primary language is german. However mails
|
||||
written in english have been welcome all the time.
|
||||
|
||||
to subscribe: write a email to majordomo@listserv.isdn4linux.de,
|
||||
Subject irrelevant, in the message body:
|
||||
subscribe isdn4linux <your_email_address>
|
||||
|
||||
To write to the mailing-list, write to isdn4linux@listserv.isdn4linux.de
|
||||
|
||||
This mailinglist is bidirectionally gated to the newsgroup
|
||||
|
||||
de.alt.comm.isdn4linux
|
||||
|
||||
There is also a well maintained FAQ in English available at
|
||||
https://www.mhessler.de/i4lfaq/
|
||||
It can be viewed online, or downloaded in sgml/text/html format.
|
||||
The FAQ can also be viewed online at
|
||||
https://www.isdn4linux.de/faq/i4lfaq.html
|
||||
or downloaded from
|
||||
ftp://ftp.isdn4linux.de/pub/isdn4linux/FAQ/
|
||||
|
||||
1.1 Technical details
|
||||
|
||||
In the following Text, the terms MSN and EAZ are used.
|
||||
|
||||
MSN is the abbreviation for (M)ultiple(S)ubscriber(N)umber, and applies
|
||||
to Euro(EDSS1)-type lines. Usually it is simply the phone number.
|
||||
|
||||
EAZ is the abbreviation of (E)ndgeraete(A)uswahl(Z)iffer and
|
||||
applies to German 1TR6-type lines. This is a one-digit string,
|
||||
simply appended to the base phone number
|
||||
|
||||
The internal handling is nearly identical, so replace the appropriate
|
||||
term to that one, which applies to your local ISDN-environment.
|
||||
|
||||
When the link-level-module isdn.o is loaded, it supports up to 16
|
||||
low-level-modules with up to 64 channels. (The number 64 is arbitrarily
|
||||
chosen and can be configured at compile-time --ISDN_MAX in isdn.h).
|
||||
A low-level-driver can register itself through an interface (which is
|
||||
defined in isdnif.h) and gets assigned a slot.
|
||||
The following char-devices are made available for each channel:
|
||||
|
||||
A raw-control-device with the following functions:
|
||||
write: raw D-channel-messages (format: depends on driver).
|
||||
read: raw D-channel-messages (format: depends on driver).
|
||||
ioctl: depends on driver, i.e. for the ICN-driver, the base-address of
|
||||
the ports and the shared memory on the card can be set and read
|
||||
also the boot-code and the protocol software can be loaded into
|
||||
the card.
|
||||
|
||||
O N L Y !!! for debugging (no locking against other devices):
|
||||
One raw-data-device with the following functions:
|
||||
write: data to B-channel.
|
||||
read: data from B-channel.
|
||||
|
||||
In addition the following devices are made available:
|
||||
|
||||
128 tty-devices (64 cuix and 64 ttyIx) with integrated modem-emulator:
|
||||
The functionality is almost the same as that of a serial device
|
||||
(the line-discs are handled by the kernel), which lets you run
|
||||
SLIP, CSLIP and asynchronous PPP through the devices. We have tested
|
||||
Seyon, minicom, CSLIP (uri-dip) PPP, mgetty, XCept and Hylafax.
|
||||
|
||||
The modem-emulation supports the following:
|
||||
1.3.1 Commands:
|
||||
|
||||
ATA Answer incoming call.
|
||||
ATD<No.> Dial, the number may contain:
|
||||
[0-9] and [,#.*WPT-S]
|
||||
the latter are ignored until 'S'.
|
||||
The 'S' must precede the number, if
|
||||
the line is a SPV (German 1TR6).
|
||||
ATE0 Echo off.
|
||||
ATE1 Echo on (default).
|
||||
ATH Hang-up.
|
||||
ATH1 Off hook (ignored).
|
||||
ATH0 Hang-up.
|
||||
ATI Return "ISDN for Linux...".
|
||||
ATI0 "
|
||||
ATI1 "
|
||||
ATI2 Report of last connection.
|
||||
ATO On line (data mode).
|
||||
ATQ0 Enable result codes (default).
|
||||
ATQ1 Disable result codes (default).
|
||||
ATSx=y Set register x to y.
|
||||
ATSx? Show contents of register x.
|
||||
ATV0 Numeric responses.
|
||||
ATV1 English responses (default).
|
||||
ATZ Load registers and EAZ/MSN from Profile.
|
||||
AT&Bx Set Send-Packet-size to x (max. 4000)
|
||||
The real packet-size may be limited by the
|
||||
low-level-driver used. e.g. the HiSax-Module-
|
||||
limit is 2000. You will get NO Error-Message,
|
||||
if you set it to higher values, because at the
|
||||
time of giving this command the corresponding
|
||||
driver may not be selected (see "Automatic
|
||||
Assignment") however the size of outgoing packets
|
||||
will be limited correctly.
|
||||
AT&D0 Ignore DTR
|
||||
AT&D2 DTR-low-edge: Hang up and return to
|
||||
command mode (default).
|
||||
AT&D3 Same as AT&D2 but also resets all registers.
|
||||
AT&Ex Set the EAZ/MSN for this channel to x.
|
||||
AT&F Reset all registers and profile to "factory-defaults"
|
||||
AT&Lx Set list of phone numbers to listen on. x is a
|
||||
list of wildcard patterns separated by semicolon.
|
||||
If this is set, it has precedence over the MSN set
|
||||
by AT&E.
|
||||
AT&Rx Select V.110 bitrate adaption.
|
||||
This command enables V.110 protocol with 9600 baud
|
||||
(x=9600), 19200 baud (x=19200) or 38400 baud
|
||||
(x=38400). A value of x=0 disables V.110 switching
|
||||
back to default X.75. This command sets the following
|
||||
Registers:
|
||||
Reg 14 (Layer-2 protocol):
|
||||
x = 0: 0
|
||||
x = 9600: 7
|
||||
x = 19200: 8
|
||||
x = 38400: 9
|
||||
Reg 18.2 = 1
|
||||
Reg 19 (Additional Service Indicator):
|
||||
x = 0: 0
|
||||
x = 9600: 197
|
||||
x = 19200: 199
|
||||
x = 38400: 198
|
||||
Note on value in Reg 19:
|
||||
There is _NO_ common convention for 38400 baud.
|
||||
The value 198 is chosen arbitrarily. Users
|
||||
_MUST_ negotiate this value before establishing
|
||||
a connection.
|
||||
AT&Sx Set window-size (x = 1..8) (not yet implemented)
|
||||
AT&V Show all settings.
|
||||
AT&W0 Write registers and EAZ/MSN to profile. See also
|
||||
iprofd (5.c in this README).
|
||||
AT&X0 BTX-mode and T.70-mode off (default)
|
||||
AT&X1 BTX-mode on. (S13.1=1, S13.5=0 S14=0, S16=7, S18=7, S19=0)
|
||||
AT&X2 T.70-mode on. (S13.1=1, S13.5=1, S14=0, S16=7, S18=7, S19=0)
|
||||
AT+Rx Resume a suspended call with CallID x (x = 1,2,3...)
|
||||
AT+Sx Suspend a call with CallID x (x = 1,2,3...)
|
||||
|
||||
For voice-mode commands refer to README.audio
|
||||
|
||||
1.3.2 Escape sequence:
|
||||
During a connection, the emulation reacts just like
|
||||
a normal modem to the escape sequence <DELAY>+++<DELAY>.
|
||||
(The escape character - default '+' - can be set in the
|
||||
register 2).
|
||||
The DELAY must at least be 1.5 seconds long and delay
|
||||
between the escape characters must not exceed 0.5 seconds.
|
||||
|
||||
1.3.3 Registers:
|
||||
|
||||
Nr. Default Description
|
||||
0 0 Answer on ring number.
|
||||
(no auto-answer if S0=0).
|
||||
1 0 Count of rings.
|
||||
2 43 Escape character.
|
||||
(a value >= 128 disables the escape sequence).
|
||||
3 13 Carriage return character (ASCII).
|
||||
4 10 Line feed character (ASCII).
|
||||
5 8 Backspace character (ASCII).
|
||||
6 3 Delay in seconds before dialing.
|
||||
7 60 Wait for carrier.
|
||||
8 2 Pause time for comma (ignored)
|
||||
9 6 Carrier detect time (ignored)
|
||||
10 7 Carrier loss to disconnect time (ignored).
|
||||
11 70 Touch tone timing (ignored).
|
||||
12 69 Bit coded register:
|
||||
Bit 0: 0 = Suppress response messages.
|
||||
1 = Show response messages.
|
||||
Bit 1: 0 = English response messages.
|
||||
1 = Numeric response messages.
|
||||
Bit 2: 0 = Echo off.
|
||||
1 = Echo on.
|
||||
Bit 3 0 = DCD always on.
|
||||
1 = DCD follows carrier.
|
||||
Bit 4 0 = CTS follows RTS
|
||||
1 = Ignore RTS, CTS always on.
|
||||
Bit 5 0 = return to command mode on DTR low.
|
||||
1 = Same as 0 but also resets all
|
||||
registers.
|
||||
See also register 13, bit 2
|
||||
Bit 6 0 = DSR always on.
|
||||
1 = DSR only on if channel is available.
|
||||
Bit 7 0 = Cisco-PPP-flag-hack off (default).
|
||||
1 = Cisco-PPP-flag-hack on.
|
||||
13 0 Bit coded register:
|
||||
Bit 0: 0 = Use delayed tty-send-algorithm
|
||||
1 = Direct tty-send.
|
||||
Bit 1: 0 = T.70 protocol (Only for BTX!) off
|
||||
1 = T.70 protocol (Only for BTX!) on
|
||||
Bit 2: 0 = Don't hangup on DTR low.
|
||||
1 = Hangup on DTR low.
|
||||
Bit 3: 0 = Standard response messages
|
||||
1 = Extended response messages
|
||||
Bit 4: 0 = CALLER NUMBER before every RING.
|
||||
1 = CALLER NUMBER after first RING.
|
||||
Bit 5: 0 = T.70 extended protocol off
|
||||
1 = T.70 extended protocol on
|
||||
Bit 6: 0 = Special RUNG Message off
|
||||
1 = Special RUNG Message on
|
||||
"RUNG" is delivered on a ttyI, if
|
||||
an incoming call happened (RING) and
|
||||
the remote party hung up before any
|
||||
local ATA was given.
|
||||
Bit 7: 0 = Don't show display messages from net
|
||||
1 = Show display messages from net
|
||||
(S12 Bit 1 must be 0 too)
|
||||
14 0 Layer-2 protocol:
|
||||
0 = X75/LAPB with I-frames
|
||||
1 = X75/LAPB with UI-frames
|
||||
2 = X75/LAPB with BUI-frames
|
||||
3 = HDLC
|
||||
4 = Transparent (audio)
|
||||
7 = V.110, 9600 baud
|
||||
8 = V.110, 19200 baud
|
||||
9 = V.110, 38400 baud
|
||||
10 = Analog Modem (only if hardware supports this)
|
||||
11 = Fax G3 (only if hardware supports this)
|
||||
15 0 Layer-3 protocol:
|
||||
0 = transparent
|
||||
1 = transparent with audio features (e.g. DSP)
|
||||
2 = Fax G3 Class 2 commands (S14 has to be set to 11)
|
||||
3 = Fax G3 Class 1 commands (S14 has to be set to 11)
|
||||
16 250 Send-Packet-size/16
|
||||
17 8 Window-size (not yet implemented)
|
||||
18 4 Bit coded register, Service-Octet-1 to accept,
|
||||
or to be used on dialout:
|
||||
Bit 0: Service 1 (audio) when set.
|
||||
Bit 1: Service 5 (BTX) when set.
|
||||
Bit 2: Service 7 (data) when set.
|
||||
Note: It is possible to set more than one
|
||||
bit. In this case, on incoming calls
|
||||
the selected services are accepted,
|
||||
and if the service is "audio", the
|
||||
Layer-2-protocol is automatically
|
||||
changed to 4 regardless of the setting
|
||||
of register 14. On outgoing calls,
|
||||
the most significant 1-bit is chosen to
|
||||
select the outgoing service octet.
|
||||
19 0 Service-Octet-2
|
||||
20 0 Bit coded register (readonly)
|
||||
Service-Octet-1 of last call.
|
||||
Bit mapping is the same as register 18
|
||||
21 0 Bit coded register (readonly)
|
||||
Set on incoming call (during RING) to
|
||||
octet 3 of calling party number IE (Numbering plan)
|
||||
See section 4.5.10 of ITU Q.931
|
||||
22 0 Bit coded register (readonly)
|
||||
Set on incoming call (during RING) to
|
||||
octet 3a of calling party number IE (Screening info)
|
||||
See section 4.5.10 of ITU Q.931
|
||||
23 0 Bit coded register:
|
||||
Bit 0: 0 = Add CPN to RING message off
|
||||
1 = Add CPN to RING message on
|
||||
Bit 1: 0 = Add CPN to FCON message off
|
||||
1 = Add CPN to FCON message on
|
||||
Bit 2: 0 = Add CDN to RING/FCON message off
|
||||
1 = Add CDN to RING/FCON message on
|
||||
|
||||
Last but not least a (at the moment fairly primitive) device to request
|
||||
the line-status (/dev/isdninfo) is made available.
|
||||
|
||||
Automatic assignment of devices to lines:
|
||||
|
||||
All inactive physical lines are listening to all EAZs for incoming
|
||||
calls and are NOT assigned to a specific tty or network interface.
|
||||
When an incoming call is detected, the driver looks first for a network
|
||||
interface and then for an opened tty which:
|
||||
|
||||
1. is configured for the same EAZ.
|
||||
2. has the same protocol settings for the B-channel.
|
||||
3. (only for network interfaces if the security flag is set)
|
||||
contains the caller number in its access list.
|
||||
4. Either the channel is not bound exclusively to another Net-interface, or
|
||||
it is bound AND the other checks apply to exactly this interface.
|
||||
(For usage of the bind-features, refer to the isdnctrl-man-page)
|
||||
|
||||
Only when a matching interface or tty is found is the call accepted
|
||||
and the "connection" between the low-level-layer and the link-level-layer
|
||||
is established and kept until the end of the connection.
|
||||
In all other cases no connection is established. Isdn4linux can be
|
||||
configured to either do NOTHING in this case (which is useful, if
|
||||
other, external devices with the same EAZ/MSN are connected to the bus)
|
||||
or to reject the call actively. (isdnctrl busreject ...)
|
||||
|
||||
For an outgoing call, the inactive physical lines are searched.
|
||||
The call is placed on the first physical line, which supports the
|
||||
requested protocols for the B-channel. If a net-interface, however
|
||||
is pre-bound to a channel, this channel is used directly.
|
||||
|
||||
This makes it possible to configure several network interfaces and ttys
|
||||
for one EAZ, if the network interfaces are set to secure operation.
|
||||
If an incoming call matches one network interface, it gets connected to it.
|
||||
If another incoming call for the same EAZ arrives, which does not match
|
||||
a network interface, the first tty gets a "RING" and so on.
|
||||
|
||||
2 System prerequisites:
|
||||
|
||||
ATTENTION!
|
||||
|
||||
Always use the latest module utilities. The current version is
|
||||
named in Documentation/Changes. Some old versions of insmod
|
||||
are not capable of setting the driver-Ids correctly.
|
||||
|
||||
3. Lowlevel-driver configuration.
|
||||
|
||||
Configuration depends on how the drivers are built. See the
|
||||
README.<yourDriver> for information on driver-specific setup.
|
||||
|
||||
4. Device-inodes
|
||||
|
||||
The major and minor numbers and their names are described in
|
||||
Documentation/admin-guide/devices.rst. The major numbers are:
|
||||
|
||||
43 for the ISDN-tty's.
|
||||
44 for the ISDN-callout-tty's.
|
||||
45 for control/info/debug devices.
|
||||
|
||||
5. Application
|
||||
|
||||
a) For some card-types, firmware has to be loaded into the cards, before
|
||||
proceeding with device-independent setup. See README.<yourDriver>
|
||||
for how to do that.
|
||||
|
||||
b) If you only intend to use ttys, you are nearly ready now.
|
||||
|
||||
c) If you want to have really permanent "Modem"-settings on disk, you
|
||||
can start the daemon iprofd. Give it a path to a file at the command-
|
||||
line. It will store the profile-settings in this file every time
|
||||
an AT&W0 is performed on any ISDN-tty. If the file already exists,
|
||||
all profiles are initialized from this file. If you want to unload
|
||||
any of the modules, kill iprofd first.
|
||||
|
||||
d) For networking, continue: Create an interface:
|
||||
isdnctrl addif isdn0
|
||||
|
||||
e) Set the EAZ (or MSN for Euro-ISDN):
|
||||
isdnctrl eaz isdn0 2
|
||||
|
||||
(For 1TR6 a single digit is allowed, for Euro-ISDN the number is your
|
||||
real MSN e.g.: Phone-Number)
|
||||
|
||||
f) Set the number for outgoing calls on the interface:
|
||||
isdnctrl addphone isdn0 out 1234567
|
||||
... (this can be executed more than once, all assigned numbers are
|
||||
tried in order)
|
||||
and the number(s) for incoming calls:
|
||||
isdnctrl addphone isdn0 in 1234567
|
||||
|
||||
g) Set the timeout for hang-up:
|
||||
isdnctrl huptimeout isdn0 <timeout_in_seconds>
|
||||
|
||||
h) additionally you may activate charge-hang-up (= Hang up before
|
||||
next charge-info, this only works, if your isdn-provider transmits
|
||||
the charge-info during and after the connection):
|
||||
isdnctrl chargehup isdn0 on
|
||||
|
||||
i) Set the dial mode of the interface:
|
||||
isdnctrl dialmode isdn0 auto
|
||||
"off" means that you (or the system) cannot make any connection
|
||||
(neither incoming or outgoing connections are possible). Use
|
||||
this if you want to be sure that no connections will be made.
|
||||
"auto" means that the interface is in auto-dial mode, and will
|
||||
attempt to make a connection whenever a network data packet needs
|
||||
the interface's link. Note that this can cause unexpected dialouts,
|
||||
and lead to a high phone bill! Some daemons or other pc's that use
|
||||
this interface can cause this.
|
||||
Incoming connections are also possible.
|
||||
"manual" is a dial mode created to prevent the unexpected dialouts.
|
||||
In this mode, the interface will never make any connections on its
|
||||
own. You must explicitly initiate a connection with "isdnctrl dial
|
||||
isdn0". However, after an idle time of no traffic as configured for
|
||||
the huptimeout value with isdnctrl, the connection _will_ be ended.
|
||||
If you don't want any automatic hangup, set the huptimeout value to 0.
|
||||
"manual" is the default.
|
||||
|
||||
j) Setup the interface with ifconfig as usual, and set a route to it.
|
||||
|
||||
k) (optional) If you run X11 and have Tcl/Tk-wish version 4.0, you can use
|
||||
the script tools/tcltk/isdnmon. You can add actions for line-status
|
||||
changes. See the comments at the beginning of the script for how to
|
||||
do that. There are other tty-based tools in the tools-subdirectory
|
||||
contributed by Michael Knigge (imon), Volker Götz (imontty) and
|
||||
Andreas Kool (isdnmon).
|
||||
|
||||
l) For initial testing, you can set the verbose-level to 2 (default: 0).
|
||||
Then all incoming calls are logged, even if they are not addressed
|
||||
to one of the configured net-interfaces:
|
||||
isdnctrl verbose 2
|
||||
|
||||
Now you are ready! A ping to the set address should now result in an
|
||||
automatic dial-out (look at syslog kernel-messages).
|
||||
The phone numbers and EAZs can be assigned at any time with isdnctrl.
|
||||
You can add as many interfaces as you like with addif following the
|
||||
directions above. Of course, there may be some limitations. But we have
|
||||
tested as many as 20 interfaces without any problem. However, if you
|
||||
don't give an interface name to addif, the kernel will assign a name
|
||||
which starts with "eth". The number of "eth"-interfaces is limited by
|
||||
the kernel.
|
||||
|
||||
5. Additional options for isdnctrl:
|
||||
|
||||
"isdnctrl secure <InterfaceName> on"
|
||||
Only incoming calls, for which the caller-id is listed in the access
|
||||
list of the interface are accepted. You can add caller-id's With the
|
||||
command "isdnctrl addphone <InterfaceName> in <caller-id>"
|
||||
Euro-ISDN does not transmit the leading '0' of the caller-id for an
|
||||
incoming call, therefore you should configure it accordingly.
|
||||
If the real number for the dialout e.g. is "09311234567" the number
|
||||
to configure here is "9311234567". The pattern-match function
|
||||
works similar to the shell mechanism.
|
||||
|
||||
? one arbitrary digit
|
||||
* zero or arbitrary many digits
|
||||
[123] one of the digits in the list
|
||||
[1-5] one digit between '1' and '5'
|
||||
a '^' as the first character in a list inverts the list
|
||||
|
||||
|
||||
"isdnctrl secure <InterfaceName> off"
|
||||
Switch off secure operation (default).
|
||||
|
||||
"isdnctrl ihup <InterfaceName> [on|off]"
|
||||
Switch the hang-up-timer for incoming calls on or off.
|
||||
|
||||
"isdnctrl eaz <InterfaceName>"
|
||||
Returns the EAZ of an interface.
|
||||
|
||||
"isdnctrl delphone <InterfaceName> in|out <number>"
|
||||
Deletes a number from one of the access-lists of the interface.
|
||||
|
||||
"isdnctrl delif <InterfaceName>"
|
||||
Removes the interface (and possible slaves) from the kernel.
|
||||
(You have to unregister it with "ifconfig <InterfaceName> down" before).
|
||||
|
||||
"isdnctrl callback <InterfaceName> [on|off]"
|
||||
Switches an interface to callback-mode. In this mode, an incoming call
|
||||
will be rejected and after this the remote-station will be called. If
|
||||
you test this feature by using ping, some routers will re-dial very
|
||||
quickly, so that the callback from isdn4linux may not be recognized.
|
||||
In this case use ping with the option -i <sec> to increase the interval
|
||||
between echo-packets.
|
||||
|
||||
"isdnctrl cbdelay <InterfaceName> [seconds]"
|
||||
Sets the delay (default 5 sec) between an incoming call and start of
|
||||
dialing when callback is enabled.
|
||||
|
||||
"isdnctrl cbhup <InterfaceName> [on|off]"
|
||||
This enables (default) or disables an active hangup (reject) when getting an
|
||||
incoming call for an interface which is configured for callback.
|
||||
|
||||
"isdnctrl encap <InterfaceName> <EncapType>"
|
||||
Selects the type of packet-encapsulation. The encapsulation can be changed
|
||||
only while an interface is down.
|
||||
|
||||
At the moment the following values are supported:
|
||||
|
||||
rawip (Default) Selects raw-IP-encapsulation. This means, MAC-headers
|
||||
are stripped off.
|
||||
ip IP with type-field. Same as IP but the type-field of the MAC-header
|
||||
is preserved.
|
||||
x25iface X.25 interface encapsulation (first byte semantics as defined in
|
||||
../networking/x25-iface.txt). Use this for running the linux
|
||||
X.25 network protocol stack (AF_X25 sockets) on top of isdn.
|
||||
cisco-h A special-mode for communicating with a Cisco, which is configured
|
||||
to do "hdlc"
|
||||
ethernet No stripping. Packets are sent with full MAC-header.
|
||||
The Ethernet-address of the interface is faked, from its
|
||||
IP-address: fc:fc:i1:i2:i3:i4, where i1-4 are the IP-addr.-values.
|
||||
syncppp Synchronous PPP
|
||||
|
||||
uihdlc HDLC with UI-frame-header (for use with DOS ISPA, option -h1)
|
||||
|
||||
|
||||
NOTE: x25iface encapsulation is currently experimental. Please
|
||||
read README.x25 for further details
|
||||
|
||||
|
||||
Watching packets, using standard-tcpdump will fail for all encapsulations
|
||||
except ethernet because tcpdump does not know how to handle packets
|
||||
without MAC-header. A patch for tcpdump is included in the utility-package
|
||||
mentioned above.
|
||||
|
||||
"isdnctrl l2_prot <InterfaceName> <L2-ProtocolName>"
|
||||
Selects a layer-2-protocol.
|
||||
(With the ICN-driver and the HiSax-driver, "x75i" and "hdlc" is available.
|
||||
With other drivers, "x75ui", "x75bui", "x25dte", "x25dce" may be
|
||||
possible too. See README.x25 for x25 related l2 protocols.)
|
||||
|
||||
isdnctrl l3_prot <InterfaceName> <L3-ProtocolName>
|
||||
The same for layer-3. (At the moment only "trans" is allowed)
|
||||
|
||||
"isdnctrl list <InterfaceName>"
|
||||
Shows all parameters of an interface and the charge-info.
|
||||
Try "all" as the interface name.
|
||||
|
||||
"isdnctrl hangup <InterfaceName>"
|
||||
Forces hangup of an interface.
|
||||
|
||||
"isdnctrl bind <InterfaceName> <DriverId>,<ChannelNumber> [exclusive]"
|
||||
If you are using more than one ISDN card, it is sometimes necessary to
|
||||
dial out using a specific card or even preserve a specific channel for
|
||||
dialout of a specific net-interface. This can be done with the above
|
||||
command. Replace <DriverId> by whatever you assigned while loading the
|
||||
module. The <ChannelNumber> is counted from zero. The upper limit
|
||||
depends on the card used. At the moment no card supports more than
|
||||
2 channels, so the upper limit is one.
|
||||
|
||||
"isdnctrl unbind <InterfaceName>"
|
||||
unbinds a previously bound interface.
|
||||
|
||||
"isdnctrl busreject <DriverId> on|off"
|
||||
If switched on, isdn4linux replies a REJECT to incoming calls, it
|
||||
cannot match to any configured interface.
|
||||
If switched off, nothing happens in this case.
|
||||
You normally should NOT enable this feature, if the ISDN adapter is not
|
||||
the only device connected to the S0-bus. Otherwise it could happen that
|
||||
isdn4linux rejects an incoming call, which belongs to another device on
|
||||
the bus.
|
||||
|
||||
"isdnctrl addslave <InterfaceName> <SlaveName>
|
||||
Creates a slave interface for channel-bundling. Slave interfaces are
|
||||
not seen by the kernel, but their ISDN-part can be configured with
|
||||
isdnctrl as usual. (Phone numbers, EAZ/MSN, timeouts etc.) If more
|
||||
than two channels are to be bundled, feel free to create as many as you
|
||||
want. InterfaceName must be a real interface, NOT a slave. Slave interfaces
|
||||
start dialing, if the master interface resp. the previous slave interface
|
||||
has a load of more than 7000 cps. They hangup if the load goes under 7000
|
||||
cps, according to their "huptimeout"-parameter.
|
||||
|
||||
"isdnctrl sdelay <InterfaceName> secs."
|
||||
This sets the minimum time an Interface has to be fully loaded, until
|
||||
it sends a dial-request to its slave.
|
||||
|
||||
"isdnctrl dial <InterfaceName>"
|
||||
Forces an interface to start dialing even if no packets are to be
|
||||
transferred.
|
||||
|
||||
"isdnctrl mapping <DriverId> MSN0,MSN1,MSN2,...MSN9"
|
||||
This installs a mapping table for EAZ<->MSN-mapping for a single line.
|
||||
Missing MSN's have to be given as "-" or can be omitted, if at the end
|
||||
of the commandline.
|
||||
With this command, it's now possible to have an interface listening to
|
||||
mixed 1TR6- and Euro-Type lines. In this case, the interface has to be
|
||||
configured to a 1TR6-type EAZ (one digit). The mapping is also valid
|
||||
for tty-emulation. Seen from the interface/tty-level the mapping
|
||||
CAN be used, however it's possible to use single tty's/interfaces with
|
||||
real MSN's (more digits) also, in which case the mapping will be ignored.
|
||||
Here is an example:
|
||||
|
||||
You have a 1TR6-type line with base-nr. 1234567 and a Euro-line with
|
||||
MSN's 987654, 987655 and 987656. The DriverId for the Euro-line is "EURO".
|
||||
|
||||
isdnctrl mapping EURO -,987654,987655,987656,-,987655
|
||||
...
|
||||
isdnctrl eaz isdn0 1 # listen on 12345671(1tr6) and 987654(euro)
|
||||
...
|
||||
isdnctrl eaz isdn1 4 # listen on 12345674(1tr6) only.
|
||||
...
|
||||
isdnctrl eaz isdn2 987654 # listen on 987654(euro) only.
|
||||
|
||||
Same scheme is used with AT&E... at the tty's.
|
||||
|
||||
6. If you want to write a new low-level-driver, you are welcome.
|
||||
The interface to the link-level-module is described in the file INTERFACE.
|
||||
If the interface should be expanded for any reason, don't do it
|
||||
on your own, send me a mail containing the proposed changes and
|
||||
some reasoning about them.
|
||||
If other drivers will not be affected, I will include the changes
|
||||
in the next release.
|
||||
For developers only, there is a second mailing-list. Write to me
|
||||
(fritz@isdn4linux.de), if you want to join that list.
|
||||
|
||||
Have fun!
|
||||
|
||||
-Fritz
|
||||
|
|
@ -1,26 +0,0 @@
|
|||
|
||||
The FAQ for isdn4linux
|
||||
======================
|
||||
|
||||
Please note that there is a big FAQ available in the isdn4k-utils.
|
||||
You find it in:
|
||||
isdn4k-utils/FAQ/i4lfaq.sgml
|
||||
|
||||
In case you just want to see the FAQ online, or download the newest version,
|
||||
you can have a look at my website:
|
||||
https://www.mhessler.de/i4lfaq/ (view + download)
|
||||
or:
|
||||
https://www.isdn4linux.de/faq/4lfaq.html (view)
|
||||
|
||||
As the extension tells, the FAQ is in SGML format, and you can convert it
|
||||
into text/html/... format by using the sgml2txt/sgml2html/... tools.
|
||||
Alternatively, you can also do a 'configure; make all' in the FAQ directory.
|
||||
|
||||
|
||||
Please have a look at the FAQ before posting anything in the Mailinglist,
|
||||
or the newsgroup!
|
||||
|
||||
|
||||
Matthias Hessler
|
||||
hessler@isdn4linux.de
|
||||
|
|
@ -1,659 +0,0 @@
|
|||
HiSax is a Linux hardware-level driver for passive ISDN cards with Siemens
|
||||
chipset (ISAC_S 2085/2086/2186, HSCX SAB 82525). It is based on the Teles
|
||||
driver from Jan den Ouden.
|
||||
It is meant to be used with isdn4linux, an ISDN link-level module for Linux
|
||||
written by Fritz Elfert.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
|
||||
Supported cards
|
||||
---------------
|
||||
|
||||
Teles 8.0/16.0/16.3 and compatible ones
|
||||
Teles 16.3c
|
||||
Teles S0/PCMCIA
|
||||
Teles PCI
|
||||
Teles S0Box
|
||||
Creatix S0Box
|
||||
Creatix PnP S0
|
||||
Compaq ISDN S0 ISA card
|
||||
AVM A1 (Fritz, Teledat 150)
|
||||
AVM Fritz PCMCIA
|
||||
AVM Fritz PnP
|
||||
AVM Fritz PCI
|
||||
ELSA Microlink PCC-16, PCF, PCF-Pro, PCC-8
|
||||
ELSA Quickstep 1000
|
||||
ELSA Quickstep 1000PCI
|
||||
ELSA Quickstep 3000 (same settings as QS1000)
|
||||
ELSA Quickstep 3000PCI
|
||||
ELSA PCMCIA
|
||||
ITK ix1-micro Rev.2
|
||||
Eicon Diva 2.0 ISA and PCI (S0 and U interface, no PRO version)
|
||||
Eicon Diva 2.01 ISA and PCI
|
||||
Eicon Diva 2.02 PCI
|
||||
Eicon Diva Piccola
|
||||
ASUSCOM NETWORK INC. ISDNLink 128K PC adapter (order code I-IN100-ST-D)
|
||||
Dynalink IS64PH (OEM version of ASUSCOM NETWORK INC. ISDNLink 128K adapter)
|
||||
PCBIT-DP (OEM version of ASUSCOM NETWORK INC. ISDNLink)
|
||||
HFC-2BS0 based cards (TeleInt SA1)
|
||||
Sedlbauer Speed Card (Speed Win, Teledat 100, PCI, Fax+)
|
||||
Sedlbauer Speed Star/Speed Star2 (PCMCIA)
|
||||
Sedlbauer ISDN-Controller PC/104
|
||||
USR Sportster internal TA (compatible Stollmann tina-pp V3)
|
||||
USR internal TA PCI
|
||||
ith Kommunikationstechnik GmbH MIC 16 ISA card
|
||||
Traverse Technologie NETjet PCI S0 card and NETspider U card
|
||||
Ovislink ISDN sc100-p card (NETjet driver)
|
||||
Dr. Neuhaus Niccy PnP/PCI
|
||||
Siemens I-Surf 1.0
|
||||
Siemens I-Surf 2.0 (with IPAC, try type 12 asuscom)
|
||||
ACER P10
|
||||
HST Saphir
|
||||
Berkom Telekom A4T
|
||||
Scitel Quadro
|
||||
Gazel ISDN cards
|
||||
HFC-PCI based cards
|
||||
Winbond W6692 based cards
|
||||
HFC-S+, HFC-SP/PCMCIA cards
|
||||
formula-n enternow
|
||||
Gerdes Power ISDN
|
||||
|
||||
Note: PCF, PCF-Pro: up to now, only the ISDN part is supported
|
||||
PCC-8: not tested yet
|
||||
Eicon.Diehl Diva U interface not tested
|
||||
|
||||
If you know other passive cards with the Siemens chipset, please let me know.
|
||||
You can combine any card, if there is no conflict between the resources
|
||||
(io, mem, irq).
|
||||
|
||||
|
||||
Configuring the driver
|
||||
----------------------
|
||||
|
||||
The HiSax driver can either be built directly into the kernel or as a module.
|
||||
It can be configured using the command line feature while loading the kernel
|
||||
with LILO or LOADLIN or, if built as a module, using insmod/modprobe with
|
||||
parameters.
|
||||
There is also some config needed before you compile the kernel and/or
|
||||
modules. It is included in the normal "make [menu]config" target at the
|
||||
kernel. Don't forget it, especially to select the right D-channel protocol.
|
||||
|
||||
Please note: In older versions of the HiSax driver, all PnP cards
|
||||
needed to be configured with isapnp and worked only with the HiSax
|
||||
driver used as a module.
|
||||
|
||||
In the current version, HiSax will automatically use the in-kernel
|
||||
ISAPnP support, provided you selected it during kernel configuration
|
||||
(CONFIG_ISAPNP), if you don't give the io=, irq= command line parameters.
|
||||
|
||||
The affected card types are: 4,7,12,14,19,27-30
|
||||
|
||||
a) when built as a module
|
||||
-------------------------
|
||||
|
||||
insmod/modprobe hisax.o \
|
||||
io=iobase irq=IRQ mem=membase type=card_type \
|
||||
protocol=D_channel_protocol id=idstring
|
||||
|
||||
or, if several cards are installed:
|
||||
|
||||
insmod/modprobe hisax.o \
|
||||
io=iobase1,iobase2,... irq=IRQ1,IRQ2,... mem=membase1,membase2,... \
|
||||
type=card_type1,card_type2,... \
|
||||
protocol=D_channel_protocol1,D_channel_protocol2,... \
|
||||
id=idstring1%idstring2 ...
|
||||
|
||||
where "iobaseN" represents the I/O base address of the Nth card, "membaseN"
|
||||
the memory base address of the Nth card, etc.
|
||||
|
||||
The reason for the delimiter "%" being used in the idstrings is that ","
|
||||
won't work with the current modules package.
|
||||
|
||||
The parameters may be specified in any order. For example, the "io"
|
||||
parameter may precede the "irq" parameter, or vice versa. If several
|
||||
cards are installed, the ordering within the comma separated parameter
|
||||
lists must of course be consistent.
|
||||
|
||||
Only parameters applicable to the card type need to be specified. For
|
||||
example, the Teles 16.3 card is not memory-mapped, so the "mem"
|
||||
parameter may be omitted for this card. Sometimes it may be necessary
|
||||
to specify a dummy parameter, however. This is the case when there is
|
||||
a card of a different type later in the list that needs a parameter
|
||||
which the preceding card does not. For instance, if a Teles 16.0 card
|
||||
is listed after a Teles 16.3 card, a dummy memory base parameter of 0
|
||||
must be specified for the 16.3. Instead of a dummy value, the parameter
|
||||
can also be skipped by simply omitting the value. For example:
|
||||
mem=,0xd0000. See example 6 below.
|
||||
|
||||
The parameter for the D-Channel protocol may be omitted if you selected the
|
||||
correct one during kernel config. Valid values are "1" for German 1TR6,
|
||||
"2" for EDSS1 (Euro ISDN), "3" for leased lines (no D-Channel) and "4"
|
||||
for US NI1.
|
||||
With US NI1 you have to include your SPID into the MSN setting in the form
|
||||
<MSN>:<SPID> for example (your phonenumber is 1234 your SPID 5678):
|
||||
AT&E1234:5678 on ttyI interfaces
|
||||
isdnctrl eaz ippp0 1234:5678 on network devices
|
||||
|
||||
The Creatix/Teles PnP cards use io1= and io2= instead of io= for specifying
|
||||
the I/O addresses of the ISAC and HSCX chips, respectively.
|
||||
|
||||
Card types:
|
||||
|
||||
Type Required parameters (in addition to type and protocol)
|
||||
|
||||
1 Teles 16.0 irq, mem, io
|
||||
2 Teles 8.0 irq, mem
|
||||
3 Teles 16.3 (non PnP) irq, io
|
||||
4 Creatix/Teles PnP irq, io0 (ISAC), io1 (HSCX)
|
||||
5 AVM A1 (Fritz) irq, io
|
||||
6 ELSA PCC/PCF cards io or nothing for autodetect (the iobase is
|
||||
required only if you have more than one ELSA
|
||||
card in your PC)
|
||||
7 ELSA Quickstep 1000 irq, io (from isapnp setup)
|
||||
8 Teles 16.3 PCMCIA irq, io
|
||||
9 ITK ix1-micro Rev.2 irq, io
|
||||
10 ELSA PCMCIA irq, io (set with card manager)
|
||||
11 Eicon.Diehl Diva ISA PnP irq, io
|
||||
11 Eicon.Diehl Diva PCI no parameter
|
||||
12 ASUS COM ISDNLink irq, io (from isapnp setup)
|
||||
13 HFC-2BS0 based cards irq, io
|
||||
14 Teles 16.3c PnP irq, io
|
||||
15 Sedlbauer Speed Card irq, io
|
||||
15 Sedlbauer PC/104 irq, io
|
||||
15 Sedlbauer Speed PCI no parameter
|
||||
16 USR Sportster internal irq, io
|
||||
17 MIC card irq, io
|
||||
18 ELSA Quickstep 1000PCI no parameter
|
||||
19 Compaq ISDN S0 ISA card irq, io0, io1, io (from isapnp setup io=IO2)
|
||||
20 NETjet PCI card no parameter
|
||||
21 Teles PCI no parameter
|
||||
22 Sedlbauer Speed Star (PCMCIA) irq, io (set with card manager)
|
||||
24 Dr. Neuhaus Niccy PnP irq, io0, io1 (from isapnp setup)
|
||||
24 Dr. Neuhaus Niccy PCI no parameter
|
||||
25 Teles S0Box irq, io (of the used lpt port)
|
||||
26 AVM A1 PCMCIA (Fritz!) irq, io (set with card manager)
|
||||
27 AVM PnP (Fritz!PnP) irq, io (from isapnp setup)
|
||||
27 AVM PCI (Fritz!PCI) no parameter
|
||||
28 Sedlbauer Speed Fax+ irq, io (from isapnp setup)
|
||||
29 Siemens I-Surf 1.0 irq, io, memory (from isapnp setup)
|
||||
30 ACER P10 irq, io (from isapnp setup)
|
||||
31 HST Saphir irq, io
|
||||
32 Telekom A4T none
|
||||
33 Scitel Quadro subcontroller (4*S0, subctrl 1...4)
|
||||
34 Gazel ISDN cards (ISA) irq,io
|
||||
34 Gazel ISDN cards (PCI) none
|
||||
35 HFC 2BDS0 PCI none
|
||||
36 W6692 based PCI cards none
|
||||
37 HFC 2BDS0 S+, SP irq,io
|
||||
38 NETspider U PCI card none
|
||||
39 HFC 2BDS0 SP/PCMCIA irq,io (set with cardmgr)
|
||||
40 hotplug interface
|
||||
41 Formula-n enter:now PCI none
|
||||
|
||||
At the moment IRQ sharing is only possible with PCI cards. Please make sure
|
||||
that your IRQ is free and enabled for ISA use.
|
||||
|
||||
|
||||
Examples for module loading
|
||||
|
||||
1. Teles 16.3, Euro ISDN, I/O base 280 hex, IRQ 10
|
||||
modprobe hisax type=3 protocol=2 io=0x280 irq=10
|
||||
|
||||
2. Teles 16.0, 1TR6 ISDN, I/O base d80 hex, IRQ 5, Memory d0000 hex
|
||||
modprobe hisax protocol=1 type=1 io=0xd80 mem=0xd0000 irq=5
|
||||
|
||||
3. Fritzcard, Euro ISDN, I/O base 340 hex, IRQ 10 and ELSA PCF, Euro ISDN
|
||||
modprobe hisax type=5,6 protocol=2,2 io=0x340 irq=10 id=Fritz%Elsa
|
||||
|
||||
4. Any ELSA PCC/PCF card, Euro ISDN
|
||||
modprobe hisax type=6 protocol=2
|
||||
|
||||
5. Teles 16.3 PnP, Euro ISDN, with isapnp configured
|
||||
isapnp config: (INT 0 (IRQ 10 (MODE +E)))
|
||||
(IO 0 (BASE 0x0580))
|
||||
(IO 1 (BASE 0x0180))
|
||||
modprobe hisax type=4 protocol=2 irq=10 io0=0x580 io1=0x180
|
||||
|
||||
In the current version of HiSax, you can instead simply use
|
||||
|
||||
modprobe hisax type=4 protocol=2
|
||||
|
||||
if you configured your kernel for ISAPnP. Don't run isapnp in
|
||||
this case!
|
||||
|
||||
6. Teles 16.3, Euro ISDN, I/O base 280 hex, IRQ 12 and
|
||||
Teles 16.0, 1TR6, IRQ 5, Memory d0000 hex
|
||||
modprobe hisax type=3,1 protocol=2,1 io=0x280 mem=0,0xd0000
|
||||
|
||||
Please note the dummy 0 memory address for the Teles 16.3, used as a
|
||||
placeholder as described above, in the last example.
|
||||
|
||||
7. Teles PCMCIA, Euro ISDN, I/O base 180 hex, IRQ 15 (default values)
|
||||
modprobe hisax type=8 protocol=2 io=0x180 irq=15
|
||||
|
||||
|
||||
b) using LILO/LOADLIN, with the driver compiled directly into the kernel
|
||||
------------------------------------------------------------------------
|
||||
|
||||
hisax=typ1,dp1,pa_1,pb_1,pc_1[,typ2,dp2,pa_2 ... \
|
||||
typn,dpn,pa_n,pb_n,pc_n][,idstring1[,idstring2,...,idstringn]]
|
||||
|
||||
where
|
||||
typ1 = type of 1st card (default depends on kernel settings)
|
||||
dp1 = D-Channel protocol of 1st card. 1=1TR6, 2=EDSS1, 3=leased
|
||||
pa_1 = 1st parameter (depending on the type of the card)
|
||||
pb_1 = 2nd parameter ( " " " " " " " )
|
||||
pc_1 = 3rd parameter ( " " " " " " " )
|
||||
|
||||
typ2,dp2,pa_2,pb_2,pc_2 = Parameters of the second card (defaults: none)
|
||||
typn,dpn,pa_n,pb_n,pc_n = Parameters of the n'th card (up to 16 cards are
|
||||
supported)
|
||||
|
||||
idstring = Driver ID for accessing the particular card with utility
|
||||
programs and for identification when using a line monitor
|
||||
(default: "HiSax")
|
||||
|
||||
Note: the ID string must start with an alphabetical character!
|
||||
|
||||
Card types:
|
||||
|
||||
type
|
||||
1 Teles 16.0 pa=irq pb=membase pc=iobase
|
||||
2 Teles 8.0 pa=irq pb=membase
|
||||
3 Teles 16.3 pa=irq pb=iobase
|
||||
4 Creatix/Teles PNP ONLY WORKS AS A MODULE !
|
||||
5 AVM A1 (Fritz) pa=irq pb=iobase
|
||||
6 ELSA PCC/PCF cards pa=iobase or nothing for autodetect
|
||||
7 ELSA Quickstep 1000 ONLY WORKS AS A MODULE !
|
||||
8 Teles S0 PCMCIA pa=irq pb=iobase
|
||||
9 ITK ix1-micro Rev.2 pa=irq pb=iobase
|
||||
10 ELSA PCMCIA pa=irq, pb=io (set with card manager)
|
||||
11 Eicon.Diehl Diva ISAPnP ONLY WORKS AS A MODULE !
|
||||
11 Eicon.Diehl Diva PCI no parameter
|
||||
12 ASUS COM ISDNLink ONLY WORKS AS A MODULE !
|
||||
13 HFC-2BS0 based cards pa=irq pb=io
|
||||
14 Teles 16.3c PnP ONLY WORKS AS A MODULE !
|
||||
15 Sedlbauer Speed Card pa=irq pb=io (Speed Win only as module !)
|
||||
15 Sedlbauer PC/104 pa=irq pb=io
|
||||
15 Sedlbauer Speed PCI no parameter
|
||||
16 USR Sportster internal pa=irq pb=io
|
||||
17 MIC card pa=irq pb=io
|
||||
18 ELSA Quickstep 1000PCI no parameter
|
||||
19 Compaq ISDN S0 ISA card ONLY WORKS AS A MODULE !
|
||||
20 NETjet PCI card no parameter
|
||||
21 Teles PCI no parameter
|
||||
22 Sedlbauer Speed Star (PCMCIA) pa=irq, pb=io (set with card manager)
|
||||
24 Dr. Neuhaus Niccy PnP ONLY WORKS AS A MODULE !
|
||||
24 Dr. Neuhaus Niccy PCI no parameter
|
||||
25 Teles S0Box pa=irq, pb=io (of the used lpt port)
|
||||
26 AVM A1 PCMCIA (Fritz!) pa=irq, pb=io (set with card manager)
|
||||
27 AVM PnP (Fritz!PnP) ONLY WORKS AS A MODULE !
|
||||
27 AVM PCI (Fritz!PCI) no parameter
|
||||
28 Sedlbauer Speed Fax+ ONLY WORKS AS A MODULE !
|
||||
29 Siemens I-Surf 1.0 ONLY WORKS AS A MODULE !
|
||||
30 ACER P10 ONLY WORKS AS A MODULE !
|
||||
31 HST Saphir pa=irq, pb=io
|
||||
32 Telekom A4T no parameter
|
||||
33 Scitel Quadro subcontroller (4*S0, subctrl 1...4)
|
||||
34 Gazel ISDN cards (ISA) pa=irq, pb=io
|
||||
34 Gazel ISDN cards (PCI) no parameter
|
||||
35 HFC 2BDS0 PCI no parameter
|
||||
36 W6692 based PCI cards none
|
||||
37 HFC 2BDS0 S+,SP/PCMCIA ONLY WORKS AS A MODULE !
|
||||
38 NETspider U PCI card none
|
||||
39 HFC 2BDS0 SP/PCMCIA ONLY WORKS AS A MODULE !
|
||||
40 hotplug interface ONLY WORKS AS A MODULE !
|
||||
41 Formula-n enter:now PCI none
|
||||
|
||||
Running the driver
|
||||
------------------
|
||||
|
||||
When you insmod isdn.o and hisax.o (or with the in-kernel version, during
|
||||
boot time), a few lines should appear in your syslog. Look for something like:
|
||||
|
||||
Apr 13 21:01:59 kke01 kernel: HiSax: Driver for Siemens chip set ISDN cards
|
||||
Apr 13 21:01:59 kke01 kernel: HiSax: Version 2.9
|
||||
Apr 13 21:01:59 kke01 kernel: HiSax: Revisions 1.14/1.9/1.10/1.25/1.8
|
||||
Apr 13 21:01:59 kke01 kernel: HiSax: Total 1 card defined
|
||||
Apr 13 21:01:59 kke01 kernel: HiSax: Card 1 Protocol EDSS1 Id=HiSax1 (0)
|
||||
Apr 13 21:01:59 kke01 kernel: HiSax: Elsa driver Rev. 1.13
|
||||
...
|
||||
Apr 13 21:01:59 kke01 kernel: Elsa: PCF-Pro found at 0x360 Rev.:C IRQ 10
|
||||
Apr 13 21:01:59 kke01 kernel: Elsa: timer OK; resetting card
|
||||
Apr 13 21:01:59 kke01 kernel: Elsa: HSCX version A: V2.1 B: V2.1
|
||||
Apr 13 21:01:59 kke01 kernel: Elsa: ISAC 2086/2186 V1.1
|
||||
...
|
||||
Apr 13 21:01:59 kke01 kernel: HiSax: DSS1 Rev. 1.14
|
||||
Apr 13 21:01:59 kke01 kernel: HiSax: 2 channels added
|
||||
|
||||
This means that the card is ready for use.
|
||||
Cabling problems or line-downs are not detected, and only some ELSA cards can
|
||||
detect the S0 power.
|
||||
|
||||
Remember that, according to the new strategy for accessing low-level drivers
|
||||
from within isdn4linux, you should also define a driver ID while doing
|
||||
insmod: Simply append hisax_id=<SomeString> to the insmod command line. This
|
||||
string MUST NOT start with a digit or a small 'x'!
|
||||
|
||||
At this point you can run a 'cat /dev/isdnctrl0' and view debugging messages.
|
||||
|
||||
At the moment, debugging messages are enabled with the hisaxctrl tool:
|
||||
|
||||
hisaxctrl <DriverId> DebugCmd <debugging_flags>
|
||||
|
||||
<DriverId> default is HiSax, if you didn't specify one.
|
||||
|
||||
DebugCmd is 1 for generic debugging
|
||||
11 for layer 1 development debugging
|
||||
13 for layer 3 development debugging
|
||||
|
||||
where <debugging_flags> is the integer sum of the following debugging
|
||||
options you wish enabled:
|
||||
|
||||
With DebugCmd set to 1:
|
||||
|
||||
0x0001 Link-level <--> hardware-level communication
|
||||
0x0002 Top state machine
|
||||
0x0004 D-Channel Frames for isdnlog
|
||||
0x0008 D-Channel Q.921
|
||||
0x0010 B-Channel X.75
|
||||
0x0020 D-Channel l2
|
||||
0x0040 B-Channel l2
|
||||
0x0080 D-Channel link state debugging
|
||||
0x0100 B-Channel link state debugging
|
||||
0x0200 TEI debug
|
||||
0x0400 LOCK debug in callc.c
|
||||
0x0800 More paranoid debug in callc.c (not for normal use)
|
||||
0x1000 D-Channel l1 state debugging
|
||||
0x2000 B-Channel l1 state debugging
|
||||
|
||||
With DebugCmd set to 11:
|
||||
|
||||
0x0001 Warnings (default: on)
|
||||
0x0002 IRQ status
|
||||
0x0004 ISAC
|
||||
0x0008 ISAC FIFO
|
||||
0x0010 HSCX
|
||||
0x0020 HSCX FIFO (attention: full B-Channel output!)
|
||||
0x0040 D-Channel LAPD frame types
|
||||
0x0080 IPAC debug
|
||||
0x0100 HFC receive debug
|
||||
0x0200 ISAC monitor debug
|
||||
0x0400 D-Channel frames for isdnlog (set with 1 0x4 too)
|
||||
0x0800 D-Channel message verbose
|
||||
|
||||
With DebugCmd set to 13:
|
||||
|
||||
1 Warnings (default: on)
|
||||
2 l3 protocol descriptor errors
|
||||
4 l3 state machine
|
||||
8 charge info debugging (1TR6)
|
||||
|
||||
For example, 'hisaxctrl HiSax 1 0x3ff' enables full generic debugging.
|
||||
|
||||
Because of some obscure problems with some switch equipment, the delay
|
||||
between the CONNECT message and sending the first data on the B-channel is now
|
||||
configurable with
|
||||
|
||||
hisaxctrl <DriverId> 2 <delay>
|
||||
<delay> in ms Value between 50 and 800 ms is recommended.
|
||||
|
||||
Downloading Firmware
|
||||
--------------------
|
||||
At the moment, the Sedlbauer speed fax+ is the only card, which
|
||||
needs to download firmware.
|
||||
The firmware is downloaded with the hisaxctrl tool:
|
||||
|
||||
hisaxctrl <DriverId> 9 <firmware_filename>
|
||||
|
||||
<DriverId> default is HiSax, if you didn't specify one,
|
||||
|
||||
where <firmware_filename> is the filename of the firmware file.
|
||||
|
||||
For example, 'hisaxctrl HiSax 9 ISAR.BIN' downloads the firmware for
|
||||
ISAR based cards (like the Sedlbauer speed fax+).
|
||||
|
||||
Warning
|
||||
-------
|
||||
HiSax is a work in progress and may crash your machine.
|
||||
For certification look at HiSax.cert file.
|
||||
|
||||
Limitations
|
||||
-----------
|
||||
At this time, HiSax only works on Euro ISDN lines and German 1TR6 lines.
|
||||
For leased lines see appendix.
|
||||
|
||||
Bugs
|
||||
----
|
||||
If you find any, please let me know.
|
||||
|
||||
|
||||
Thanks
|
||||
------
|
||||
Special thanks to:
|
||||
|
||||
Emil Stephan for the name HiSax which is a mix of HSCX and ISAC.
|
||||
|
||||
Fritz Elfert, Jan den Ouden, Michael Hipp, Michael Wein,
|
||||
Andreas Kool, Pekka Sarnila, Sim Yskes, Johan Myrre'en,
|
||||
Klaus-Peter Nischke (ITK AG), Christof Petig, Werner Fehn (ELSA GmbH),
|
||||
Volker Schmidt
|
||||
Edgar Toernig and Marcus Niemann for the Sedlbauer driver
|
||||
Stephan von Krawczynski
|
||||
Juergen Quade for the Leased Line part
|
||||
Klaus Lichtenwalder (Klaus.Lichtenwalder@WebForum.DE), for ELSA PCMCIA support
|
||||
Enrik Berkhan (enrik@starfleet.inka.de) for S0BOX specific stuff
|
||||
Ton van Rosmalen for Teles PCI
|
||||
Petr Novak <petr.novak@i.cz> for Winbond W6692 support
|
||||
Werner Cornelius <werner@isdn4linux.de> for HFC-PCI, HFC-S(+/P) and supplementary services support
|
||||
and more people who are hunting bugs. (If I forgot somebody, please
|
||||
send me a mail).
|
||||
|
||||
Firma ELSA GmbH
|
||||
Firma Eicon.Diehl GmbH
|
||||
Firma Dynalink NL
|
||||
Firma ASUSCOM NETWORK INC. Taiwan
|
||||
Firma S.u.S.E
|
||||
Firma ith Kommunikationstechnik GmbH
|
||||
Firma Traverse Technologie Australia
|
||||
Firma Medusa GmbH (www.medusa.de).
|
||||
Firma Quant-X Austria for sponsoring a DEC Alpha board+CPU
|
||||
Firma Cologne Chip Designs GmbH
|
||||
|
||||
My girl friend and partner in life Ute for her patience with me.
|
||||
|
||||
|
||||
Enjoy,
|
||||
|
||||
Karsten Keil
|
||||
keil@isdn4linux.de
|
||||
|
||||
|
||||
Appendix: Teles PCMCIA driver
|
||||
-----------------------------
|
||||
|
||||
See
|
||||
http://www.linux.no/teles_cs.txt
|
||||
for instructions.
|
||||
|
||||
Appendix: Linux and ISDN-leased lines
|
||||
-------------------------------------
|
||||
|
||||
Original from Juergen Quade, new version KKe.
|
||||
|
||||
Attention NEW VERSION, the old leased line syntax won't work !!!
|
||||
|
||||
You can use HiSax to connect your Linux-Box via an ISDN leased line
|
||||
to e.g. the Internet:
|
||||
|
||||
1. Build a kernel which includes the HiSax driver either as a module
|
||||
or as part of the kernel.
|
||||
cd /usr/src/linux
|
||||
make menuconfig
|
||||
<ISDN subsystem - ISDN support -- HiSax>
|
||||
make clean; make zImage; make modules; make modules_install
|
||||
2. Install the new kernel
|
||||
cp /usr/src/linux/arch/x86/boot/zImage /etc/kernel/linux.isdn
|
||||
vi /etc/lilo.conf
|
||||
<add new kernel in the bootable image section>
|
||||
lilo
|
||||
3. in case the hisax driver is a "fixed" part of the kernel, configure
|
||||
the driver with lilo:
|
||||
vi /etc/lilo.conf
|
||||
<add HiSax driver parameter in the global section (see below)>
|
||||
lilo
|
||||
Your lilo.conf _might_ look like the following:
|
||||
|
||||
# LILO configuration-file
|
||||
# global section
|
||||
# teles 16.0 on IRQ=5, MEM=0xd8000, PORT=0xd80
|
||||
append="hisax=1,3,5,0xd8000,0xd80,HiSax"
|
||||
# teles 16.3 (non pnp) on IRQ=15, PORT=0xd80
|
||||
# append="hisax=3,3,5,0xd8000,0xd80,HiSax"
|
||||
boot=/dev/sda
|
||||
compact # faster, but won't work on all systems.
|
||||
linear
|
||||
read-only
|
||||
prompt
|
||||
timeout=100
|
||||
vga = normal # force sane state
|
||||
# Linux bootable partition config begins
|
||||
image = /etc/kernel/linux.isdn
|
||||
root = /dev/sda1
|
||||
label = linux.isdn
|
||||
#
|
||||
image = /etc/kernel/linux-2.0.30
|
||||
root = /dev/sda1
|
||||
label = linux.secure
|
||||
|
||||
In the line starting with "append" you have to adapt the parameters
|
||||
according to your card (see above in this file)
|
||||
|
||||
3. boot the new linux.isdn kernel
|
||||
4. start the ISDN subsystem:
|
||||
a) load - if necessary - the modules (depends, whether you compiled
|
||||
the ISDN driver as module or not)
|
||||
According to the type of card you have to specify the necessary
|
||||
driver parameter (irq, io, mem, type, protocol).
|
||||
For the leased line the protocol is "3". See the table above for
|
||||
the parameters, which you have to specify depending on your card.
|
||||
b) configure i4l
|
||||
/sbin/isdnctrl addif isdn0
|
||||
# EAZ 1 -- B1 channel 2 --B2 channel
|
||||
/sbin/isdnctrl eaz isdn0 1
|
||||
/sbin/isdnctrl secure isdn0 on
|
||||
/sbin/isdnctrl huptimeout isdn0 0
|
||||
/sbin/isdnctrl l2_prot isdn0 hdlc
|
||||
# Attention you must not set an outgoing number !!! This won't work !!!
|
||||
# The incoming number is LEASED0 for the first card, LEASED1 for the
|
||||
# second and so on.
|
||||
/sbin/isdnctrl addphone isdn0 in LEASED0
|
||||
# Here is no need to bind the channel.
|
||||
c) in case the remote partner is a CISCO:
|
||||
/sbin/isdnctrl encap isdn0 cisco-h
|
||||
d) configure the interface
|
||||
/sbin/ifconfig isdn0 ${LOCAL_IP} pointopoint ${REMOTE_IP}
|
||||
e) set the routes
|
||||
/sbin/route add -host ${REMOTE_IP} isdn0
|
||||
/sbin/route add default gw ${REMOTE_IP}
|
||||
f) switch the card into leased mode for each used B-channel
|
||||
/sbin/hisaxctrl HiSax 5 1
|
||||
|
||||
Remarks:
|
||||
a) Use state of the art isdn4k-utils
|
||||
|
||||
Here an example script:
|
||||
#!/bin/sh
|
||||
# Start/Stop ISDN leased line connection
|
||||
|
||||
I4L_AS_MODULE=yes
|
||||
I4L_REMOTE_IS_CISCO=no
|
||||
I4L_MODULE_PARAMS="type=16 io=0x268 irq=7 "
|
||||
I4L_DEBUG=no
|
||||
I4L_LEASED_128K=yes
|
||||
LOCAL_IP=192.168.1.1
|
||||
REMOTE_IP=192.168.2.1
|
||||
|
||||
case "$1" in
|
||||
start)
|
||||
echo "Starting ISDN ..."
|
||||
if [ ${I4L_AS_MODULE} = "yes" ]; then
|
||||
echo "loading modules..."
|
||||
/sbin/modprobe hisax ${I4L_MODULE_PARAMS}
|
||||
fi
|
||||
# configure interface
|
||||
/sbin/isdnctrl addif isdn0
|
||||
/sbin/isdnctrl secure isdn0 on
|
||||
if [ ${I4L_DEBUG} = "yes" ]; then
|
||||
/sbin/isdnctrl verbose 7
|
||||
/sbin/hisaxctrl HiSax 1 0xffff
|
||||
/sbin/hisaxctrl HiSax 11 0xff
|
||||
cat /dev/isdnctrl >/tmp/lea.log &
|
||||
fi
|
||||
if [ ${I4L_REMOTE_IS_CISCO} = "yes" ]; then
|
||||
/sbin/isdnctrl encap isdn0 cisco-h
|
||||
fi
|
||||
/sbin/isdnctrl huptimeout isdn0 0
|
||||
# B-CHANNEL 1
|
||||
/sbin/isdnctrl eaz isdn0 1
|
||||
/sbin/isdnctrl l2_prot isdn0 hdlc
|
||||
# 1. card
|
||||
/sbin/isdnctrl addphone isdn0 in LEASED0
|
||||
if [ ${I4L_LEASED_128K} = "yes" ]; then
|
||||
/sbin/isdnctrl addslave isdn0 isdn0s
|
||||
/sbin/isdnctrl secure isdn0s on
|
||||
/sbin/isdnctrl huptimeout isdn0s 0
|
||||
# B-CHANNEL 2
|
||||
/sbin/isdnctrl eaz isdn0s 2
|
||||
/sbin/isdnctrl l2_prot isdn0s hdlc
|
||||
# 1. card
|
||||
/sbin/isdnctrl addphone isdn0s in LEASED0
|
||||
if [ ${I4L_REMOTE_IS_CISCO} = "yes" ]; then
|
||||
/sbin/isdnctrl encap isdn0s cisco-h
|
||||
fi
|
||||
fi
|
||||
/sbin/isdnctrl dialmode isdn0 manual
|
||||
# configure tcp/ip
|
||||
/sbin/ifconfig isdn0 ${LOCAL_IP} pointopoint ${REMOTE_IP}
|
||||
/sbin/route add -host ${REMOTE_IP} isdn0
|
||||
/sbin/route add default gw ${REMOTE_IP}
|
||||
# switch to leased mode
|
||||
# B-CHANNEL 1
|
||||
/sbin/hisaxctrl HiSax 5 1
|
||||
if [ ${I4L_LEASED_128K} = "yes" ]; then
|
||||
# B-CHANNEL 2
|
||||
sleep 10; /* Wait for master */
|
||||
/sbin/hisaxctrl HiSax 5 2
|
||||
fi
|
||||
;;
|
||||
stop)
|
||||
/sbin/ifconfig isdn0 down
|
||||
/sbin/isdnctrl delif isdn0
|
||||
if [ ${I4L_DEBUG} = "yes" ]; then
|
||||
killall cat
|
||||
fi
|
||||
if [ ${I4L_AS_MODULE} = "yes" ]; then
|
||||
/sbin/rmmod hisax
|
||||
/sbin/rmmod isdn
|
||||
/sbin/rmmod ppp
|
||||
/sbin/rmmod slhc
|
||||
fi
|
||||
;;
|
||||
*)
|
||||
echo "Usage: $0 {start|stop}"
|
||||
exit 1
|
||||
esac
|
||||
exit 0
|
|
@ -1,138 +0,0 @@
|
|||
$Id: README.audio,v 1.8 1999/07/11 17:17:29 armin Exp $
|
||||
|
||||
ISDN subsystem for Linux.
|
||||
Description of audio mode.
|
||||
|
||||
When enabled during kernel configuration, the tty emulator of the ISDN
|
||||
subsystem is capable of a reduced set of commands to support audio.
|
||||
This document describes the commands supported and the format of
|
||||
audio data.
|
||||
|
||||
Commands for enabling/disabling audio mode:
|
||||
|
||||
AT+FCLASS=8 Enable audio mode.
|
||||
This affects the following registers:
|
||||
S18: Bits 0 and 2 are set.
|
||||
S16: Set to 48 and any further change to
|
||||
larger values is blocked.
|
||||
AT+FCLASS=0 Disable audio mode.
|
||||
Register 18 is set to 4.
|
||||
AT+FCLASS=? Show possible modes.
|
||||
AT+FCLASS? Report current mode (0 or 8).
|
||||
|
||||
Commands supported in audio mode:
|
||||
|
||||
All audio mode commands have one of the following forms:
|
||||
|
||||
AT+Vxx? Show current setting.
|
||||
AT+Vxx=? Show possible settings.
|
||||
AT+Vxx=v Set simple parameter.
|
||||
AT+Vxx=v,v ... Set complex parameter.
|
||||
|
||||
where xx is a two-character code and v are alphanumerical parameters.
|
||||
The following commands are supported:
|
||||
|
||||
AT+VNH=x Auto hangup setting. NO EFFECT, supported
|
||||
for compatibility only.
|
||||
AT+VNH? Always reporting "1"
|
||||
AT+VNH=? Always reporting "1"
|
||||
|
||||
AT+VIP Reset all audio parameters.
|
||||
|
||||
AT+VLS=x Line select. x is one of the following:
|
||||
0 = No device.
|
||||
2 = Phone line.
|
||||
AT+VLS=? Always reporting "0,2"
|
||||
AT+VLS? Show current line.
|
||||
|
||||
AT+VRX Start recording. Emulator responds with
|
||||
CONNECT and starts sending audio data to
|
||||
the application. See below for data format
|
||||
|
||||
AT+VSD=x,y Set silence-detection parameters.
|
||||
Possible parameters:
|
||||
x = 0 ... 31 sensitivity threshold level.
|
||||
(default 0 , deactivated)
|
||||
y = 0 ... 255 range of interval in units
|
||||
of 0.1 second. (default 70)
|
||||
AT+VSD=? Report possible parameters.
|
||||
AT+VSD? Show current parameters.
|
||||
|
||||
AT+VDD=x,y Set DTMF-detection parameters.
|
||||
Only possible if online and during this connection.
|
||||
Possible parameters:
|
||||
x = 0 ... 15 sensitivity threshold level.
|
||||
(default 0 , I4L soft-decode)
|
||||
(1-15 soft-decode off, hardware on)
|
||||
y = 0 ... 255 tone duration in units of 5ms.
|
||||
Not for I4L soft decode (default 8, 40ms)
|
||||
AT+VDD=? Report possible parameters.
|
||||
AT+VDD? Show current parameters.
|
||||
|
||||
AT+VSM=x Select audio data format.
|
||||
Possible parameters:
|
||||
2 = ADPCM-2
|
||||
3 = ADPCM-3
|
||||
4 = ADPCM-4
|
||||
5 = aLAW
|
||||
6 = uLAW
|
||||
AT+VSM=? Show possible audio formats.
|
||||
|
||||
AT+VTX Start audio playback. Emulator responds
|
||||
with CONNECT and starts sending audio data
|
||||
received from the application via phone line.
|
||||
General behavior and description of data formats/protocol.
|
||||
when a connection is made:
|
||||
|
||||
On incoming calls, if the application responds to a RING
|
||||
with ATA, depending on the calling service, the emulator
|
||||
responds with either CONNECT (data call) or VCON (voice call).
|
||||
|
||||
On outgoing voice calls, the emulator responds with VCON
|
||||
upon connection setup.
|
||||
|
||||
Audio recording.
|
||||
|
||||
When receiving audio data, a kind of bisync protocol is used.
|
||||
Upon AT+VRX command, the emulator responds with CONNECT, and
|
||||
starts sending audio data to the application. There are several
|
||||
escape sequences defined, all using DLE (0x10) as Escape char:
|
||||
|
||||
<DLE><ETX> End of audio data. (i.e. caused by a
|
||||
hangup of the remote side) Emulator stops
|
||||
recording, responding with VCON.
|
||||
<DLE><DC4> Abort recording, (send by appl.) Emulator
|
||||
stops recording, sends DLE,ETX.
|
||||
<DLE><DLE> Escape sequence for DLE in data stream.
|
||||
<DLE>0 Touchtone "0" received.
|
||||
...
|
||||
<DLE>9 Touchtone "9" received.
|
||||
<DLE># Touchtone "#" received.
|
||||
<DLE>* Touchtone "*" received.
|
||||
<DLE>A Touchtone "A" received.
|
||||
<DLE>B Touchtone "B" received.
|
||||
<DLE>C Touchtone "C" received.
|
||||
<DLE>D Touchtone "D" received.
|
||||
|
||||
<DLE>q quiet. Silence detected after non-silence.
|
||||
<DLE>s silence. Silence detected from the
|
||||
start of recording.
|
||||
|
||||
Currently unsupported DLE sequences:
|
||||
|
||||
<DLE>c FAX calling tone received.
|
||||
<DLE>b busy tone received.
|
||||
|
||||
Audio playback.
|
||||
|
||||
When sending audio data, upon AT+VTX command, emulator responds with
|
||||
CONNECT, and starts transferring data from application to the phone line.
|
||||
The same DLE sequences apply to this mode.
|
||||
|
||||
Full-Duplex-Audio:
|
||||
|
||||
When _both_ commands for recording and playback are given in _one_
|
||||
AT-command-line (i.e.: "AT+VTX+VRX"), full-duplex-mode is selected.
|
||||
In this mode, the only way to stop recording is sending <DLE><DC4>
|
||||
and the only way to stop playback is to send <DLE><ETX>.
|
||||
|
|
@ -1,259 +0,0 @@
|
|||
Description of the "concap" encapsulation protocol interface
|
||||
============================================================
|
||||
|
||||
The "concap" interface is intended to be used by network device
|
||||
drivers that need to process an encapsulation protocol.
|
||||
It is assumed that the protocol interacts with a linux network device by
|
||||
- data transmission
|
||||
- connection control (establish, release)
|
||||
Thus, the mnemonic: "CONnection CONtrolling eNCAPsulation Protocol".
|
||||
|
||||
This is currently only used inside the isdn subsystem. But it might
|
||||
also be useful to other kinds of network devices. Thus, if you want
|
||||
to suggest changes that improve usability or performance of the
|
||||
interface, please let me know. I'm willing to include them in future
|
||||
releases (even if I needed to adapt the current isdn code to the
|
||||
changed interface).
|
||||
|
||||
|
||||
Why is this useful?
|
||||
===================
|
||||
|
||||
The encapsulation protocol used on top of WAN connections or permanent
|
||||
point-to-point links are frequently chosen upon bilateral agreement.
|
||||
Thus, a device driver for a certain type of hardware must support
|
||||
several different encapsulation protocols at once.
|
||||
|
||||
The isdn device driver did already support several different
|
||||
encapsulation protocols. The encapsulation protocol is configured by a
|
||||
user space utility (isdnctrl). The isdn network interface code then
|
||||
uses several case statements which select appropriate actions
|
||||
depending on the currently configured encapsulation protocol.
|
||||
|
||||
In contrast, LAN network interfaces always used a single encapsulation
|
||||
protocol which is unique to the hardware type of the interface. The LAN
|
||||
encapsulation is usually done by just sticking a header on the data. Thus,
|
||||
traditional linux network device drivers used to process the
|
||||
encapsulation protocol directly (usually by just providing a hard_header()
|
||||
method in the device structure) using some hardware type specific support
|
||||
functions. This is simple, direct and efficient. But it doesn't fit all
|
||||
the requirements for complex WAN encapsulations.
|
||||
|
||||
|
||||
The configurability of the encapsulation protocol to be used
|
||||
makes isdn network interfaces more flexible, but also much more
|
||||
complex than traditional lan network interfaces.
|
||||
|
||||
|
||||
Many Encapsulation protocols used on top of WAN connections will not just
|
||||
stick a header on the data. They also might need to set up or release
|
||||
the WAN connection. They also might want to send other data for their
|
||||
private purpose over the wire, e.g. ppp does a lot of link level
|
||||
negotiation before the first piece of user data can be transmitted.
|
||||
Such encapsulation protocols for WAN devices are typically more complex
|
||||
than encapsulation protocols for lan devices. Thus, network interface
|
||||
code for typical WAN devices also tends to be more complex.
|
||||
|
||||
|
||||
In order to support Linux' x25 PLP implementation on top of
|
||||
isdn network interfaces I could have introduced yet another branch to
|
||||
the various case statements inside drivers/isdn/isdn_net.c.
|
||||
This eventually made isdn_net.c even more complex. In addition, it made
|
||||
isdn_net.c harder to maintain. Thus, by identifying an abstract
|
||||
interface between the network interface code and the encapsulation
|
||||
protocol, complexity could be reduced and maintainability could be
|
||||
increased.
|
||||
|
||||
|
||||
Likewise, a similar encapsulation protocol will frequently be needed by
|
||||
several different interfaces of even different hardware type, e.g. the
|
||||
synchronous ppp implementation used by the isdn driver and the
|
||||
asynchronous ppp implementation used by the ppp driver have a lot of
|
||||
similar code in them. By cleanly separating the encapsulation protocol
|
||||
from the hardware specific interface stuff such code could be shared
|
||||
better in future.
|
||||
|
||||
|
||||
When operating over dial-up-connections (e.g. telephone lines via modem,
|
||||
non-permanent virtual circuits of wide area networks, ISDN) many
|
||||
encapsulation protocols will need to control the connection. Therefore,
|
||||
some basic connection control primitives are supported. The type and
|
||||
semantics of the connection (i.e the ISO layer where connection service
|
||||
is provided) is outside our scope and might be different depending on
|
||||
the encapsulation protocol used, e.g. for a ppp module using our service
|
||||
on top of a modem connection a connect_request will result in dialing
|
||||
a (somewhere else configured) remote phone number. For an X25-interface
|
||||
module (LAPB semantics, as defined in Documentation/networking/x25-iface.txt)
|
||||
a connect_request will ask for establishing a reliable lapb
|
||||
datalink connection.
|
||||
|
||||
|
||||
The encapsulation protocol currently provides the following
|
||||
service primitives to the network device.
|
||||
|
||||
- create a new encapsulation protocol instance
|
||||
- delete encapsulation protocol instance and free all its resources
|
||||
- initialize (open) the encapsulation protocol instance for use.
|
||||
- deactivate (close) an encapsulation protocol instance.
|
||||
- process (xmit) data handed down by upper protocol layer
|
||||
- receive data from lower (hardware) layer
|
||||
- process connect indication from lower (hardware) layer
|
||||
- process disconnect indication from lower (hardware) layer
|
||||
|
||||
|
||||
The network interface driver accesses those primitives via callbacks
|
||||
provided by the encapsulation protocol instance within a
|
||||
struct concap_proto_ops.
|
||||
|
||||
struct concap_proto_ops{
|
||||
|
||||
/* create a new encapsulation protocol instance of same type */
|
||||
struct concap_proto * (*proto_new) (void);
|
||||
|
||||
/* delete encapsulation protocol instance and free all its resources.
|
||||
cprot may no longer be referenced after calling this */
|
||||
void (*proto_del)(struct concap_proto *cprot);
|
||||
|
||||
/* initialize the protocol's data. To be called at interface startup
|
||||
or when the device driver resets the interface. All services of the
|
||||
encapsulation protocol may be used after this*/
|
||||
int (*restart)(struct concap_proto *cprot,
|
||||
struct net_device *ndev,
|
||||
struct concap_device_ops *dops);
|
||||
|
||||
/* deactivate an encapsulation protocol instance. The encapsulation
|
||||
protocol may not call any *dops methods after this. */
|
||||
int (*close)(struct concap_proto *cprot);
|
||||
|
||||
/* process a frame handed down to us by upper layer */
|
||||
int (*encap_and_xmit)(struct concap_proto *cprot, struct sk_buff *skb);
|
||||
|
||||
/* to be called for each data entity received from lower layer*/
|
||||
int (*data_ind)(struct concap_proto *cprot, struct sk_buff *skb);
|
||||
|
||||
/* to be called when a connection was set up/down.
|
||||
Protocols that don't process these primitives might fill in
|
||||
dummy methods here */
|
||||
int (*connect_ind)(struct concap_proto *cprot);
|
||||
int (*disconn_ind)(struct concap_proto *cprot);
|
||||
};
|
||||
|
||||
|
||||
The data structures are defined in the header file include/linux/concap.h.
|
||||
|
||||
|
||||
A Network interface using encapsulation protocols must also provide
|
||||
some service primitives to the encapsulation protocol:
|
||||
|
||||
- request data being submitted by lower layer (device hardware)
|
||||
- request a connection being set up by lower layer
|
||||
- request a connection being released by lower layer
|
||||
|
||||
The encapsulation protocol accesses those primitives via callbacks
|
||||
provided by the network interface within a struct concap_device_ops.
|
||||
|
||||
struct concap_device_ops{
|
||||
|
||||
/* to request data be submitted by device */
|
||||
int (*data_req)(struct concap_proto *, struct sk_buff *);
|
||||
|
||||
/* Control methods must be set to NULL by devices which do not
|
||||
support connection control. */
|
||||
/* to request a connection be set up */
|
||||
int (*connect_req)(struct concap_proto *);
|
||||
|
||||
/* to request a connection be released */
|
||||
int (*disconn_req)(struct concap_proto *);
|
||||
};
|
||||
|
||||
The network interface does not explicitly provide a receive service
|
||||
because the encapsulation protocol directly calls netif_rx().
|
||||
|
||||
|
||||
|
||||
|
||||
An encapsulation protocol itself is actually the
|
||||
struct concap_proto{
|
||||
struct net_device *net_dev; /* net device using our service */
|
||||
struct concap_device_ops *dops; /* callbacks provided by device */
|
||||
struct concap_proto_ops *pops; /* callbacks provided by us */
|
||||
int flags;
|
||||
void *proto_data; /* protocol specific private data, to
|
||||
be accessed via *pops methods only*/
|
||||
/*
|
||||
:
|
||||
whatever
|
||||
:
|
||||
*/
|
||||
};
|
||||
|
||||
Most of this is filled in when the device requests the protocol to
|
||||
be reset (opend). The network interface must provide the net_dev and
|
||||
dops pointers. Other concap_proto members should be considered private
|
||||
data that are only accessed by the pops callback functions. Likewise,
|
||||
a concap proto should access the network device's private data
|
||||
only by means of the callbacks referred to by the dops pointer.
|
||||
|
||||
|
||||
A possible extended device structure which uses the connection controlling
|
||||
encapsulation services could look like this:
|
||||
|
||||
struct concap_device{
|
||||
struct net_device net_dev;
|
||||
struct my_priv /* device->local stuff */
|
||||
/* the my_priv struct might contain a
|
||||
struct concap_device_ops *dops;
|
||||
to provide the device specific callbacks
|
||||
*/
|
||||
struct concap_proto *cprot; /* callbacks provided by protocol */
|
||||
};
|
||||
|
||||
|
||||
|
||||
Misc Thoughts
|
||||
=============
|
||||
|
||||
The concept of the concap proto might help to reuse protocol code and
|
||||
reduce the complexity of certain network interface implementations.
|
||||
The trade off is that it introduces yet another procedure call layer
|
||||
when processing the protocol. This has of course some impact on
|
||||
performance. However, typically the concap interface will be used by
|
||||
devices attached to slow lines (like telephone, isdn, leased synchronous
|
||||
lines). For such slow lines, the overhead is probably negligible.
|
||||
This might no longer hold for certain high speed WAN links (like
|
||||
ATM).
|
||||
|
||||
|
||||
If general linux network interfaces explicitly supported concap
|
||||
protocols (e.g. by a member struct concap_proto* in struct net_device)
|
||||
then the interface of the service function could be changed
|
||||
by passing a pointer of type (struct net_device*) instead of
|
||||
type (struct concap_proto*). Doing so would make many of the service
|
||||
functions compatible to network device support functions.
|
||||
|
||||
e.g. instead of the concap protocol's service function
|
||||
|
||||
int (*encap_and_xmit)(struct concap_proto *cprot, struct sk_buff *skb);
|
||||
|
||||
we could have
|
||||
|
||||
int (*encap_and_xmit)(struct net_device *ndev, struct sk_buff *skb);
|
||||
|
||||
As this is compatible to the dev->hard_start_xmit() method, the device
|
||||
driver could directly register the concap protocol's encap_and_xmit()
|
||||
function as its hard_start_xmit() method. This would eliminate one
|
||||
procedure call layer.
|
||||
|
||||
|
||||
The device's data request function could also be defined as
|
||||
|
||||
int (*data_req)(struct net_device *ndev, struct sk_buff *skb);
|
||||
|
||||
This might even allow for some protocol stacking. And the network
|
||||
interface might even register the same data_req() function directly
|
||||
as its hard_start_xmit() method when a zero layer encapsulation
|
||||
protocol is configured. Thus, eliminating the performance penalty
|
||||
of the concap interface when a trivial concap protocol is used.
|
||||
Nevertheless, the device remains able to support encapsulation
|
||||
protocol configuration.
|
||||
|
|
@ -1,127 +0,0 @@
|
|||
The isdn diversion services are a supporting module working together with
|
||||
the isdn4linux and the HiSax module for passive cards.
|
||||
Active cards, TAs and cards using a own or other driver than the HiSax
|
||||
module need to be adapted to the HL<->LL interface described in a separate
|
||||
document. The diversion services may be used with all cards supported by
|
||||
the HiSax driver.
|
||||
The diversion kernel interface and controlling tool divertctrl were written
|
||||
by Werner Cornelius (werner@isdn4linux.de or werner@titro.de) under the
|
||||
GNU General Public License.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
Table of contents
|
||||
=================
|
||||
|
||||
1. Features of the i4l diversion services
|
||||
(Or what can the i4l diversion services do for me)
|
||||
|
||||
2. Required hard- and software
|
||||
|
||||
3. Compiling, installing and loading/unloading the module
|
||||
Tracing calling and diversion information
|
||||
|
||||
4. Tracing calling and diversion information
|
||||
|
||||
5. Format of the divert device ASCII output
|
||||
|
||||
|
||||
1. Features of the i4l diversion services
|
||||
(Or what can the i4l diversion services do for me)
|
||||
|
||||
The i4l diversion services offers call forwarding and logging normally
|
||||
only supported by isdn phones. Incoming calls may be diverted
|
||||
unconditionally (CFU), when not reachable (CFNR) or on busy condition
|
||||
(CFB).
|
||||
The diversions may be invoked statically in the providers exchange
|
||||
as normally done by isdn phones. In this case all incoming calls
|
||||
with a special (or all) service identifiers are forwarded if the
|
||||
forwarding reason is met. Activated static services may also be
|
||||
interrogated (queried).
|
||||
The i4l diversion services additionally offers a dynamic version of
|
||||
call forwarding which is not preprogrammed inside the providers exchange
|
||||
but dynamically activated by i4l.
|
||||
In this case all incoming calls are checked by rules that may be
|
||||
compared to the mechanism of ipfwadm or ipchains. If a given rule matches
|
||||
the checking process is finished and the rule matching will be applied
|
||||
to the call.
|
||||
The rules include primary and secondary service identifiers, called
|
||||
number and subaddress, callers number and subaddress and whether the rule
|
||||
matches to all filtered calls or only those when all B-channel resources
|
||||
are exhausted.
|
||||
Actions that may be invoked by a rule are ignore, proceed, reject,
|
||||
direct divert or delayed divert of a call.
|
||||
All incoming calls matching a rule except the ignore rule a reported and
|
||||
logged as ASCII via the proc filesystem (/proc/net/isdn/divert). If proceed
|
||||
is selected the call will be held in a proceeding state (without ringing)
|
||||
for a certain amount of time to let an external program or client decide
|
||||
how to handle the call.
|
||||
|
||||
|
||||
2. Required hard- and software
|
||||
|
||||
For using the i4l diversion services the isdn line must be of a EURO/DSS1
|
||||
type. Additionally the i4l services only work together with the HiSax
|
||||
driver for passive isdn cards. All HiSax supported cards may be used for
|
||||
the diversion purposes.
|
||||
The static diversion services require the provider having static services
|
||||
CFU, CFNR, CFB activated on an MSN-line. The static services may not be
|
||||
used on a point-to-point connection. Further the static services are only
|
||||
available in some countries (for example germany). Countries requiring the
|
||||
keypad protocol for activating static diversions (like the netherlands) are
|
||||
not supported but may use the tty devices for this purpose.
|
||||
The dynamic diversion services may be used in all countries if the provider
|
||||
enables the feature CF (call forwarding). This should work on both MSN- and
|
||||
point-to-point lines.
|
||||
To add and delete rules the additional divertctrl program is needed. This
|
||||
program is part of the isdn4kutils package.
|
||||
|
||||
3. Compiling, installing and loading/unloading the module
|
||||
Tracing calling and diversion information
|
||||
|
||||
|
||||
To compile the i4l code with diversion support you need to say yes to the
|
||||
DSS1 diversion services when selecting the i4l options in the kernel
|
||||
config (menuconfig or config).
|
||||
After having properly activated a make modules and make modules_install all
|
||||
required modules will be correctly installed in the needed modules dirs.
|
||||
As the diversion services are currently not included in the scripts of most
|
||||
standard distributions you will have to add a "insmod dss1_divert" after
|
||||
having loaded the global isdn module.
|
||||
The module can be loaded without any command line parameters.
|
||||
If the module is actually loaded and active may be checked with a
|
||||
"cat /proc/modules" or "ls /proc/net/isdn/divert". The divert file is
|
||||
dynamically created by the diversion module and removed when the module is
|
||||
unloaded.
|
||||
|
||||
|
||||
4. Tracing calling and diversion information
|
||||
|
||||
You also may put a "cat /proc/net/isdn/divert" in the background with the
|
||||
output redirected to a file. Then all actions of the module are logged.
|
||||
The divert file in the proc system may be opened more than once, so in
|
||||
conjunction with inetd and a small remote client on other machines inside
|
||||
your network incoming calls and reactions by the module may be shown on
|
||||
every listening machine.
|
||||
If a call is reported as proceeding an external program or client may
|
||||
specify during a certain amount of time (normally 4 to 10 seconds) what
|
||||
to do with that call.
|
||||
To unload the module all open files to the device in the proc system must
|
||||
be closed. Otherwise the module (and isdn.o) may not be unloaded.
|
||||
|
||||
5. Format of the divert device ASCII output
|
||||
|
||||
To be done later
|
||||
|
|
@ -1,45 +0,0 @@
|
|||
|
||||
Fax with isdn4linux
|
||||
===================
|
||||
|
||||
When enabled during kernel configuration, the tty emulator
|
||||
of the ISDN subsystem is capable of the Fax Class 2 commands.
|
||||
|
||||
This only makes sense under the following conditions :
|
||||
|
||||
- You need the commands as dummy, because you are using
|
||||
hylafax (with patch) for AVM capi.
|
||||
- You want to use the fax capabilities of your isdn-card.
|
||||
(supported cards are listed below)
|
||||
|
||||
|
||||
NOTE: This implementation does *not* support fax with passive
|
||||
ISDN-cards (known as softfax). The low-level driver of
|
||||
the ISDN-card and/or the card itself must support this.
|
||||
|
||||
|
||||
Supported ISDN-Cards
|
||||
--------------------
|
||||
|
||||
Eicon DIVA Server BRI/PCI
|
||||
- full support with both B-channels.
|
||||
|
||||
Eicon DIVA Server 4BRI/PCI
|
||||
- full support with all B-channels.
|
||||
|
||||
Eicon DIVA Server PRI/PCI
|
||||
- full support on amount of B-channels
|
||||
depending on DSPs on board.
|
||||
|
||||
|
||||
|
||||
The command set is known as Class 2 (not Class 2.0) and
|
||||
can be activated by AT+FCLASS=2
|
||||
|
||||
|
||||
The interface between the link-level-module and the hardware-level driver
|
||||
is described in the files INTERFACE.fax and INTERFACE.
|
||||
|
||||
Armin
|
||||
mac@melware.de
|
||||
|
|
@ -48,9 +48,8 @@ GigaSet 307x Device Driver
|
|||
|
||||
1.2. Software
|
||||
--------
|
||||
The driver works with the Kernel CAPI subsystem as well as the old
|
||||
ISDN4Linux subsystem, so it can be used with any software which is able
|
||||
to use CAPI 2.0 or ISDN4Linux for ISDN connections (voice or data).
|
||||
The driver works with the Kernel CAPI subsystem and can be used with any
|
||||
software which is able to use CAPI 2.0 for ISDN connections (voice or data).
|
||||
|
||||
There are some user space tools available at
|
||||
https://sourceforge.net/projects/gigaset307x/
|
||||
|
@ -92,7 +91,7 @@ GigaSet 307x Device Driver
|
|||
gigaset debug debug level (see section 3.2.)
|
||||
|
||||
startmode initial operation mode (see section 2.5.):
|
||||
bas_gigaset ) 1=ISDN4linux/CAPI (default), 0=Unimodem
|
||||
bas_gigaset ) 1=CAPI (default), 0=Unimodem
|
||||
ser_gigaset )
|
||||
usb_gigaset ) cidmode initial Call-ID mode setting (see section
|
||||
2.5.): 1=on (default), 0=off
|
||||
|
@ -154,18 +153,10 @@ GigaSet 307x Device Driver
|
|||
|
||||
2.3. CAPI
|
||||
----
|
||||
If the driver is compiled with CAPI support (kernel configuration option
|
||||
GIGASET_CAPI) the devices will show up as CAPI controllers as soon as the
|
||||
corresponding driver module is loaded, and can then be used with CAPI 2.0
|
||||
kernel and user space applications. For user space access, the module
|
||||
capi.ko must be loaded.
|
||||
|
||||
Legacy ISDN4Linux applications are supported via the capidrv
|
||||
compatibility driver. The kernel module capidrv.ko must be loaded
|
||||
explicitly with the command
|
||||
modprobe capidrv
|
||||
if needed, and cannot be unloaded again without unloading the driver
|
||||
first. (These are limitations of capidrv.)
|
||||
The devices will show up as CAPI controllers as soon as the
|
||||
corresponding driver module is loaded, and can then be used with
|
||||
CAPI 2.0 kernel and user space applications. For user space access,
|
||||
the module capi.ko must be loaded.
|
||||
|
||||
Most distributions handle loading and unloading of the various CAPI
|
||||
modules automatically via the command capiinit(1) from the capi4k-utils
|
||||
|
@ -173,16 +164,6 @@ GigaSet 307x Device Driver
|
|||
Gigaset drivers because it doesn't support more than one module per
|
||||
driver.
|
||||
|
||||
2.4. ISDN4Linux
|
||||
----------
|
||||
If the driver is compiled without CAPI support (native ISDN4Linux
|
||||
variant), it registers the device with the legacy ISDN4Linux subsystem
|
||||
after loading the module. It can then be used with ISDN4Linux
|
||||
applications only. Most distributions provide some configuration utility
|
||||
for setting up that subsystem. Otherwise you can use some HOWTOs like
|
||||
http://www.linuxhaven.de/dlhp/HOWTO/DE-ISDN-HOWTO-5.html
|
||||
|
||||
|
||||
2.5. Unimodem mode
|
||||
-------------
|
||||
In this mode the device works like a modem connected to a serial port
|
||||
|
@ -281,8 +262,7 @@ GigaSet 307x Device Driver
|
|||
number. Dialing "***" (three asterisks) calls all extensions
|
||||
simultaneously (global call).
|
||||
|
||||
This holds for both CAPI 2.0 and ISDN4Linux applications. Unimodem mode
|
||||
does not support internal calls.
|
||||
Unimodem mode does not support internal calls.
|
||||
|
||||
2.8. Unregistered Wireless Devices (M101/M105)
|
||||
-----------------------------------------
|
||||
|
|
|
@ -1,41 +0,0 @@
|
|||
The driver for the HFC-PCI and HFC-PCI-A chips from CCD may be used
|
||||
for many OEM cards using this chips.
|
||||
Additionally the driver has a special feature which makes it possible
|
||||
to read the echo-channel of the isdn bus. So all frames in both directions
|
||||
may be logged.
|
||||
When the echo logging feature is used the number of available B-channels
|
||||
for a HFC-PCI card is reduced to 1. Of course this is only relevant to
|
||||
the card, not to the isdn line.
|
||||
To activate the echo mode the following ioctls must be entered:
|
||||
|
||||
hisaxctrl <driver/cardname> 10 1
|
||||
|
||||
This reduces the available channels to 1. There must not be open connections
|
||||
through this card when entering the command.
|
||||
And then:
|
||||
|
||||
hisaxctrl <driver/cardname> 12 1
|
||||
|
||||
This enables the echo mode. If Hex logging is activated the isdnctrlx
|
||||
devices show a output with a line beginning of HEX: for the providers
|
||||
exchange and ECHO: for isdn devices sending to the provider.
|
||||
|
||||
If more than one HFC-PCI cards are installed, a specific card may be selected
|
||||
at the hisax module load command line. Supply the load command with the desired
|
||||
IO-address of the desired card.
|
||||
Example:
|
||||
There tree cards installed in your machine at IO-base addresses 0xd000, 0xd400
|
||||
and 0xdc00
|
||||
If you want to use the card at 0xd400 standalone you should supply the insmod
|
||||
or depmod with type=35 io=0xd400.
|
||||
If you want to use all three cards, but the order needs to be at 0xdc00,0xd400,
|
||||
0xd000 you may give the parameters type=35,35,35 io=0xdc00,0xd400,0xd00
|
||||
Then the desired card will be the initialised in the desired order.
|
||||
If the io parameter is used the io addresses of all used cards should be
|
||||
supplied else the parameter is assumed 0 and a auto search for a free card is
|
||||
invoked which may not give the wanted result.
|
||||
|
||||
Comments and reports to werner@isdn4linux.de or werner@isdn-development.de
|
||||
|
||||
|
||||
|
|
@ -1,58 +0,0 @@
|
|||
Some additional information for setting up a syncPPP
|
||||
connection using network interfaces.
|
||||
---------------------------------------------------------------
|
||||
|
||||
You need one thing beside the isdn4linux package:
|
||||
|
||||
a patched pppd .. (I called it ipppd to show the difference)
|
||||
|
||||
Compiling isdn4linux with sync PPP:
|
||||
-----------------------------------
|
||||
To compile isdn4linux with the sync PPP part, you have
|
||||
to answer the appropriate question when doing a "make config"
|
||||
Don't forget to load the slhc.o
|
||||
module before the isdn.o module, if VJ-compression support
|
||||
is not compiled into your kernel. (e.g if you have no PPP or
|
||||
CSLIP in the kernel)
|
||||
|
||||
Using isdn4linux with sync PPP:
|
||||
-------------------------------
|
||||
Sync PPP is just another encapsulation for isdn4linux. The
|
||||
name to enable sync PPP encapsulation is 'syncppp' .. e.g:
|
||||
|
||||
/sbin/isdnctrl encap ippp0 syncppp
|
||||
|
||||
The name of the interface is here 'ippp0'. You need
|
||||
one interface with the name 'ippp0' to saturate the
|
||||
ipppd, which checks the ppp version via this interface.
|
||||
Currently, all devices must have the name ipppX where
|
||||
'X' is a decimal value.
|
||||
|
||||
To set up a PPP connection you need the ipppd .. You must start
|
||||
the ipppd once after installing the modules. The ipppd
|
||||
communicates with the isdn4linux link-level driver using the
|
||||
/dev/ippp0 to /dev/ippp15 devices. One ipppd can handle
|
||||
all devices at once. If you want to use two PPP connections
|
||||
at the same time, you have to connect the ipppd to two
|
||||
devices .. and so on.
|
||||
I've implemented one additional option for the ipppd:
|
||||
'useifip' will get (if set to not 0.0.0.0) the IP address
|
||||
for the negotiation from the attached network-interface.
|
||||
(also: ipppd will try to negotiate pointopoint IP as remote IP)
|
||||
You must disable BSD-compression, this implementation can't
|
||||
handle compressed packets.
|
||||
|
||||
Check the etc/rc.isdn.syncppp in the isdn4kernel-util package
|
||||
for an example setup script.
|
||||
|
||||
To use the MPPP stuff, you must configure a slave device
|
||||
with isdn4linux. Now call the ipppd with the '+mp' option.
|
||||
To increase the number of links, you must use the
|
||||
'addlink' option of the isdnctrl tool. (rc.isdn.syncppp.MPPP is
|
||||
an example script)
|
||||
|
||||
enjoy it,
|
||||
michael
|
||||
|
||||
|
||||
|
|
@ -1,184 +0,0 @@
|
|||
|
||||
X.25 support within isdn4linux
|
||||
==============================
|
||||
|
||||
This is alpha/beta test code. Use it completely at your own risk.
|
||||
As new versions appear, the stuff described here might suddenly change
|
||||
or become invalid without notice.
|
||||
|
||||
Keep in mind:
|
||||
|
||||
You are using several new parts of the 2.2.x kernel series which
|
||||
have not been tested in a large scale. Therefore, you might encounter
|
||||
more bugs as usual.
|
||||
|
||||
- If you connect to an X.25 neighbour not operated by yourself, ASK the
|
||||
other side first. Be prepared that bugs in the protocol implementation
|
||||
might result in problems.
|
||||
|
||||
- This implementation has never wiped out my whole hard disk yet. But as
|
||||
this is experimental code, don't blame me if that happened to you.
|
||||
Backing up important data will never harm.
|
||||
|
||||
- Monitor your isdn connections while using this software. This should
|
||||
prevent you from undesired phone bills in case of driver problems.
|
||||
|
||||
|
||||
|
||||
|
||||
How to configure the kernel
|
||||
===========================
|
||||
|
||||
The ITU-T (former CCITT) X.25 network protocol layer has been implemented
|
||||
in the Linux source tree since version 2.1.16. The isdn subsystem might be
|
||||
useful to run X.25 on top of ISDN. If you want to try it, select
|
||||
|
||||
"CCITT X.25 Packet Layer"
|
||||
|
||||
from the networking options as well as
|
||||
|
||||
"ISDN Support" and "X.25 PLP on Top of ISDN"
|
||||
|
||||
from the ISDN subsystem options when you configure your kernel for
|
||||
compilation. You currently also need to enable
|
||||
"Prompt for development and/or incomplete code/drivers" from the
|
||||
"Code maturity level options" menu. For the x25trace utility to work
|
||||
you also need to enable "Packet socket".
|
||||
|
||||
For local testing it is also recommended to enable the isdnloop driver
|
||||
from the isdn subsystem's configuration menu.
|
||||
|
||||
For testing, it is recommended that all isdn drivers and the X.25 PLP
|
||||
protocol are compiled as loadable modules. Like this, you can recover
|
||||
from certain errors by simply unloading and reloading the modules.
|
||||
|
||||
|
||||
|
||||
What's it for? How to use it?
|
||||
=============================
|
||||
|
||||
X.25 on top of isdn might be useful with two different scenarios:
|
||||
|
||||
- You might want to access a public X.25 data network from your Linux box.
|
||||
You can use i4l if you were physically connected to the X.25 switch
|
||||
by an ISDN B-channel (leased line as well as dial up connection should
|
||||
work).
|
||||
|
||||
This corresponds to ITU-T recommendation X.31 Case A (circuit-mode
|
||||
access to PSPDN [packet switched public data network]).
|
||||
|
||||
NOTE: X.31 also covers a Case B (access to PSPDN via virtual
|
||||
circuit / packet mode service). The latter mode (which in theory
|
||||
also allows using the D-channel) is not supported by isdn4linux.
|
||||
It should however be possible to establish such packet mode connections
|
||||
with certain active isdn cards provided that the firmware supports X.31
|
||||
and the driver exports this functionality to the user. Currently,
|
||||
the AVM B1 driver is the only driver which does so. (It should be
|
||||
possible to access D-channel X.31 with active AVM cards using the
|
||||
CAPI interface of the AVM-B1 driver).
|
||||
|
||||
- Or you might want to operate certain ISDN teleservices on your linux
|
||||
box. A lot of those teleservices run on top of the ISO-8208
|
||||
(DTE-DTE mode) network layer protocol. ISO-8208 is essentially the
|
||||
same as ITU-T X.25.
|
||||
|
||||
Popular candidates of such teleservices are EUROfile transfer or any
|
||||
teleservice applying ITU-T recommendation T.90.
|
||||
|
||||
To use the X.25 protocol on top of isdn, just create an isdn network
|
||||
interface as usual, configure your own and/or peer's ISDN numbers,
|
||||
and choose x25iface encapsulation by
|
||||
|
||||
isdnctrl encap <iface-name> x25iface.
|
||||
|
||||
Once encap is set like this, the device can be used by the X.25 packet layer.
|
||||
|
||||
All the stuff needed for X.25 is implemented inside the isdn link
|
||||
level (mainly isdn_net.c and some new source files). Thus, it should
|
||||
work with every existing HL driver. I was able to successfully open X.25
|
||||
connections on top of the isdnloop driver and the hisax driver.
|
||||
"x25iface"-encapsulation bypasses demand dialing. Dialing will be
|
||||
initiated when the upper (X.25 packet) layer requests the lapb datalink to
|
||||
be established. But hangup timeout is still active. Whenever a hangup
|
||||
occurs, all existing X.25 connections on that link will be cleared
|
||||
It is recommended to use sufficiently large hangup-timeouts for the
|
||||
isdn interfaces.
|
||||
|
||||
|
||||
In order to set up a conforming protocol stack you also need to
|
||||
specify the proper l2_prot parameter:
|
||||
|
||||
To operate in ISO-8208 X.25 DTE-DTE mode, use
|
||||
|
||||
isdnctrl l2_prot <iface-name> x75i
|
||||
|
||||
To access an X.25 network switch via isdn (your linux box is the DTE), use
|
||||
|
||||
isdnctrl l2_prot <iface-name> x25dte
|
||||
|
||||
To mimic an X.25 network switch (DCE side of the connection), use
|
||||
|
||||
isdnctrl l2_prot <iface-name> x25dce
|
||||
|
||||
However, x25dte or x25dce is currently not supported by any real HL
|
||||
level driver. The main difference between x75i and x25dte/dce is that
|
||||
x25d[tc]e uses fixed lap_b addresses. With x75i, the side which
|
||||
initiates the isdn connection uses the DTE's lap_b address while the
|
||||
called side used the DCE's lap_b address. Thus, l2_prot x75i might
|
||||
probably work if you access a public X.25 network as long as the
|
||||
corresponding isdn connection is set up by you. At least one test
|
||||
was successful to connect via isdn4linux to an X.25 switch using this
|
||||
trick. At the switch side, a terminal adapter X.21 was used to connect
|
||||
it to the isdn.
|
||||
|
||||
|
||||
How to set up a test installation?
|
||||
==================================
|
||||
|
||||
To test X.25 on top of isdn, you need to get
|
||||
|
||||
- a recent version of the "isdnctrl" program that supports setting the new
|
||||
X.25 specific parameters.
|
||||
|
||||
- the x25-utils-2.X package from
|
||||
ftp://ftp.hes.iki.fi/pub/ham/linux/ax25/x25utils-*
|
||||
(don't confuse the x25-utils with the ax25-utils)
|
||||
|
||||
- an application program that uses linux PF_X25 sockets (some are
|
||||
contained in the x25-util package).
|
||||
|
||||
Before compiling the user level utilities make sure that the compiler/
|
||||
preprocessor will fetch the proper kernel header files of this kernel
|
||||
source tree. Either make /usr/include/linux a symbolic link pointing to
|
||||
this kernel's include/linux directory or set the appropriate compiler flags.
|
||||
|
||||
When all drivers and interfaces are loaded and configured you need to
|
||||
ifconfig the network interfaces up and add X.25-routes to them. Use
|
||||
the usual ifconfig tool.
|
||||
|
||||
ifconfig <iface-name> up
|
||||
|
||||
But a special x25route tool (distributed with the x25-util package)
|
||||
is needed to set up X.25 routes. I.e.
|
||||
|
||||
x25route add 01 <iface-name>
|
||||
|
||||
will cause all x.25 connections to the destination X.25-address
|
||||
"01" to be routed to your created isdn network interface.
|
||||
|
||||
There are currently no real X.25 applications available. However, for
|
||||
tests, the x25-utils package contains a modified version of telnet
|
||||
and telnetd that uses X.25 sockets instead of tcp/ip sockets. You can
|
||||
use those for your first tests. Furthermore, you might check
|
||||
ftp://ftp.hamburg.pop.de/pub/LOCAL/linux/i4l-eft/ which contains some
|
||||
alpha-test implementation ("eftp4linux") of the EUROfile transfer
|
||||
protocol.
|
||||
|
||||
The scripts distributed with the eftp4linux test releases might also
|
||||
provide useful examples for setting up X.25 on top of isdn.
|
||||
|
||||
The x25-utility package also contains an x25trace tool that can be
|
||||
used to monitor X.25 packets received by the network interfaces.
|
||||
The /proc/net/x25* files also contain useful information.
|
||||
|
||||
- Henner
|
|
@ -1,224 +0,0 @@
|
|||
simple isdn4linux PPP FAQ .. to be continued .. not 'debugged'
|
||||
-------------------------------------------------------------------
|
||||
|
||||
Q01: what's pppd, ipppd, syncPPP, asyncPPP ??
|
||||
Q02: error message "this system lacks PPP support"
|
||||
Q03: strange information using 'ifconfig'
|
||||
Q04: MPPP?? What's that and how can I use it ...
|
||||
Q05: I tried MPPP but it doesn't work
|
||||
Q06: can I use asynchronous PPP encapsulation with network devices
|
||||
Q07: A SunISDN machine can't connect to my i4l system
|
||||
Q08: I wanna talk to several machines, which need different configs
|
||||
Q09: Starting the ipppd, I get only error messages from i4l
|
||||
Q10: I wanna use dynamic IP address assignment
|
||||
Q11: I can't connect. How can I check where the problem is.
|
||||
Q12: How can I reduce login delay?
|
||||
|
||||
-------------------------------------------------------------------
|
||||
|
||||
Q01: pppd, ipppd, syncPPP, asyncPPP .. what is that ?
|
||||
what should I use?
|
||||
A: The pppd is for asynchronous PPP .. asynchronous means
|
||||
here, the framing is character based. (e.g when
|
||||
using ttyI* or tty* devices)
|
||||
|
||||
The ipppd handles PPP packets coming in HDLC
|
||||
frames (bit based protocol) ... The PPP driver
|
||||
in isdn4linux pushes all IP packets direct
|
||||
to the network layer and all PPP protocol
|
||||
frames to the /dev/ippp* device.
|
||||
So, the ipppd is a simple external network
|
||||
protocol handler.
|
||||
|
||||
If you login into a remote machine using the
|
||||
/dev/ttyI* devices and then enable PPP on the
|
||||
remote terminal server -> use the 'old' pppd
|
||||
|
||||
If your remote side immediately starts to send
|
||||
frames ... you probably connect to a
|
||||
syncPPP machine .. use the network device part
|
||||
of isdn4linux with the 'syncppp' encapsulation
|
||||
and make sure, that the ipppd is running and
|
||||
connected to at least one /dev/ippp*. Check the
|
||||
isdn4linux manual on how to configure a network device.
|
||||
|
||||
--
|
||||
|
||||
Q02: when I start the ipppd .. I only get the
|
||||
error message "this system lacks PPP support"
|
||||
A: check that at least the device 'ippp0' exists.
|
||||
(you can check this e.g with the program 'ifconfig')
|
||||
The ipppd NEEDS this device under THIS name ..
|
||||
If this device doesn't exists, use:
|
||||
isdnctrl addif ippp0
|
||||
isdnctrl encap ippp0 syncppp
|
||||
... (see isdn4linux doc for more) ...
|
||||
A: Maybe you have compiled the ipppd with another
|
||||
kernel source tree than the kernel you currently
|
||||
run ...
|
||||
|
||||
--
|
||||
|
||||
Q03: when I list the netdevices with ifconfig I see, that
|
||||
my ISDN interface has a HWaddr and IRQ=0 and Base
|
||||
address = 0
|
||||
A: The device is a fake ethernet device .. ignore IRQ and baseaddr
|
||||
You need the HWaddr only for ethernet encapsulation.
|
||||
|
||||
--
|
||||
|
||||
Q04: MPPP?? What's that and how can I use it ...
|
||||
|
||||
A: MPPP or MP or MPP (Warning: MP is also an
|
||||
acronym for 'Multi Processor') stands for
|
||||
Multi Point to Point and means bundling
|
||||
of several channels to one logical stream.
|
||||
To enable MPPP negotiation you must call the
|
||||
ipppd with the '+mp' option.
|
||||
You must also configure a slave device for
|
||||
every additional channel. (see the i4l manual
|
||||
for more)
|
||||
To use channel bundling you must first activate
|
||||
the 'master' or initial call. Now you can add
|
||||
the slave channels with the command:
|
||||
isdnctrl addlink <device>
|
||||
e.g:
|
||||
isdnctrl addlink ippp0
|
||||
This is different from other encapsulations of
|
||||
isdn4linux! With syncPPP, there is no automatic
|
||||
activation of slave devices.
|
||||
|
||||
--
|
||||
|
||||
Q05: I tried MPPP but it doesn't work .. the ipppd
|
||||
writes in the debug log something like:
|
||||
.. rcvd [0][proto=0x3d] c0 00 00 00 80 fd 01 01 00 0a ...
|
||||
.. sent [0][LCP ProtRej id=0x2 00 3d c0 00 00 00 80 fd 01 ...
|
||||
|
||||
A: you forgot to compile MPPP/RFC1717 support into the
|
||||
ISDN Subsystem. Recompile with this option enabled.
|
||||
|
||||
--
|
||||
|
||||
Q06: can I use asynchronous PPP encapsulation
|
||||
over the network interface of isdn4linux ..
|
||||
|
||||
A: No .. that's not possible .. Use the standard
|
||||
PPP package over the /dev/ttyI* devices. You
|
||||
must not use the ipppd for this.
|
||||
|
||||
--
|
||||
|
||||
Q07: A SunISDN machine tries to connect my i4l system,
|
||||
which doesn't work.
|
||||
Checking the debug log I just saw garbage like:
|
||||
!![ ... fill in the line ... ]!!
|
||||
|
||||
A: The Sun tries to talk asynchronous PPP ... i4l
|
||||
can't understand this ... try to use the ttyI*
|
||||
devices with the standard PPP/pppd package
|
||||
|
||||
A: (from Alexanter Strauss: )
|
||||
!![ ... fill in mail ]!!
|
||||
|
||||
--
|
||||
|
||||
Q08: I wanna talk to remote machines, which need
|
||||
a different configuration. The only way
|
||||
I found to do this is to kill the ipppd and
|
||||
start a new one with another config to connect
|
||||
to the second machine.
|
||||
|
||||
A: you must bind a network interface explicitly to
|
||||
an ippp device, where you can connect a (for this
|
||||
interface) individually configured ipppd.
|
||||
|
||||
--
|
||||
|
||||
Q09: When I start the ipppd I only get error messages
|
||||
from the i4l driver ..
|
||||
|
||||
A: When starting, the ipppd calls functions which may
|
||||
trigger a network packet. (e.g gethostbyname()).
|
||||
Without the ipppd (at this moment, it is not
|
||||
fully started) we can't handle this network request.
|
||||
Try to configure hostnames necessary for the ipppd
|
||||
in your local /etc/hosts file or in a way, that
|
||||
your system can resolve it without using an
|
||||
isdn/ippp network-interface.
|
||||
|
||||
--
|
||||
|
||||
Q10: I wanna use dynamic IP address assignment ... How
|
||||
must I configure the network device.
|
||||
|
||||
A: At least you must have a route which forwards
|
||||
a packet to the ippp network-interface to trigger
|
||||
the dial-on-demand.
|
||||
A default route to the ippp-interface will work.
|
||||
Now you must choose a dummy IP address for your
|
||||
interface.
|
||||
If for some reason you can't set the default
|
||||
route to the ippp interface, you may take any
|
||||
address of the subnet from which you expect your
|
||||
dynamic IP number and set a 'network route' for
|
||||
this subnet to the ippp interface.
|
||||
To allow overriding of the dummy address you
|
||||
must call the ipppd with the 'ipcp-accept-local' option.
|
||||
|
||||
A: You must know, how the ipppd gets the addresses it wanna
|
||||
configure. If you don't give any option, the ipppd
|
||||
tries to negotiate the local host address!
|
||||
With the option 'noipdefault' it requests an address
|
||||
from the remote machine. With 'useifip' it gets the
|
||||
addresses from the net interface. Or you set the address
|
||||
on the option line with the <a.b.c.d:e.f.g.h> option.
|
||||
Note: the IP address of the remote machine must be configured
|
||||
locally or the remote machine must send it in an IPCP request.
|
||||
If your side doesn't know the IP address after negotiation, it
|
||||
closes the connection!
|
||||
You must allow overriding of address with the 'ipcp-accept-*'
|
||||
options, if you have set your own or the remote address
|
||||
explicitly.
|
||||
|
||||
A: Maybe you try these options .. e.g:
|
||||
|
||||
/sbin/ipppd :$REMOTE noipdefault /dev/ippp0
|
||||
|
||||
where REMOTE must be the address of the remote machine (the
|
||||
machine, which gives you your address)
|
||||
|
||||
--
|
||||
|
||||
Q11: I can't connect. How can I check where the problem is.
|
||||
|
||||
A: A good help log is the debug output from the ipppd...
|
||||
Check whether you can find there:
|
||||
- only a few LCP-conf-req SENT messages (less then 10)
|
||||
and then a Term-REQ:
|
||||
-> check whether your ISDN card is well configured
|
||||
it seems, that your machine doesn't dial
|
||||
(IRQ,IO,Proto, etc problems)
|
||||
Configure your ISDN card to print debug messages and
|
||||
check the /dev/isdnctrl output next time. There
|
||||
you can see, whether there is activity on the card/line.
|
||||
- there are at least a few RECV messages in the log:
|
||||
-> fine: your card is dialing and your remote machine
|
||||
tries to talk with you. Maybe only a missing
|
||||
authentication. Check your ipppd configuration again.
|
||||
- the ipppd exits for some reason:
|
||||
-> not good ... check /var/adm/syslog and /var/adm/daemon.
|
||||
Could be a bug in the ipppd.
|
||||
|
||||
--
|
||||
|
||||
Q12: How can I reduce login delay?
|
||||
|
||||
A: Log a login session ('debug' log) and check which options
|
||||
your remote side rejects. Next time configure your ipppd
|
||||
to not negotiate these options. Another 'side effect' is, that
|
||||
this increases redundancy. (e.g your remote side is buggy and
|
||||
rejects options in a wrong way).
|
||||
|
||||
|
||||
|
|
@ -220,7 +220,21 @@ Usage
|
|||
In order to use AF_XDP sockets there are two parts needed. The
|
||||
user-space application and the XDP program. For a complete setup and
|
||||
usage example, please refer to the sample application. The user-space
|
||||
side is xdpsock_user.c and the XDP side xdpsock_kern.c.
|
||||
side is xdpsock_user.c and the XDP side is part of libbpf.
|
||||
|
||||
The XDP code sample included in tools/lib/bpf/xsk.c is the following::
|
||||
|
||||
SEC("xdp_sock") int xdp_sock_prog(struct xdp_md *ctx)
|
||||
{
|
||||
int index = ctx->rx_queue_index;
|
||||
|
||||
// A set entry here means that the correspnding queue_id
|
||||
// has an active AF_XDP socket bound to it.
|
||||
if (bpf_map_lookup_elem(&xsks_map, &index))
|
||||
return bpf_redirect_map(&xsks_map, index, 0);
|
||||
|
||||
return XDP_PASS;
|
||||
}
|
||||
|
||||
Naive ring dequeue and enqueue could look like this::
|
||||
|
||||
|
|
|
@ -73,7 +73,7 @@ operation.
|
|||
AQ is used for submitting management commands, and the
|
||||
results/responses are reported asynchronously through ACQ.
|
||||
|
||||
ENA introduces a very small set of management commands with room for
|
||||
ENA introduces a small set of management commands with room for
|
||||
vendor-specific extensions. Most of the management operations are
|
||||
framed in a generic Get/Set feature command.
|
||||
|
||||
|
@ -202,11 +202,14 @@ delay value to each level.
|
|||
The user can enable/disable adaptive moderation, modify the interrupt
|
||||
delay table and restore its default values through sysfs.
|
||||
|
||||
RX copybreak:
|
||||
=============
|
||||
The rx_copybreak is initialized by default to ENA_DEFAULT_RX_COPYBREAK
|
||||
and can be configured by the ETHTOOL_STUNABLE command of the
|
||||
SIOCETHTOOL ioctl.
|
||||
|
||||
SKB:
|
||||
====
|
||||
The driver-allocated SKB for frames received from Rx handling using
|
||||
NAPI context. The allocation method depends on the size of the packet.
|
||||
If the frame length is larger than rx_copybreak, napi_get_frags()
|
||||
|
|
|
@ -0,0 +1,439 @@
|
|||
aQuantia AQtion Driver for the aQuantia Multi-Gigabit PCI Express Family of
|
||||
Ethernet Adapters
|
||||
=============================================================================
|
||||
|
||||
Contents
|
||||
========
|
||||
|
||||
- Identifying Your Adapter
|
||||
- Configuration
|
||||
- Supported ethtool options
|
||||
- Command Line Parameters
|
||||
- Config file parameters
|
||||
- Support
|
||||
- License
|
||||
|
||||
Identifying Your Adapter
|
||||
========================
|
||||
|
||||
The driver in this release is compatible with AQC-100, AQC-107, AQC-108 based ethernet adapters.
|
||||
|
||||
|
||||
SFP+ Devices (for AQC-100 based adapters)
|
||||
----------------------------------
|
||||
|
||||
This release tested with passive Direct Attach Cables (DAC) and SFP+/LC Optical Transceiver.
|
||||
|
||||
Configuration
|
||||
=========================
|
||||
Viewing Link Messages
|
||||
---------------------
|
||||
Link messages will not be displayed to the console if the distribution is
|
||||
restricting system messages. In order to see network driver link messages on
|
||||
your console, set dmesg to eight by entering the following:
|
||||
|
||||
dmesg -n 8
|
||||
|
||||
NOTE: This setting is not saved across reboots.
|
||||
|
||||
Jumbo Frames
|
||||
------------
|
||||
The driver supports Jumbo Frames for all adapters. Jumbo Frames support is
|
||||
enabled by changing the MTU to a value larger than the default of 1500.
|
||||
The maximum value for the MTU is 16000. Use the `ip` command to
|
||||
increase the MTU size. For example:
|
||||
|
||||
ip link set mtu 16000 dev enp1s0
|
||||
|
||||
ethtool
|
||||
-------
|
||||
The driver utilizes the ethtool interface for driver configuration and
|
||||
diagnostics, as well as displaying statistical information. The latest
|
||||
ethtool version is required for this functionality.
|
||||
|
||||
NAPI
|
||||
----
|
||||
NAPI (Rx polling mode) is supported in the atlantic driver.
|
||||
|
||||
Supported ethtool options
|
||||
============================
|
||||
Viewing adapter settings
|
||||
---------------------
|
||||
ethtool <ethX>
|
||||
|
||||
Output example:
|
||||
|
||||
Settings for enp1s0:
|
||||
Supported ports: [ TP ]
|
||||
Supported link modes: 100baseT/Full
|
||||
1000baseT/Full
|
||||
10000baseT/Full
|
||||
2500baseT/Full
|
||||
5000baseT/Full
|
||||
Supported pause frame use: Symmetric
|
||||
Supports auto-negotiation: Yes
|
||||
Supported FEC modes: Not reported
|
||||
Advertised link modes: 100baseT/Full
|
||||
1000baseT/Full
|
||||
10000baseT/Full
|
||||
2500baseT/Full
|
||||
5000baseT/Full
|
||||
Advertised pause frame use: Symmetric
|
||||
Advertised auto-negotiation: Yes
|
||||
Advertised FEC modes: Not reported
|
||||
Speed: 10000Mb/s
|
||||
Duplex: Full
|
||||
Port: Twisted Pair
|
||||
PHYAD: 0
|
||||
Transceiver: internal
|
||||
Auto-negotiation: on
|
||||
MDI-X: Unknown
|
||||
Supports Wake-on: g
|
||||
Wake-on: d
|
||||
Link detected: yes
|
||||
|
||||
---
|
||||
Note: AQrate speeds (2.5/5 Gb/s) will be displayed only with linux kernels > 4.10.
|
||||
But you can still use these speeds:
|
||||
ethtool -s eth0 autoneg off speed 2500
|
||||
|
||||
Viewing adapter information
|
||||
---------------------
|
||||
ethtool -i <ethX>
|
||||
|
||||
Output example:
|
||||
|
||||
driver: atlantic
|
||||
version: 5.2.0-050200rc5-generic-kern
|
||||
firmware-version: 3.1.78
|
||||
expansion-rom-version:
|
||||
bus-info: 0000:01:00.0
|
||||
supports-statistics: yes
|
||||
supports-test: no
|
||||
supports-eeprom-access: no
|
||||
supports-register-dump: yes
|
||||
supports-priv-flags: no
|
||||
|
||||
|
||||
Viewing Ethernet adapter statistics:
|
||||
---------------------
|
||||
ethtool -S <ethX>
|
||||
|
||||
Output example:
|
||||
NIC statistics:
|
||||
InPackets: 13238607
|
||||
InUCast: 13293852
|
||||
InMCast: 52
|
||||
InBCast: 3
|
||||
InErrors: 0
|
||||
OutPackets: 23703019
|
||||
OutUCast: 23704941
|
||||
OutMCast: 67
|
||||
OutBCast: 11
|
||||
InUCastOctects: 213182760
|
||||
OutUCastOctects: 22698443
|
||||
InMCastOctects: 6600
|
||||
OutMCastOctects: 8776
|
||||
InBCastOctects: 192
|
||||
OutBCastOctects: 704
|
||||
InOctects: 2131839552
|
||||
OutOctects: 226938073
|
||||
InPacketsDma: 95532300
|
||||
OutPacketsDma: 59503397
|
||||
InOctetsDma: 1137102462
|
||||
OutOctetsDma: 2394339518
|
||||
InDroppedDma: 0
|
||||
Queue[0] InPackets: 23567131
|
||||
Queue[0] OutPackets: 20070028
|
||||
Queue[0] InJumboPackets: 0
|
||||
Queue[0] InLroPackets: 0
|
||||
Queue[0] InErrors: 0
|
||||
Queue[1] InPackets: 45428967
|
||||
Queue[1] OutPackets: 11306178
|
||||
Queue[1] InJumboPackets: 0
|
||||
Queue[1] InLroPackets: 0
|
||||
Queue[1] InErrors: 0
|
||||
Queue[2] InPackets: 3187011
|
||||
Queue[2] OutPackets: 13080381
|
||||
Queue[2] InJumboPackets: 0
|
||||
Queue[2] InLroPackets: 0
|
||||
Queue[2] InErrors: 0
|
||||
Queue[3] InPackets: 23349136
|
||||
Queue[3] OutPackets: 15046810
|
||||
Queue[3] InJumboPackets: 0
|
||||
Queue[3] InLroPackets: 0
|
||||
Queue[3] InErrors: 0
|
||||
|
||||
Interrupt coalescing support
|
||||
---------------------------------
|
||||
ITR mode, TX/RX coalescing timings could be viewed with:
|
||||
|
||||
ethtool -c <ethX>
|
||||
|
||||
and changed with:
|
||||
|
||||
ethtool -C <ethX> tx-usecs <usecs> rx-usecs <usecs>
|
||||
|
||||
To disable coalescing:
|
||||
|
||||
ethtool -C <ethX> tx-usecs 0 rx-usecs 0 tx-max-frames 1 tx-max-frames 1
|
||||
|
||||
Wake on LAN support
|
||||
---------------------------------
|
||||
|
||||
WOL support by magic packet:
|
||||
|
||||
ethtool -s <ethX> wol g
|
||||
|
||||
To disable WOL:
|
||||
|
||||
ethtool -s <ethX> wol d
|
||||
|
||||
Set and check the driver message level
|
||||
---------------------------------
|
||||
|
||||
Set message level
|
||||
|
||||
ethtool -s <ethX> msglvl <level>
|
||||
|
||||
Level values:
|
||||
|
||||
0x0001 - general driver status.
|
||||
0x0002 - hardware probing.
|
||||
0x0004 - link state.
|
||||
0x0008 - periodic status check.
|
||||
0x0010 - interface being brought down.
|
||||
0x0020 - interface being brought up.
|
||||
0x0040 - receive error.
|
||||
0x0080 - transmit error.
|
||||
0x0200 - interrupt handling.
|
||||
0x0400 - transmit completion.
|
||||
0x0800 - receive completion.
|
||||
0x1000 - packet contents.
|
||||
0x2000 - hardware status.
|
||||
0x4000 - Wake-on-LAN status.
|
||||
|
||||
By default, the level of debugging messages is set 0x0001(general driver status).
|
||||
|
||||
Check message level
|
||||
|
||||
ethtool <ethX> | grep "Current message level"
|
||||
|
||||
If you want to disable the output of messages
|
||||
|
||||
ethtool -s <ethX> msglvl 0
|
||||
|
||||
RX flow rules (ntuple filters)
|
||||
---------------------------------
|
||||
There are separate rules supported, that applies in that order:
|
||||
1. 16 VLAN ID rules
|
||||
2. 16 L2 EtherType rules
|
||||
3. 8 L3/L4 5-Tuple rules
|
||||
|
||||
|
||||
The driver utilizes the ethtool interface for configuring ntuple filters,
|
||||
via "ethtool -N <device> <filter>".
|
||||
|
||||
To enable or disable the RX flow rules:
|
||||
|
||||
ethtool -K ethX ntuple <on|off>
|
||||
|
||||
When disabling ntuple filters, all the user programed filters are
|
||||
flushed from the driver cache and hardware. All needed filters must
|
||||
be re-added when ntuple is re-enabled.
|
||||
|
||||
Because of the fixed order of the rules, the location of filters is also fixed:
|
||||
- Locations 0 - 15 for VLAN ID filters
|
||||
- Locations 16 - 31 for L2 EtherType filters
|
||||
- Locations 32 - 39 for L3/L4 5-tuple filters (locations 32, 36 for IPv6)
|
||||
|
||||
The L3/L4 5-tuple (protocol, source and destination IP address, source and
|
||||
destination TCP/UDP/SCTP port) is compared against 8 filters. For IPv4, up to
|
||||
8 source and destination addresses can be matched. For IPv6, up to 2 pairs of
|
||||
addresses can be supported. Source and destination ports are only compared for
|
||||
TCP/UDP/SCTP packets.
|
||||
|
||||
To add a filter that directs packet to queue 5, use <-N|-U|--config-nfc|--config-ntuple> switch:
|
||||
|
||||
ethtool -N <ethX> flow-type udp4 src-ip 10.0.0.1 dst-ip 10.0.0.2 src-port 2000 dst-port 2001 action 5 <loc 32>
|
||||
|
||||
- action is the queue number.
|
||||
- loc is the rule number.
|
||||
|
||||
For "flow-type ip4|udp4|tcp4|sctp4|ip6|udp6|tcp6|sctp6" you must set the loc
|
||||
number within 32 - 39.
|
||||
For "flow-type ip4|udp4|tcp4|sctp4|ip6|udp6|tcp6|sctp6" you can set 8 rules
|
||||
for traffic IPv4 or you can set 2 rules for traffic IPv6. Loc number traffic
|
||||
IPv6 is 32 and 36.
|
||||
At the moment you can not use IPv4 and IPv6 filters at the same time.
|
||||
|
||||
Example filter for IPv6 filter traffic:
|
||||
|
||||
sudo ethtool -N <ethX> flow-type tcp6 src-ip 2001:db8:0:f101::1 dst-ip 2001:db8:0:f101::2 action 1 loc 32
|
||||
sudo ethtool -N <ethX> flow-type ip6 src-ip 2001:db8:0:f101::2 dst-ip 2001:db8:0:f101::5 action -1 loc 36
|
||||
|
||||
Example filter for IPv4 filter traffic:
|
||||
|
||||
sudo ethtool -N <ethX> flow-type udp4 src-ip 10.0.0.4 dst-ip 10.0.0.7 src-port 2000 dst-port 2001 loc 32
|
||||
sudo ethtool -N <ethX> flow-type tcp4 src-ip 10.0.0.3 dst-ip 10.0.0.9 src-port 2000 dst-port 2001 loc 33
|
||||
sudo ethtool -N <ethX> flow-type ip4 src-ip 10.0.0.6 dst-ip 10.0.0.4 loc 34
|
||||
|
||||
If you set action -1, then all traffic corresponding to the filter will be discarded.
|
||||
The maximum value action is 31.
|
||||
|
||||
|
||||
The VLAN filter (VLAN id) is compared against 16 filters.
|
||||
VLAN id must be accompanied by mask 0xF000. That is to distinguish VLAN filter
|
||||
from L2 Ethertype filter with UserPriority since both User Priority and VLAN ID
|
||||
are passed in the same 'vlan' parameter.
|
||||
|
||||
To add a filter that directs packets from VLAN 2001 to queue 5:
|
||||
ethtool -N <ethX> flow-type ip4 vlan 2001 m 0xF000 action 1 loc 0
|
||||
|
||||
|
||||
L2 EtherType filters allows filter packet by EtherType field or both EtherType
|
||||
and User Priority (PCP) field of 802.1Q.
|
||||
UserPriority (vlan) parameter must be accompanied by mask 0x1FFF. That is to
|
||||
distinguish VLAN filter from L2 Ethertype filter with UserPriority since both
|
||||
User Priority and VLAN ID are passed in the same 'vlan' parameter.
|
||||
|
||||
To add a filter that directs IP4 packess of priority 3 to queue 3:
|
||||
ethtool -N <ethX> flow-type ether proto 0x800 vlan 0x600 m 0x1FFF action 3 loc 16
|
||||
|
||||
|
||||
To see the list of filters currently present:
|
||||
|
||||
ethtool <-u|-n|--show-nfc|--show-ntuple> <ethX>
|
||||
|
||||
Rules may be deleted from the table itself. This is done using:
|
||||
|
||||
sudo ethtool <-N|-U|--config-nfc|--config-ntuple> <ethX> delete <loc>
|
||||
|
||||
- loc is the rule number to be deleted.
|
||||
|
||||
Rx filters is an interface to load the filter table that funnels all flow
|
||||
into queue 0 unless an alternative queue is specified using "action". In that
|
||||
case, any flow that matches the filter criteria will be directed to the
|
||||
appropriate queue. RX filters is supported on all kernels 2.6.30 and later.
|
||||
|
||||
RSS for UDP
|
||||
---------------------------------
|
||||
Currently, NIC does not support RSS for fragmented IP packets, which leads to
|
||||
incorrect working of RSS for fragmented UDP traffic. To disable RSS for UDP the
|
||||
RX Flow L3/L4 rule may be used.
|
||||
|
||||
Example:
|
||||
ethtool -N eth0 flow-type udp4 action 0 loc 32
|
||||
|
||||
Command Line Parameters
|
||||
=======================
|
||||
The following command line parameters are available on atlantic driver:
|
||||
|
||||
aq_itr -Interrupt throttling mode
|
||||
----------------------------------------
|
||||
Accepted values: 0, 1, 0xFFFF
|
||||
Default value: 0xFFFF
|
||||
0 - Disable interrupt throttling.
|
||||
1 - Enable interrupt throttling and use specified tx and rx rates.
|
||||
0xFFFF - Auto throttling mode. Driver will choose the best RX and TX
|
||||
interrupt throtting settings based on link speed.
|
||||
|
||||
aq_itr_tx - TX interrupt throttle rate
|
||||
----------------------------------------
|
||||
Accepted values: 0 - 0x1FF
|
||||
Default value: 0
|
||||
TX side throttling in microseconds. Adapter will setup maximum interrupt delay
|
||||
to this value. Minimum interrupt delay will be a half of this value
|
||||
|
||||
aq_itr_rx - RX interrupt throttle rate
|
||||
----------------------------------------
|
||||
Accepted values: 0 - 0x1FF
|
||||
Default value: 0
|
||||
RX side throttling in microseconds. Adapter will setup maximum interrupt delay
|
||||
to this value. Minimum interrupt delay will be a half of this value
|
||||
|
||||
Note: ITR settings could be changed in runtime by ethtool -c means (see below)
|
||||
|
||||
Config file parameters
|
||||
=======================
|
||||
For some fine tuning and performance optimizations,
|
||||
some parameters can be changed in the {source_dir}/aq_cfg.h file.
|
||||
|
||||
AQ_CFG_RX_PAGEORDER
|
||||
----------------------------------------
|
||||
Default value: 0
|
||||
RX page order override. Thats a power of 2 number of RX pages allocated for
|
||||
each descriptor. Received descriptor size is still limited by AQ_CFG_RX_FRAME_MAX.
|
||||
Increasing pageorder makes page reuse better (actual on iommu enabled systems).
|
||||
|
||||
AQ_CFG_RX_REFILL_THRES
|
||||
----------------------------------------
|
||||
Default value: 32
|
||||
RX refill threshold. RX path will not refill freed descriptors until the
|
||||
specified number of free descriptors is observed. Larger values may help
|
||||
better page reuse but may lead to packet drops as well.
|
||||
|
||||
AQ_CFG_VECS_DEF
|
||||
------------------------------------------------------------
|
||||
Number of queues
|
||||
Valid Range: 0 - 8 (up to AQ_CFG_VECS_MAX)
|
||||
Default value: 8
|
||||
Notice this value will be capped by the number of cores available on the system.
|
||||
|
||||
AQ_CFG_IS_RSS_DEF
|
||||
------------------------------------------------------------
|
||||
Enable/disable Receive Side Scaling
|
||||
|
||||
This feature allows the adapter to distribute receive processing
|
||||
across multiple CPU-cores and to prevent from overloading a single CPU core.
|
||||
|
||||
Valid values
|
||||
0 - disabled
|
||||
1 - enabled
|
||||
|
||||
Default value: 1
|
||||
|
||||
AQ_CFG_NUM_RSS_QUEUES_DEF
|
||||
------------------------------------------------------------
|
||||
Number of queues for Receive Side Scaling
|
||||
Valid Range: 0 - 8 (up to AQ_CFG_VECS_DEF)
|
||||
|
||||
Default value: AQ_CFG_VECS_DEF
|
||||
|
||||
AQ_CFG_IS_LRO_DEF
|
||||
------------------------------------------------------------
|
||||
Enable/disable Large Receive Offload
|
||||
|
||||
This offload enables the adapter to coalesce multiple TCP segments and indicate
|
||||
them as a single coalesced unit to the OS networking subsystem.
|
||||
The system consumes less energy but it also introduces more latency in packets processing.
|
||||
|
||||
Valid values
|
||||
0 - disabled
|
||||
1 - enabled
|
||||
|
||||
Default value: 1
|
||||
|
||||
AQ_CFG_TX_CLEAN_BUDGET
|
||||
----------------------------------------
|
||||
Maximum descriptors to cleanup on TX at once.
|
||||
Default value: 256
|
||||
|
||||
After the aq_cfg.h file changed the driver must be rebuilt to take effect.
|
||||
|
||||
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 support@aquantia.com
|
||||
|
||||
License
|
||||
=======
|
||||
|
||||
aQuantia Corporation Network Driver
|
||||
Copyright(c) 2014 - 2019 aQuantia Corporation.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it
|
||||
under the terms and conditions of the GNU General Public License,
|
||||
version 2, as published by the Free Software Foundation.
|
|
@ -0,0 +1,123 @@
|
|||
.. SPDX-License-Identifier: GPL-2.0+
|
||||
|
||||
==============================================================
|
||||
Linux kernel driver for Compute Engine Virtual Ethernet (gve):
|
||||
==============================================================
|
||||
|
||||
Supported Hardware
|
||||
===================
|
||||
The GVE driver binds to a single PCI device id used by the virtual
|
||||
Ethernet device found in some Compute Engine VMs.
|
||||
|
||||
+--------------+----------+---------+
|
||||
|Field | Value | Comments|
|
||||
+==============+==========+=========+
|
||||
|Vendor ID | `0x1AE0` | Google |
|
||||
+--------------+----------+---------+
|
||||
|Device ID | `0x0042` | |
|
||||
+--------------+----------+---------+
|
||||
|Sub-vendor ID | `0x1AE0` | Google |
|
||||
+--------------+----------+---------+
|
||||
|Sub-device ID | `0x0058` | |
|
||||
+--------------+----------+---------+
|
||||
|Revision ID | `0x0` | |
|
||||
+--------------+----------+---------+
|
||||
|Device Class | `0x200` | Ethernet|
|
||||
+--------------+----------+---------+
|
||||
|
||||
PCI Bars
|
||||
========
|
||||
The gVNIC PCI device exposes three 32-bit memory BARS:
|
||||
- Bar0 - Device configuration and status registers.
|
||||
- Bar1 - MSI-X vector table
|
||||
- Bar2 - IRQ, RX and TX doorbells
|
||||
|
||||
Device Interactions
|
||||
===================
|
||||
The driver interacts with the device in the following ways:
|
||||
- Registers
|
||||
- A block of MMIO registers
|
||||
- See gve_register.h for more detail
|
||||
- Admin Queue
|
||||
- See description below
|
||||
- Reset
|
||||
- At any time the device can be reset
|
||||
- Interrupts
|
||||
- See supported interrupts below
|
||||
- Transmit and Receive Queues
|
||||
- See description below
|
||||
|
||||
Registers
|
||||
---------
|
||||
All registers are MMIO and big endian.
|
||||
|
||||
The registers are used for initializing and configuring the device as well as
|
||||
querying device status in response to management interrupts.
|
||||
|
||||
Admin Queue (AQ)
|
||||
----------------
|
||||
The Admin Queue is a PAGE_SIZE memory block, treated as an array of AQ
|
||||
commands, used by the driver to issue commands to the device and set up
|
||||
resources.The driver and the device maintain a count of how many commands
|
||||
have been submitted and executed. To issue AQ commands, the driver must do
|
||||
the following (with proper locking):
|
||||
|
||||
1) Copy new commands into next available slots in the AQ array
|
||||
2) Increment its counter by he number of new commands
|
||||
3) Write the counter into the GVE_ADMIN_QUEUE_DOORBELL register
|
||||
4) Poll the ADMIN_QUEUE_EVENT_COUNTER register until it equals
|
||||
the value written to the doorbell, or until a timeout.
|
||||
|
||||
The device will update the status field in each AQ command reported as
|
||||
executed through the ADMIN_QUEUE_EVENT_COUNTER register.
|
||||
|
||||
Device Resets
|
||||
-------------
|
||||
A device reset is triggered by writing 0x0 to the AQ PFN register.
|
||||
This causes the device to release all resources allocated by the
|
||||
driver, including the AQ itself.
|
||||
|
||||
Interrupts
|
||||
----------
|
||||
The following interrupts are supported by the driver:
|
||||
|
||||
Management Interrupt
|
||||
~~~~~~~~~~~~~~~~~~~~
|
||||
The management interrupt is used by the device to tell the driver to
|
||||
look at the GVE_DEVICE_STATUS register.
|
||||
|
||||
The handler for the management irq simply queues the service task in
|
||||
the workqueue to check the register and acks the irq.
|
||||
|
||||
Notification Block Interrupts
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
The notification block interrupts are used to tell the driver to poll
|
||||
the queues associated with that interrupt.
|
||||
|
||||
The handler for these irqs schedule the napi for that block to run
|
||||
and poll the queues.
|
||||
|
||||
Traffic Queues
|
||||
--------------
|
||||
gVNIC's queues are composed of a descriptor ring and a buffer and are
|
||||
assigned to a notification block.
|
||||
|
||||
The descriptor rings are power-of-two-sized ring buffers consisting of
|
||||
fixed-size descriptors. They advance their head pointer using a __be32
|
||||
doorbell located in Bar2. The tail pointers are advanced by consuming
|
||||
descriptors in-order and updating a __be32 counter. Both the doorbell
|
||||
and the counter overflow to zero.
|
||||
|
||||
Each queue's buffers must be registered in advance with the device as a
|
||||
queue page list, and packet data can only be put in those pages.
|
||||
|
||||
Transmit
|
||||
~~~~~~~~
|
||||
gve maps the buffers for transmit rings into a FIFO and copies the packets
|
||||
into the FIFO before sending them to the NIC.
|
||||
|
||||
Receive
|
||||
~~~~~~~
|
||||
The buffers for receive rings are put into a data ring that is the same
|
||||
length as the descriptor ring and the head and tail pointers advance over
|
||||
the rings together.
|
|
@ -21,6 +21,8 @@ Contents:
|
|||
intel/i40e
|
||||
intel/iavf
|
||||
intel/ice
|
||||
google/gve
|
||||
mellanox/mlx5
|
||||
|
||||
.. only:: subproject
|
||||
|
||||
|
|
|
@ -0,0 +1,192 @@
|
|||
.. SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB
|
||||
|
||||
=================================================
|
||||
Mellanox ConnectX(R) mlx5 core VPI Network Driver
|
||||
=================================================
|
||||
|
||||
Copyright (c) 2019, Mellanox Technologies LTD.
|
||||
|
||||
Contents
|
||||
========
|
||||
|
||||
- `Enabling the driver and kconfig options`_
|
||||
- `Devlink info`_
|
||||
- `Devlink health reporters`_
|
||||
|
||||
Enabling the driver and kconfig options
|
||||
================================================
|
||||
|
||||
| mlx5 core is modular and most of the major mlx5 core driver features can be selected (compiled in/out)
|
||||
| at build time via kernel Kconfig flags.
|
||||
| Basic features, ethernet net device rx/tx offloads and XDP, are available with the most basic flags
|
||||
| CONFIG_MLX5_CORE=y/m and CONFIG_MLX5_CORE_EN=y.
|
||||
| For the list of advanced features please see below.
|
||||
|
||||
**CONFIG_MLX5_CORE=(y/m/n)** (module mlx5_core.ko)
|
||||
|
||||
| The driver can be enabled by choosing CONFIG_MLX5_CORE=y/m in kernel config.
|
||||
| This will provide mlx5 core driver for mlx5 ulps to interface with (mlx5e, mlx5_ib).
|
||||
|
||||
|
||||
**CONFIG_MLX5_CORE_EN=(y/n)**
|
||||
|
||||
| Choosing this option will allow basic ethernet netdevice support with all of the standard rx/tx offloads.
|
||||
| mlx5e is the mlx5 ulp driver which provides netdevice kernel interface, when chosen, mlx5e will be
|
||||
| built-in into mlx5_core.ko.
|
||||
|
||||
|
||||
**CONFIG_MLX5_EN_ARFS=(y/n)**
|
||||
|
||||
| Enables Hardware-accelerated receive flow steering (arfs) support, and ntuple filtering.
|
||||
| https://community.mellanox.com/s/article/howto-configure-arfs-on-connectx-4
|
||||
|
||||
|
||||
**CONFIG_MLX5_EN_RXNFC=(y/n)**
|
||||
|
||||
| Enables ethtool receive network flow classification, which allows user defined
|
||||
| flow rules to direct traffic into arbitrary rx queue via ethtool set/get_rxnfc API.
|
||||
|
||||
|
||||
**CONFIG_MLX5_CORE_EN_DCB=(y/n)**:
|
||||
|
||||
| Enables `Data Center Bridging (DCB) Support <https://community.mellanox.com/s/article/howto-auto-config-pfc-and-ets-on-connectx-4-via-lldp-dcbx>`_.
|
||||
|
||||
|
||||
**CONFIG_MLX5_MPFS=(y/n)**
|
||||
|
||||
| Ethernet Multi-Physical Function Switch (MPFS) support in ConnectX NIC.
|
||||
| MPFs is required for when `Multi-Host <http://www.mellanox.com/page/multihost>`_ configuration is enabled to allow passing
|
||||
| user configured unicast MAC addresses to the requesting PF.
|
||||
|
||||
|
||||
**CONFIG_MLX5_ESWITCH=(y/n)**
|
||||
|
||||
| Ethernet SRIOV E-Switch support in ConnectX NIC. E-Switch provides internal SRIOV packet steering
|
||||
| and switching for the enabled VFs and PF in two available modes:
|
||||
| 1) `Legacy SRIOV mode (L2 mac vlan steering based) <https://community.mellanox.com/s/article/howto-configure-sr-iov-for-connectx-4-connectx-5-with-kvm--ethernet-x>`_.
|
||||
| 2) `Switchdev mode (eswitch offloads) <https://www.mellanox.com/related-docs/prod_software/ASAP2_Hardware_Offloading_for_vSwitches_User_Manual_v4.4.pdf>`_.
|
||||
|
||||
|
||||
**CONFIG_MLX5_CORE_IPOIB=(y/n)**
|
||||
|
||||
| IPoIB offloads & acceleration support.
|
||||
| Requires CONFIG_MLX5_CORE_EN to provide an accelerated interface for the rdma
|
||||
| IPoIB ulp netdevice.
|
||||
|
||||
|
||||
**CONFIG_MLX5_FPGA=(y/n)**
|
||||
|
||||
| Build support for the Innova family of network cards by Mellanox Technologies.
|
||||
| Innova network cards are comprised of a ConnectX chip and an FPGA chip on one board.
|
||||
| If you select this option, the mlx5_core driver will include the Innova FPGA core and allow
|
||||
| building sandbox-specific client drivers.
|
||||
|
||||
|
||||
**CONFIG_MLX5_EN_IPSEC=(y/n)**
|
||||
|
||||
| Enables `IPSec XFRM cryptography-offload accelaration <http://www.mellanox.com/related-docs/prod_software/Mellanox_Innova_IPsec_Ethernet_Adapter_Card_User_Manual.pdf>`_.
|
||||
|
||||
**CONFIG_MLX5_EN_TLS=(y/n)**
|
||||
|
||||
| TLS cryptography-offload accelaration.
|
||||
|
||||
|
||||
**CONFIG_MLX5_INFINIBAND=(y/n/m)** (module mlx5_ib.ko)
|
||||
|
||||
| Provides low-level InfiniBand/RDMA and `RoCE <https://community.mellanox.com/s/article/recommended-network-configuration-examples-for-roce-deployment>`_ support.
|
||||
|
||||
|
||||
**External options** ( Choose if the corresponding mlx5 feature is required )
|
||||
|
||||
- CONFIG_PTP_1588_CLOCK: When chosen, mlx5 ptp support will be enabled
|
||||
- CONFIG_VXLAN: When chosen, mlx5 vxaln support will be enabled.
|
||||
- CONFIG_MLXFW: When chosen, mlx5 firmware flashing support will be enabled (via devlink and ethtool).
|
||||
|
||||
Devlink info
|
||||
============
|
||||
|
||||
The devlink info reports the running and stored firmware versions on device.
|
||||
It also prints the device PSID which represents the HCA board type ID.
|
||||
|
||||
User command example::
|
||||
|
||||
$ devlink dev info pci/0000:00:06.0
|
||||
pci/0000:00:06.0:
|
||||
driver mlx5_core
|
||||
versions:
|
||||
fixed:
|
||||
fw.psid MT_0000000009
|
||||
running:
|
||||
fw.version 16.26.0100
|
||||
stored:
|
||||
fw.version 16.26.0100
|
||||
|
||||
Devlink health reporters
|
||||
========================
|
||||
|
||||
tx reporter
|
||||
-----------
|
||||
The tx reporter is responsible of two error scenarios:
|
||||
|
||||
- TX timeout
|
||||
Report on kernel tx timeout detection.
|
||||
Recover by searching lost interrupts.
|
||||
- TX error completion
|
||||
Report on error tx completion.
|
||||
Recover by flushing the TX queue and reset it.
|
||||
|
||||
TX reporter also support Diagnose callback, on which it provides
|
||||
real time information of its send queues status.
|
||||
|
||||
User commands examples:
|
||||
|
||||
- Diagnose send queues status::
|
||||
|
||||
$ devlink health diagnose pci/0000:82:00.0 reporter tx
|
||||
|
||||
- Show number of tx errors indicated, number of recover flows ended successfully,
|
||||
is autorecover enabled and graceful period from last recover::
|
||||
|
||||
$ devlink health show pci/0000:82:00.0 reporter tx
|
||||
|
||||
fw reporter
|
||||
-----------
|
||||
The fw reporter implements diagnose and dump callbacks.
|
||||
It follows symptoms of fw error such as fw syndrome by triggering
|
||||
fw core dump and storing it into the dump buffer.
|
||||
The fw reporter diagnose command can be triggered any time by the user to check
|
||||
current fw status.
|
||||
|
||||
User commands examples:
|
||||
|
||||
- Check fw heath status::
|
||||
|
||||
$ devlink health diagnose pci/0000:82:00.0 reporter fw
|
||||
|
||||
- Read FW core dump if already stored or trigger new one::
|
||||
|
||||
$ devlink health dump show pci/0000:82:00.0 reporter fw
|
||||
|
||||
NOTE: This command can run only on the PF which has fw tracer ownership,
|
||||
running it on other PF or any VF will return "Operation not permitted".
|
||||
|
||||
fw fatal reporter
|
||||
-----------------
|
||||
The fw fatal reporter implements dump and recover callbacks.
|
||||
It follows fatal errors indications by CR-space dump and recover flow.
|
||||
The CR-space dump uses vsc interface which is valid even if the FW command
|
||||
interface is not functional, which is the case in most FW fatal errors.
|
||||
The recover function runs recover flow which reloads the driver and triggers fw
|
||||
reset if needed.
|
||||
|
||||
User commands examples:
|
||||
|
||||
- Run fw recover flow manually::
|
||||
|
||||
$ devlink health recover pci/0000:82:00.0 reporter fw_fatal
|
||||
|
||||
- Read FW CR-space dump if already strored or trigger new one::
|
||||
|
||||
$ devlink health dump show pci/0000:82:00.1 reporter fw_fatal
|
||||
|
||||
NOTE: This command can run only on PF.
|
|
@ -0,0 +1,183 @@
|
|||
.. SPDX-License-Identifier: GPL-2.0
|
||||
|
||||
==========================================
|
||||
Broadcom RoboSwitch Ethernet switch driver
|
||||
==========================================
|
||||
|
||||
The Broadcom RoboSwitch Ethernet switch family is used in quite a range of
|
||||
xDSL router, cable modems and other multimedia devices.
|
||||
|
||||
The actual implementation supports the devices BCM5325E, BCM5365, BCM539x,
|
||||
BCM53115 and BCM53125 as well as BCM63XX.
|
||||
|
||||
Implementation details
|
||||
======================
|
||||
|
||||
The driver is located in ``drivers/net/dsa/b53/`` and is implemented as a
|
||||
DSA driver; see ``Documentation/networking/dsa/dsa.rst`` for details on the
|
||||
subsystem and what it provides.
|
||||
|
||||
The switch is, if possible, configured to enable a Broadcom specific 4-bytes
|
||||
switch tag which gets inserted by the switch for every packet forwarded to the
|
||||
CPU interface, conversely, the CPU network interface should insert a similar
|
||||
tag for packets entering the CPU port. The tag format is described in
|
||||
``net/dsa/tag_brcm.c``.
|
||||
|
||||
The configuration of the device depends on whether or not tagging is
|
||||
supported.
|
||||
|
||||
The interface names and example network configuration are used according the
|
||||
configuration described in the :ref:`dsa-config-showcases`.
|
||||
|
||||
Configuration with tagging support
|
||||
----------------------------------
|
||||
|
||||
The tagging based configuration is desired. It is not specific to the b53
|
||||
DSA driver and will work like all DSA drivers which supports tagging.
|
||||
|
||||
See :ref:`dsa-tagged-configuration`.
|
||||
|
||||
Configuration without tagging support
|
||||
-------------------------------------
|
||||
|
||||
Older models (5325, 5365) support a different tag format that is not supported
|
||||
yet. 539x and 531x5 require managed mode and some special handling, which is
|
||||
also not yet supported. The tagging support is disabled in these cases and the
|
||||
switch need a different configuration.
|
||||
|
||||
The configuration slightly differ from the :ref:`dsa-vlan-configuration`.
|
||||
|
||||
The b53 tags the CPU port in all VLANs, since otherwise any PVID untagged
|
||||
VLAN programming would basically change the CPU port's default PVID and make
|
||||
it untagged, undesirable.
|
||||
|
||||
In difference to the configuration described in :ref:`dsa-vlan-configuration`
|
||||
the default VLAN 1 has to be removed from the slave interface configuration in
|
||||
single port and gateway configuration, while there is no need to add an extra
|
||||
VLAN configuration in the bridge showcase.
|
||||
|
||||
single port
|
||||
~~~~~~~~~~~
|
||||
The configuration can only be set up via VLAN tagging and bridge setup.
|
||||
By default packages are tagged with vid 1:
|
||||
|
||||
.. code-block:: sh
|
||||
|
||||
# tag traffic on CPU port
|
||||
ip link add link eth0 name eth0.1 type vlan id 1
|
||||
ip link add link eth0 name eth0.2 type vlan id 2
|
||||
ip link add link eth0 name eth0.3 type vlan id 3
|
||||
|
||||
# The master interface needs to be brought up before the slave ports.
|
||||
ip link set eth0 up
|
||||
ip link set eth0.1 up
|
||||
ip link set eth0.2 up
|
||||
ip link set eth0.3 up
|
||||
|
||||
# bring up the slave interfaces
|
||||
ip link set wan up
|
||||
ip link set lan1 up
|
||||
ip link set lan2 up
|
||||
|
||||
# create bridge
|
||||
ip link add name br0 type bridge
|
||||
|
||||
# activate VLAN filtering
|
||||
ip link set dev br0 type bridge vlan_filtering 1
|
||||
|
||||
# add ports to bridges
|
||||
ip link set dev wan master br0
|
||||
ip link set dev lan1 master br0
|
||||
ip link set dev lan2 master br0
|
||||
|
||||
# tag traffic on ports
|
||||
bridge vlan add dev lan1 vid 2 pvid untagged
|
||||
bridge vlan del dev lan1 vid 1
|
||||
bridge vlan add dev lan2 vid 3 pvid untagged
|
||||
bridge vlan del dev lan2 vid 1
|
||||
|
||||
# configure the VLANs
|
||||
ip addr add 192.0.2.1/30 dev eth0.1
|
||||
ip addr add 192.0.2.5/30 dev eth0.2
|
||||
ip addr add 192.0.2.9/30 dev eth0.3
|
||||
|
||||
# bring up the bridge devices
|
||||
ip link set br0 up
|
||||
|
||||
|
||||
bridge
|
||||
~~~~~~
|
||||
|
||||
.. code-block:: sh
|
||||
|
||||
# tag traffic on CPU port
|
||||
ip link add link eth0 name eth0.1 type vlan id 1
|
||||
|
||||
# The master interface needs to be brought up before the slave ports.
|
||||
ip link set eth0 up
|
||||
ip link set eth0.1 up
|
||||
|
||||
# bring up the slave interfaces
|
||||
ip link set wan up
|
||||
ip link set lan1 up
|
||||
ip link set lan2 up
|
||||
|
||||
# create bridge
|
||||
ip link add name br0 type bridge
|
||||
|
||||
# activate VLAN filtering
|
||||
ip link set dev br0 type bridge vlan_filtering 1
|
||||
|
||||
# add ports to bridge
|
||||
ip link set dev wan master br0
|
||||
ip link set dev lan1 master br0
|
||||
ip link set dev lan2 master br0
|
||||
ip link set eth0.1 master br0
|
||||
|
||||
# configure the bridge
|
||||
ip addr add 192.0.2.129/25 dev br0
|
||||
|
||||
# bring up the bridge
|
||||
ip link set dev br0 up
|
||||
|
||||
gateway
|
||||
~~~~~~~
|
||||
|
||||
.. code-block:: sh
|
||||
|
||||
# tag traffic on CPU port
|
||||
ip link add link eth0 name eth0.1 type vlan id 1
|
||||
ip link add link eth0 name eth0.2 type vlan id 2
|
||||
|
||||
# The master interface needs to be brought up before the slave ports.
|
||||
ip link set eth0 up
|
||||
ip link set eth0.1 up
|
||||
ip link set eth0.2 up
|
||||
|
||||
# bring up the slave interfaces
|
||||
ip link set wan up
|
||||
ip link set lan1 up
|
||||
ip link set lan2 up
|
||||
|
||||
# create bridge
|
||||
ip link add name br0 type bridge
|
||||
|
||||
# activate VLAN filtering
|
||||
ip link set dev br0 type bridge vlan_filtering 1
|
||||
|
||||
# add ports to bridges
|
||||
ip link set dev wan master br0
|
||||
ip link set eth0.1 master br0
|
||||
ip link set dev lan1 master br0
|
||||
ip link set dev lan2 master br0
|
||||
|
||||
# tag traffic on ports
|
||||
bridge vlan add dev wan vid 2 pvid untagged
|
||||
bridge vlan del dev wan vid 1
|
||||
|
||||
# configure the VLANs
|
||||
ip addr add 192.0.2.1/30 dev eth0.2
|
||||
ip addr add 192.0.2.129/25 dev br0
|
||||
|
||||
# bring up the bridge devices
|
||||
ip link set br0 up
|
|
@ -0,0 +1,292 @@
|
|||
.. SPDX-License-Identifier: GPL-2.0
|
||||
|
||||
=======================================
|
||||
DSA switch configuration from userspace
|
||||
=======================================
|
||||
|
||||
The DSA switch configuration is not integrated into the main userspace
|
||||
network configuration suites by now and has to be performed manualy.
|
||||
|
||||
.. _dsa-config-showcases:
|
||||
|
||||
Configuration showcases
|
||||
-----------------------
|
||||
|
||||
To configure a DSA switch a couple of commands need to be executed. In this
|
||||
documentation some common configuration scenarios are handled as showcases:
|
||||
|
||||
*single port*
|
||||
Every switch port acts as a different configurable Ethernet port
|
||||
|
||||
*bridge*
|
||||
Every switch port is part of one configurable Ethernet bridge
|
||||
|
||||
*gateway*
|
||||
Every switch port except one upstream port is part of a configurable
|
||||
Ethernet bridge.
|
||||
The upstream port acts as different configurable Ethernet port.
|
||||
|
||||
All configurations are performed with tools from iproute2, which is available
|
||||
at https://www.kernel.org/pub/linux/utils/net/iproute2/
|
||||
|
||||
Through DSA every port of a switch is handled like a normal linux Ethernet
|
||||
interface. The CPU port is the switch port connected to an Ethernet MAC chip.
|
||||
The corresponding linux Ethernet interface is called the master interface.
|
||||
All other corresponding linux interfaces are called slave interfaces.
|
||||
|
||||
The slave interfaces depend on the master interface. They can only brought up,
|
||||
when the master interface is up.
|
||||
|
||||
In this documentation the following Ethernet interfaces are used:
|
||||
|
||||
*eth0*
|
||||
the master interface
|
||||
|
||||
*lan1*
|
||||
a slave interface
|
||||
|
||||
*lan2*
|
||||
another slave interface
|
||||
|
||||
*lan3*
|
||||
a third slave interface
|
||||
|
||||
*wan*
|
||||
A slave interface dedicated for upstream traffic
|
||||
|
||||
Further Ethernet interfaces can be configured similar.
|
||||
The configured IPs and networks are:
|
||||
|
||||
*single port*
|
||||
* lan1: 192.0.2.1/30 (192.0.2.0 - 192.0.2.3)
|
||||
* lan2: 192.0.2.5/30 (192.0.2.4 - 192.0.2.7)
|
||||
* lan3: 192.0.2.9/30 (192.0.2.8 - 192.0.2.11)
|
||||
|
||||
*bridge*
|
||||
* br0: 192.0.2.129/25 (192.0.2.128 - 192.0.2.255)
|
||||
|
||||
*gateway*
|
||||
* br0: 192.0.2.129/25 (192.0.2.128 - 192.0.2.255)
|
||||
* wan: 192.0.2.1/30 (192.0.2.0 - 192.0.2.3)
|
||||
|
||||
.. _dsa-tagged-configuration:
|
||||
|
||||
Configuration with tagging support
|
||||
----------------------------------
|
||||
|
||||
The tagging based configuration is desired and supported by the majority of
|
||||
DSA switches. These switches are capable to tag incoming and outgoing traffic
|
||||
without using a VLAN based configuration.
|
||||
|
||||
single port
|
||||
~~~~~~~~~~~
|
||||
|
||||
.. code-block:: sh
|
||||
|
||||
# configure each interface
|
||||
ip addr add 192.0.2.1/30 dev lan1
|
||||
ip addr add 192.0.2.5/30 dev lan2
|
||||
ip addr add 192.0.2.9/30 dev lan3
|
||||
|
||||
# The master interface needs to be brought up before the slave ports.
|
||||
ip link set eth0 up
|
||||
|
||||
# bring up the slave interfaces
|
||||
ip link set lan1 up
|
||||
ip link set lan2 up
|
||||
ip link set lan3 up
|
||||
|
||||
bridge
|
||||
~~~~~~
|
||||
|
||||
.. code-block:: sh
|
||||
|
||||
# The master interface needs to be brought up before the slave ports.
|
||||
ip link set eth0 up
|
||||
|
||||
# bring up the slave interfaces
|
||||
ip link set lan1 up
|
||||
ip link set lan2 up
|
||||
ip link set lan3 up
|
||||
|
||||
# create bridge
|
||||
ip link add name br0 type bridge
|
||||
|
||||
# add ports to bridge
|
||||
ip link set dev lan1 master br0
|
||||
ip link set dev lan2 master br0
|
||||
ip link set dev lan3 master br0
|
||||
|
||||
# configure the bridge
|
||||
ip addr add 192.0.2.129/25 dev br0
|
||||
|
||||
# bring up the bridge
|
||||
ip link set dev br0 up
|
||||
|
||||
gateway
|
||||
~~~~~~~
|
||||
|
||||
.. code-block:: sh
|
||||
|
||||
# The master interface needs to be brought up before the slave ports.
|
||||
ip link set eth0 up
|
||||
|
||||
# bring up the slave interfaces
|
||||
ip link set wan up
|
||||
ip link set lan1 up
|
||||
ip link set lan2 up
|
||||
|
||||
# configure the upstream port
|
||||
ip addr add 192.0.2.1/30 dev wan
|
||||
|
||||
# create bridge
|
||||
ip link add name br0 type bridge
|
||||
|
||||
# add ports to bridge
|
||||
ip link set dev lan1 master br0
|
||||
ip link set dev lan2 master br0
|
||||
|
||||
# configure the bridge
|
||||
ip addr add 192.0.2.129/25 dev br0
|
||||
|
||||
# bring up the bridge
|
||||
ip link set dev br0 up
|
||||
|
||||
.. _dsa-vlan-configuration:
|
||||
|
||||
Configuration without tagging support
|
||||
-------------------------------------
|
||||
|
||||
A minority of switches are not capable to use a taging protocol
|
||||
(DSA_TAG_PROTO_NONE). These switches can be configured by a VLAN based
|
||||
configuration.
|
||||
|
||||
single port
|
||||
~~~~~~~~~~~
|
||||
The configuration can only be set up via VLAN tagging and bridge setup.
|
||||
|
||||
.. code-block:: sh
|
||||
|
||||
# tag traffic on CPU port
|
||||
ip link add link eth0 name eth0.1 type vlan id 1
|
||||
ip link add link eth0 name eth0.2 type vlan id 2
|
||||
ip link add link eth0 name eth0.3 type vlan id 3
|
||||
|
||||
# The master interface needs to be brought up before the slave ports.
|
||||
ip link set eth0 up
|
||||
ip link set eth0.1 up
|
||||
ip link set eth0.2 up
|
||||
ip link set eth0.3 up
|
||||
|
||||
# bring up the slave interfaces
|
||||
ip link set lan1 up
|
||||
ip link set lan1 up
|
||||
ip link set lan3 up
|
||||
|
||||
# create bridge
|
||||
ip link add name br0 type bridge
|
||||
|
||||
# activate VLAN filtering
|
||||
ip link set dev br0 type bridge vlan_filtering 1
|
||||
|
||||
# add ports to bridges
|
||||
ip link set dev lan1 master br0
|
||||
ip link set dev lan2 master br0
|
||||
ip link set dev lan3 master br0
|
||||
|
||||
# tag traffic on ports
|
||||
bridge vlan add dev lan1 vid 1 pvid untagged
|
||||
bridge vlan add dev lan2 vid 2 pvid untagged
|
||||
bridge vlan add dev lan3 vid 3 pvid untagged
|
||||
|
||||
# configure the VLANs
|
||||
ip addr add 192.0.2.1/30 dev eth0.1
|
||||
ip addr add 192.0.2.5/30 dev eth0.2
|
||||
ip addr add 192.0.2.9/30 dev eth0.3
|
||||
|
||||
# bring up the bridge devices
|
||||
ip link set br0 up
|
||||
|
||||
|
||||
bridge
|
||||
~~~~~~
|
||||
|
||||
.. code-block:: sh
|
||||
|
||||
# tag traffic on CPU port
|
||||
ip link add link eth0 name eth0.1 type vlan id 1
|
||||
|
||||
# The master interface needs to be brought up before the slave ports.
|
||||
ip link set eth0 up
|
||||
ip link set eth0.1 up
|
||||
|
||||
# bring up the slave interfaces
|
||||
ip link set lan1 up
|
||||
ip link set lan2 up
|
||||
ip link set lan3 up
|
||||
|
||||
# create bridge
|
||||
ip link add name br0 type bridge
|
||||
|
||||
# activate VLAN filtering
|
||||
ip link set dev br0 type bridge vlan_filtering 1
|
||||
|
||||
# add ports to bridge
|
||||
ip link set dev lan1 master br0
|
||||
ip link set dev lan2 master br0
|
||||
ip link set dev lan3 master br0
|
||||
ip link set eth0.1 master br0
|
||||
|
||||
# tag traffic on ports
|
||||
bridge vlan add dev lan1 vid 1 pvid untagged
|
||||
bridge vlan add dev lan2 vid 1 pvid untagged
|
||||
bridge vlan add dev lan3 vid 1 pvid untagged
|
||||
|
||||
# configure the bridge
|
||||
ip addr add 192.0.2.129/25 dev br0
|
||||
|
||||
# bring up the bridge
|
||||
ip link set dev br0 up
|
||||
|
||||
gateway
|
||||
~~~~~~~
|
||||
|
||||
.. code-block:: sh
|
||||
|
||||
# tag traffic on CPU port
|
||||
ip link add link eth0 name eth0.1 type vlan id 1
|
||||
ip link add link eth0 name eth0.2 type vlan id 2
|
||||
|
||||
# The master interface needs to be brought up before the slave ports.
|
||||
ip link set eth0 up
|
||||
ip link set eth0.1 up
|
||||
ip link set eth0.2 up
|
||||
|
||||
# bring up the slave interfaces
|
||||
ip link set wan up
|
||||
ip link set lan1 up
|
||||
ip link set lan2 up
|
||||
|
||||
# create bridge
|
||||
ip link add name br0 type bridge
|
||||
|
||||
# activate VLAN filtering
|
||||
ip link set dev br0 type bridge vlan_filtering 1
|
||||
|
||||
# add ports to bridges
|
||||
ip link set dev wan master br0
|
||||
ip link set eth0.1 master br0
|
||||
ip link set dev lan1 master br0
|
||||
ip link set dev lan2 master br0
|
||||
|
||||
# tag traffic on ports
|
||||
bridge vlan add dev lan1 vid 1 pvid untagged
|
||||
bridge vlan add dev lan2 vid 1 pvid untagged
|
||||
bridge vlan add dev wan vid 2 pvid untagged
|
||||
|
||||
# configure the VLANs
|
||||
ip addr add 192.0.2.1/30 dev eth0.2
|
||||
ip addr add 192.0.2.129/25 dev br0
|
||||
|
||||
# bring up the bridge devices
|
||||
ip link set br0 up
|
|
@ -6,6 +6,8 @@ Distributed Switch Architecture
|
|||
:maxdepth: 1
|
||||
|
||||
dsa
|
||||
b53
|
||||
bcm_sf2
|
||||
lan9303
|
||||
sja1105
|
||||
configuration
|
||||
|
|
|
@ -80,6 +80,7 @@ fib_multipath_hash_policy - INTEGER
|
|||
Possible values:
|
||||
0 - Layer 3
|
||||
1 - Layer 4
|
||||
2 - Layer 3 or inner Layer 3 if present
|
||||
|
||||
fib_sync_mem - UNSIGNED INTEGER
|
||||
Amount of dirty memory from fib entries that can be backlogged before
|
||||
|
@ -656,6 +657,26 @@ tcp_fastopen_blackhole_timeout_sec - INTEGER
|
|||
0 to disable the blackhole detection.
|
||||
By default, it is set to 1hr.
|
||||
|
||||
tcp_fastopen_key - list of comma separated 32-digit hexadecimal INTEGERs
|
||||
The list consists of a primary key and an optional backup key. The
|
||||
primary key is used for both creating and validating cookies, while the
|
||||
optional backup key is only used for validating cookies. The purpose of
|
||||
the backup key is to maximize TFO validation when keys are rotated.
|
||||
|
||||
A randomly chosen primary key may be configured by the kernel if
|
||||
the tcp_fastopen sysctl is set to 0x400 (see above), or if the
|
||||
TCP_FASTOPEN setsockopt() optname is set and a key has not been
|
||||
previously configured via sysctl. If keys are configured via
|
||||
setsockopt() by using the TCP_FASTOPEN_KEY optname, then those
|
||||
per-socket keys will be used instead of any keys that are specified via
|
||||
sysctl.
|
||||
|
||||
A key is specified as 4 8-digit hexadecimal integers which are separated
|
||||
by a '-' as: xxxxxxxx-xxxxxxxx-xxxxxxxx-xxxxxxxx. Leading zeros may be
|
||||
omitted. A primary and a backup key may be specified by separating them
|
||||
by a comma. If only one key is specified, it becomes the primary key and
|
||||
any previously configured backup keys are removed.
|
||||
|
||||
tcp_syn_retries - INTEGER
|
||||
Number of times initial SYNs for an active TCP connection attempt
|
||||
will be retransmitted. Should not be higher than 127. Default value
|
||||
|
@ -1425,14 +1446,26 @@ flowlabel_state_ranges - BOOLEAN
|
|||
FALSE: disabled
|
||||
Default: true
|
||||
|
||||
flowlabel_reflect - BOOLEAN
|
||||
Automatically reflect the flow label. Needed for Path MTU
|
||||
flowlabel_reflect - INTEGER
|
||||
Control flow label reflection. 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
|
||||
|
||||
This is a bitmask.
|
||||
1: enabled for established flows
|
||||
|
||||
Note that this prevents automatic flowlabel changes, as done
|
||||
in "tcp: change IPv6 flow-label upon receiving spurious retransmission"
|
||||
and "tcp: Change txhash on every SYN and RTO retransmit"
|
||||
|
||||
2: enabled for TCP RESET packets (no active listener)
|
||||
If set, a RST packet sent in response to a SYN packet on a closed
|
||||
port will reflect the incoming flow label.
|
||||
|
||||
4: enabled for ICMPv6 echo reply messages.
|
||||
|
||||
Default: 0
|
||||
|
||||
fib_multipath_hash_policy - INTEGER
|
||||
Controls which hash policy to use for multipath routes.
|
||||
|
@ -1440,6 +1473,7 @@ fib_multipath_hash_policy - INTEGER
|
|||
Possible values:
|
||||
0 - Layer 3 (source and destination addresses plus flow label)
|
||||
1 - Layer 4 (standard 5-tuple)
|
||||
2 - Layer 3 or inner Layer 3 if present
|
||||
|
||||
anycast_src_echo_reply - BOOLEAN
|
||||
Controls the use of anycast addresses as source addresses for ICMPv6
|
||||
|
|
|
@ -30,7 +30,7 @@ ip_ttl_propagate - BOOL
|
|||
0 - disabled / RFC 3443 [Short] Pipe Model
|
||||
1 - enabled / RFC 3443 Uniform Model (default)
|
||||
|
||||
default_ttl - BOOL
|
||||
default_ttl - INTEGER
|
||||
Default TTL value to use for MPLS packets where it cannot be
|
||||
propagated from an IP header, either because one isn't present
|
||||
or ip_ttl_propagate has been disabled.
|
||||
|
|
|
@ -202,7 +202,8 @@ the PHY/controller, of which the PHY needs to be aware.
|
|||
|
||||
*interface* is a u32 which specifies the connection type used
|
||||
between the controller and the PHY. Examples are GMII, MII,
|
||||
RGMII, and SGMII. For a full list, see include/linux/phy.h
|
||||
RGMII, and SGMII. See "PHY interface mode" below. For a full
|
||||
list, see include/linux/phy.h
|
||||
|
||||
Now just make sure that phydev->supported and phydev->advertising have any
|
||||
values pruned from them which don't make sense for your controller (a 10/100
|
||||
|
@ -225,6 +226,48 @@ When you want to disconnect from the network (even if just briefly), you call
|
|||
phy_stop(phydev). This function also stops the phylib state machine and
|
||||
disables PHY interrupts.
|
||||
|
||||
PHY interface modes
|
||||
===================
|
||||
|
||||
The PHY interface mode supplied in the phy_connect() family of functions
|
||||
defines the initial operating mode of the PHY interface. This is not
|
||||
guaranteed to remain constant; there are PHYs which dynamically change
|
||||
their interface mode without software interaction depending on the
|
||||
negotiation results.
|
||||
|
||||
Some of the interface modes are described below:
|
||||
|
||||
``PHY_INTERFACE_MODE_1000BASEX``
|
||||
This defines the 1000BASE-X single-lane serdes link as defined by the
|
||||
802.3 standard section 36. The link operates at a fixed bit rate of
|
||||
1.25Gbaud using a 10B/8B encoding scheme, resulting in an underlying
|
||||
data rate of 1Gbps. Embedded in the data stream is a 16-bit control
|
||||
word which is used to negotiate the duplex and pause modes with the
|
||||
remote end. This does not include "up-clocked" variants such as 2.5Gbps
|
||||
speeds (see below.)
|
||||
|
||||
``PHY_INTERFACE_MODE_2500BASEX``
|
||||
This defines a variant of 1000BASE-X which is clocked 2.5 times faster,
|
||||
than the 802.3 standard giving a fixed bit rate of 3.125Gbaud.
|
||||
|
||||
``PHY_INTERFACE_MODE_SGMII``
|
||||
This is used for Cisco SGMII, which is a modification of 1000BASE-X
|
||||
as defined by the 802.3 standard. The SGMII link consists of a single
|
||||
serdes lane running at a fixed bit rate of 1.25Gbaud with 10B/8B
|
||||
encoding. The underlying data rate is 1Gbps, with the slower speeds of
|
||||
100Mbps and 10Mbps being achieved through replication of each data symbol.
|
||||
The 802.3 control word is re-purposed to send the negotiated speed and
|
||||
duplex information from to the MAC, and for the MAC to acknowledge
|
||||
receipt. This does not include "up-clocked" variants such as 2.5Gbps
|
||||
speeds.
|
||||
|
||||
Note: mismatched SGMII vs 1000BASE-X configuration on a link can
|
||||
successfully pass data in some circumstances, but the 16-bit control
|
||||
word will not be correctly interpreted, which may cause mismatches in
|
||||
duplex, pause or other settings. This is dependent on the MAC and/or
|
||||
PHY behaviour.
|
||||
|
||||
|
||||
Pause frames / flow control
|
||||
===========================
|
||||
|
||||
|
|
|
@ -98,6 +98,7 @@ this documentation.
|
|||
4. Add::
|
||||
|
||||
struct phylink *phylink;
|
||||
struct phylink_config phylink_config;
|
||||
|
||||
to the driver's private data structure. We shall refer to the
|
||||
driver's private data pointer as ``priv`` below, and the driver's
|
||||
|
@ -223,8 +224,10 @@ this documentation.
|
|||
.. code-block:: c
|
||||
|
||||
struct phylink *phylink;
|
||||
priv->phylink_config.dev = &dev.dev;
|
||||
priv->phylink_config.type = PHYLINK_NETDEV;
|
||||
|
||||
phylink = phylink_create(dev, node, phy_mode, &phylink_ops);
|
||||
phylink = phylink_create(&priv->phylink_config, node, phy_mode, &phylink_ops);
|
||||
if (IS_ERR(phylink)) {
|
||||
err = PTR_ERR(phylink);
|
||||
fail probe;
|
||||
|
|
|
@ -206,7 +206,11 @@ TX
|
|||
|
||||
Segments transmitted from an offloaded socket can get out of sync
|
||||
in similar ways to the receive side-retransmissions - local drops
|
||||
are possible, though network reorders are not.
|
||||
are possible, though network reorders are not. There are currently
|
||||
two mechanisms for dealing with out of order segments.
|
||||
|
||||
Crypto state rebuilding
|
||||
~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Whenever an out of order segment is transmitted the driver provides
|
||||
the device with enough information to perform cryptographic operations.
|
||||
|
@ -225,6 +229,35 @@ was just a retransmission. The former is simpler, and does not require
|
|||
retransmission detection therefore it is the recommended method until
|
||||
such time it is proven inefficient.
|
||||
|
||||
Next record sync
|
||||
~~~~~~~~~~~~~~~~
|
||||
|
||||
Whenever an out of order segment is detected the driver requests
|
||||
that the ``ktls`` software fallback code encrypt it. If the segment's
|
||||
sequence number is lower than expected the driver assumes retransmission
|
||||
and doesn't change device state. If the segment is in the future, it
|
||||
may imply a local drop, the driver asks the stack to sync the device
|
||||
to the next record state and falls back to software.
|
||||
|
||||
Resync request is indicated with:
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
void tls_offload_tx_resync_request(struct sock *sk, u32 got_seq, u32 exp_seq)
|
||||
|
||||
Until resync is complete driver should not access its expected TCP
|
||||
sequence number (as it will be updated from a different context).
|
||||
Following helper should be used to test if resync is complete:
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
bool tls_offload_tx_resync_pending(struct sock *sk)
|
||||
|
||||
Next time ``ktls`` pushes a record it will first send its TCP sequence number
|
||||
and TLS record number to the driver. Stack will also make sure that
|
||||
the new record will start on a segment boundary (like it does when
|
||||
the connection is initially added).
|
||||
|
||||
RX
|
||||
--
|
||||
|
||||
|
@ -268,6 +301,9 @@ Device can only detect that segment 4 also contains a TLS header
|
|||
if it knows the length of the previous record from segment 2. In this case
|
||||
the device will lose synchronization with the stream.
|
||||
|
||||
Stream scan resynchronization
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
When the device gets out of sync and the stream reaches TCP sequence
|
||||
numbers more than a max size record past the expected TCP sequence number,
|
||||
the device starts scanning for a known header pattern. For example
|
||||
|
@ -298,6 +334,22 @@ Special care has to be taken if the confirmation request is passed
|
|||
asynchronously to the packet stream and record may get processed
|
||||
by the kernel before the confirmation request.
|
||||
|
||||
Stack-driven resynchronization
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
The driver may also request the stack to perform resynchronization
|
||||
whenever it sees the records are no longer getting decrypted.
|
||||
If the connection is configured in this mode the stack automatically
|
||||
schedules resynchronization after it has received two completely encrypted
|
||||
records.
|
||||
|
||||
The stack waits for the socket to drain and informs the device about
|
||||
the next expected record number and its TCP sequence number. If the
|
||||
records continue to be received fully encrypted stack retries the
|
||||
synchronization with an exponential back off (first after 2 encrypted
|
||||
records, then after 4 records, after 8, after 16... up until every
|
||||
128 records).
|
||||
|
||||
Error handling
|
||||
==============
|
||||
|
||||
|
@ -379,7 +431,6 @@ by the driver:
|
|||
but did not arrive in the expected order
|
||||
* ``tx_tls_drop_no_sync_data`` - number of TX packets dropped because
|
||||
they arrived out of order and associated record could not be found
|
||||
(see also :ref:`pre_tls_data`)
|
||||
|
||||
Notable corner cases, exceptions and additional requirements
|
||||
============================================================
|
||||
|
@ -462,21 +513,3 @@ Redirects leak clear text
|
|||
|
||||
In the RX direction, if segment has already been decrypted by the device
|
||||
and it gets redirected or mirrored - clear text will be transmitted out.
|
||||
|
||||
.. _pre_tls_data:
|
||||
|
||||
Transmission of pre-TLS data
|
||||
----------------------------
|
||||
|
||||
User can enqueue some already encrypted and framed records before enabling
|
||||
``ktls`` on the socket. Those records have to get sent as they are. This is
|
||||
perfectly easy to handle in the software case - such data will be waiting
|
||||
in the TCP layer, TLS ULP won't see it. In the offloaded case when pre-queued
|
||||
segment reaches transmission point it appears to be out of order (before the
|
||||
expected TCP sequence number) and the stack does not have a record information
|
||||
associated.
|
||||
|
||||
All segments without record information cannot, however, be assumed to be
|
||||
pre-queued data, because a race condition exists between TCP stack queuing
|
||||
a retransmission, the driver seeing the retransmission and TCP ACK arriving
|
||||
for the retransmitted data.
|
||||
|
|
|
@ -23,8 +23,8 @@ running, the suggested command should tell you.
|
|||
|
||||
Again, keep in mind that this list assumes you are already functionally
|
||||
running a Linux kernel. Also, not all tools are necessary on all
|
||||
systems; obviously, if you don't have any ISDN hardware, for example,
|
||||
you probably needn't concern yourself with isdn4k-utils.
|
||||
systems; obviously, if you don't have any PC Card hardware, for example,
|
||||
you probably needn't concern yourself with pcmciautils.
|
||||
|
||||
====================== =============== ========================================
|
||||
Program Minimal version Command to check the version
|
||||
|
@ -45,7 +45,6 @@ btrfs-progs 0.18 btrfsck
|
|||
pcmciautils 004 pccardctl -V
|
||||
quota-tools 3.09 quota -V
|
||||
PPP 2.4.0 pppd --version
|
||||
isdn4k-utils 3.1pre1 isdnctrl 2>&1|grep version
|
||||
nfs-utils 1.0.5 showmount --version
|
||||
procps 3.2.0 ps --version
|
||||
oprofile 0.9 oprofiled --version
|
||||
|
@ -277,12 +276,6 @@ which can be made by::
|
|||
|
||||
as root.
|
||||
|
||||
Isdn4k-utils
|
||||
------------
|
||||
|
||||
Due to changes in the length of the phone number field, isdn4k-utils
|
||||
needs to be recompiled or (preferably) upgraded.
|
||||
|
||||
NFS-utils
|
||||
---------
|
||||
|
||||
|
@ -446,11 +439,6 @@ PPP
|
|||
|
||||
- <ftp://ftp.samba.org/pub/ppp/>
|
||||
|
||||
Isdn4k-utils
|
||||
------------
|
||||
|
||||
- <ftp://ftp.isdn4linux.de/pub/isdn4linux/utils/>
|
||||
|
||||
NFS-utils
|
||||
---------
|
||||
|
||||
|
|
73
MAINTAINERS
73
MAINTAINERS
|
@ -1147,6 +1147,15 @@ L: linux-media@vger.kernel.org
|
|||
S: Maintained
|
||||
F: drivers/media/i2c/aptina-pll.*
|
||||
|
||||
AQUANTIA ETHERNET DRIVER (atlantic)
|
||||
M: Igor Russkikh <igor.russkikh@aquantia.com>
|
||||
L: netdev@vger.kernel.org
|
||||
S: Supported
|
||||
W: http://www.aquantia.com
|
||||
Q: http://patchwork.ozlabs.org/project/netdev/list/
|
||||
F: drivers/net/ethernet/aquantia/atlantic/
|
||||
F: Documentation/networking/device_drivers/aquantia/atlantic.txt
|
||||
|
||||
ARC FRAMEBUFFER DRIVER
|
||||
M: Jaya Kumar <jayalk@intworks.biz>
|
||||
S: Maintained
|
||||
|
@ -4953,13 +4962,6 @@ L: linux-kernel@vger.kernel.org
|
|||
S: Maintained
|
||||
F: drivers/staging/fsl-dpaa2/ethsw
|
||||
|
||||
DPAA2 PTP CLOCK DRIVER
|
||||
M: Yangbo Lu <yangbo.lu@nxp.com>
|
||||
L: netdev@vger.kernel.org
|
||||
S: Maintained
|
||||
F: drivers/net/ethernet/freescale/dpaa2/dpaa2-ptp*
|
||||
F: drivers/net/ethernet/freescale/dpaa2/dprtc*
|
||||
|
||||
DPT_I2O SCSI RAID DRIVER
|
||||
M: Adaptec OEM Raid Solutions <aacraid@microsemi.com>
|
||||
L: linux-scsi@vger.kernel.org
|
||||
|
@ -5631,7 +5633,8 @@ F: include/linux/dynamic_debug.h
|
|||
DYNAMIC INTERRUPT MODERATION
|
||||
M: Tal Gilboa <talgi@mellanox.com>
|
||||
S: Maintained
|
||||
F: include/linux/net_dim.h
|
||||
F: include/linux/dim.h
|
||||
F: lib/dim/
|
||||
|
||||
DZ DECSTATION DZ11 SERIAL DRIVER
|
||||
M: "Maciej W. Rozycki" <macro@linux-mips.org>
|
||||
|
@ -6414,6 +6417,8 @@ FREESCALE QORIQ PTP CLOCK DRIVER
|
|||
M: Yangbo Lu <yangbo.lu@nxp.com>
|
||||
L: netdev@vger.kernel.org
|
||||
S: Maintained
|
||||
F: drivers/net/ethernet/freescale/dpaa2/dpaa2-ptp*
|
||||
F: drivers/net/ethernet/freescale/dpaa2/dprtc*
|
||||
F: drivers/net/ethernet/freescale/enetc/enetc_ptp.c
|
||||
F: drivers/ptp/ptp_qoriq.c
|
||||
F: drivers/ptp/ptp_qoriq_debugfs.c
|
||||
|
@ -6746,9 +6751,7 @@ M: Paul Bolle <pebolle@tiscali.nl>
|
|||
L: gigaset307x-common@lists.sourceforge.net
|
||||
W: http://gigaset307x.sourceforge.net/
|
||||
S: Odd Fixes
|
||||
F: Documentation/isdn/README.gigaset
|
||||
F: drivers/isdn/gigaset/
|
||||
F: include/uapi/linux/gigaset_dev.h
|
||||
F: drivers/staging/isdn/gigaset/
|
||||
|
||||
GNSS SUBSYSTEM
|
||||
M: Johan Hovold <johan@kernel.org>
|
||||
|
@ -6771,6 +6774,15 @@ L: linux-input@vger.kernel.org
|
|||
S: Maintained
|
||||
F: drivers/input/touchscreen/goodix.c
|
||||
|
||||
GOOGLE ETHERNET DRIVERS
|
||||
M: Catherine Sullivan <csully@google.com>
|
||||
R: Sagi Shahar <sagis@google.com>
|
||||
R: Jon Olson <jonolson@google.com>
|
||||
L: netdev@vger.kernel.org
|
||||
S: Supported
|
||||
F: Documentation/networking/device_drivers/google/gve.txt
|
||||
F: drivers/net/ethernet/google
|
||||
|
||||
GPD POCKET FAN DRIVER
|
||||
M: Hans de Goede <hdegoede@redhat.com>
|
||||
L: platform-driver-x86@vger.kernel.org
|
||||
|
@ -8432,18 +8444,26 @@ S: Supported
|
|||
W: http://www.linux-iscsi.org
|
||||
F: drivers/infiniband/ulp/isert
|
||||
|
||||
ISDN SUBSYSTEM
|
||||
ISDN/mISDN SUBSYSTEM
|
||||
M: Karsten Keil <isdn@linux-pingi.de>
|
||||
L: isdn4linux@listserv.isdn4linux.de (subscribers-only)
|
||||
L: netdev@vger.kernel.org
|
||||
W: http://www.isdn4linux.de
|
||||
T: git git://git.kernel.org/pub/scm/linux/kernel/git/kkeil/isdn-2.6.git
|
||||
S: Maintained
|
||||
F: drivers/isdn/mISDN
|
||||
F: drivers/isdn/hardware
|
||||
|
||||
ISDN/CAPI SUBSYSTEM
|
||||
M: Karsten Keil <isdn@linux-pingi.de>
|
||||
L: isdn4linux@listserv.isdn4linux.de (subscribers-only)
|
||||
L: netdev@vger.kernel.org
|
||||
W: http://www.isdn4linux.de
|
||||
S: Odd Fixes
|
||||
F: Documentation/isdn/
|
||||
F: drivers/isdn/
|
||||
F: include/linux/isdn.h
|
||||
F: drivers/isdn/capi/
|
||||
F: drivers/staging/isdn/
|
||||
F: net/bluetooth/cmtp/
|
||||
F: include/linux/isdn/
|
||||
F: include/uapi/linux/isdn.h
|
||||
F: include/uapi/linux/isdn/
|
||||
|
||||
IT87 HARDWARE MONITORING DRIVER
|
||||
|
@ -10170,6 +10190,7 @@ Q: http://patchwork.ozlabs.org/project/netdev/list/
|
|||
S: Supported
|
||||
F: drivers/net/ethernet/mellanox/mlx5/core/
|
||||
F: include/linux/mlx5/
|
||||
F: Documentation/networking/device_drivers/mellanox/
|
||||
|
||||
MELLANOX MLX5 IB driver
|
||||
M: Leon Romanovsky <leonro@mellanox.com>
|
||||
|
@ -10943,7 +10964,7 @@ F: drivers/net/ethernet/neterion/
|
|||
|
||||
NETFILTER
|
||||
M: Pablo Neira Ayuso <pablo@netfilter.org>
|
||||
M: Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>
|
||||
M: Jozsef Kadlecsik <kadlec@netfilter.org>
|
||||
M: Florian Westphal <fw@strlen.de>
|
||||
L: netfilter-devel@vger.kernel.org
|
||||
L: coreteam@netfilter.org
|
||||
|
@ -11156,6 +11177,15 @@ L: netdev@vger.kernel.org
|
|||
S: Supported
|
||||
F: drivers/net/ethernet/qlogic/netxen/
|
||||
|
||||
NEXTHOP
|
||||
M: David Ahern <dsahern@kernel.org>
|
||||
L: netdev@vger.kernel.org
|
||||
S: Maintained
|
||||
F: include/net/nexthop.h
|
||||
F: include/uapi/linux/nexthop.h
|
||||
F: include/net/netns/nexthop.h
|
||||
F: net/ipv4/nexthop.c
|
||||
|
||||
NFC SUBSYSTEM
|
||||
L: netdev@vger.kernel.org
|
||||
S: Orphan
|
||||
|
@ -11949,6 +11979,14 @@ F: kernel/padata.c
|
|||
F: include/linux/padata.h
|
||||
F: Documentation/padata.txt
|
||||
|
||||
PAGE POOL
|
||||
M: Jesper Dangaard Brouer <hawk@kernel.org>
|
||||
M: Ilias Apalodimas <ilias.apalodimas@linaro.org>
|
||||
L: netdev@vger.kernel.org
|
||||
S: Supported
|
||||
F: net/core/page_pool.c
|
||||
F: include/net/page_pool.h
|
||||
|
||||
PANASONIC LAPTOP ACPI EXTRAS DRIVER
|
||||
M: Harald Welte <laforge@gnumonks.org>
|
||||
L: platform-driver-x86@vger.kernel.org
|
||||
|
@ -17361,6 +17399,7 @@ N: xdp
|
|||
XDP SOCKETS (AF_XDP)
|
||||
M: Björn Töpel <bjorn.topel@intel.com>
|
||||
M: Magnus Karlsson <magnus.karlsson@intel.com>
|
||||
R: Jonathan Lemon <jonathan.lemon@gmail.com>
|
||||
L: netdev@vger.kernel.org
|
||||
L: bpf@vger.kernel.org
|
||||
S: Maintained
|
||||
|
|
|
@ -122,6 +122,8 @@
|
|||
#define SO_RCVTIMEO_NEW 66
|
||||
#define SO_SNDTIMEO_NEW 67
|
||||
|
||||
#define SO_DETACH_REUSEPORT_BPF 68
|
||||
|
||||
#if !defined(__KERNEL__)
|
||||
|
||||
#if __BITS_PER_LONG == 64
|
||||
|
|
|
@ -733,7 +733,8 @@ static inline void emit_a32_alu_r64(const bool is64, const s8 dst[],
|
|||
|
||||
/* ALU operation */
|
||||
emit_alu_r(rd[1], rs, true, false, op, ctx);
|
||||
emit_a32_mov_i(rd[0], 0, ctx);
|
||||
if (!ctx->prog->aux->verifier_zext)
|
||||
emit_a32_mov_i(rd[0], 0, ctx);
|
||||
}
|
||||
|
||||
arm_bpf_put_reg64(dst, rd, ctx);
|
||||
|
@ -755,8 +756,9 @@ static inline void emit_a32_mov_r64(const bool is64, const s8 dst[],
|
|||
struct jit_ctx *ctx) {
|
||||
if (!is64) {
|
||||
emit_a32_mov_r(dst_lo, src_lo, ctx);
|
||||
/* Zero out high 4 bytes */
|
||||
emit_a32_mov_i(dst_hi, 0, ctx);
|
||||
if (!ctx->prog->aux->verifier_zext)
|
||||
/* Zero out high 4 bytes */
|
||||
emit_a32_mov_i(dst_hi, 0, ctx);
|
||||
} else if (__LINUX_ARM_ARCH__ < 6 &&
|
||||
ctx->cpu_architecture < CPU_ARCH_ARMv5TE) {
|
||||
/* complete 8 byte move */
|
||||
|
@ -1057,17 +1059,20 @@ static inline void emit_ldx_r(const s8 dst[], const s8 src,
|
|||
case BPF_B:
|
||||
/* Load a Byte */
|
||||
emit(ARM_LDRB_I(rd[1], rm, off), ctx);
|
||||
emit_a32_mov_i(rd[0], 0, ctx);
|
||||
if (!ctx->prog->aux->verifier_zext)
|
||||
emit_a32_mov_i(rd[0], 0, ctx);
|
||||
break;
|
||||
case BPF_H:
|
||||
/* Load a HalfWord */
|
||||
emit(ARM_LDRH_I(rd[1], rm, off), ctx);
|
||||
emit_a32_mov_i(rd[0], 0, ctx);
|
||||
if (!ctx->prog->aux->verifier_zext)
|
||||
emit_a32_mov_i(rd[0], 0, ctx);
|
||||
break;
|
||||
case BPF_W:
|
||||
/* Load a Word */
|
||||
emit(ARM_LDR_I(rd[1], rm, off), ctx);
|
||||
emit_a32_mov_i(rd[0], 0, ctx);
|
||||
if (!ctx->prog->aux->verifier_zext)
|
||||
emit_a32_mov_i(rd[0], 0, ctx);
|
||||
break;
|
||||
case BPF_DW:
|
||||
/* Load a Double Word */
|
||||
|
@ -1356,6 +1361,11 @@ static int build_insn(const struct bpf_insn *insn, struct jit_ctx *ctx)
|
|||
case BPF_ALU64 | BPF_MOV | BPF_X:
|
||||
switch (BPF_SRC(code)) {
|
||||
case BPF_X:
|
||||
if (imm == 1) {
|
||||
/* Special mov32 for zext */
|
||||
emit_a32_mov_i(dst_hi, 0, ctx);
|
||||
break;
|
||||
}
|
||||
emit_a32_mov_r64(is64, dst, src, ctx);
|
||||
break;
|
||||
case BPF_K:
|
||||
|
@ -1435,7 +1445,8 @@ static int build_insn(const struct bpf_insn *insn, struct jit_ctx *ctx)
|
|||
}
|
||||
emit_udivmod(rd_lo, rd_lo, rt, ctx, BPF_OP(code));
|
||||
arm_bpf_put_reg32(dst_lo, rd_lo, ctx);
|
||||
emit_a32_mov_i(dst_hi, 0, ctx);
|
||||
if (!ctx->prog->aux->verifier_zext)
|
||||
emit_a32_mov_i(dst_hi, 0, ctx);
|
||||
break;
|
||||
case BPF_ALU64 | BPF_DIV | BPF_K:
|
||||
case BPF_ALU64 | BPF_DIV | BPF_X:
|
||||
|
@ -1450,7 +1461,8 @@ static int build_insn(const struct bpf_insn *insn, struct jit_ctx *ctx)
|
|||
return -EINVAL;
|
||||
if (imm)
|
||||
emit_a32_alu_i(dst_lo, imm, ctx, BPF_OP(code));
|
||||
emit_a32_mov_i(dst_hi, 0, ctx);
|
||||
if (!ctx->prog->aux->verifier_zext)
|
||||
emit_a32_mov_i(dst_hi, 0, ctx);
|
||||
break;
|
||||
/* dst = dst << imm */
|
||||
case BPF_ALU64 | BPF_LSH | BPF_K:
|
||||
|
@ -1485,7 +1497,8 @@ static int build_insn(const struct bpf_insn *insn, struct jit_ctx *ctx)
|
|||
/* dst = ~dst */
|
||||
case BPF_ALU | BPF_NEG:
|
||||
emit_a32_alu_i(dst_lo, 0, ctx, BPF_OP(code));
|
||||
emit_a32_mov_i(dst_hi, 0, ctx);
|
||||
if (!ctx->prog->aux->verifier_zext)
|
||||
emit_a32_mov_i(dst_hi, 0, ctx);
|
||||
break;
|
||||
/* dst = ~dst (64 bit) */
|
||||
case BPF_ALU64 | BPF_NEG:
|
||||
|
@ -1541,11 +1554,13 @@ emit_bswap_uxt:
|
|||
#else /* ARMv6+ */
|
||||
emit(ARM_UXTH(rd[1], rd[1]), ctx);
|
||||
#endif
|
||||
emit(ARM_EOR_R(rd[0], rd[0], rd[0]), ctx);
|
||||
if (!ctx->prog->aux->verifier_zext)
|
||||
emit(ARM_EOR_R(rd[0], rd[0], rd[0]), ctx);
|
||||
break;
|
||||
case 32:
|
||||
/* zero-extend 32 bits into 64 bits */
|
||||
emit(ARM_EOR_R(rd[0], rd[0], rd[0]), ctx);
|
||||
if (!ctx->prog->aux->verifier_zext)
|
||||
emit(ARM_EOR_R(rd[0], rd[0], rd[0]), ctx);
|
||||
break;
|
||||
case 64:
|
||||
/* nop */
|
||||
|
@ -1835,6 +1850,11 @@ void bpf_jit_compile(struct bpf_prog *prog)
|
|||
/* Nothing to do here. We support Internal BPF. */
|
||||
}
|
||||
|
||||
bool bpf_jit_needs_zext(void)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *prog)
|
||||
{
|
||||
struct bpf_prog *tmp, *orig_prog = prog;
|
||||
|
|
|
@ -431,6 +431,12 @@
|
|||
compatible = "fsl,enetc";
|
||||
reg = <0x000100 0 0 0 0>;
|
||||
};
|
||||
ethernet@0,4 {
|
||||
compatible = "fsl,enetc-ptp";
|
||||
reg = <0x000400 0 0 0 0>;
|
||||
clocks = <&clockgen 4 0>;
|
||||
little-endian;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
|
|
@ -609,6 +609,14 @@
|
|||
<GIC_SPI 209 IRQ_TYPE_LEVEL_HIGH>;
|
||||
};
|
||||
|
||||
ptp-timer@8b95000 {
|
||||
compatible = "fsl,dpaa2-ptp";
|
||||
reg = <0x0 0x8b95000 0x0 0x100>;
|
||||
clocks = <&clockgen 4 0>;
|
||||
little-endian;
|
||||
fsl,extts-fifo;
|
||||
};
|
||||
|
||||
cluster1_core0_watchdog: wdt@c000000 {
|
||||
compatible = "arm,sp805-wdt", "arm,primecell";
|
||||
reg = <0x0 0xc000000 0x0 0x1000>;
|
||||
|
|
|
@ -321,6 +321,14 @@
|
|||
};
|
||||
};
|
||||
|
||||
ptp-timer@8b95000 {
|
||||
compatible = "fsl,dpaa2-ptp";
|
||||
reg = <0x0 0x8b95000 0x0 0x100>;
|
||||
clocks = <&clockgen 4 1>;
|
||||
little-endian;
|
||||
fsl,extts-fifo;
|
||||
};
|
||||
|
||||
fsl_mc: fsl-mc@80c000000 {
|
||||
compatible = "fsl,qoriq-mc";
|
||||
reg = <0x00000008 0x0c000000 0 0x40>, /* MC portal base */
|
||||
|
|
|
@ -848,6 +848,14 @@
|
|||
dma-coherent;
|
||||
};
|
||||
|
||||
ptp-timer@8b95000 {
|
||||
compatible = "fsl,dpaa2-ptp";
|
||||
reg = <0x0 0x8b95000 0x0 0x100>;
|
||||
clocks = <&clockgen 4 1>;
|
||||
little-endian;
|
||||
fsl,extts-fifo;
|
||||
};
|
||||
|
||||
fsl_mc: fsl-mc@80c000000 {
|
||||
compatible = "fsl,qoriq-mc";
|
||||
reg = <0x00000008 0x0c000000 0 0x40>,
|
||||
|
|
|
@ -929,7 +929,8 @@
|
|||
sgmiisys: sgmiisys@1b128000 {
|
||||
compatible = "mediatek,mt7622-sgmiisys",
|
||||
"syscon";
|
||||
reg = <0 0x1b128000 0 0x1000>;
|
||||
reg = <0 0x1b128000 0 0x3000>;
|
||||
#clock-cells = <1>;
|
||||
mediatek,physpeed = "2500";
|
||||
};
|
||||
};
|
||||
|
|
|
@ -132,11 +132,12 @@
|
|||
<0x1270000 0x100>,
|
||||
<0x1280000 0x100>,
|
||||
<0x1800000 0x80000>,
|
||||
<0x1880000 0x10000>;
|
||||
<0x1880000 0x10000>,
|
||||
<0x1060000 0x10000>;
|
||||
reg-names = "sys", "rew", "qs", "port0", "port1",
|
||||
"port2", "port3", "port4", "port5", "port6",
|
||||
"port7", "port8", "port9", "port10", "qsys",
|
||||
"ana";
|
||||
"ana", "s2";
|
||||
interrupts = <21 22>;
|
||||
interrupt-names = "xtr", "inj";
|
||||
|
||||
|
|
|
@ -116,6 +116,32 @@
|
|||
};
|
||||
};
|
||||
|
||||
eth0: ethernet@19000000 {
|
||||
compatible = "qca,ar9330-eth";
|
||||
reg = <0x19000000 0x200>;
|
||||
interrupts = <4>;
|
||||
|
||||
resets = <&rst 9>, <&rst 22>;
|
||||
reset-names = "mac", "mdio";
|
||||
clocks = <&pll ATH79_CLK_AHB>, <&pll ATH79_CLK_AHB>;
|
||||
clock-names = "eth", "mdio";
|
||||
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
eth1: ethernet@1a000000 {
|
||||
compatible = "qca,ar9330-eth";
|
||||
reg = <0x1a000000 0x200>;
|
||||
interrupts = <5>;
|
||||
|
||||
resets = <&rst 13>, <&rst 23>;
|
||||
reset-names = "mac", "mdio";
|
||||
clocks = <&pll ATH79_CLK_AHB>, <&pll ATH79_CLK_AHB>;
|
||||
clock-names = "eth", "mdio";
|
||||
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
usb: usb@1b000100 {
|
||||
compatible = "chipidea,usb2";
|
||||
reg = <0x1b000000 0x200>;
|
||||
|
|
|
@ -76,3 +76,11 @@
|
|||
reg = <0>;
|
||||
};
|
||||
};
|
||||
|
||||
ð0 {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
ð1 {
|
||||
status = "okay";
|
||||
};
|
||||
|
|
|
@ -210,7 +210,6 @@ CONFIG_NET_ACT_NAT=m
|
|||
CONFIG_NET_ACT_PEDIT=m
|
||||
CONFIG_NET_ACT_SIMP=m
|
||||
CONFIG_NET_ACT_SKBEDIT=m
|
||||
CONFIG_NET_CLS_IND=y
|
||||
CONFIG_CFG80211=m
|
||||
CONFIG_MAC80211=m
|
||||
CONFIG_MAC80211_MESH=y
|
||||
|
|
|
@ -215,7 +215,6 @@ CONFIG_NET_ACT_NAT=m
|
|||
CONFIG_NET_ACT_PEDIT=m
|
||||
CONFIG_NET_ACT_SIMP=m
|
||||
CONFIG_NET_ACT_SKBEDIT=m
|
||||
CONFIG_NET_CLS_IND=y
|
||||
CONFIG_CFG80211=m
|
||||
CONFIG_MAC80211=m
|
||||
CONFIG_MAC80211_MESH=y
|
||||
|
|
|
@ -212,7 +212,6 @@ CONFIG_NET_ACT_NAT=m
|
|||
CONFIG_NET_ACT_PEDIT=m
|
||||
CONFIG_NET_ACT_SIMP=m
|
||||
CONFIG_NET_ACT_SKBEDIT=m
|
||||
CONFIG_NET_CLS_IND=y
|
||||
CONFIG_CFG80211=m
|
||||
CONFIG_MAC80211=m
|
||||
CONFIG_MAC80211_MESH=y
|
||||
|
|
|
@ -74,7 +74,6 @@ CONFIG_NET_CLS_RSVP=m
|
|||
CONFIG_NET_CLS_RSVP6=m
|
||||
CONFIG_NET_CLS_ACT=y
|
||||
CONFIG_NET_ACT_POLICE=y
|
||||
CONFIG_NET_CLS_IND=y
|
||||
# CONFIG_WIRELESS is not set
|
||||
CONFIG_DEVTMPFS=y
|
||||
CONFIG_BLK_DEV_LOOP=y
|
||||
|
|
|
@ -76,7 +76,6 @@ CONFIG_NET_CLS_RSVP=m
|
|||
CONFIG_NET_CLS_RSVP6=m
|
||||
CONFIG_NET_CLS_ACT=y
|
||||
CONFIG_NET_ACT_POLICE=y
|
||||
CONFIG_NET_CLS_IND=y
|
||||
# CONFIG_WIRELESS is not set
|
||||
CONFIG_DEVTMPFS=y
|
||||
CONFIG_BLK_DEV_LOOP=y
|
||||
|
|
|
@ -77,7 +77,6 @@ CONFIG_NET_CLS_RSVP=m
|
|||
CONFIG_NET_CLS_RSVP6=m
|
||||
CONFIG_NET_CLS_ACT=y
|
||||
CONFIG_NET_ACT_POLICE=y
|
||||
CONFIG_NET_CLS_IND=y
|
||||
# CONFIG_WIRELESS is not set
|
||||
CONFIG_DEVTMPFS=y
|
||||
CONFIG_BLK_DEV_LOOP=y
|
||||
|
|
|
@ -78,7 +78,6 @@ CONFIG_NET_CLS_RSVP=m
|
|||
CONFIG_NET_CLS_RSVP6=m
|
||||
CONFIG_NET_CLS_ACT=y
|
||||
CONFIG_NET_ACT_POLICE=y
|
||||
CONFIG_NET_CLS_IND=y
|
||||
# CONFIG_WIRELESS is not set
|
||||
CONFIG_DEVTMPFS=y
|
||||
CONFIG_BLK_DEV_LOOP=y
|
||||
|
|
|
@ -75,7 +75,6 @@ CONFIG_NET_CLS_RSVP=m
|
|||
CONFIG_NET_CLS_RSVP6=m
|
||||
CONFIG_NET_CLS_ACT=y
|
||||
CONFIG_NET_ACT_POLICE=y
|
||||
CONFIG_NET_CLS_IND=y
|
||||
# CONFIG_WIRELESS is not set
|
||||
CONFIG_DEVTMPFS=y
|
||||
CONFIG_BLK_DEV_LOOP=y
|
||||
|
|
|
@ -212,7 +212,6 @@ CONFIG_NET_ACT_NAT=m
|
|||
CONFIG_NET_ACT_PEDIT=m
|
||||
CONFIG_NET_ACT_SIMP=m
|
||||
CONFIG_NET_ACT_SKBEDIT=m
|
||||
CONFIG_NET_CLS_IND=y
|
||||
CONFIG_CFG80211=m
|
||||
CONFIG_MAC80211=m
|
||||
CONFIG_MAC80211_MESH=y
|
||||
|
|
|
@ -103,7 +103,6 @@ CONFIG_GACT_PROB=y
|
|||
CONFIG_NET_ACT_MIRRED=m
|
||||
CONFIG_NET_ACT_IPT=m
|
||||
CONFIG_NET_ACT_PEDIT=m
|
||||
CONFIG_NET_CLS_IND=y
|
||||
CONFIG_HAMRADIO=y
|
||||
CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
|
||||
CONFIG_MTD=y
|
||||
|
|
|
@ -133,6 +133,8 @@
|
|||
#define SO_RCVTIMEO_NEW 66
|
||||
#define SO_SNDTIMEO_NEW 67
|
||||
|
||||
#define SO_DETACH_REUSEPORT_BPF 68
|
||||
|
||||
#if !defined(__KERNEL__)
|
||||
|
||||
#if __BITS_PER_LONG == 64
|
||||
|
|
|
@ -114,6 +114,8 @@
|
|||
#define SO_RCVTIMEO_NEW 0x4040
|
||||
#define SO_SNDTIMEO_NEW 0x4041
|
||||
|
||||
#define SO_DETACH_REUSEPORT_BPF 0x4042
|
||||
|
||||
#if !defined(__KERNEL__)
|
||||
|
||||
#if __BITS_PER_LONG == 64
|
||||
|
|
|
@ -301,7 +301,6 @@ CONFIG_NET_ACT_NAT=m
|
|||
CONFIG_NET_ACT_PEDIT=m
|
||||
CONFIG_NET_ACT_SIMP=m
|
||||
CONFIG_NET_ACT_SKBEDIT=m
|
||||
CONFIG_NET_CLS_IND=y
|
||||
CONFIG_IRDA=m
|
||||
CONFIG_IRLAN=m
|
||||
CONFIG_IRNET=m
|
||||
|
|
|
@ -500,6 +500,9 @@ static int bpf_jit_build_body(struct bpf_prog *fp, u32 *image,
|
|||
case BPF_ALU | BPF_LSH | BPF_X: /* (u32) dst <<= (u32) src */
|
||||
/* slw clears top 32 bits */
|
||||
PPC_SLW(dst_reg, dst_reg, src_reg);
|
||||
/* skip zero extension move, but set address map. */
|
||||
if (insn_is_zext(&insn[i + 1]))
|
||||
addrs[++i] = ctx->idx * 4;
|
||||
break;
|
||||
case BPF_ALU64 | BPF_LSH | BPF_X: /* dst <<= src; */
|
||||
PPC_SLD(dst_reg, dst_reg, src_reg);
|
||||
|
@ -507,6 +510,8 @@ static int bpf_jit_build_body(struct bpf_prog *fp, u32 *image,
|
|||
case BPF_ALU | BPF_LSH | BPF_K: /* (u32) dst <<== (u32) imm */
|
||||
/* with imm 0, we still need to clear top 32 bits */
|
||||
PPC_SLWI(dst_reg, dst_reg, imm);
|
||||
if (insn_is_zext(&insn[i + 1]))
|
||||
addrs[++i] = ctx->idx * 4;
|
||||
break;
|
||||
case BPF_ALU64 | BPF_LSH | BPF_K: /* dst <<== imm */
|
||||
if (imm != 0)
|
||||
|
@ -514,12 +519,16 @@ static int bpf_jit_build_body(struct bpf_prog *fp, u32 *image,
|
|||
break;
|
||||
case BPF_ALU | BPF_RSH | BPF_X: /* (u32) dst >>= (u32) src */
|
||||
PPC_SRW(dst_reg, dst_reg, src_reg);
|
||||
if (insn_is_zext(&insn[i + 1]))
|
||||
addrs[++i] = ctx->idx * 4;
|
||||
break;
|
||||
case BPF_ALU64 | BPF_RSH | BPF_X: /* dst >>= src */
|
||||
PPC_SRD(dst_reg, dst_reg, src_reg);
|
||||
break;
|
||||
case BPF_ALU | BPF_RSH | BPF_K: /* (u32) dst >>= (u32) imm */
|
||||
PPC_SRWI(dst_reg, dst_reg, imm);
|
||||
if (insn_is_zext(&insn[i + 1]))
|
||||
addrs[++i] = ctx->idx * 4;
|
||||
break;
|
||||
case BPF_ALU64 | BPF_RSH | BPF_K: /* dst >>= imm */
|
||||
if (imm != 0)
|
||||
|
@ -544,6 +553,11 @@ static int bpf_jit_build_body(struct bpf_prog *fp, u32 *image,
|
|||
*/
|
||||
case BPF_ALU | BPF_MOV | BPF_X: /* (u32) dst = src */
|
||||
case BPF_ALU64 | BPF_MOV | BPF_X: /* dst = src */
|
||||
if (imm == 1) {
|
||||
/* special mov32 for zext */
|
||||
PPC_RLWINM(dst_reg, dst_reg, 0, 0, 31);
|
||||
break;
|
||||
}
|
||||
PPC_MR(dst_reg, src_reg);
|
||||
goto bpf_alu32_trunc;
|
||||
case BPF_ALU | BPF_MOV | BPF_K: /* (u32) dst = imm */
|
||||
|
@ -551,11 +565,13 @@ static int bpf_jit_build_body(struct bpf_prog *fp, u32 *image,
|
|||
PPC_LI32(dst_reg, imm);
|
||||
if (imm < 0)
|
||||
goto bpf_alu32_trunc;
|
||||
else if (insn_is_zext(&insn[i + 1]))
|
||||
addrs[++i] = ctx->idx * 4;
|
||||
break;
|
||||
|
||||
bpf_alu32_trunc:
|
||||
/* Truncate to 32-bits */
|
||||
if (BPF_CLASS(code) == BPF_ALU)
|
||||
if (BPF_CLASS(code) == BPF_ALU && !fp->aux->verifier_zext)
|
||||
PPC_RLWINM(dst_reg, dst_reg, 0, 0, 31);
|
||||
break;
|
||||
|
||||
|
@ -614,10 +630,13 @@ emit_clear:
|
|||
case 16:
|
||||
/* zero-extend 16 bits into 64 bits */
|
||||
PPC_RLDICL(dst_reg, dst_reg, 0, 48);
|
||||
if (insn_is_zext(&insn[i + 1]))
|
||||
addrs[++i] = ctx->idx * 4;
|
||||
break;
|
||||
case 32:
|
||||
/* zero-extend 32 bits into 64 bits */
|
||||
PPC_RLDICL(dst_reg, dst_reg, 0, 32);
|
||||
if (!fp->aux->verifier_zext)
|
||||
/* zero-extend 32 bits into 64 bits */
|
||||
PPC_RLDICL(dst_reg, dst_reg, 0, 32);
|
||||
break;
|
||||
case 64:
|
||||
/* nop */
|
||||
|
@ -694,14 +713,20 @@ emit_clear:
|
|||
/* dst = *(u8 *)(ul) (src + off) */
|
||||
case BPF_LDX | BPF_MEM | BPF_B:
|
||||
PPC_LBZ(dst_reg, src_reg, off);
|
||||
if (insn_is_zext(&insn[i + 1]))
|
||||
addrs[++i] = ctx->idx * 4;
|
||||
break;
|
||||
/* dst = *(u16 *)(ul) (src + off) */
|
||||
case BPF_LDX | BPF_MEM | BPF_H:
|
||||
PPC_LHZ(dst_reg, src_reg, off);
|
||||
if (insn_is_zext(&insn[i + 1]))
|
||||
addrs[++i] = ctx->idx * 4;
|
||||
break;
|
||||
/* dst = *(u32 *)(ul) (src + off) */
|
||||
case BPF_LDX | BPF_MEM | BPF_W:
|
||||
PPC_LWZ(dst_reg, src_reg, off);
|
||||
if (insn_is_zext(&insn[i + 1]))
|
||||
addrs[++i] = ctx->idx * 4;
|
||||
break;
|
||||
/* dst = *(u64 *)(ul) (src + off) */
|
||||
case BPF_LDX | BPF_MEM | BPF_DW:
|
||||
|
@ -1042,6 +1067,11 @@ struct powerpc64_jit_data {
|
|||
struct codegen_context ctx;
|
||||
};
|
||||
|
||||
bool bpf_jit_needs_zext(void)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *fp)
|
||||
{
|
||||
u32 proglen;
|
||||
|
|
|
@ -731,6 +731,7 @@ static int emit_insn(const struct bpf_insn *insn, struct rv_jit_context *ctx,
|
|||
{
|
||||
bool is64 = BPF_CLASS(insn->code) == BPF_ALU64 ||
|
||||
BPF_CLASS(insn->code) == BPF_JMP;
|
||||
struct bpf_prog_aux *aux = ctx->prog->aux;
|
||||
int rvoff, i = insn - ctx->prog->insnsi;
|
||||
u8 rd = -1, rs = -1, code = insn->code;
|
||||
s16 off = insn->off;
|
||||
|
@ -742,8 +743,13 @@ static int emit_insn(const struct bpf_insn *insn, struct rv_jit_context *ctx,
|
|||
/* dst = src */
|
||||
case BPF_ALU | BPF_MOV | BPF_X:
|
||||
case BPF_ALU64 | BPF_MOV | BPF_X:
|
||||
if (imm == 1) {
|
||||
/* Special mov32 for zext */
|
||||
emit_zext_32(rd, ctx);
|
||||
break;
|
||||
}
|
||||
emit(is64 ? rv_addi(rd, rs, 0) : rv_addiw(rd, rs, 0), ctx);
|
||||
if (!is64)
|
||||
if (!is64 && !aux->verifier_zext)
|
||||
emit_zext_32(rd, ctx);
|
||||
break;
|
||||
|
||||
|
@ -751,49 +757,49 @@ static int emit_insn(const struct bpf_insn *insn, struct rv_jit_context *ctx,
|
|||
case BPF_ALU | BPF_ADD | BPF_X:
|
||||
case BPF_ALU64 | BPF_ADD | BPF_X:
|
||||
emit(is64 ? rv_add(rd, rd, rs) : rv_addw(rd, rd, rs), ctx);
|
||||
if (!is64)
|
||||
if (!is64 && !aux->verifier_zext)
|
||||
emit_zext_32(rd, ctx);
|
||||
break;
|
||||
case BPF_ALU | BPF_SUB | BPF_X:
|
||||
case BPF_ALU64 | BPF_SUB | BPF_X:
|
||||
emit(is64 ? rv_sub(rd, rd, rs) : rv_subw(rd, rd, rs), ctx);
|
||||
if (!is64)
|
||||
if (!is64 && !aux->verifier_zext)
|
||||
emit_zext_32(rd, ctx);
|
||||
break;
|
||||
case BPF_ALU | BPF_AND | BPF_X:
|
||||
case BPF_ALU64 | BPF_AND | BPF_X:
|
||||
emit(rv_and(rd, rd, rs), ctx);
|
||||
if (!is64)
|
||||
if (!is64 && !aux->verifier_zext)
|
||||
emit_zext_32(rd, ctx);
|
||||
break;
|
||||
case BPF_ALU | BPF_OR | BPF_X:
|
||||
case BPF_ALU64 | BPF_OR | BPF_X:
|
||||
emit(rv_or(rd, rd, rs), ctx);
|
||||
if (!is64)
|
||||
if (!is64 && !aux->verifier_zext)
|
||||
emit_zext_32(rd, ctx);
|
||||
break;
|
||||
case BPF_ALU | BPF_XOR | BPF_X:
|
||||
case BPF_ALU64 | BPF_XOR | BPF_X:
|
||||
emit(rv_xor(rd, rd, rs), ctx);
|
||||
if (!is64)
|
||||
if (!is64 && !aux->verifier_zext)
|
||||
emit_zext_32(rd, ctx);
|
||||
break;
|
||||
case BPF_ALU | BPF_MUL | BPF_X:
|
||||
case BPF_ALU64 | BPF_MUL | BPF_X:
|
||||
emit(is64 ? rv_mul(rd, rd, rs) : rv_mulw(rd, rd, rs), ctx);
|
||||
if (!is64)
|
||||
if (!is64 && !aux->verifier_zext)
|
||||
emit_zext_32(rd, ctx);
|
||||
break;
|
||||
case BPF_ALU | BPF_DIV | BPF_X:
|
||||
case BPF_ALU64 | BPF_DIV | BPF_X:
|
||||
emit(is64 ? rv_divu(rd, rd, rs) : rv_divuw(rd, rd, rs), ctx);
|
||||
if (!is64)
|
||||
if (!is64 && !aux->verifier_zext)
|
||||
emit_zext_32(rd, ctx);
|
||||
break;
|
||||
case BPF_ALU | BPF_MOD | BPF_X:
|
||||
case BPF_ALU64 | BPF_MOD | BPF_X:
|
||||
emit(is64 ? rv_remu(rd, rd, rs) : rv_remuw(rd, rd, rs), ctx);
|
||||
if (!is64)
|
||||
if (!is64 && !aux->verifier_zext)
|
||||
emit_zext_32(rd, ctx);
|
||||
break;
|
||||
case BPF_ALU | BPF_LSH | BPF_X:
|
||||
|
@ -805,13 +811,13 @@ static int emit_insn(const struct bpf_insn *insn, struct rv_jit_context *ctx,
|
|||
case BPF_ALU | BPF_RSH | BPF_X:
|
||||
case BPF_ALU64 | BPF_RSH | BPF_X:
|
||||
emit(is64 ? rv_srl(rd, rd, rs) : rv_srlw(rd, rd, rs), ctx);
|
||||
if (!is64)
|
||||
if (!is64 && !aux->verifier_zext)
|
||||
emit_zext_32(rd, ctx);
|
||||
break;
|
||||
case BPF_ALU | BPF_ARSH | BPF_X:
|
||||
case BPF_ALU64 | BPF_ARSH | BPF_X:
|
||||
emit(is64 ? rv_sra(rd, rd, rs) : rv_sraw(rd, rd, rs), ctx);
|
||||
if (!is64)
|
||||
if (!is64 && !aux->verifier_zext)
|
||||
emit_zext_32(rd, ctx);
|
||||
break;
|
||||
|
||||
|
@ -820,7 +826,7 @@ static int emit_insn(const struct bpf_insn *insn, struct rv_jit_context *ctx,
|
|||
case BPF_ALU64 | BPF_NEG:
|
||||
emit(is64 ? rv_sub(rd, RV_REG_ZERO, rd) :
|
||||
rv_subw(rd, RV_REG_ZERO, rd), ctx);
|
||||
if (!is64)
|
||||
if (!is64 && !aux->verifier_zext)
|
||||
emit_zext_32(rd, ctx);
|
||||
break;
|
||||
|
||||
|
@ -885,7 +891,7 @@ out_be:
|
|||
case BPF_ALU | BPF_MOV | BPF_K:
|
||||
case BPF_ALU64 | BPF_MOV | BPF_K:
|
||||
emit_imm(rd, imm, ctx);
|
||||
if (!is64)
|
||||
if (!is64 && !aux->verifier_zext)
|
||||
emit_zext_32(rd, ctx);
|
||||
break;
|
||||
|
||||
|
@ -900,7 +906,7 @@ out_be:
|
|||
emit(is64 ? rv_add(rd, rd, RV_REG_T1) :
|
||||
rv_addw(rd, rd, RV_REG_T1), ctx);
|
||||
}
|
||||
if (!is64)
|
||||
if (!is64 && !aux->verifier_zext)
|
||||
emit_zext_32(rd, ctx);
|
||||
break;
|
||||
case BPF_ALU | BPF_SUB | BPF_K:
|
||||
|
@ -913,7 +919,7 @@ out_be:
|
|||
emit(is64 ? rv_sub(rd, rd, RV_REG_T1) :
|
||||
rv_subw(rd, rd, RV_REG_T1), ctx);
|
||||
}
|
||||
if (!is64)
|
||||
if (!is64 && !aux->verifier_zext)
|
||||
emit_zext_32(rd, ctx);
|
||||
break;
|
||||
case BPF_ALU | BPF_AND | BPF_K:
|
||||
|
@ -924,7 +930,7 @@ out_be:
|
|||
emit_imm(RV_REG_T1, imm, ctx);
|
||||
emit(rv_and(rd, rd, RV_REG_T1), ctx);
|
||||
}
|
||||
if (!is64)
|
||||
if (!is64 && !aux->verifier_zext)
|
||||
emit_zext_32(rd, ctx);
|
||||
break;
|
||||
case BPF_ALU | BPF_OR | BPF_K:
|
||||
|
@ -935,7 +941,7 @@ out_be:
|
|||
emit_imm(RV_REG_T1, imm, ctx);
|
||||
emit(rv_or(rd, rd, RV_REG_T1), ctx);
|
||||
}
|
||||
if (!is64)
|
||||
if (!is64 && !aux->verifier_zext)
|
||||
emit_zext_32(rd, ctx);
|
||||
break;
|
||||
case BPF_ALU | BPF_XOR | BPF_K:
|
||||
|
@ -946,7 +952,7 @@ out_be:
|
|||
emit_imm(RV_REG_T1, imm, ctx);
|
||||
emit(rv_xor(rd, rd, RV_REG_T1), ctx);
|
||||
}
|
||||
if (!is64)
|
||||
if (!is64 && !aux->verifier_zext)
|
||||
emit_zext_32(rd, ctx);
|
||||
break;
|
||||
case BPF_ALU | BPF_MUL | BPF_K:
|
||||
|
@ -954,7 +960,7 @@ out_be:
|
|||
emit_imm(RV_REG_T1, imm, ctx);
|
||||
emit(is64 ? rv_mul(rd, rd, RV_REG_T1) :
|
||||
rv_mulw(rd, rd, RV_REG_T1), ctx);
|
||||
if (!is64)
|
||||
if (!is64 && !aux->verifier_zext)
|
||||
emit_zext_32(rd, ctx);
|
||||
break;
|
||||
case BPF_ALU | BPF_DIV | BPF_K:
|
||||
|
@ -962,7 +968,7 @@ out_be:
|
|||
emit_imm(RV_REG_T1, imm, ctx);
|
||||
emit(is64 ? rv_divu(rd, rd, RV_REG_T1) :
|
||||
rv_divuw(rd, rd, RV_REG_T1), ctx);
|
||||
if (!is64)
|
||||
if (!is64 && !aux->verifier_zext)
|
||||
emit_zext_32(rd, ctx);
|
||||
break;
|
||||
case BPF_ALU | BPF_MOD | BPF_K:
|
||||
|
@ -970,7 +976,7 @@ out_be:
|
|||
emit_imm(RV_REG_T1, imm, ctx);
|
||||
emit(is64 ? rv_remu(rd, rd, RV_REG_T1) :
|
||||
rv_remuw(rd, rd, RV_REG_T1), ctx);
|
||||
if (!is64)
|
||||
if (!is64 && !aux->verifier_zext)
|
||||
emit_zext_32(rd, ctx);
|
||||
break;
|
||||
case BPF_ALU | BPF_LSH | BPF_K:
|
||||
|
@ -1263,6 +1269,8 @@ out_be:
|
|||
emit_imm(RV_REG_T1, off, ctx);
|
||||
emit(rv_add(RV_REG_T1, RV_REG_T1, rs), ctx);
|
||||
emit(rv_lbu(rd, 0, RV_REG_T1), ctx);
|
||||
if (insn_is_zext(&insn[1]))
|
||||
return 1;
|
||||
break;
|
||||
case BPF_LDX | BPF_MEM | BPF_H:
|
||||
if (is_12b_int(off)) {
|
||||
|
@ -1273,6 +1281,8 @@ out_be:
|
|||
emit_imm(RV_REG_T1, off, ctx);
|
||||
emit(rv_add(RV_REG_T1, RV_REG_T1, rs), ctx);
|
||||
emit(rv_lhu(rd, 0, RV_REG_T1), ctx);
|
||||
if (insn_is_zext(&insn[1]))
|
||||
return 1;
|
||||
break;
|
||||
case BPF_LDX | BPF_MEM | BPF_W:
|
||||
if (is_12b_int(off)) {
|
||||
|
@ -1283,6 +1293,8 @@ out_be:
|
|||
emit_imm(RV_REG_T1, off, ctx);
|
||||
emit(rv_add(RV_REG_T1, RV_REG_T1, rs), ctx);
|
||||
emit(rv_lwu(rd, 0, RV_REG_T1), ctx);
|
||||
if (insn_is_zext(&insn[1]))
|
||||
return 1;
|
||||
break;
|
||||
case BPF_LDX | BPF_MEM | BPF_DW:
|
||||
if (is_12b_int(off)) {
|
||||
|
@ -1527,6 +1539,11 @@ static void bpf_flush_icache(void *start, void *end)
|
|||
flush_icache_range((unsigned long)start, (unsigned long)end);
|
||||
}
|
||||
|
||||
bool bpf_jit_needs_zext(void)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *prog)
|
||||
{
|
||||
bool tmp_blinded = false, extra_pass = false;
|
||||
|
|
|
@ -299,9 +299,11 @@ static inline void reg_set_seen(struct bpf_jit *jit, u32 b1)
|
|||
|
||||
#define EMIT_ZERO(b1) \
|
||||
({ \
|
||||
/* llgfr %dst,%dst (zero extend to 64 bit) */ \
|
||||
EMIT4(0xb9160000, b1, b1); \
|
||||
REG_SET_SEEN(b1); \
|
||||
if (!fp->aux->verifier_zext) { \
|
||||
/* llgfr %dst,%dst (zero extend to 64 bit) */ \
|
||||
EMIT4(0xb9160000, b1, b1); \
|
||||
REG_SET_SEEN(b1); \
|
||||
} \
|
||||
})
|
||||
|
||||
/*
|
||||
|
@ -520,6 +522,8 @@ static noinline int bpf_jit_insn(struct bpf_jit *jit, struct bpf_prog *fp, int i
|
|||
case BPF_ALU | BPF_MOV | BPF_X: /* dst = (u32) src */
|
||||
/* llgfr %dst,%src */
|
||||
EMIT4(0xb9160000, dst_reg, src_reg);
|
||||
if (insn_is_zext(&insn[1]))
|
||||
insn_count = 2;
|
||||
break;
|
||||
case BPF_ALU64 | BPF_MOV | BPF_X: /* dst = src */
|
||||
/* lgr %dst,%src */
|
||||
|
@ -528,6 +532,8 @@ static noinline int bpf_jit_insn(struct bpf_jit *jit, struct bpf_prog *fp, int i
|
|||
case BPF_ALU | BPF_MOV | BPF_K: /* dst = (u32) imm */
|
||||
/* llilf %dst,imm */
|
||||
EMIT6_IMM(0xc00f0000, dst_reg, imm);
|
||||
if (insn_is_zext(&insn[1]))
|
||||
insn_count = 2;
|
||||
break;
|
||||
case BPF_ALU64 | BPF_MOV | BPF_K: /* dst = imm */
|
||||
/* lgfi %dst,imm */
|
||||
|
@ -639,6 +645,8 @@ static noinline int bpf_jit_insn(struct bpf_jit *jit, struct bpf_prog *fp, int i
|
|||
EMIT4(0xb9970000, REG_W0, src_reg);
|
||||
/* llgfr %dst,%rc */
|
||||
EMIT4(0xb9160000, dst_reg, rc_reg);
|
||||
if (insn_is_zext(&insn[1]))
|
||||
insn_count = 2;
|
||||
break;
|
||||
}
|
||||
case BPF_ALU64 | BPF_DIV | BPF_X: /* dst = dst / src */
|
||||
|
@ -676,6 +684,8 @@ static noinline int bpf_jit_insn(struct bpf_jit *jit, struct bpf_prog *fp, int i
|
|||
EMIT_CONST_U32(imm));
|
||||
/* llgfr %dst,%rc */
|
||||
EMIT4(0xb9160000, dst_reg, rc_reg);
|
||||
if (insn_is_zext(&insn[1]))
|
||||
insn_count = 2;
|
||||
break;
|
||||
}
|
||||
case BPF_ALU64 | BPF_DIV | BPF_K: /* dst = dst / imm */
|
||||
|
@ -864,10 +874,13 @@ static noinline int bpf_jit_insn(struct bpf_jit *jit, struct bpf_prog *fp, int i
|
|||
case 16: /* dst = (u16) cpu_to_be16(dst) */
|
||||
/* llghr %dst,%dst */
|
||||
EMIT4(0xb9850000, dst_reg, dst_reg);
|
||||
if (insn_is_zext(&insn[1]))
|
||||
insn_count = 2;
|
||||
break;
|
||||
case 32: /* dst = (u32) cpu_to_be32(dst) */
|
||||
/* llgfr %dst,%dst */
|
||||
EMIT4(0xb9160000, dst_reg, dst_reg);
|
||||
if (!fp->aux->verifier_zext)
|
||||
/* llgfr %dst,%dst */
|
||||
EMIT4(0xb9160000, dst_reg, dst_reg);
|
||||
break;
|
||||
case 64: /* dst = (u64) cpu_to_be64(dst) */
|
||||
break;
|
||||
|
@ -882,12 +895,15 @@ static noinline int bpf_jit_insn(struct bpf_jit *jit, struct bpf_prog *fp, int i
|
|||
EMIT4_DISP(0x88000000, dst_reg, REG_0, 16);
|
||||
/* llghr %dst,%dst */
|
||||
EMIT4(0xb9850000, dst_reg, dst_reg);
|
||||
if (insn_is_zext(&insn[1]))
|
||||
insn_count = 2;
|
||||
break;
|
||||
case 32: /* dst = (u32) cpu_to_le32(dst) */
|
||||
/* lrvr %dst,%dst */
|
||||
EMIT4(0xb91f0000, dst_reg, dst_reg);
|
||||
/* llgfr %dst,%dst */
|
||||
EMIT4(0xb9160000, dst_reg, dst_reg);
|
||||
if (!fp->aux->verifier_zext)
|
||||
/* llgfr %dst,%dst */
|
||||
EMIT4(0xb9160000, dst_reg, dst_reg);
|
||||
break;
|
||||
case 64: /* dst = (u64) cpu_to_le64(dst) */
|
||||
/* lrvgr %dst,%dst */
|
||||
|
@ -968,16 +984,22 @@ static noinline int bpf_jit_insn(struct bpf_jit *jit, struct bpf_prog *fp, int i
|
|||
/* llgc %dst,0(off,%src) */
|
||||
EMIT6_DISP_LH(0xe3000000, 0x0090, dst_reg, src_reg, REG_0, off);
|
||||
jit->seen |= SEEN_MEM;
|
||||
if (insn_is_zext(&insn[1]))
|
||||
insn_count = 2;
|
||||
break;
|
||||
case BPF_LDX | BPF_MEM | BPF_H: /* dst = *(u16 *)(ul) (src + off) */
|
||||
/* llgh %dst,0(off,%src) */
|
||||
EMIT6_DISP_LH(0xe3000000, 0x0091, dst_reg, src_reg, REG_0, off);
|
||||
jit->seen |= SEEN_MEM;
|
||||
if (insn_is_zext(&insn[1]))
|
||||
insn_count = 2;
|
||||
break;
|
||||
case BPF_LDX | BPF_MEM | BPF_W: /* dst = *(u32 *)(ul) (src + off) */
|
||||
/* llgf %dst,off(%src) */
|
||||
jit->seen |= SEEN_MEM;
|
||||
EMIT6_DISP_LH(0xe3000000, 0x0016, dst_reg, src_reg, REG_0, off);
|
||||
if (insn_is_zext(&insn[1]))
|
||||
insn_count = 2;
|
||||
break;
|
||||
case BPF_LDX | BPF_MEM | BPF_DW: /* dst = *(u64 *)(ul) (src + off) */
|
||||
/* lg %dst,0(off,%src) */
|
||||
|
@ -1282,6 +1304,11 @@ static int bpf_jit_prog(struct bpf_jit *jit, struct bpf_prog *fp)
|
|||
return 0;
|
||||
}
|
||||
|
||||
bool bpf_jit_needs_zext(void)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* Compile eBPF program "fp"
|
||||
*/
|
||||
|
|
|
@ -63,7 +63,6 @@ CONFIG_NET_SCH_NETEM=y
|
|||
CONFIG_NET_CLS_TCINDEX=y
|
||||
CONFIG_NET_CLS_ROUTE4=y
|
||||
CONFIG_NET_CLS_FW=y
|
||||
CONFIG_NET_CLS_IND=y
|
||||
CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
|
||||
CONFIG_MTD=y
|
||||
CONFIG_MTD_BLOCK=y
|
||||
|
|
|
@ -62,7 +62,6 @@ CONFIG_NET_SCH_NETEM=y
|
|||
CONFIG_NET_CLS_TCINDEX=y
|
||||
CONFIG_NET_CLS_ROUTE4=y
|
||||
CONFIG_NET_CLS_FW=y
|
||||
CONFIG_NET_CLS_IND=y
|
||||
CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
|
||||
CONFIG_MTD=y
|
||||
CONFIG_MTD_BLOCK=y
|
||||
|
|
|
@ -142,7 +142,6 @@ CONFIG_GACT_PROB=y
|
|||
CONFIG_NET_ACT_MIRRED=m
|
||||
CONFIG_NET_ACT_IPT=m
|
||||
CONFIG_NET_ACT_PEDIT=m
|
||||
CONFIG_NET_CLS_IND=y
|
||||
CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
|
||||
CONFIG_FW_LOADER=m
|
||||
CONFIG_CONNECTOR=m
|
||||
|
|
|
@ -115,6 +115,8 @@
|
|||
#define SO_RCVTIMEO_NEW 0x0044
|
||||
#define SO_SNDTIMEO_NEW 0x0045
|
||||
|
||||
#define SO_DETACH_REUSEPORT_BPF 0x0047
|
||||
|
||||
#if !defined(__KERNEL__)
|
||||
|
||||
|
||||
|
|
|
@ -908,6 +908,8 @@ static int build_insn(const struct bpf_insn *insn, struct jit_ctx *ctx)
|
|||
/* dst = src */
|
||||
case BPF_ALU | BPF_MOV | BPF_X:
|
||||
emit_alu3_K(SRL, src, 0, dst, ctx);
|
||||
if (insn_is_zext(&insn[1]))
|
||||
return 1;
|
||||
break;
|
||||
case BPF_ALU64 | BPF_MOV | BPF_X:
|
||||
emit_reg_move(src, dst, ctx);
|
||||
|
@ -942,6 +944,8 @@ static int build_insn(const struct bpf_insn *insn, struct jit_ctx *ctx)
|
|||
case BPF_ALU | BPF_DIV | BPF_X:
|
||||
emit_write_y(G0, ctx);
|
||||
emit_alu(DIV, src, dst, ctx);
|
||||
if (insn_is_zext(&insn[1]))
|
||||
return 1;
|
||||
break;
|
||||
case BPF_ALU64 | BPF_DIV | BPF_X:
|
||||
emit_alu(UDIVX, src, dst, ctx);
|
||||
|
@ -975,6 +979,8 @@ static int build_insn(const struct bpf_insn *insn, struct jit_ctx *ctx)
|
|||
break;
|
||||
case BPF_ALU | BPF_RSH | BPF_X:
|
||||
emit_alu(SRL, src, dst, ctx);
|
||||
if (insn_is_zext(&insn[1]))
|
||||
return 1;
|
||||
break;
|
||||
case BPF_ALU64 | BPF_RSH | BPF_X:
|
||||
emit_alu(SRLX, src, dst, ctx);
|
||||
|
@ -997,9 +1003,12 @@ static int build_insn(const struct bpf_insn *insn, struct jit_ctx *ctx)
|
|||
case 16:
|
||||
emit_alu_K(SLL, dst, 16, ctx);
|
||||
emit_alu_K(SRL, dst, 16, ctx);
|
||||
if (insn_is_zext(&insn[1]))
|
||||
return 1;
|
||||
break;
|
||||
case 32:
|
||||
emit_alu_K(SRL, dst, 0, ctx);
|
||||
if (!ctx->prog->aux->verifier_zext)
|
||||
emit_alu_K(SRL, dst, 0, ctx);
|
||||
break;
|
||||
case 64:
|
||||
/* nop */
|
||||
|
@ -1021,6 +1030,8 @@ static int build_insn(const struct bpf_insn *insn, struct jit_ctx *ctx)
|
|||
emit_alu3_K(AND, dst, 0xff, dst, ctx);
|
||||
emit_alu3_K(SLL, tmp, 8, tmp, ctx);
|
||||
emit_alu(OR, tmp, dst, ctx);
|
||||
if (insn_is_zext(&insn[1]))
|
||||
return 1;
|
||||
break;
|
||||
|
||||
case 32:
|
||||
|
@ -1037,6 +1048,8 @@ static int build_insn(const struct bpf_insn *insn, struct jit_ctx *ctx)
|
|||
emit_alu3_K(AND, dst, 0xff, dst, ctx); /* dst = dst & 0xff */
|
||||
emit_alu3_K(SLL, dst, 24, dst, ctx); /* dst = dst << 24 */
|
||||
emit_alu(OR, tmp, dst, ctx); /* dst = dst | tmp */
|
||||
if (insn_is_zext(&insn[1]))
|
||||
return 1;
|
||||
break;
|
||||
|
||||
case 64:
|
||||
|
@ -1050,6 +1063,8 @@ static int build_insn(const struct bpf_insn *insn, struct jit_ctx *ctx)
|
|||
/* dst = imm */
|
||||
case BPF_ALU | BPF_MOV | BPF_K:
|
||||
emit_loadimm32(imm, dst, ctx);
|
||||
if (insn_is_zext(&insn[1]))
|
||||
return 1;
|
||||
break;
|
||||
case BPF_ALU64 | BPF_MOV | BPF_K:
|
||||
emit_loadimm_sext(imm, dst, ctx);
|
||||
|
@ -1132,6 +1147,8 @@ static int build_insn(const struct bpf_insn *insn, struct jit_ctx *ctx)
|
|||
break;
|
||||
case BPF_ALU | BPF_RSH | BPF_K:
|
||||
emit_alu_K(SRL, dst, imm, ctx);
|
||||
if (insn_is_zext(&insn[1]))
|
||||
return 1;
|
||||
break;
|
||||
case BPF_ALU64 | BPF_RSH | BPF_K:
|
||||
emit_alu_K(SRLX, dst, imm, ctx);
|
||||
|
@ -1144,7 +1161,8 @@ static int build_insn(const struct bpf_insn *insn, struct jit_ctx *ctx)
|
|||
break;
|
||||
|
||||
do_alu32_trunc:
|
||||
if (BPF_CLASS(code) == BPF_ALU)
|
||||
if (BPF_CLASS(code) == BPF_ALU &&
|
||||
!ctx->prog->aux->verifier_zext)
|
||||
emit_alu_K(SRL, dst, 0, ctx);
|
||||
break;
|
||||
|
||||
|
@ -1265,6 +1283,8 @@ static int build_insn(const struct bpf_insn *insn, struct jit_ctx *ctx)
|
|||
rs2 = RS2(tmp);
|
||||
}
|
||||
emit(opcode | RS1(src) | rs2 | RD(dst), ctx);
|
||||
if (opcode != LD64 && insn_is_zext(&insn[1]))
|
||||
return 1;
|
||||
break;
|
||||
}
|
||||
/* ST: *(size *)(dst + off) = imm */
|
||||
|
@ -1432,6 +1452,11 @@ static void jit_fill_hole(void *area, unsigned int size)
|
|||
*ptr++ = 0x91d02005; /* ta 5 */
|
||||
}
|
||||
|
||||
bool bpf_jit_needs_zext(void)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
struct sparc64_jit_data {
|
||||
struct bpf_binary_header *header;
|
||||
u8 *image;
|
||||
|
|
|
@ -253,13 +253,14 @@ static inline void emit_ia32_mov_r(const u8 dst, const u8 src, bool dstk,
|
|||
/* dst = src */
|
||||
static inline void emit_ia32_mov_r64(const bool is64, const u8 dst[],
|
||||
const u8 src[], bool dstk,
|
||||
bool sstk, u8 **pprog)
|
||||
bool sstk, u8 **pprog,
|
||||
const struct bpf_prog_aux *aux)
|
||||
{
|
||||
emit_ia32_mov_r(dst_lo, src_lo, dstk, sstk, pprog);
|
||||
if (is64)
|
||||
/* complete 8 byte move */
|
||||
emit_ia32_mov_r(dst_hi, src_hi, dstk, sstk, pprog);
|
||||
else
|
||||
else if (!aux->verifier_zext)
|
||||
/* zero out high 4 bytes */
|
||||
emit_ia32_mov_i(dst_hi, 0, dstk, pprog);
|
||||
}
|
||||
|
@ -313,7 +314,8 @@ static inline void emit_ia32_mul_r(const u8 dst, const u8 src, bool dstk,
|
|||
}
|
||||
|
||||
static inline void emit_ia32_to_le_r64(const u8 dst[], s32 val,
|
||||
bool dstk, u8 **pprog)
|
||||
bool dstk, u8 **pprog,
|
||||
const struct bpf_prog_aux *aux)
|
||||
{
|
||||
u8 *prog = *pprog;
|
||||
int cnt = 0;
|
||||
|
@ -334,12 +336,14 @@ static inline void emit_ia32_to_le_r64(const u8 dst[], s32 val,
|
|||
*/
|
||||
EMIT2(0x0F, 0xB7);
|
||||
EMIT1(add_2reg(0xC0, dreg_lo, dreg_lo));
|
||||
/* xor dreg_hi,dreg_hi */
|
||||
EMIT2(0x33, add_2reg(0xC0, dreg_hi, dreg_hi));
|
||||
if (!aux->verifier_zext)
|
||||
/* xor dreg_hi,dreg_hi */
|
||||
EMIT2(0x33, add_2reg(0xC0, dreg_hi, dreg_hi));
|
||||
break;
|
||||
case 32:
|
||||
/* xor dreg_hi,dreg_hi */
|
||||
EMIT2(0x33, add_2reg(0xC0, dreg_hi, dreg_hi));
|
||||
if (!aux->verifier_zext)
|
||||
/* xor dreg_hi,dreg_hi */
|
||||
EMIT2(0x33, add_2reg(0xC0, dreg_hi, dreg_hi));
|
||||
break;
|
||||
case 64:
|
||||
/* nop */
|
||||
|
@ -358,7 +362,8 @@ static inline void emit_ia32_to_le_r64(const u8 dst[], s32 val,
|
|||
}
|
||||
|
||||
static inline void emit_ia32_to_be_r64(const u8 dst[], s32 val,
|
||||
bool dstk, u8 **pprog)
|
||||
bool dstk, u8 **pprog,
|
||||
const struct bpf_prog_aux *aux)
|
||||
{
|
||||
u8 *prog = *pprog;
|
||||
int cnt = 0;
|
||||
|
@ -380,16 +385,18 @@ static inline void emit_ia32_to_be_r64(const u8 dst[], s32 val,
|
|||
EMIT2(0x0F, 0xB7);
|
||||
EMIT1(add_2reg(0xC0, dreg_lo, dreg_lo));
|
||||
|
||||
/* xor dreg_hi,dreg_hi */
|
||||
EMIT2(0x33, add_2reg(0xC0, dreg_hi, dreg_hi));
|
||||
if (!aux->verifier_zext)
|
||||
/* xor dreg_hi,dreg_hi */
|
||||
EMIT2(0x33, add_2reg(0xC0, dreg_hi, dreg_hi));
|
||||
break;
|
||||
case 32:
|
||||
/* Emit 'bswap eax' to swap lower 4 bytes */
|
||||
EMIT1(0x0F);
|
||||
EMIT1(add_1reg(0xC8, dreg_lo));
|
||||
|
||||
/* xor dreg_hi,dreg_hi */
|
||||
EMIT2(0x33, add_2reg(0xC0, dreg_hi, dreg_hi));
|
||||
if (!aux->verifier_zext)
|
||||
/* xor dreg_hi,dreg_hi */
|
||||
EMIT2(0x33, add_2reg(0xC0, dreg_hi, dreg_hi));
|
||||
break;
|
||||
case 64:
|
||||
/* Emit 'bswap eax' to swap lower 4 bytes */
|
||||
|
@ -569,7 +576,7 @@ static inline void emit_ia32_alu_r(const bool is64, const bool hi, const u8 op,
|
|||
static inline void emit_ia32_alu_r64(const bool is64, const u8 op,
|
||||
const u8 dst[], const u8 src[],
|
||||
bool dstk, bool sstk,
|
||||
u8 **pprog)
|
||||
u8 **pprog, const struct bpf_prog_aux *aux)
|
||||
{
|
||||
u8 *prog = *pprog;
|
||||
|
||||
|
@ -577,7 +584,7 @@ static inline void emit_ia32_alu_r64(const bool is64, const u8 op,
|
|||
if (is64)
|
||||
emit_ia32_alu_r(is64, true, op, dst_hi, src_hi, dstk, sstk,
|
||||
&prog);
|
||||
else
|
||||
else if (!aux->verifier_zext)
|
||||
emit_ia32_mov_i(dst_hi, 0, dstk, &prog);
|
||||
*pprog = prog;
|
||||
}
|
||||
|
@ -668,7 +675,8 @@ static inline void emit_ia32_alu_i(const bool is64, const bool hi, const u8 op,
|
|||
/* ALU operation (64 bit) */
|
||||
static inline void emit_ia32_alu_i64(const bool is64, const u8 op,
|
||||
const u8 dst[], const u32 val,
|
||||
bool dstk, u8 **pprog)
|
||||
bool dstk, u8 **pprog,
|
||||
const struct bpf_prog_aux *aux)
|
||||
{
|
||||
u8 *prog = *pprog;
|
||||
u32 hi = 0;
|
||||
|
@ -679,7 +687,7 @@ static inline void emit_ia32_alu_i64(const bool is64, const u8 op,
|
|||
emit_ia32_alu_i(is64, false, op, dst_lo, val, dstk, &prog);
|
||||
if (is64)
|
||||
emit_ia32_alu_i(is64, true, op, dst_hi, hi, dstk, &prog);
|
||||
else
|
||||
else if (!aux->verifier_zext)
|
||||
emit_ia32_mov_i(dst_hi, 0, dstk, &prog);
|
||||
|
||||
*pprog = prog;
|
||||
|
@ -724,9 +732,6 @@ static inline void emit_ia32_lsh_r64(const u8 dst[], const u8 src[],
|
|||
{
|
||||
u8 *prog = *pprog;
|
||||
int cnt = 0;
|
||||
static int jmp_label1 = -1;
|
||||
static int jmp_label2 = -1;
|
||||
static int jmp_label3 = -1;
|
||||
u8 dreg_lo = dstk ? IA32_EAX : dst_lo;
|
||||
u8 dreg_hi = dstk ? IA32_EDX : dst_hi;
|
||||
|
||||
|
@ -745,79 +750,23 @@ static inline void emit_ia32_lsh_r64(const u8 dst[], const u8 src[],
|
|||
/* mov ecx,src_lo */
|
||||
EMIT2(0x8B, add_2reg(0xC0, src_lo, IA32_ECX));
|
||||
|
||||
/* shld dreg_hi,dreg_lo,cl */
|
||||
EMIT3(0x0F, 0xA5, add_2reg(0xC0, dreg_hi, dreg_lo));
|
||||
/* shl dreg_lo,cl */
|
||||
EMIT2(0xD3, add_1reg(0xE0, dreg_lo));
|
||||
|
||||
/* if ecx >= 32, mov dreg_lo into dreg_hi and clear dreg_lo */
|
||||
|
||||
/* cmp ecx,32 */
|
||||
EMIT3(0x83, add_1reg(0xF8, IA32_ECX), 32);
|
||||
/* Jumps when >= 32 */
|
||||
if (is_imm8(jmp_label(jmp_label1, 2)))
|
||||
EMIT2(IA32_JAE, jmp_label(jmp_label1, 2));
|
||||
else
|
||||
EMIT2_off32(0x0F, IA32_JAE + 0x10, jmp_label(jmp_label1, 6));
|
||||
/* skip the next two instructions (4 bytes) when < 32 */
|
||||
EMIT2(IA32_JB, 4);
|
||||
|
||||
/* < 32 */
|
||||
/* shl dreg_hi,cl */
|
||||
EMIT2(0xD3, add_1reg(0xE0, dreg_hi));
|
||||
/* mov ebx,dreg_lo */
|
||||
EMIT2(0x8B, add_2reg(0xC0, dreg_lo, IA32_EBX));
|
||||
/* shl dreg_lo,cl */
|
||||
EMIT2(0xD3, add_1reg(0xE0, dreg_lo));
|
||||
|
||||
/* IA32_ECX = -IA32_ECX + 32 */
|
||||
/* neg ecx */
|
||||
EMIT2(0xF7, add_1reg(0xD8, IA32_ECX));
|
||||
/* add ecx,32 */
|
||||
EMIT3(0x83, add_1reg(0xC0, IA32_ECX), 32);
|
||||
|
||||
/* shr ebx,cl */
|
||||
EMIT2(0xD3, add_1reg(0xE8, IA32_EBX));
|
||||
/* or dreg_hi,ebx */
|
||||
EMIT2(0x09, add_2reg(0xC0, dreg_hi, IA32_EBX));
|
||||
|
||||
/* goto out; */
|
||||
if (is_imm8(jmp_label(jmp_label3, 2)))
|
||||
EMIT2(0xEB, jmp_label(jmp_label3, 2));
|
||||
else
|
||||
EMIT1_off32(0xE9, jmp_label(jmp_label3, 5));
|
||||
|
||||
/* >= 32 */
|
||||
if (jmp_label1 == -1)
|
||||
jmp_label1 = cnt;
|
||||
|
||||
/* cmp ecx,64 */
|
||||
EMIT3(0x83, add_1reg(0xF8, IA32_ECX), 64);
|
||||
/* Jumps when >= 64 */
|
||||
if (is_imm8(jmp_label(jmp_label2, 2)))
|
||||
EMIT2(IA32_JAE, jmp_label(jmp_label2, 2));
|
||||
else
|
||||
EMIT2_off32(0x0F, IA32_JAE + 0x10, jmp_label(jmp_label2, 6));
|
||||
|
||||
/* >= 32 && < 64 */
|
||||
/* sub ecx,32 */
|
||||
EMIT3(0x83, add_1reg(0xE8, IA32_ECX), 32);
|
||||
/* shl dreg_lo,cl */
|
||||
EMIT2(0xD3, add_1reg(0xE0, dreg_lo));
|
||||
/* mov dreg_hi,dreg_lo */
|
||||
EMIT2(0x89, add_2reg(0xC0, dreg_hi, dreg_lo));
|
||||
|
||||
/* xor dreg_lo,dreg_lo */
|
||||
EMIT2(0x33, add_2reg(0xC0, dreg_lo, dreg_lo));
|
||||
|
||||
/* goto out; */
|
||||
if (is_imm8(jmp_label(jmp_label3, 2)))
|
||||
EMIT2(0xEB, jmp_label(jmp_label3, 2));
|
||||
else
|
||||
EMIT1_off32(0xE9, jmp_label(jmp_label3, 5));
|
||||
|
||||
/* >= 64 */
|
||||
if (jmp_label2 == -1)
|
||||
jmp_label2 = cnt;
|
||||
/* xor dreg_lo,dreg_lo */
|
||||
EMIT2(0x33, add_2reg(0xC0, dreg_lo, dreg_lo));
|
||||
/* xor dreg_hi,dreg_hi */
|
||||
EMIT2(0x33, add_2reg(0xC0, dreg_hi, dreg_hi));
|
||||
|
||||
if (jmp_label3 == -1)
|
||||
jmp_label3 = cnt;
|
||||
|
||||
if (dstk) {
|
||||
/* mov dword ptr [ebp+off],dreg_lo */
|
||||
EMIT3(0x89, add_2reg(0x40, IA32_EBP, dreg_lo),
|
||||
|
@ -836,9 +785,6 @@ static inline void emit_ia32_arsh_r64(const u8 dst[], const u8 src[],
|
|||
{
|
||||
u8 *prog = *pprog;
|
||||
int cnt = 0;
|
||||
static int jmp_label1 = -1;
|
||||
static int jmp_label2 = -1;
|
||||
static int jmp_label3 = -1;
|
||||
u8 dreg_lo = dstk ? IA32_EAX : dst_lo;
|
||||
u8 dreg_hi = dstk ? IA32_EDX : dst_hi;
|
||||
|
||||
|
@ -857,79 +803,23 @@ static inline void emit_ia32_arsh_r64(const u8 dst[], const u8 src[],
|
|||
/* mov ecx,src_lo */
|
||||
EMIT2(0x8B, add_2reg(0xC0, src_lo, IA32_ECX));
|
||||
|
||||
/* shrd dreg_lo,dreg_hi,cl */
|
||||
EMIT3(0x0F, 0xAD, add_2reg(0xC0, dreg_lo, dreg_hi));
|
||||
/* sar dreg_hi,cl */
|
||||
EMIT2(0xD3, add_1reg(0xF8, dreg_hi));
|
||||
|
||||
/* if ecx >= 32, mov dreg_hi to dreg_lo and set/clear dreg_hi depending on sign */
|
||||
|
||||
/* cmp ecx,32 */
|
||||
EMIT3(0x83, add_1reg(0xF8, IA32_ECX), 32);
|
||||
/* Jumps when >= 32 */
|
||||
if (is_imm8(jmp_label(jmp_label1, 2)))
|
||||
EMIT2(IA32_JAE, jmp_label(jmp_label1, 2));
|
||||
else
|
||||
EMIT2_off32(0x0F, IA32_JAE + 0x10, jmp_label(jmp_label1, 6));
|
||||
/* skip the next two instructions (5 bytes) when < 32 */
|
||||
EMIT2(IA32_JB, 5);
|
||||
|
||||
/* < 32 */
|
||||
/* lshr dreg_lo,cl */
|
||||
EMIT2(0xD3, add_1reg(0xE8, dreg_lo));
|
||||
/* mov ebx,dreg_hi */
|
||||
EMIT2(0x8B, add_2reg(0xC0, dreg_hi, IA32_EBX));
|
||||
/* ashr dreg_hi,cl */
|
||||
EMIT2(0xD3, add_1reg(0xF8, dreg_hi));
|
||||
|
||||
/* IA32_ECX = -IA32_ECX + 32 */
|
||||
/* neg ecx */
|
||||
EMIT2(0xF7, add_1reg(0xD8, IA32_ECX));
|
||||
/* add ecx,32 */
|
||||
EMIT3(0x83, add_1reg(0xC0, IA32_ECX), 32);
|
||||
|
||||
/* shl ebx,cl */
|
||||
EMIT2(0xD3, add_1reg(0xE0, IA32_EBX));
|
||||
/* or dreg_lo,ebx */
|
||||
EMIT2(0x09, add_2reg(0xC0, dreg_lo, IA32_EBX));
|
||||
|
||||
/* goto out; */
|
||||
if (is_imm8(jmp_label(jmp_label3, 2)))
|
||||
EMIT2(0xEB, jmp_label(jmp_label3, 2));
|
||||
else
|
||||
EMIT1_off32(0xE9, jmp_label(jmp_label3, 5));
|
||||
|
||||
/* >= 32 */
|
||||
if (jmp_label1 == -1)
|
||||
jmp_label1 = cnt;
|
||||
|
||||
/* cmp ecx,64 */
|
||||
EMIT3(0x83, add_1reg(0xF8, IA32_ECX), 64);
|
||||
/* Jumps when >= 64 */
|
||||
if (is_imm8(jmp_label(jmp_label2, 2)))
|
||||
EMIT2(IA32_JAE, jmp_label(jmp_label2, 2));
|
||||
else
|
||||
EMIT2_off32(0x0F, IA32_JAE + 0x10, jmp_label(jmp_label2, 6));
|
||||
|
||||
/* >= 32 && < 64 */
|
||||
/* sub ecx,32 */
|
||||
EMIT3(0x83, add_1reg(0xE8, IA32_ECX), 32);
|
||||
/* ashr dreg_hi,cl */
|
||||
EMIT2(0xD3, add_1reg(0xF8, dreg_hi));
|
||||
/* mov dreg_lo,dreg_hi */
|
||||
EMIT2(0x89, add_2reg(0xC0, dreg_lo, dreg_hi));
|
||||
|
||||
/* ashr dreg_hi,imm8 */
|
||||
/* sar dreg_hi,31 */
|
||||
EMIT3(0xC1, add_1reg(0xF8, dreg_hi), 31);
|
||||
|
||||
/* goto out; */
|
||||
if (is_imm8(jmp_label(jmp_label3, 2)))
|
||||
EMIT2(0xEB, jmp_label(jmp_label3, 2));
|
||||
else
|
||||
EMIT1_off32(0xE9, jmp_label(jmp_label3, 5));
|
||||
|
||||
/* >= 64 */
|
||||
if (jmp_label2 == -1)
|
||||
jmp_label2 = cnt;
|
||||
/* ashr dreg_hi,imm8 */
|
||||
EMIT3(0xC1, add_1reg(0xF8, dreg_hi), 31);
|
||||
/* mov dreg_lo,dreg_hi */
|
||||
EMIT2(0x89, add_2reg(0xC0, dreg_lo, dreg_hi));
|
||||
|
||||
if (jmp_label3 == -1)
|
||||
jmp_label3 = cnt;
|
||||
|
||||
if (dstk) {
|
||||
/* mov dword ptr [ebp+off],dreg_lo */
|
||||
EMIT3(0x89, add_2reg(0x40, IA32_EBP, dreg_lo),
|
||||
|
@ -948,9 +838,6 @@ static inline void emit_ia32_rsh_r64(const u8 dst[], const u8 src[], bool dstk,
|
|||
{
|
||||
u8 *prog = *pprog;
|
||||
int cnt = 0;
|
||||
static int jmp_label1 = -1;
|
||||
static int jmp_label2 = -1;
|
||||
static int jmp_label3 = -1;
|
||||
u8 dreg_lo = dstk ? IA32_EAX : dst_lo;
|
||||
u8 dreg_hi = dstk ? IA32_EDX : dst_hi;
|
||||
|
||||
|
@ -969,77 +856,23 @@ static inline void emit_ia32_rsh_r64(const u8 dst[], const u8 src[], bool dstk,
|
|||
/* mov ecx,src_lo */
|
||||
EMIT2(0x8B, add_2reg(0xC0, src_lo, IA32_ECX));
|
||||
|
||||
/* shrd dreg_lo,dreg_hi,cl */
|
||||
EMIT3(0x0F, 0xAD, add_2reg(0xC0, dreg_lo, dreg_hi));
|
||||
/* shr dreg_hi,cl */
|
||||
EMIT2(0xD3, add_1reg(0xE8, dreg_hi));
|
||||
|
||||
/* if ecx >= 32, mov dreg_hi to dreg_lo and clear dreg_hi */
|
||||
|
||||
/* cmp ecx,32 */
|
||||
EMIT3(0x83, add_1reg(0xF8, IA32_ECX), 32);
|
||||
/* Jumps when >= 32 */
|
||||
if (is_imm8(jmp_label(jmp_label1, 2)))
|
||||
EMIT2(IA32_JAE, jmp_label(jmp_label1, 2));
|
||||
else
|
||||
EMIT2_off32(0x0F, IA32_JAE + 0x10, jmp_label(jmp_label1, 6));
|
||||
/* skip the next two instructions (4 bytes) when < 32 */
|
||||
EMIT2(IA32_JB, 4);
|
||||
|
||||
/* < 32 */
|
||||
/* lshr dreg_lo,cl */
|
||||
EMIT2(0xD3, add_1reg(0xE8, dreg_lo));
|
||||
/* mov ebx,dreg_hi */
|
||||
EMIT2(0x8B, add_2reg(0xC0, dreg_hi, IA32_EBX));
|
||||
/* shr dreg_hi,cl */
|
||||
EMIT2(0xD3, add_1reg(0xE8, dreg_hi));
|
||||
|
||||
/* IA32_ECX = -IA32_ECX + 32 */
|
||||
/* neg ecx */
|
||||
EMIT2(0xF7, add_1reg(0xD8, IA32_ECX));
|
||||
/* add ecx,32 */
|
||||
EMIT3(0x83, add_1reg(0xC0, IA32_ECX), 32);
|
||||
|
||||
/* shl ebx,cl */
|
||||
EMIT2(0xD3, add_1reg(0xE0, IA32_EBX));
|
||||
/* or dreg_lo,ebx */
|
||||
EMIT2(0x09, add_2reg(0xC0, dreg_lo, IA32_EBX));
|
||||
|
||||
/* goto out; */
|
||||
if (is_imm8(jmp_label(jmp_label3, 2)))
|
||||
EMIT2(0xEB, jmp_label(jmp_label3, 2));
|
||||
else
|
||||
EMIT1_off32(0xE9, jmp_label(jmp_label3, 5));
|
||||
|
||||
/* >= 32 */
|
||||
if (jmp_label1 == -1)
|
||||
jmp_label1 = cnt;
|
||||
/* cmp ecx,64 */
|
||||
EMIT3(0x83, add_1reg(0xF8, IA32_ECX), 64);
|
||||
/* Jumps when >= 64 */
|
||||
if (is_imm8(jmp_label(jmp_label2, 2)))
|
||||
EMIT2(IA32_JAE, jmp_label(jmp_label2, 2));
|
||||
else
|
||||
EMIT2_off32(0x0F, IA32_JAE + 0x10, jmp_label(jmp_label2, 6));
|
||||
|
||||
/* >= 32 && < 64 */
|
||||
/* sub ecx,32 */
|
||||
EMIT3(0x83, add_1reg(0xE8, IA32_ECX), 32);
|
||||
/* shr dreg_hi,cl */
|
||||
EMIT2(0xD3, add_1reg(0xE8, dreg_hi));
|
||||
/* mov dreg_lo,dreg_hi */
|
||||
EMIT2(0x89, add_2reg(0xC0, dreg_lo, dreg_hi));
|
||||
/* xor dreg_hi,dreg_hi */
|
||||
EMIT2(0x33, add_2reg(0xC0, dreg_hi, dreg_hi));
|
||||
|
||||
/* goto out; */
|
||||
if (is_imm8(jmp_label(jmp_label3, 2)))
|
||||
EMIT2(0xEB, jmp_label(jmp_label3, 2));
|
||||
else
|
||||
EMIT1_off32(0xE9, jmp_label(jmp_label3, 5));
|
||||
|
||||
/* >= 64 */
|
||||
if (jmp_label2 == -1)
|
||||
jmp_label2 = cnt;
|
||||
/* xor dreg_lo,dreg_lo */
|
||||
EMIT2(0x33, add_2reg(0xC0, dreg_lo, dreg_lo));
|
||||
/* xor dreg_hi,dreg_hi */
|
||||
EMIT2(0x33, add_2reg(0xC0, dreg_hi, dreg_hi));
|
||||
|
||||
if (jmp_label3 == -1)
|
||||
jmp_label3 = cnt;
|
||||
|
||||
if (dstk) {
|
||||
/* mov dword ptr [ebp+off],dreg_lo */
|
||||
EMIT3(0x89, add_2reg(0x40, IA32_EBP, dreg_lo),
|
||||
|
@ -1069,27 +902,10 @@ static inline void emit_ia32_lsh_i64(const u8 dst[], const u32 val,
|
|||
}
|
||||
/* Do LSH operation */
|
||||
if (val < 32) {
|
||||
/* shl dreg_hi,imm8 */
|
||||
EMIT3(0xC1, add_1reg(0xE0, dreg_hi), val);
|
||||
/* mov ebx,dreg_lo */
|
||||
EMIT2(0x8B, add_2reg(0xC0, dreg_lo, IA32_EBX));
|
||||
/* shld dreg_hi,dreg_lo,imm8 */
|
||||
EMIT4(0x0F, 0xA4, add_2reg(0xC0, dreg_hi, dreg_lo), val);
|
||||
/* shl dreg_lo,imm8 */
|
||||
EMIT3(0xC1, add_1reg(0xE0, dreg_lo), val);
|
||||
|
||||
/* IA32_ECX = 32 - val */
|
||||
/* mov ecx,val */
|
||||
EMIT2(0xB1, val);
|
||||
/* movzx ecx,ecx */
|
||||
EMIT3(0x0F, 0xB6, add_2reg(0xC0, IA32_ECX, IA32_ECX));
|
||||
/* neg ecx */
|
||||
EMIT2(0xF7, add_1reg(0xD8, IA32_ECX));
|
||||
/* add ecx,32 */
|
||||
EMIT3(0x83, add_1reg(0xC0, IA32_ECX), 32);
|
||||
|
||||
/* shr ebx,cl */
|
||||
EMIT2(0xD3, add_1reg(0xE8, IA32_EBX));
|
||||
/* or dreg_hi,ebx */
|
||||
EMIT2(0x09, add_2reg(0xC0, dreg_hi, IA32_EBX));
|
||||
} else if (val >= 32 && val < 64) {
|
||||
u32 value = val - 32;
|
||||
|
||||
|
@ -1135,27 +951,10 @@ static inline void emit_ia32_rsh_i64(const u8 dst[], const u32 val,
|
|||
|
||||
/* Do RSH operation */
|
||||
if (val < 32) {
|
||||
/* shr dreg_lo,imm8 */
|
||||
EMIT3(0xC1, add_1reg(0xE8, dreg_lo), val);
|
||||
/* mov ebx,dreg_hi */
|
||||
EMIT2(0x8B, add_2reg(0xC0, dreg_hi, IA32_EBX));
|
||||
/* shrd dreg_lo,dreg_hi,imm8 */
|
||||
EMIT4(0x0F, 0xAC, add_2reg(0xC0, dreg_lo, dreg_hi), val);
|
||||
/* shr dreg_hi,imm8 */
|
||||
EMIT3(0xC1, add_1reg(0xE8, dreg_hi), val);
|
||||
|
||||
/* IA32_ECX = 32 - val */
|
||||
/* mov ecx,val */
|
||||
EMIT2(0xB1, val);
|
||||
/* movzx ecx,ecx */
|
||||
EMIT3(0x0F, 0xB6, add_2reg(0xC0, IA32_ECX, IA32_ECX));
|
||||
/* neg ecx */
|
||||
EMIT2(0xF7, add_1reg(0xD8, IA32_ECX));
|
||||
/* add ecx,32 */
|
||||
EMIT3(0x83, add_1reg(0xC0, IA32_ECX), 32);
|
||||
|
||||
/* shl ebx,cl */
|
||||
EMIT2(0xD3, add_1reg(0xE0, IA32_EBX));
|
||||
/* or dreg_lo,ebx */
|
||||
EMIT2(0x09, add_2reg(0xC0, dreg_lo, IA32_EBX));
|
||||
} else if (val >= 32 && val < 64) {
|
||||
u32 value = val - 32;
|
||||
|
||||
|
@ -1200,27 +999,10 @@ static inline void emit_ia32_arsh_i64(const u8 dst[], const u32 val,
|
|||
}
|
||||
/* Do RSH operation */
|
||||
if (val < 32) {
|
||||
/* shr dreg_lo,imm8 */
|
||||
EMIT3(0xC1, add_1reg(0xE8, dreg_lo), val);
|
||||
/* mov ebx,dreg_hi */
|
||||
EMIT2(0x8B, add_2reg(0xC0, dreg_hi, IA32_EBX));
|
||||
/* shrd dreg_lo,dreg_hi,imm8 */
|
||||
EMIT4(0x0F, 0xAC, add_2reg(0xC0, dreg_lo, dreg_hi), val);
|
||||
/* ashr dreg_hi,imm8 */
|
||||
EMIT3(0xC1, add_1reg(0xF8, dreg_hi), val);
|
||||
|
||||
/* IA32_ECX = 32 - val */
|
||||
/* mov ecx,val */
|
||||
EMIT2(0xB1, val);
|
||||
/* movzx ecx,ecx */
|
||||
EMIT3(0x0F, 0xB6, add_2reg(0xC0, IA32_ECX, IA32_ECX));
|
||||
/* neg ecx */
|
||||
EMIT2(0xF7, add_1reg(0xD8, IA32_ECX));
|
||||
/* add ecx,32 */
|
||||
EMIT3(0x83, add_1reg(0xC0, IA32_ECX), 32);
|
||||
|
||||
/* shl ebx,cl */
|
||||
EMIT2(0xD3, add_1reg(0xE0, IA32_EBX));
|
||||
/* or dreg_lo,ebx */
|
||||
EMIT2(0x09, add_2reg(0xC0, dreg_lo, IA32_EBX));
|
||||
} else if (val >= 32 && val < 64) {
|
||||
u32 value = val - 32;
|
||||
|
||||
|
@ -1713,8 +1495,13 @@ static int do_jit(struct bpf_prog *bpf_prog, int *addrs, u8 *image,
|
|||
case BPF_ALU64 | BPF_MOV | BPF_X:
|
||||
switch (BPF_SRC(code)) {
|
||||
case BPF_X:
|
||||
emit_ia32_mov_r64(is64, dst, src, dstk,
|
||||
sstk, &prog);
|
||||
if (imm32 == 1) {
|
||||
/* Special mov32 for zext. */
|
||||
emit_ia32_mov_i(dst_hi, 0, dstk, &prog);
|
||||
break;
|
||||
}
|
||||
emit_ia32_mov_r64(is64, dst, src, dstk, sstk,
|
||||
&prog, bpf_prog->aux);
|
||||
break;
|
||||
case BPF_K:
|
||||
/* Sign-extend immediate value to dst reg */
|
||||
|
@ -1754,11 +1541,13 @@ static int do_jit(struct bpf_prog *bpf_prog, int *addrs, u8 *image,
|
|||
switch (BPF_SRC(code)) {
|
||||
case BPF_X:
|
||||
emit_ia32_alu_r64(is64, BPF_OP(code), dst,
|
||||
src, dstk, sstk, &prog);
|
||||
src, dstk, sstk, &prog,
|
||||
bpf_prog->aux);
|
||||
break;
|
||||
case BPF_K:
|
||||
emit_ia32_alu_i64(is64, BPF_OP(code), dst,
|
||||
imm32, dstk, &prog);
|
||||
imm32, dstk, &prog,
|
||||
bpf_prog->aux);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
@ -1777,7 +1566,8 @@ static int do_jit(struct bpf_prog *bpf_prog, int *addrs, u8 *image,
|
|||
false, &prog);
|
||||
break;
|
||||
}
|
||||
emit_ia32_mov_i(dst_hi, 0, dstk, &prog);
|
||||
if (!bpf_prog->aux->verifier_zext)
|
||||
emit_ia32_mov_i(dst_hi, 0, dstk, &prog);
|
||||
break;
|
||||
case BPF_ALU | BPF_LSH | BPF_X:
|
||||
case BPF_ALU | BPF_RSH | BPF_X:
|
||||
|
@ -1797,7 +1587,8 @@ static int do_jit(struct bpf_prog *bpf_prog, int *addrs, u8 *image,
|
|||
&prog);
|
||||
break;
|
||||
}
|
||||
emit_ia32_mov_i(dst_hi, 0, dstk, &prog);
|
||||
if (!bpf_prog->aux->verifier_zext)
|
||||
emit_ia32_mov_i(dst_hi, 0, dstk, &prog);
|
||||
break;
|
||||
/* dst = dst / src(imm) */
|
||||
/* dst = dst % src(imm) */
|
||||
|
@ -1819,7 +1610,8 @@ static int do_jit(struct bpf_prog *bpf_prog, int *addrs, u8 *image,
|
|||
&prog);
|
||||
break;
|
||||
}
|
||||
emit_ia32_mov_i(dst_hi, 0, dstk, &prog);
|
||||
if (!bpf_prog->aux->verifier_zext)
|
||||
emit_ia32_mov_i(dst_hi, 0, dstk, &prog);
|
||||
break;
|
||||
case BPF_ALU64 | BPF_DIV | BPF_K:
|
||||
case BPF_ALU64 | BPF_DIV | BPF_X:
|
||||
|
@ -1836,7 +1628,8 @@ static int do_jit(struct bpf_prog *bpf_prog, int *addrs, u8 *image,
|
|||
EMIT2_off32(0xC7, add_1reg(0xC0, IA32_ECX), imm32);
|
||||
emit_ia32_shift_r(BPF_OP(code), dst_lo, IA32_ECX, dstk,
|
||||
false, &prog);
|
||||
emit_ia32_mov_i(dst_hi, 0, dstk, &prog);
|
||||
if (!bpf_prog->aux->verifier_zext)
|
||||
emit_ia32_mov_i(dst_hi, 0, dstk, &prog);
|
||||
break;
|
||||
/* dst = dst << imm */
|
||||
case BPF_ALU64 | BPF_LSH | BPF_K:
|
||||
|
@ -1872,7 +1665,8 @@ static int do_jit(struct bpf_prog *bpf_prog, int *addrs, u8 *image,
|
|||
case BPF_ALU | BPF_NEG:
|
||||
emit_ia32_alu_i(is64, false, BPF_OP(code),
|
||||
dst_lo, 0, dstk, &prog);
|
||||
emit_ia32_mov_i(dst_hi, 0, dstk, &prog);
|
||||
if (!bpf_prog->aux->verifier_zext)
|
||||
emit_ia32_mov_i(dst_hi, 0, dstk, &prog);
|
||||
break;
|
||||
/* dst = ~dst (64 bit) */
|
||||
case BPF_ALU64 | BPF_NEG:
|
||||
|
@ -1892,11 +1686,13 @@ static int do_jit(struct bpf_prog *bpf_prog, int *addrs, u8 *image,
|
|||
break;
|
||||
/* dst = htole(dst) */
|
||||
case BPF_ALU | BPF_END | BPF_FROM_LE:
|
||||
emit_ia32_to_le_r64(dst, imm32, dstk, &prog);
|
||||
emit_ia32_to_le_r64(dst, imm32, dstk, &prog,
|
||||
bpf_prog->aux);
|
||||
break;
|
||||
/* dst = htobe(dst) */
|
||||
case BPF_ALU | BPF_END | BPF_FROM_BE:
|
||||
emit_ia32_to_be_r64(dst, imm32, dstk, &prog);
|
||||
emit_ia32_to_be_r64(dst, imm32, dstk, &prog,
|
||||
bpf_prog->aux);
|
||||
break;
|
||||
/* dst = imm64 */
|
||||
case BPF_LD | BPF_IMM | BPF_DW: {
|
||||
|
@ -2051,6 +1847,8 @@ static int do_jit(struct bpf_prog *bpf_prog, int *addrs, u8 *image,
|
|||
case BPF_B:
|
||||
case BPF_H:
|
||||
case BPF_W:
|
||||
if (!bpf_prog->aux->verifier_zext)
|
||||
break;
|
||||
if (dstk) {
|
||||
EMIT3(0xC7, add_1reg(0x40, IA32_EBP),
|
||||
STACK_VAR(dst_hi));
|
||||
|
@ -2475,6 +2273,11 @@ notyet:
|
|||
return proglen;
|
||||
}
|
||||
|
||||
bool bpf_jit_needs_zext(void)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *prog)
|
||||
{
|
||||
struct bpf_binary_header *header = NULL;
|
||||
|
|
|
@ -52,6 +52,17 @@ config BT_HCIBTUSB_BCM
|
|||
|
||||
Say Y here to compile support for Broadcom protocol.
|
||||
|
||||
config BT_HCIBTUSB_MTK
|
||||
bool "MediaTek protocol support"
|
||||
depends on BT_HCIBTUSB
|
||||
default n
|
||||
help
|
||||
The MediaTek protocol support enables firmware download
|
||||
support and chip initialization for MediaTek Bluetooth
|
||||
USB controllers.
|
||||
|
||||
Say Y here to compile support for MediaTek protocol.
|
||||
|
||||
config BT_HCIBTUSB_RTL
|
||||
bool "Realtek protocol support"
|
||||
depends on BT_HCIBTUSB
|
||||
|
@ -237,6 +248,7 @@ config BT_HCIUART_AG6XX
|
|||
config BT_HCIUART_MRVL
|
||||
bool "Marvell protocol support"
|
||||
depends on BT_HCIUART
|
||||
depends on BT_HCIUART_SERDEV
|
||||
select BT_HCIUART_H4
|
||||
help
|
||||
Marvell is serial protocol for communication between Bluetooth
|
||||
|
|
|
@ -359,7 +359,8 @@ static int bpa10x_set_diag(struct hci_dev *hdev, bool enable)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int bpa10x_probe(struct usb_interface *intf, const struct usb_device_id *id)
|
||||
static int bpa10x_probe(struct usb_interface *intf,
|
||||
const struct usb_device_id *id)
|
||||
{
|
||||
struct bpa10x_data *data;
|
||||
struct hci_dev *hdev;
|
||||
|
|
|
@ -335,6 +335,7 @@ static const struct bcm_subver_table bcm_uart_subver_table[] = {
|
|||
{ 0x230f, "BCM4356A2" }, /* 001.003.015 */
|
||||
{ 0x220e, "BCM20702A1" }, /* 001.002.014 */
|
||||
{ 0x4217, "BCM4329B1" }, /* 002.002.023 */
|
||||
{ 0x6106, "BCM4359C0" }, /* 003.001.006 */
|
||||
{ }
|
||||
};
|
||||
|
||||
|
|
|
@ -115,10 +115,12 @@ struct btmtk_hci_wmt_params {
|
|||
struct btmtkuart_dev {
|
||||
struct hci_dev *hdev;
|
||||
struct serdev_device *serdev;
|
||||
struct clk *clk;
|
||||
|
||||
struct clk *clk;
|
||||
struct clk *osc;
|
||||
struct regulator *vcc;
|
||||
struct gpio_desc *reset;
|
||||
struct gpio_desc *boot;
|
||||
struct pinctrl *pinctrl;
|
||||
struct pinctrl_state *pins_runtime;
|
||||
struct pinctrl_state *pins_boot;
|
||||
|
@ -911,6 +913,19 @@ static int btmtkuart_parse_dt(struct serdev_device *serdev)
|
|||
return err;
|
||||
}
|
||||
|
||||
bdev->osc = devm_clk_get_optional(&serdev->dev, "osc");
|
||||
if (IS_ERR(bdev->osc)) {
|
||||
err = PTR_ERR(bdev->osc);
|
||||
return err;
|
||||
}
|
||||
|
||||
bdev->boot = devm_gpiod_get_optional(&serdev->dev, "boot",
|
||||
GPIOD_OUT_LOW);
|
||||
if (IS_ERR(bdev->boot)) {
|
||||
err = PTR_ERR(bdev->boot);
|
||||
return err;
|
||||
}
|
||||
|
||||
bdev->pinctrl = devm_pinctrl_get(&serdev->dev);
|
||||
if (IS_ERR(bdev->pinctrl)) {
|
||||
err = PTR_ERR(bdev->pinctrl);
|
||||
|
@ -919,8 +934,10 @@ static int btmtkuart_parse_dt(struct serdev_device *serdev)
|
|||
|
||||
bdev->pins_boot = pinctrl_lookup_state(bdev->pinctrl,
|
||||
"default");
|
||||
if (IS_ERR(bdev->pins_boot)) {
|
||||
if (IS_ERR(bdev->pins_boot) && !bdev->boot) {
|
||||
err = PTR_ERR(bdev->pins_boot);
|
||||
dev_err(&serdev->dev,
|
||||
"Should assign RXD to LOW at boot stage\n");
|
||||
return err;
|
||||
}
|
||||
|
||||
|
@ -996,13 +1013,25 @@ static int btmtkuart_probe(struct serdev_device *serdev)
|
|||
set_bit(HCI_QUIRK_NON_PERSISTENT_SETUP, &hdev->quirks);
|
||||
|
||||
if (btmtkuart_is_standalone(bdev)) {
|
||||
/* Switch to the specific pin state for the booting requires */
|
||||
pinctrl_select_state(bdev->pinctrl, bdev->pins_boot);
|
||||
err = clk_prepare_enable(bdev->osc);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
if (bdev->boot) {
|
||||
gpiod_set_value_cansleep(bdev->boot, 1);
|
||||
} else {
|
||||
/* Switch to the specific pin state for the booting
|
||||
* requires.
|
||||
*/
|
||||
pinctrl_select_state(bdev->pinctrl, bdev->pins_boot);
|
||||
}
|
||||
|
||||
/* Power on */
|
||||
err = regulator_enable(bdev->vcc);
|
||||
if (err < 0)
|
||||
if (err < 0) {
|
||||
clk_disable_unprepare(bdev->osc);
|
||||
return err;
|
||||
}
|
||||
|
||||
/* Reset if the reset-gpios is available otherwise the board
|
||||
* -level design should be guaranteed.
|
||||
|
@ -1017,6 +1046,10 @@ static int btmtkuart_probe(struct serdev_device *serdev)
|
|||
* mode the device requires for UART transfers.
|
||||
*/
|
||||
msleep(50);
|
||||
|
||||
if (bdev->boot)
|
||||
devm_gpiod_put(&serdev->dev, bdev->boot);
|
||||
|
||||
pinctrl_select_state(bdev->pinctrl, bdev->pins_runtime);
|
||||
|
||||
/* A standalone device doesn't depends on power domain on SoC,
|
||||
|
@ -1037,10 +1070,8 @@ static int btmtkuart_probe(struct serdev_device *serdev)
|
|||
return 0;
|
||||
|
||||
err_regulator_disable:
|
||||
if (btmtkuart_is_standalone(bdev)) {
|
||||
pinctrl_select_state(bdev->pinctrl, bdev->pins_boot);
|
||||
if (btmtkuart_is_standalone(bdev))
|
||||
regulator_disable(bdev->vcc);
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
@ -1050,9 +1081,9 @@ static void btmtkuart_remove(struct serdev_device *serdev)
|
|||
struct btmtkuart_dev *bdev = serdev_device_get_drvdata(serdev);
|
||||
struct hci_dev *hdev = bdev->hdev;
|
||||
|
||||
if (btmtkuart_is_standalone(bdev)) {
|
||||
pinctrl_select_state(bdev->pinctrl, bdev->pins_boot);
|
||||
if (btmtkuart_is_standalone(bdev)) {
|
||||
regulator_disable(bdev->vcc);
|
||||
clk_disable_unprepare(bdev->osc);
|
||||
}
|
||||
|
||||
hci_unregister_dev(hdev);
|
||||
|
|
|
@ -131,6 +131,7 @@ static void qca_tlv_check_data(struct rome_config *config,
|
|||
* In case VSE is skipped, only the last segment is acked.
|
||||
*/
|
||||
config->dnld_mode = tlv_patch->download_mode;
|
||||
config->dnld_type = config->dnld_mode;
|
||||
|
||||
BT_DBG("Total Length : %d bytes",
|
||||
le32_to_cpu(tlv_patch->total_size));
|
||||
|
@ -251,6 +252,31 @@ out:
|
|||
return err;
|
||||
}
|
||||
|
||||
static int qca_inject_cmd_complete_event(struct hci_dev *hdev)
|
||||
{
|
||||
struct hci_event_hdr *hdr;
|
||||
struct hci_ev_cmd_complete *evt;
|
||||
struct sk_buff *skb;
|
||||
|
||||
skb = bt_skb_alloc(sizeof(*hdr) + sizeof(*evt) + 1, GFP_KERNEL);
|
||||
if (!skb)
|
||||
return -ENOMEM;
|
||||
|
||||
hdr = skb_put(skb, sizeof(*hdr));
|
||||
hdr->evt = HCI_EV_CMD_COMPLETE;
|
||||
hdr->plen = sizeof(*evt) + 1;
|
||||
|
||||
evt = skb_put(skb, sizeof(*evt));
|
||||
evt->ncmd = 1;
|
||||
evt->opcode = QCA_HCI_CC_OPCODE;
|
||||
|
||||
skb_put_u8(skb, QCA_HCI_CC_SUCCESS);
|
||||
|
||||
hci_skb_pkt_type(skb) = HCI_EVENT_PKT;
|
||||
|
||||
return hci_recv_frame(hdev, skb);
|
||||
}
|
||||
|
||||
static int qca_download_firmware(struct hci_dev *hdev,
|
||||
struct rome_config *config)
|
||||
{
|
||||
|
@ -284,11 +310,22 @@ static int qca_download_firmware(struct hci_dev *hdev,
|
|||
ret = qca_tlv_send_segment(hdev, segsize, segment,
|
||||
config->dnld_mode);
|
||||
if (ret)
|
||||
break;
|
||||
goto out;
|
||||
|
||||
segment += segsize;
|
||||
}
|
||||
|
||||
/* Latest qualcomm chipsets are not sending a command complete event
|
||||
* for every fw packet sent. They only respond with a vendor specific
|
||||
* event for the last packet. This optimization in the chip will
|
||||
* decrease the BT in initialization time. Here we will inject a command
|
||||
* complete event to avoid a command timeout error message.
|
||||
*/
|
||||
if (config->dnld_type == ROME_SKIP_EVT_VSE_CC ||
|
||||
config->dnld_type == ROME_SKIP_EVT_VSE)
|
||||
return qca_inject_cmd_complete_event(hdev);
|
||||
|
||||
out:
|
||||
release_firmware(fw);
|
||||
|
||||
return ret;
|
||||
|
@ -319,7 +356,8 @@ int qca_set_bdaddr_rome(struct hci_dev *hdev, const bdaddr_t *bdaddr)
|
|||
EXPORT_SYMBOL_GPL(qca_set_bdaddr_rome);
|
||||
|
||||
int qca_uart_setup(struct hci_dev *hdev, uint8_t baudrate,
|
||||
enum qca_btsoc_type soc_type, u32 soc_ver)
|
||||
enum qca_btsoc_type soc_type, u32 soc_ver,
|
||||
const char *firmware_name)
|
||||
{
|
||||
struct rome_config config;
|
||||
int err;
|
||||
|
@ -352,7 +390,10 @@ int qca_uart_setup(struct hci_dev *hdev, uint8_t baudrate,
|
|||
|
||||
/* Download NVM configuration */
|
||||
config.type = TLV_TYPE_NVM;
|
||||
if (qca_is_wcn399x(soc_type))
|
||||
if (firmware_name)
|
||||
snprintf(config.fwname, sizeof(config.fwname),
|
||||
"qca/%s", firmware_name);
|
||||
else if (qca_is_wcn399x(soc_type))
|
||||
snprintf(config.fwname, sizeof(config.fwname),
|
||||
"qca/crnv%02x.bin", rom_ver);
|
||||
else
|
||||
|
|
|
@ -28,6 +28,9 @@
|
|||
#define QCA_WCN3990_POWERON_PULSE 0xFC
|
||||
#define QCA_WCN3990_POWEROFF_PULSE 0xC0
|
||||
|
||||
#define QCA_HCI_CC_OPCODE 0xFC00
|
||||
#define QCA_HCI_CC_SUCCESS 0x00
|
||||
|
||||
enum qca_baudrate {
|
||||
QCA_BAUDRATE_115200 = 0,
|
||||
QCA_BAUDRATE_57600,
|
||||
|
@ -69,6 +72,7 @@ struct rome_config {
|
|||
char fwname[64];
|
||||
uint8_t user_baud_rate;
|
||||
enum rome_tlv_dnld_mode dnld_mode;
|
||||
enum rome_tlv_dnld_mode dnld_type;
|
||||
};
|
||||
|
||||
struct edl_event_hdr {
|
||||
|
@ -127,7 +131,8 @@ enum qca_btsoc_type {
|
|||
|
||||
int qca_set_bdaddr_rome(struct hci_dev *hdev, const bdaddr_t *bdaddr);
|
||||
int qca_uart_setup(struct hci_dev *hdev, uint8_t baudrate,
|
||||
enum qca_btsoc_type soc_type, u32 soc_ver);
|
||||
enum qca_btsoc_type soc_type, u32 soc_ver,
|
||||
const char *firmware_name);
|
||||
int qca_read_soc_version(struct hci_dev *hdev, u32 *soc_version);
|
||||
int qca_set_bdaddr(struct hci_dev *hdev, const bdaddr_t *bdaddr);
|
||||
static inline bool qca_is_wcn399x(enum qca_btsoc_type soc_type)
|
||||
|
@ -142,7 +147,8 @@ static inline int qca_set_bdaddr_rome(struct hci_dev *hdev, const bdaddr_t *bdad
|
|||
}
|
||||
|
||||
static inline int qca_uart_setup(struct hci_dev *hdev, uint8_t baudrate,
|
||||
enum qca_btsoc_type soc_type, u32 soc_ver)
|
||||
enum qca_btsoc_type soc_type, u32 soc_ver,
|
||||
const char *firmware_name)
|
||||
{
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
#define RTL_ROM_LMP_3499 0x3499
|
||||
#define RTL_ROM_LMP_8723A 0x1200
|
||||
#define RTL_ROM_LMP_8723B 0x8723
|
||||
#define RTL_ROM_LMP_8723D 0x8873
|
||||
#define RTL_ROM_LMP_8821A 0x8821
|
||||
#define RTL_ROM_LMP_8761A 0x8761
|
||||
#define RTL_ROM_LMP_8822B 0x8822
|
||||
|
@ -107,6 +108,13 @@ static const struct id_table ic_id_table[] = {
|
|||
.fw_name = "rtl_bt/rtl8723ds_fw.bin",
|
||||
.cfg_name = "rtl_bt/rtl8723ds_config" },
|
||||
|
||||
/* 8723DU */
|
||||
{ IC_INFO(RTL_ROM_LMP_8723D, 0x826C),
|
||||
.config_needed = true,
|
||||
.has_rom_version = true,
|
||||
.fw_name = "rtl_bt/rtl8723d_fw.bin",
|
||||
.cfg_name = "rtl_bt/rtl8723d_config" },
|
||||
|
||||
/* 8821A */
|
||||
{ IC_INFO(RTL_ROM_LMP_8821A, 0xa),
|
||||
.config_needed = false,
|
||||
|
@ -637,6 +645,26 @@ int btrtl_setup_realtek(struct hci_dev *hdev)
|
|||
}
|
||||
EXPORT_SYMBOL_GPL(btrtl_setup_realtek);
|
||||
|
||||
int btrtl_shutdown_realtek(struct hci_dev *hdev)
|
||||
{
|
||||
struct sk_buff *skb;
|
||||
int ret;
|
||||
|
||||
/* According to the vendor driver, BT must be reset on close to avoid
|
||||
* firmware crash.
|
||||
*/
|
||||
skb = __hci_cmd_sync(hdev, HCI_OP_RESET, 0, NULL, HCI_INIT_TIMEOUT);
|
||||
if (IS_ERR(skb)) {
|
||||
ret = PTR_ERR(skb);
|
||||
bt_dev_err(hdev, "HCI reset during shutdown failed");
|
||||
return ret;
|
||||
}
|
||||
kfree_skb(skb);
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(btrtl_shutdown_realtek);
|
||||
|
||||
static unsigned int btrtl_convert_baudrate(u32 device_baudrate)
|
||||
{
|
||||
switch (device_baudrate) {
|
||||
|
|
|
@ -55,6 +55,7 @@ void btrtl_free(struct btrtl_device_info *btrtl_dev);
|
|||
int btrtl_download_firmware(struct hci_dev *hdev,
|
||||
struct btrtl_device_info *btrtl_dev);
|
||||
int btrtl_setup_realtek(struct hci_dev *hdev);
|
||||
int btrtl_shutdown_realtek(struct hci_dev *hdev);
|
||||
int btrtl_get_uart_settings(struct hci_dev *hdev,
|
||||
struct btrtl_device_info *btrtl_dev,
|
||||
unsigned int *controller_baudrate,
|
||||
|
@ -83,6 +84,11 @@ static inline int btrtl_setup_realtek(struct hci_dev *hdev)
|
|||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
static inline int btrtl_shutdown_realtek(struct hci_dev *hdev)
|
||||
{
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
static inline int btrtl_get_uart_settings(struct hci_dev *hdev,
|
||||
struct btrtl_device_info *btrtl_dev,
|
||||
unsigned int *controller_baudrate,
|
||||
|
|
|
@ -286,6 +286,7 @@ static int btsdio_probe(struct sdio_func *func,
|
|||
switch (func->device) {
|
||||
case SDIO_DEVICE_ID_BROADCOM_43341:
|
||||
case SDIO_DEVICE_ID_BROADCOM_43430:
|
||||
case SDIO_DEVICE_ID_BROADCOM_4356:
|
||||
return -ENODEV;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
#include <linux/usb.h>
|
||||
#include <linux/usb/quirks.h>
|
||||
#include <linux/firmware.h>
|
||||
#include <linux/iopoll.h>
|
||||
#include <linux/of_device.h>
|
||||
#include <linux/of_irq.h>
|
||||
#include <linux/suspend.h>
|
||||
|
@ -55,6 +56,7 @@ static struct usb_driver btusb_driver;
|
|||
#define BTUSB_BCM2045 0x40000
|
||||
#define BTUSB_IFNUM_2 0x80000
|
||||
#define BTUSB_CW6622 0x100000
|
||||
#define BTUSB_MEDIATEK 0x200000
|
||||
|
||||
static const struct usb_device_id btusb_table[] = {
|
||||
/* Generic Bluetooth USB device */
|
||||
|
@ -264,7 +266,9 @@ static const struct usb_device_id blacklist_table[] = {
|
|||
{ USB_DEVICE(0x04ca, 0x3015), .driver_info = BTUSB_QCA_ROME },
|
||||
{ USB_DEVICE(0x04ca, 0x3016), .driver_info = BTUSB_QCA_ROME },
|
||||
{ USB_DEVICE(0x04ca, 0x301a), .driver_info = BTUSB_QCA_ROME },
|
||||
{ USB_DEVICE(0x13d3, 0x3491), .driver_info = BTUSB_QCA_ROME },
|
||||
{ USB_DEVICE(0x13d3, 0x3496), .driver_info = BTUSB_QCA_ROME },
|
||||
{ USB_DEVICE(0x13d3, 0x3501), .driver_info = BTUSB_QCA_ROME },
|
||||
|
||||
/* Broadcom BCM2035 */
|
||||
{ USB_DEVICE(0x0a5c, 0x2009), .driver_info = BTUSB_BCM92035 },
|
||||
|
@ -346,6 +350,10 @@ static const struct usb_device_id blacklist_table[] = {
|
|||
{ USB_VENDOR_AND_INTERFACE_INFO(0x0bda, 0xe0, 0x01, 0x01),
|
||||
.driver_info = BTUSB_REALTEK },
|
||||
|
||||
/* MediaTek Bluetooth devices */
|
||||
{ USB_VENDOR_AND_INTERFACE_INFO(0x0e8d, 0xe0, 0x01, 0x01),
|
||||
.driver_info = BTUSB_MEDIATEK },
|
||||
|
||||
/* Additional Realtek 8723AE Bluetooth devices */
|
||||
{ USB_DEVICE(0x0930, 0x021d), .driver_info = BTUSB_REALTEK },
|
||||
{ USB_DEVICE(0x13d3, 0x3394), .driver_info = BTUSB_REALTEK },
|
||||
|
@ -426,6 +434,7 @@ static const struct dmi_system_id btusb_needs_reset_resume_table[] = {
|
|||
#define BTUSB_DIAG_RUNNING 10
|
||||
#define BTUSB_OOB_WAKE_ENABLED 11
|
||||
#define BTUSB_HW_RESET_ACTIVE 12
|
||||
#define BTUSB_TX_WAIT_VND_EVT 13
|
||||
|
||||
struct btusb_data {
|
||||
struct hci_dev *hdev;
|
||||
|
@ -449,6 +458,7 @@ struct btusb_data {
|
|||
struct usb_anchor bulk_anchor;
|
||||
struct usb_anchor isoc_anchor;
|
||||
struct usb_anchor diag_anchor;
|
||||
struct usb_anchor ctrl_anchor;
|
||||
spinlock_t rxlock;
|
||||
|
||||
struct sk_buff *evt_skb;
|
||||
|
@ -1202,6 +1212,7 @@ static void btusb_stop_traffic(struct btusb_data *data)
|
|||
usb_kill_anchored_urbs(&data->bulk_anchor);
|
||||
usb_kill_anchored_urbs(&data->isoc_anchor);
|
||||
usb_kill_anchored_urbs(&data->diag_anchor);
|
||||
usb_kill_anchored_urbs(&data->ctrl_anchor);
|
||||
}
|
||||
|
||||
static int btusb_close(struct hci_dev *hdev)
|
||||
|
@ -2437,6 +2448,568 @@ static int btusb_shutdown_intel_new(struct hci_dev *hdev)
|
|||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_BT_HCIBTUSB_MTK
|
||||
|
||||
#define FIRMWARE_MT7663 "mediatek/mt7663pr2h.bin"
|
||||
#define FIRMWARE_MT7668 "mediatek/mt7668pr2h.bin"
|
||||
|
||||
#define HCI_WMT_MAX_EVENT_SIZE 64
|
||||
|
||||
enum {
|
||||
BTMTK_WMT_PATCH_DWNLD = 0x1,
|
||||
BTMTK_WMT_FUNC_CTRL = 0x6,
|
||||
BTMTK_WMT_RST = 0x7,
|
||||
BTMTK_WMT_SEMAPHORE = 0x17,
|
||||
};
|
||||
|
||||
enum {
|
||||
BTMTK_WMT_INVALID,
|
||||
BTMTK_WMT_PATCH_UNDONE,
|
||||
BTMTK_WMT_PATCH_DONE,
|
||||
BTMTK_WMT_ON_UNDONE,
|
||||
BTMTK_WMT_ON_DONE,
|
||||
BTMTK_WMT_ON_PROGRESS,
|
||||
};
|
||||
|
||||
struct btmtk_wmt_hdr {
|
||||
u8 dir;
|
||||
u8 op;
|
||||
__le16 dlen;
|
||||
u8 flag;
|
||||
} __packed;
|
||||
|
||||
struct btmtk_hci_wmt_cmd {
|
||||
struct btmtk_wmt_hdr hdr;
|
||||
u8 data[256];
|
||||
} __packed;
|
||||
|
||||
struct btmtk_hci_wmt_evt {
|
||||
struct hci_event_hdr hhdr;
|
||||
struct btmtk_wmt_hdr whdr;
|
||||
} __packed;
|
||||
|
||||
struct btmtk_hci_wmt_evt_funcc {
|
||||
struct btmtk_hci_wmt_evt hwhdr;
|
||||
__be16 status;
|
||||
} __packed;
|
||||
|
||||
struct btmtk_tci_sleep {
|
||||
u8 mode;
|
||||
__le16 duration;
|
||||
__le16 host_duration;
|
||||
u8 host_wakeup_pin;
|
||||
u8 time_compensation;
|
||||
} __packed;
|
||||
|
||||
struct btmtk_hci_wmt_params {
|
||||
u8 op;
|
||||
u8 flag;
|
||||
u16 dlen;
|
||||
const void *data;
|
||||
u32 *status;
|
||||
};
|
||||
|
||||
static void btusb_mtk_wmt_recv(struct urb *urb)
|
||||
{
|
||||
struct hci_dev *hdev = urb->context;
|
||||
struct btusb_data *data = hci_get_drvdata(hdev);
|
||||
struct hci_event_hdr *hdr;
|
||||
struct sk_buff *skb;
|
||||
int err;
|
||||
|
||||
if (urb->status == 0 && urb->actual_length > 0) {
|
||||
hdev->stat.byte_rx += urb->actual_length;
|
||||
|
||||
/* WMT event shouldn't be fragmented and the size should be
|
||||
* less than HCI_WMT_MAX_EVENT_SIZE.
|
||||
*/
|
||||
skb = bt_skb_alloc(HCI_WMT_MAX_EVENT_SIZE, GFP_ATOMIC);
|
||||
if (!skb) {
|
||||
hdev->stat.err_rx++;
|
||||
goto err_out;
|
||||
}
|
||||
|
||||
hci_skb_pkt_type(skb) = HCI_EVENT_PKT;
|
||||
skb_put_data(skb, urb->transfer_buffer, urb->actual_length);
|
||||
|
||||
hdr = (void *)skb->data;
|
||||
/* Fix up the vendor event id with 0xff for vendor specific
|
||||
* instead of 0xe4 so that event send via monitoring socket can
|
||||
* be parsed properly.
|
||||
*/
|
||||
hdr->evt = 0xff;
|
||||
|
||||
/* When someone waits for the WMT event, the skb is being cloned
|
||||
* and being processed the events from there then.
|
||||
*/
|
||||
if (test_bit(BTUSB_TX_WAIT_VND_EVT, &data->flags)) {
|
||||
data->evt_skb = skb_clone(skb, GFP_KERNEL);
|
||||
if (!data->evt_skb)
|
||||
goto err_out;
|
||||
}
|
||||
|
||||
err = hci_recv_frame(hdev, skb);
|
||||
if (err < 0)
|
||||
goto err_free_skb;
|
||||
|
||||
if (test_and_clear_bit(BTUSB_TX_WAIT_VND_EVT,
|
||||
&data->flags)) {
|
||||
/* Barrier to sync with other CPUs */
|
||||
smp_mb__after_atomic();
|
||||
wake_up_bit(&data->flags,
|
||||
BTUSB_TX_WAIT_VND_EVT);
|
||||
}
|
||||
err_out:
|
||||
return;
|
||||
err_free_skb:
|
||||
kfree_skb(data->evt_skb);
|
||||
data->evt_skb = NULL;
|
||||
return;
|
||||
} else if (urb->status == -ENOENT) {
|
||||
/* Avoid suspend failed when usb_kill_urb */
|
||||
return;
|
||||
}
|
||||
|
||||
usb_mark_last_busy(data->udev);
|
||||
|
||||
/* The URB complete handler is still called with urb->actual_length = 0
|
||||
* when the event is not available, so we should keep re-submitting
|
||||
* URB until WMT event returns, Also, It's necessary to wait some time
|
||||
* between the two consecutive control URBs to relax the target device
|
||||
* to generate the event. Otherwise, the WMT event cannot return from
|
||||
* the device successfully.
|
||||
*/
|
||||
udelay(100);
|
||||
|
||||
usb_anchor_urb(urb, &data->ctrl_anchor);
|
||||
err = usb_submit_urb(urb, GFP_ATOMIC);
|
||||
if (err < 0) {
|
||||
/* -EPERM: urb is being killed;
|
||||
* -ENODEV: device got disconnected
|
||||
*/
|
||||
if (err != -EPERM && err != -ENODEV)
|
||||
bt_dev_err(hdev, "urb %p failed to resubmit (%d)",
|
||||
urb, -err);
|
||||
usb_unanchor_urb(urb);
|
||||
}
|
||||
}
|
||||
|
||||
static int btusb_mtk_submit_wmt_recv_urb(struct hci_dev *hdev)
|
||||
{
|
||||
struct btusb_data *data = hci_get_drvdata(hdev);
|
||||
struct usb_ctrlrequest *dr;
|
||||
unsigned char *buf;
|
||||
int err, size = 64;
|
||||
unsigned int pipe;
|
||||
struct urb *urb;
|
||||
|
||||
urb = usb_alloc_urb(0, GFP_KERNEL);
|
||||
if (!urb)
|
||||
return -ENOMEM;
|
||||
|
||||
dr = kmalloc(sizeof(*dr), GFP_KERNEL);
|
||||
if (!dr) {
|
||||
usb_free_urb(urb);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
dr->bRequestType = USB_TYPE_VENDOR | USB_DIR_IN;
|
||||
dr->bRequest = 1;
|
||||
dr->wIndex = cpu_to_le16(0);
|
||||
dr->wValue = cpu_to_le16(48);
|
||||
dr->wLength = cpu_to_le16(size);
|
||||
|
||||
buf = kmalloc(size, GFP_KERNEL);
|
||||
if (!buf) {
|
||||
kfree(dr);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
pipe = usb_rcvctrlpipe(data->udev, 0);
|
||||
|
||||
usb_fill_control_urb(urb, data->udev, pipe, (void *)dr,
|
||||
buf, size, btusb_mtk_wmt_recv, hdev);
|
||||
|
||||
urb->transfer_flags |= URB_FREE_BUFFER;
|
||||
|
||||
usb_anchor_urb(urb, &data->ctrl_anchor);
|
||||
err = usb_submit_urb(urb, GFP_KERNEL);
|
||||
if (err < 0) {
|
||||
if (err != -EPERM && err != -ENODEV)
|
||||
bt_dev_err(hdev, "urb %p submission failed (%d)",
|
||||
urb, -err);
|
||||
usb_unanchor_urb(urb);
|
||||
}
|
||||
|
||||
usb_free_urb(urb);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static int btusb_mtk_hci_wmt_sync(struct hci_dev *hdev,
|
||||
struct btmtk_hci_wmt_params *wmt_params)
|
||||
{
|
||||
struct btusb_data *data = hci_get_drvdata(hdev);
|
||||
struct btmtk_hci_wmt_evt_funcc *wmt_evt_funcc;
|
||||
u32 hlen, status = BTMTK_WMT_INVALID;
|
||||
struct btmtk_hci_wmt_evt *wmt_evt;
|
||||
struct btmtk_hci_wmt_cmd wc;
|
||||
struct btmtk_wmt_hdr *hdr;
|
||||
int err;
|
||||
|
||||
/* Submit control IN URB on demand to process the WMT event */
|
||||
err = btusb_mtk_submit_wmt_recv_urb(hdev);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
/* Send the WMT command and wait until the WMT event returns */
|
||||
hlen = sizeof(*hdr) + wmt_params->dlen;
|
||||
if (hlen > 255)
|
||||
return -EINVAL;
|
||||
|
||||
hdr = (struct btmtk_wmt_hdr *)&wc;
|
||||
hdr->dir = 1;
|
||||
hdr->op = wmt_params->op;
|
||||
hdr->dlen = cpu_to_le16(wmt_params->dlen + 1);
|
||||
hdr->flag = wmt_params->flag;
|
||||
memcpy(wc.data, wmt_params->data, wmt_params->dlen);
|
||||
|
||||
set_bit(BTUSB_TX_WAIT_VND_EVT, &data->flags);
|
||||
|
||||
err = __hci_cmd_send(hdev, 0xfc6f, hlen, &wc);
|
||||
|
||||
if (err < 0) {
|
||||
clear_bit(BTUSB_TX_WAIT_VND_EVT, &data->flags);
|
||||
return err;
|
||||
}
|
||||
|
||||
/* The vendor specific WMT commands are all answered by a vendor
|
||||
* specific event and will have the Command Status or Command
|
||||
* Complete as with usual HCI command flow control.
|
||||
*
|
||||
* After sending the command, wait for BTUSB_TX_WAIT_VND_EVT
|
||||
* state to be cleared. The driver specific event receive routine
|
||||
* will clear that state and with that indicate completion of the
|
||||
* WMT command.
|
||||
*/
|
||||
err = wait_on_bit_timeout(&data->flags, BTUSB_TX_WAIT_VND_EVT,
|
||||
TASK_INTERRUPTIBLE, HCI_INIT_TIMEOUT);
|
||||
if (err == -EINTR) {
|
||||
bt_dev_err(hdev, "Execution of wmt command interrupted");
|
||||
clear_bit(BTUSB_TX_WAIT_VND_EVT, &data->flags);
|
||||
return err;
|
||||
}
|
||||
|
||||
if (err) {
|
||||
bt_dev_err(hdev, "Execution of wmt command timed out");
|
||||
clear_bit(BTUSB_TX_WAIT_VND_EVT, &data->flags);
|
||||
return -ETIMEDOUT;
|
||||
}
|
||||
|
||||
/* Parse and handle the return WMT event */
|
||||
wmt_evt = (struct btmtk_hci_wmt_evt *)data->evt_skb->data;
|
||||
if (wmt_evt->whdr.op != hdr->op) {
|
||||
bt_dev_err(hdev, "Wrong op received %d expected %d",
|
||||
wmt_evt->whdr.op, hdr->op);
|
||||
err = -EIO;
|
||||
goto err_free_skb;
|
||||
}
|
||||
|
||||
switch (wmt_evt->whdr.op) {
|
||||
case BTMTK_WMT_SEMAPHORE:
|
||||
if (wmt_evt->whdr.flag == 2)
|
||||
status = BTMTK_WMT_PATCH_UNDONE;
|
||||
else
|
||||
status = BTMTK_WMT_PATCH_DONE;
|
||||
break;
|
||||
case BTMTK_WMT_FUNC_CTRL:
|
||||
wmt_evt_funcc = (struct btmtk_hci_wmt_evt_funcc *)wmt_evt;
|
||||
if (be16_to_cpu(wmt_evt_funcc->status) == 0x404)
|
||||
status = BTMTK_WMT_ON_DONE;
|
||||
else if (be16_to_cpu(wmt_evt_funcc->status) == 0x420)
|
||||
status = BTMTK_WMT_ON_PROGRESS;
|
||||
else
|
||||
status = BTMTK_WMT_ON_UNDONE;
|
||||
break;
|
||||
}
|
||||
|
||||
if (wmt_params->status)
|
||||
*wmt_params->status = status;
|
||||
|
||||
err_free_skb:
|
||||
kfree_skb(data->evt_skb);
|
||||
data->evt_skb = NULL;
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static int btusb_mtk_setup_firmware(struct hci_dev *hdev, const char *fwname)
|
||||
{
|
||||
struct btmtk_hci_wmt_params wmt_params;
|
||||
const struct firmware *fw;
|
||||
const u8 *fw_ptr;
|
||||
size_t fw_size;
|
||||
int err, dlen;
|
||||
u8 flag;
|
||||
|
||||
err = request_firmware(&fw, fwname, &hdev->dev);
|
||||
if (err < 0) {
|
||||
bt_dev_err(hdev, "Failed to load firmware file (%d)", err);
|
||||
return err;
|
||||
}
|
||||
|
||||
fw_ptr = fw->data;
|
||||
fw_size = fw->size;
|
||||
|
||||
/* The size of patch header is 30 bytes, should be skip */
|
||||
if (fw_size < 30)
|
||||
goto err_release_fw;
|
||||
|
||||
fw_size -= 30;
|
||||
fw_ptr += 30;
|
||||
flag = 1;
|
||||
|
||||
wmt_params.op = BTMTK_WMT_PATCH_DWNLD;
|
||||
wmt_params.status = NULL;
|
||||
|
||||
while (fw_size > 0) {
|
||||
dlen = min_t(int, 250, fw_size);
|
||||
|
||||
/* Tell deivice the position in sequence */
|
||||
if (fw_size - dlen <= 0)
|
||||
flag = 3;
|
||||
else if (fw_size < fw->size - 30)
|
||||
flag = 2;
|
||||
|
||||
wmt_params.flag = flag;
|
||||
wmt_params.dlen = dlen;
|
||||
wmt_params.data = fw_ptr;
|
||||
|
||||
err = btusb_mtk_hci_wmt_sync(hdev, &wmt_params);
|
||||
if (err < 0) {
|
||||
bt_dev_err(hdev, "Failed to send wmt patch dwnld (%d)",
|
||||
err);
|
||||
goto err_release_fw;
|
||||
}
|
||||
|
||||
fw_size -= dlen;
|
||||
fw_ptr += dlen;
|
||||
}
|
||||
|
||||
wmt_params.op = BTMTK_WMT_RST;
|
||||
wmt_params.flag = 4;
|
||||
wmt_params.dlen = 0;
|
||||
wmt_params.data = NULL;
|
||||
wmt_params.status = NULL;
|
||||
|
||||
/* Activate funciton the firmware providing to */
|
||||
err = btusb_mtk_hci_wmt_sync(hdev, &wmt_params);
|
||||
if (err < 0) {
|
||||
bt_dev_err(hdev, "Failed to send wmt rst (%d)", err);
|
||||
return err;
|
||||
}
|
||||
|
||||
/* Wait a few moments for firmware activation done */
|
||||
usleep_range(10000, 12000);
|
||||
|
||||
err_release_fw:
|
||||
release_firmware(fw);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static int btusb_mtk_func_query(struct hci_dev *hdev)
|
||||
{
|
||||
struct btmtk_hci_wmt_params wmt_params;
|
||||
int status, err;
|
||||
u8 param = 0;
|
||||
|
||||
/* Query whether the function is enabled */
|
||||
wmt_params.op = BTMTK_WMT_FUNC_CTRL;
|
||||
wmt_params.flag = 4;
|
||||
wmt_params.dlen = sizeof(param);
|
||||
wmt_params.data = ¶m;
|
||||
wmt_params.status = &status;
|
||||
|
||||
err = btusb_mtk_hci_wmt_sync(hdev, &wmt_params);
|
||||
if (err < 0) {
|
||||
bt_dev_err(hdev, "Failed to query function status (%d)", err);
|
||||
return err;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
static int btusb_mtk_reg_read(struct btusb_data *data, u32 reg, u32 *val)
|
||||
{
|
||||
int pipe, err, size = sizeof(u32);
|
||||
void *buf;
|
||||
|
||||
buf = kzalloc(size, GFP_KERNEL);
|
||||
if (!buf)
|
||||
return -ENOMEM;
|
||||
|
||||
pipe = usb_rcvctrlpipe(data->udev, 0);
|
||||
err = usb_control_msg(data->udev, pipe, 0x63,
|
||||
USB_TYPE_VENDOR | USB_DIR_IN,
|
||||
reg >> 16, reg & 0xffff,
|
||||
buf, size, USB_CTRL_SET_TIMEOUT);
|
||||
if (err < 0)
|
||||
goto err_free_buf;
|
||||
|
||||
*val = get_unaligned_le32(buf);
|
||||
|
||||
err_free_buf:
|
||||
kfree(buf);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static int btusb_mtk_id_get(struct btusb_data *data, u32 *id)
|
||||
{
|
||||
return btusb_mtk_reg_read(data, 0x80000008, id);
|
||||
}
|
||||
|
||||
static int btusb_mtk_setup(struct hci_dev *hdev)
|
||||
{
|
||||
struct btusb_data *data = hci_get_drvdata(hdev);
|
||||
struct btmtk_hci_wmt_params wmt_params;
|
||||
ktime_t calltime, delta, rettime;
|
||||
struct btmtk_tci_sleep tci_sleep;
|
||||
unsigned long long duration;
|
||||
struct sk_buff *skb;
|
||||
const char *fwname;
|
||||
int err, status;
|
||||
u32 dev_id;
|
||||
u8 param;
|
||||
|
||||
calltime = ktime_get();
|
||||
|
||||
err = btusb_mtk_id_get(data, &dev_id);
|
||||
if (err < 0) {
|
||||
bt_dev_err(hdev, "Failed to get device id (%d)", err);
|
||||
return err;
|
||||
}
|
||||
|
||||
switch (dev_id) {
|
||||
case 0x7663:
|
||||
fwname = FIRMWARE_MT7663;
|
||||
break;
|
||||
case 0x7668:
|
||||
fwname = FIRMWARE_MT7668;
|
||||
break;
|
||||
default:
|
||||
bt_dev_err(hdev, "Unsupported support hardware variant (%08x)",
|
||||
dev_id);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
/* Query whether the firmware is already download */
|
||||
wmt_params.op = BTMTK_WMT_SEMAPHORE;
|
||||
wmt_params.flag = 1;
|
||||
wmt_params.dlen = 0;
|
||||
wmt_params.data = NULL;
|
||||
wmt_params.status = &status;
|
||||
|
||||
err = btusb_mtk_hci_wmt_sync(hdev, &wmt_params);
|
||||
if (err < 0) {
|
||||
bt_dev_err(hdev, "Failed to query firmware status (%d)", err);
|
||||
return err;
|
||||
}
|
||||
|
||||
if (status == BTMTK_WMT_PATCH_DONE) {
|
||||
bt_dev_info(hdev, "firmware already downloaded");
|
||||
goto ignore_setup_fw;
|
||||
}
|
||||
|
||||
/* Setup a firmware which the device definitely requires */
|
||||
err = btusb_mtk_setup_firmware(hdev, fwname);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
ignore_setup_fw:
|
||||
err = readx_poll_timeout(btusb_mtk_func_query, hdev, status,
|
||||
status < 0 || status != BTMTK_WMT_ON_PROGRESS,
|
||||
2000, 5000000);
|
||||
/* -ETIMEDOUT happens */
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
/* The other errors happen in btusb_mtk_func_query */
|
||||
if (status < 0)
|
||||
return status;
|
||||
|
||||
if (status == BTMTK_WMT_ON_DONE) {
|
||||
bt_dev_info(hdev, "function already on");
|
||||
goto ignore_func_on;
|
||||
}
|
||||
|
||||
/* Enable Bluetooth protocol */
|
||||
param = 1;
|
||||
wmt_params.op = BTMTK_WMT_FUNC_CTRL;
|
||||
wmt_params.flag = 0;
|
||||
wmt_params.dlen = sizeof(param);
|
||||
wmt_params.data = ¶m;
|
||||
wmt_params.status = NULL;
|
||||
|
||||
err = btusb_mtk_hci_wmt_sync(hdev, &wmt_params);
|
||||
if (err < 0) {
|
||||
bt_dev_err(hdev, "Failed to send wmt func ctrl (%d)", err);
|
||||
return err;
|
||||
}
|
||||
|
||||
ignore_func_on:
|
||||
/* Apply the low power environment setup */
|
||||
tci_sleep.mode = 0x5;
|
||||
tci_sleep.duration = cpu_to_le16(0x640);
|
||||
tci_sleep.host_duration = cpu_to_le16(0x640);
|
||||
tci_sleep.host_wakeup_pin = 0;
|
||||
tci_sleep.time_compensation = 0;
|
||||
|
||||
skb = __hci_cmd_sync(hdev, 0xfc7a, sizeof(tci_sleep), &tci_sleep,
|
||||
HCI_INIT_TIMEOUT);
|
||||
if (IS_ERR(skb)) {
|
||||
err = PTR_ERR(skb);
|
||||
bt_dev_err(hdev, "Failed to apply low power setting (%d)", err);
|
||||
return err;
|
||||
}
|
||||
kfree_skb(skb);
|
||||
|
||||
rettime = ktime_get();
|
||||
delta = ktime_sub(rettime, calltime);
|
||||
duration = (unsigned long long)ktime_to_ns(delta) >> 10;
|
||||
|
||||
bt_dev_info(hdev, "Device setup in %llu usecs", duration);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int btusb_mtk_shutdown(struct hci_dev *hdev)
|
||||
{
|
||||
struct btmtk_hci_wmt_params wmt_params;
|
||||
u8 param = 0;
|
||||
int err;
|
||||
|
||||
/* Disable the device */
|
||||
wmt_params.op = BTMTK_WMT_FUNC_CTRL;
|
||||
wmt_params.flag = 0;
|
||||
wmt_params.dlen = sizeof(param);
|
||||
wmt_params.data = ¶m;
|
||||
wmt_params.status = NULL;
|
||||
|
||||
err = btusb_mtk_hci_wmt_sync(hdev, &wmt_params);
|
||||
if (err < 0) {
|
||||
bt_dev_err(hdev, "Failed to send wmt func ctrl (%d)", err);
|
||||
return err;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
MODULE_FIRMWARE(FIRMWARE_MT7663);
|
||||
MODULE_FIRMWARE(FIRMWARE_MT7668);
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
/* Configure an out-of-band gpio as wake-up pin, if specified in device tree */
|
||||
static int marvell_config_oob_wake(struct hci_dev *hdev)
|
||||
|
@ -3044,6 +3617,7 @@ static int btusb_probe(struct usb_interface *intf,
|
|||
init_usb_anchor(&data->bulk_anchor);
|
||||
init_usb_anchor(&data->isoc_anchor);
|
||||
init_usb_anchor(&data->diag_anchor);
|
||||
init_usb_anchor(&data->ctrl_anchor);
|
||||
spin_lock_init(&data->rxlock);
|
||||
|
||||
if (id->driver_info & BTUSB_INTEL_NEW) {
|
||||
|
@ -3157,6 +3731,15 @@ static int btusb_probe(struct usb_interface *intf,
|
|||
if (id->driver_info & BTUSB_MARVELL)
|
||||
hdev->set_bdaddr = btusb_set_bdaddr_marvell;
|
||||
|
||||
#ifdef CONFIG_BT_HCIBTUSB_MTK
|
||||
if (id->driver_info & BTUSB_MEDIATEK) {
|
||||
hdev->setup = btusb_mtk_setup;
|
||||
hdev->shutdown = btusb_mtk_shutdown;
|
||||
hdev->manufacturer = 70;
|
||||
set_bit(HCI_QUIRK_NON_PERSISTENT_SETUP, &hdev->quirks);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (id->driver_info & BTUSB_SWAVE) {
|
||||
set_bit(HCI_QUIRK_FIXUP_INQUIRY_MODE, &hdev->quirks);
|
||||
set_bit(HCI_QUIRK_BROKEN_LOCAL_COMMANDS, &hdev->quirks);
|
||||
|
@ -3184,6 +3767,7 @@ static int btusb_probe(struct usb_interface *intf,
|
|||
#ifdef CONFIG_BT_HCIBTUSB_RTL
|
||||
if (id->driver_info & BTUSB_REALTEK) {
|
||||
hdev->setup = btrtl_setup_realtek;
|
||||
hdev->shutdown = btrtl_shutdown_realtek;
|
||||
|
||||
/* Realtek devices lose their updated firmware over suspend,
|
||||
* but the USB hub doesn't notice any status change.
|
||||
|
|
|
@ -744,6 +744,11 @@ static int bcsp_close(struct hci_uart *hu)
|
|||
skb_queue_purge(&bcsp->rel);
|
||||
skb_queue_purge(&bcsp->unrel);
|
||||
|
||||
if (bcsp->rx_skb) {
|
||||
kfree_skb(bcsp->rx_skb);
|
||||
bcsp->rx_skb = NULL;
|
||||
}
|
||||
|
||||
kfree(bcsp);
|
||||
return 0;
|
||||
}
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue