Networking changes for 5.19.
Core ---- - Support TCPv6 segmentation offload with super-segments larger than 64k bytes using the IPv6 Jumbogram extension header (AKA BIG TCP). - Generalize skb freeing deferral to per-cpu lists, instead of per-socket lists. - Add a netdev statistic for packets dropped due to L2 address mismatch (rx_otherhost_dropped). - Continue work annotating skb drop reasons. - Accept alternative netdev names (ALT_IFNAME) in more netlink requests. - Add VLAN support for AF_PACKET SOCK_RAW GSO. - Allow receiving skb mark from the socket as a cmsg. - Enable memcg accounting for veth queues, sysctl tables and IPv6. BPF --- - Add libbpf support for User Statically-Defined Tracing (USDTs). - Speed up symbol resolution for kprobes multi-link attachments. - Support storing typed pointers to referenced and unreferenced objects in BPF maps. - Add support for BPF link iterator. - Introduce access to remote CPU map elements in BPF per-cpu map. - Allow middle-of-the-road settings for the kernel.unprivileged_bpf_disabled sysctl. - Implement basic types of dynamic pointers e.g. to allow for dynamically sized ringbuf reservations without extra memory copies. Protocols --------- - Retire port only listening_hash table, add a second bind table hashed by port and address. Avoid linear list walk when binding to very popular ports (e.g. 443). - Add bridge FDB bulk flush filtering support allowing user space to remove all FDB entries matching a condition. - Introduce accept_unsolicited_na sysctl for IPv6 to implement router-side changes for RFC9131. - Support for MPTCP path manager in user space. - Add MPTCP support for fallback to regular TCP for connections that have never connected additional subflows or transmitted out-of-sequence data (partial support for RFC8684 fallback). - Avoid races in MPTCP-level window tracking, stabilize and improve throughput. - Support lockless operation of GRE tunnels with seq numbers enabled. - WiFi support for host based BSS color collision detection. - Add support for SO_TXTIME/SCM_TXTIME on CAN sockets. - Support transmission w/o flow control in CAN ISOTP (ISO 15765-2). - Support zero-copy Tx with TLS 1.2 crypto offload (sendfile). - Allow matching on the number of VLAN tags via tc-flower. - Add tracepoint for tcp_set_ca_state(). Driver API ---------- - Improve error reporting from classifier and action offload. - Add support for listing line cards in switches (devlink). - Add helpers for reporting page pool statistics with ethtool -S. - Add support for reading clock cycles when using PTP virtual clocks, instead of having the driver convert to time before reporting. This makes it possible to report time from different vclocks. - Support configuring low-latency Tx descriptor push via ethtool. - Separate Clause 22 and Clause 45 MDIO accesses more explicitly. New hardware / drivers ---------------------- - Ethernet: - Marvell's Octeon NIC PCI Endpoint support (octeon_ep) - Sunplus SP7021 SoC (sp7021_emac) - Add support for Renesas RZ/V2M (in ravb) - Add support for MediaTek mt7986 switches (in mtk_eth_soc) - Ethernet PHYs: - ADIN1100 industrial PHYs (w/ 10BASE-T1L and SQI reporting) - TI DP83TD510 PHY - Microchip LAN8742/LAN88xx PHYs - WiFi: - Driver for pureLiFi X, XL, XC devices (plfxlc) - Driver for Silicon Labs devices (wfx) - Support for WCN6750 (in ath11k) - Support Realtek 8852ce devices (in rtw89) - Mobile: - MediaTek T700 modems (Intel 5G 5000 M.2 cards) - CAN: - ctucanfd: add support for CTU CAN FD open-source IP core from Czech Technical University in Prague Drivers ------- - Delete a number of old drivers still using virt_to_bus(). - Ethernet NICs: - intel: support TSO on tunnels MPLS - broadcom: support multi-buffer XDP - nfp: support VF rate limiting - sfc: use hardware tx timestamps for more than PTP - mlx5: multi-port eswitch support - hyper-v: add support for XDP_REDIRECT - atlantic: XDP support (including multi-buffer) - macb: improve real-time perf by deferring Tx processing to NAPI - High-speed Ethernet switches: - mlxsw: implement basic line card information querying - prestera: add support for traffic policing on ingress and egress - Embedded Ethernet switches: - lan966x: add support for packet DMA (FDMA) - lan966x: add support for PTP programmable pins - ti: cpsw_new: enable bc/mc storm prevention - Qualcomm 802.11ax WiFi (ath11k): - Wake-on-WLAN support for QCA6390 and WCN6855 - device recovery (firmware restart) support - support setting Specific Absorption Rate (SAR) for WCN6855 - read country code from SMBIOS for WCN6855/QCA6390 - enable keep-alive during WoWLAN suspend - implement remain-on-channel support - MediaTek WiFi (mt76): - support Wireless Ethernet Dispatch offloading packet movement between the Ethernet switch and WiFi interfaces - non-standard VHT MCS10-11 support - mt7921 AP mode support - mt7921 IPv6 NS offload support - Ethernet PHYs: - micrel: ksz9031/ksz9131: cabletest support - lan87xx: SQI support for T1 PHYs - lan937x: add interrupt support for link detection Signed-off-by: Jakub Kicinski <kuba@kernel.org> -----BEGIN PGP SIGNATURE----- iQIzBAABCAAdFiEE6jPA+I1ugmIBA4hXMUZtbf5SIrsFAmKNMPQACgkQMUZtbf5S IrsRARAAuDyYs6jFYB3p+xazZdOnbF4iAgVv71+DQGvmsCl6CB9OrsNZMlvE85OL Q3gjcRbgjrkN4lhgI8DmiGYbsUJnAvVjFdNjccz1Z/vTLYvuIM0ol54MUp5S+9WY StncOJkOGJxxR/Gi5gzVmejPDsysU3Jik+hm/fpIcz8pybXxAsFKU5waY5qfl+/T TZepfV0VCfqRDjqcF1qA5+jJZNU8pdodQlZ1+mh8bwu6Jk1ZkWkj6Ov8MWdwQldr LnPeK/9hIGzkdJYHZfajxA3t8D0K5CHzSuih2bJ9ry8ZXgVBkXEThew778/R5izW uB0YZs9COFlrIP7XHjtRTy/2xHOdYIPlj2nWhVdfuQDX8Crvt4VRN6EZ1rjko1ZJ WanfG6WHF8NH5pXBRQbh3kIMKBnYn6OIzuCfCQSqd+niHcxFIM4vRiggeXI5C5TW vJgEWfK6X+NfDiFVa3xyCrEmp5ieA/pNecpwd8rVkql+MtFAAw4vfsotLKOJEAru J/XL6UE+YuLqIJV9ACZ9x1AFXXAo661jOxBunOo4VXhXVzWS9lYYz5r5ryIkgT/8 /Fr0zjANJWgfIuNdIBtYfQ4qG+LozGq038VA06RhFUAZ5tF9DzhqJs2Q2AFuWWBC ewCePJVqo1j2Ceq2mGonXRt47OEnlePoOxTk9W+cKZb7ZWE+zEo= =Wjii -----END PGP SIGNATURE----- Merge tag 'net-next-5.19' of git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net-next Pull networking updates from Jakub Kicinski: "Core ---- - Support TCPv6 segmentation offload with super-segments larger than 64k bytes using the IPv6 Jumbogram extension header (AKA BIG TCP). - Generalize skb freeing deferral to per-cpu lists, instead of per-socket lists. - Add a netdev statistic for packets dropped due to L2 address mismatch (rx_otherhost_dropped). - Continue work annotating skb drop reasons. - Accept alternative netdev names (ALT_IFNAME) in more netlink requests. - Add VLAN support for AF_PACKET SOCK_RAW GSO. - Allow receiving skb mark from the socket as a cmsg. - Enable memcg accounting for veth queues, sysctl tables and IPv6. BPF --- - Add libbpf support for User Statically-Defined Tracing (USDTs). - Speed up symbol resolution for kprobes multi-link attachments. - Support storing typed pointers to referenced and unreferenced objects in BPF maps. - Add support for BPF link iterator. - Introduce access to remote CPU map elements in BPF per-cpu map. - Allow middle-of-the-road settings for the kernel.unprivileged_bpf_disabled sysctl. - Implement basic types of dynamic pointers e.g. to allow for dynamically sized ringbuf reservations without extra memory copies. Protocols --------- - Retire port only listening_hash table, add a second bind table hashed by port and address. Avoid linear list walk when binding to very popular ports (e.g. 443). - Add bridge FDB bulk flush filtering support allowing user space to remove all FDB entries matching a condition. - Introduce accept_unsolicited_na sysctl for IPv6 to implement router-side changes for RFC9131. - Support for MPTCP path manager in user space. - Add MPTCP support for fallback to regular TCP for connections that have never connected additional subflows or transmitted out-of-sequence data (partial support for RFC8684 fallback). - Avoid races in MPTCP-level window tracking, stabilize and improve throughput. - Support lockless operation of GRE tunnels with seq numbers enabled. - WiFi support for host based BSS color collision detection. - Add support for SO_TXTIME/SCM_TXTIME on CAN sockets. - Support transmission w/o flow control in CAN ISOTP (ISO 15765-2). - Support zero-copy Tx with TLS 1.2 crypto offload (sendfile). - Allow matching on the number of VLAN tags via tc-flower. - Add tracepoint for tcp_set_ca_state(). Driver API ---------- - Improve error reporting from classifier and action offload. - Add support for listing line cards in switches (devlink). - Add helpers for reporting page pool statistics with ethtool -S. - Add support for reading clock cycles when using PTP virtual clocks, instead of having the driver convert to time before reporting. This makes it possible to report time from different vclocks. - Support configuring low-latency Tx descriptor push via ethtool. - Separate Clause 22 and Clause 45 MDIO accesses more explicitly. New hardware / drivers ---------------------- - Ethernet: - Marvell's Octeon NIC PCI Endpoint support (octeon_ep) - Sunplus SP7021 SoC (sp7021_emac) - Add support for Renesas RZ/V2M (in ravb) - Add support for MediaTek mt7986 switches (in mtk_eth_soc) - Ethernet PHYs: - ADIN1100 industrial PHYs (w/ 10BASE-T1L and SQI reporting) - TI DP83TD510 PHY - Microchip LAN8742/LAN88xx PHYs - WiFi: - Driver for pureLiFi X, XL, XC devices (plfxlc) - Driver for Silicon Labs devices (wfx) - Support for WCN6750 (in ath11k) - Support Realtek 8852ce devices (in rtw89) - Mobile: - MediaTek T700 modems (Intel 5G 5000 M.2 cards) - CAN: - ctucanfd: add support for CTU CAN FD open-source IP core from Czech Technical University in Prague Drivers ------- - Delete a number of old drivers still using virt_to_bus(). - Ethernet NICs: - intel: support TSO on tunnels MPLS - broadcom: support multi-buffer XDP - nfp: support VF rate limiting - sfc: use hardware tx timestamps for more than PTP - mlx5: multi-port eswitch support - hyper-v: add support for XDP_REDIRECT - atlantic: XDP support (including multi-buffer) - macb: improve real-time perf by deferring Tx processing to NAPI - High-speed Ethernet switches: - mlxsw: implement basic line card information querying - prestera: add support for traffic policing on ingress and egress - Embedded Ethernet switches: - lan966x: add support for packet DMA (FDMA) - lan966x: add support for PTP programmable pins - ti: cpsw_new: enable bc/mc storm prevention - Qualcomm 802.11ax WiFi (ath11k): - Wake-on-WLAN support for QCA6390 and WCN6855 - device recovery (firmware restart) support - support setting Specific Absorption Rate (SAR) for WCN6855 - read country code from SMBIOS for WCN6855/QCA6390 - enable keep-alive during WoWLAN suspend - implement remain-on-channel support - MediaTek WiFi (mt76): - support Wireless Ethernet Dispatch offloading packet movement between the Ethernet switch and WiFi interfaces - non-standard VHT MCS10-11 support - mt7921 AP mode support - mt7921 IPv6 NS offload support - Ethernet PHYs: - micrel: ksz9031/ksz9131: cabletest support - lan87xx: SQI support for T1 PHYs - lan937x: add interrupt support for link detection" * tag 'net-next-5.19' of git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net-next: (1809 commits) ptp: ocp: Add firmware header checks ptp: ocp: fix PPS source selector debugfs reporting ptp: ocp: add .init function for sma_op vector ptp: ocp: vectorize the sma accessor functions ptp: ocp: constify selectors ptp: ocp: parameterize input/output sma selectors ptp: ocp: revise firmware display ptp: ocp: add Celestica timecard PCI ids ptp: ocp: Remove #ifdefs around PCI IDs ptp: ocp: 32-bit fixups for pci start address Revert "net/smc: fix listen processing for SMC-Rv2" ath6kl: Use cc-disable-warning to disable -Wdangling-pointer selftests/bpf: Dynptr tests bpf: Add dynptr data slices bpf: Add bpf_dynptr_read and bpf_dynptr_write bpf: Dynptr support for ring buffers bpf: Add bpf_dynptr_from_mem for local dynptrs bpf: Add verifier support for dynptrs bpf: Suppress 'passing zero to PTR_ERR' warning bpf: Introduce bpf_arch_text_invalidate for bpf_prog_pack ...
This commit is contained in:
commit
7e062cda7d
|
@ -1933,7 +1933,7 @@
|
|||
...
|
||||
255= /dev/umem/d15p15 15th partition of 16th board.
|
||||
|
||||
117 char COSA/SRP synchronous serial card
|
||||
117 char [REMOVED] COSA/SRP synchronous serial card
|
||||
0 = /dev/cosa0c0 1st board, 1st channel
|
||||
1 = /dev/cosa0c1 1st board, 2nd channel
|
||||
...
|
||||
|
|
|
@ -322,6 +322,14 @@ a leaked reference faster. A larger value may be useful to prevent false
|
|||
warnings on slow/loaded systems.
|
||||
Default value is 10, minimum 1, maximum 3600.
|
||||
|
||||
skb_defer_max
|
||||
-------------
|
||||
|
||||
Max size (in skbs) of the per-cpu list of skbs being freed
|
||||
by the cpu which allocated them. Used by TCP stack so far.
|
||||
|
||||
Default: 64
|
||||
|
||||
optmem_max
|
||||
----------
|
||||
|
||||
|
@ -374,6 +382,15 @@ option is set to SOCK_TXREHASH_DEFAULT (i. e. not overridden by setsockopt).
|
|||
If set to 1 (default), hash rethink is performed on listening socket.
|
||||
If set to 0, hash rethink is not performed.
|
||||
|
||||
gro_normal_batch
|
||||
----------------
|
||||
|
||||
Maximum number of the segments to batch up on output of GRO. When a packet
|
||||
exits GRO, either as a coalesced superframe or as an original packet which
|
||||
GRO has decided not to coalesce, it is placed on a per-NAPI list. This
|
||||
list is then passed to the stack when the number of segments reaches the
|
||||
gro_normal_batch limit.
|
||||
|
||||
2. /proc/sys/net/unix - Parameters for Unix domain sockets
|
||||
----------------------------------------------------------
|
||||
|
||||
|
|
|
@ -130,7 +130,7 @@ Byte swap instructions
|
|||
The byte swap instructions use an instruction class of ``BFP_ALU`` and a 4-bit
|
||||
code field of ``BPF_END``.
|
||||
|
||||
The byte swap instructions instructions operate on the destination register
|
||||
The byte swap instructions operate on the destination register
|
||||
only and do not use a separate source register or immediate value.
|
||||
|
||||
The 1-bit source operand field in the opcode is used to to select what byte
|
||||
|
@ -157,7 +157,7 @@ Examples:
|
|||
dst_reg = htobe64(dst_reg)
|
||||
|
||||
``BPF_FROM_LE`` and ``BPF_FROM_BE`` exist as aliases for ``BPF_TO_LE`` and
|
||||
``BPF_TO_LE`` respetively.
|
||||
``BPF_TO_BE`` respectively.
|
||||
|
||||
|
||||
Jump instructions
|
||||
|
|
|
@ -6,14 +6,13 @@ libbpf
|
|||
.. toctree::
|
||||
:maxdepth: 1
|
||||
|
||||
API Documentation <https://libbpf.readthedocs.io/en/latest/api.html>
|
||||
libbpf_naming_convention
|
||||
libbpf_build
|
||||
|
||||
This is documentation for libbpf, a userspace library for loading and
|
||||
interacting with bpf programs.
|
||||
|
||||
For API documentation see the `versioned API documentation site <https://libbpf.readthedocs.io/en/latest/api.html>`_.
|
||||
|
||||
All general BPF questions, including kernel functionality, libbpf APIs and
|
||||
their application, should be sent to bpf@vger.kernel.org mailing list.
|
||||
You can `subscribe <http://vger.kernel.org/vger-lists.html#bpf>`_ to the
|
||||
|
|
|
@ -0,0 +1,42 @@
|
|||
# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: "http://devicetree.org/schemas/arm/mediatek/mediatek,mt7622-pcie-mirror.yaml#"
|
||||
$schema: "http://devicetree.org/meta-schemas/core.yaml#"
|
||||
|
||||
title: MediaTek PCIE Mirror Controller for MT7622
|
||||
|
||||
maintainers:
|
||||
- Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
- Felix Fietkau <nbd@nbd.name>
|
||||
|
||||
description:
|
||||
The mediatek PCIE mirror provides a configuration interface for PCIE
|
||||
controller on MT7622 soc.
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
items:
|
||||
- enum:
|
||||
- mediatek,mt7622-pcie-mirror
|
||||
- const: syscon
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
soc {
|
||||
#address-cells = <2>;
|
||||
#size-cells = <2>;
|
||||
pcie_mirror: pcie-mirror@10000400 {
|
||||
compatible = "mediatek,mt7622-pcie-mirror", "syscon";
|
||||
reg = <0 0x10000400 0 0x10>;
|
||||
};
|
||||
};
|
|
@ -0,0 +1,50 @@
|
|||
# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: "http://devicetree.org/schemas/arm/mediatek/mediatek,mt7622-wed.yaml#"
|
||||
$schema: "http://devicetree.org/meta-schemas/core.yaml#"
|
||||
|
||||
title: MediaTek Wireless Ethernet Dispatch Controller for MT7622
|
||||
|
||||
maintainers:
|
||||
- Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
- Felix Fietkau <nbd@nbd.name>
|
||||
|
||||
description:
|
||||
The mediatek wireless ethernet dispatch controller can be configured to
|
||||
intercept and handle access to the WLAN DMA queues and PCIe interrupts
|
||||
and implement hardware flow offloading from ethernet to WLAN.
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
items:
|
||||
- enum:
|
||||
- mediatek,mt7622-wed
|
||||
- const: syscon
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
interrupts:
|
||||
maxItems: 1
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- interrupts
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/interrupt-controller/arm-gic.h>
|
||||
#include <dt-bindings/interrupt-controller/irq.h>
|
||||
soc {
|
||||
#address-cells = <2>;
|
||||
#size-cells = <2>;
|
||||
wed0: wed@1020a000 {
|
||||
compatible = "mediatek,mt7622-wed","syscon";
|
||||
reg = <0 0x1020a000 0 0x1000>;
|
||||
interrupts = <GIC_SPI 214 IRQ_TYPE_LEVEL_LOW>;
|
||||
};
|
||||
};
|
|
@ -36,6 +36,21 @@ properties:
|
|||
enum: [ 4, 8, 12, 16, 20, 24 ]
|
||||
default: 8
|
||||
|
||||
adi,phy-output-clock:
|
||||
description: Select clock output on GP_CLK pin. Two clocks are available:
|
||||
A 25MHz reference and a free-running 125MHz.
|
||||
The phy can alternatively automatically switch between the reference and
|
||||
the 125MHz clocks based on its internal state.
|
||||
$ref: /schemas/types.yaml#/definitions/string
|
||||
enum:
|
||||
- 25mhz-reference
|
||||
- 125mhz-free-running
|
||||
- adaptive-free-running
|
||||
|
||||
adi,phy-output-reference-clock:
|
||||
description: Enable 25MHz reference clock output on CLK25_REF pin.
|
||||
type: boolean
|
||||
|
||||
unevaluatedProperties: false
|
||||
|
||||
examples:
|
||||
|
|
|
@ -20,10 +20,14 @@ allOf:
|
|||
properties:
|
||||
compatible:
|
||||
const: aspeed,ast2600-mdio
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
description: The register range of the MDIO controller instance
|
||||
|
||||
resets:
|
||||
maxItems: 1
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
|
@ -34,11 +38,13 @@ unevaluatedProperties: false
|
|||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/clock/ast2600-clock.h>
|
||||
mdio0: mdio@1e650000 {
|
||||
compatible = "aspeed,ast2600-mdio";
|
||||
reg = <0x1e650000 0x8>;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
resets = <&syscon ASPEED_RESET_MII>;
|
||||
|
||||
ethphy0: ethernet-phy@0 {
|
||||
compatible = "ethernet-phy-ieee802.3-c22";
|
||||
|
|
|
@ -0,0 +1,66 @@
|
|||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/net/can/ctu,ctucanfd.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: CTU CAN FD Open-source IP Core Device Tree Bindings
|
||||
|
||||
description: |
|
||||
Open-source CAN FD IP core developed at the Czech Technical University in Prague
|
||||
|
||||
The core sources and documentation on project page
|
||||
[1] sources : https://gitlab.fel.cvut.cz/canbus/ctucanfd_ip_core
|
||||
[2] datasheet : https://canbus.pages.fel.cvut.cz/ctucanfd_ip_core/doc/Datasheet.pdf
|
||||
|
||||
Integration in Xilinx Zynq SoC based system together with
|
||||
OpenCores SJA1000 compatible controllers
|
||||
[3] project : https://gitlab.fel.cvut.cz/canbus/zynq/zynq-can-sja1000-top
|
||||
Martin Jerabek dimploma thesis with integration and testing
|
||||
framework description
|
||||
[4] PDF : https://dspace.cvut.cz/bitstream/handle/10467/80366/F3-DP-2019-Jerabek-Martin-Jerabek-thesis-2019-canfd.pdf
|
||||
|
||||
maintainers:
|
||||
- Pavel Pisa <pisa@cmp.felk.cvut.cz>
|
||||
- Ondrej Ille <ondrej.ille@gmail.com>
|
||||
- Martin Jerabek <martin.jerabek01@gmail.com>
|
||||
|
||||
allOf:
|
||||
- $ref: can-controller.yaml#
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
oneOf:
|
||||
- items:
|
||||
- const: ctu,ctucanfd-2
|
||||
- const: ctu,ctucanfd
|
||||
- const: ctu,ctucanfd
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
interrupts:
|
||||
maxItems: 1
|
||||
|
||||
clocks:
|
||||
description: |
|
||||
phandle of reference clock (100 MHz is appropriate
|
||||
for FPGA implementation on Zynq-7000 system).
|
||||
maxItems: 1
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- interrupts
|
||||
- clocks
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
ctu_can_fd_0: can@43c30000 {
|
||||
compatible = "ctu,ctucanfd";
|
||||
interrupts = <0 30 4>;
|
||||
clocks = <&clkc 15>;
|
||||
reg = <0x43c30000 0x10000>;
|
||||
};
|
|
@ -5,8 +5,8 @@ $id: http://devicetree.org/schemas/net/can/microchip,mcp251xfd.yaml#
|
|||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title:
|
||||
Microchip MCP2517FD and MCP2518FD stand-alone CAN controller device tree
|
||||
bindings
|
||||
Microchip MCP2517FD, MCP2518FD and MCP251863 stand-alone CAN
|
||||
controller device tree bindings
|
||||
|
||||
maintainers:
|
||||
- Marc Kleine-Budde <mkl@pengutronix.de>
|
||||
|
@ -17,13 +17,14 @@ allOf:
|
|||
properties:
|
||||
compatible:
|
||||
oneOf:
|
||||
- const: microchip,mcp2517fd
|
||||
description: for MCP2517FD
|
||||
- const: microchip,mcp2518fd
|
||||
description: for MCP2518FD
|
||||
- const: microchip,mcp251xfd
|
||||
description: to autodetect chip variant
|
||||
|
||||
- enum:
|
||||
- microchip,mcp2517fd
|
||||
- microchip,mcp2518fd
|
||||
- microchip,mcp251xfd
|
||||
- items:
|
||||
- enum:
|
||||
- microchip,mcp251863
|
||||
- const: microchip,mcp2518fd
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
|
|
|
@ -23,6 +23,7 @@ properties:
|
|||
- renesas,r8a774e1-canfd # RZ/G2H
|
||||
- renesas,r8a7795-canfd # R-Car H3
|
||||
- renesas,r8a7796-canfd # R-Car M3-W
|
||||
- renesas,r8a77961-canfd # R-Car M3-W+
|
||||
- renesas,r8a77965-canfd # R-Car M3-N
|
||||
- renesas,r8a77970-canfd # R-Car V3M
|
||||
- renesas,r8a77980-canfd # R-Car V3H
|
||||
|
@ -32,6 +33,7 @@ properties:
|
|||
|
||||
- items:
|
||||
- enum:
|
||||
- renesas,r9a07g043-canfd # RZ/G2UL
|
||||
- renesas,r9a07g044-canfd # RZ/G2{L,LC}
|
||||
- renesas,r9a07g054-canfd # RZ/V2L
|
||||
- const: renesas,rzg2l-canfd # RZ/G2L family
|
||||
|
@ -86,6 +88,7 @@ required:
|
|||
- compatible
|
||||
- reg
|
||||
- interrupts
|
||||
- interrupt-names
|
||||
- clocks
|
||||
- clock-names
|
||||
- power-domains
|
||||
|
@ -134,7 +137,6 @@ then:
|
|||
- const: rstc_n
|
||||
|
||||
required:
|
||||
- interrupt-names
|
||||
- reset-names
|
||||
else:
|
||||
properties:
|
||||
|
@ -165,6 +167,7 @@ examples:
|
|||
reg = <0xe66c0000 0x8000>;
|
||||
interrupts = <GIC_SPI 29 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 30 IRQ_TYPE_LEVEL_HIGH>;
|
||||
interrupt-names = "ch_int", "g_int";
|
||||
clocks = <&cpg CPG_MOD 914>,
|
||||
<&cpg CPG_CORE R8A7795_CLK_CANFD>,
|
||||
<&can_clk>;
|
||||
|
|
|
@ -84,13 +84,6 @@ properties:
|
|||
phys:
|
||||
maxItems: 1
|
||||
|
||||
phy-names:
|
||||
const: sgmii-phy
|
||||
description:
|
||||
Required with ZynqMP SoC when in SGMII mode.
|
||||
Should reference PS-GTR generic PHY device for this controller
|
||||
instance. See ZynqMP example.
|
||||
|
||||
resets:
|
||||
maxItems: 1
|
||||
description:
|
||||
|
@ -204,7 +197,6 @@ examples:
|
|||
reset-names = "gem1_rst";
|
||||
status = "okay";
|
||||
phy-mode = "sgmii";
|
||||
phy-names = "sgmii-phy";
|
||||
phys = <&psgtr 1 PHY_TYPE_SGMII 1 1>;
|
||||
fixed-link {
|
||||
speed = <1000>;
|
||||
|
|
|
@ -77,6 +77,15 @@ properties:
|
|||
description:
|
||||
Maximum PHY supported speed in Mbits / seconds.
|
||||
|
||||
phy-10base-t1l-2.4vpp:
|
||||
description: |
|
||||
tristate, request/disable 2.4 Vpp operating mode. The values are:
|
||||
0: Disable 2.4 Vpp operating mode.
|
||||
1: Request 2.4 Vpp operating mode from link partner.
|
||||
Absence of this property will leave configuration to default values.
|
||||
$ref: "/schemas/types.yaml#/definitions/uint32"
|
||||
enum: [0, 1]
|
||||
|
||||
broken-turn-around:
|
||||
$ref: /schemas/types.yaml#/definitions/flag
|
||||
description:
|
||||
|
|
|
@ -0,0 +1,60 @@
|
|||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/net/marvell,orion-mdio.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Marvell MDIO Ethernet Controller interface
|
||||
|
||||
maintainers:
|
||||
- Andrew Lunn <andrew@lunn.ch>
|
||||
|
||||
description: |
|
||||
The Ethernet controllers of the Marvel Kirkwood, Dove, Orion5x, MV78xx0,
|
||||
Armada 370, Armada XP, Armada 7k and Armada 8k have an identical unit that
|
||||
provides an interface with the MDIO bus. Additionally, Armada 7k and Armada
|
||||
8k has a second unit which provides an interface with the xMDIO bus. This
|
||||
driver handles these interfaces.
|
||||
|
||||
allOf:
|
||||
- $ref: "mdio.yaml#"
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
enum:
|
||||
- marvell,orion-mdio
|
||||
- marvell,xmdio
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
interrupts:
|
||||
maxItems: 1
|
||||
|
||||
clocks:
|
||||
minItems: 1
|
||||
maxItems: 4
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
|
||||
unevaluatedProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
mdio@d0072004 {
|
||||
compatible = "marvell,orion-mdio";
|
||||
reg = <0xd0072004 0x4>;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
interrupts = <30>;
|
||||
|
||||
phy0: ethernet-phy@0 {
|
||||
reg = <0>;
|
||||
};
|
||||
|
||||
phy1: ethernet-phy@1 {
|
||||
reg = <1>;
|
||||
};
|
||||
};
|
|
@ -1,54 +0,0 @@
|
|||
* Marvell MDIO Ethernet Controller interface
|
||||
|
||||
The Ethernet controllers of the Marvel Kirkwood, Dove, Orion5x,
|
||||
MV78xx0, Armada 370, Armada XP, Armada 7k and Armada 8k have an
|
||||
identical unit that provides an interface with the MDIO bus.
|
||||
Additionally, Armada 7k and Armada 8k has a second unit which
|
||||
provides an interface with the xMDIO bus. This driver handles
|
||||
these interfaces.
|
||||
|
||||
Required properties:
|
||||
- compatible: "marvell,orion-mdio" or "marvell,xmdio"
|
||||
- reg: address and length of the MDIO registers. When an interrupt is
|
||||
not present, the length is the size of the SMI register (4 bytes)
|
||||
otherwise it must be 0x84 bytes to cover the interrupt control
|
||||
registers.
|
||||
|
||||
Optional properties:
|
||||
- interrupts: interrupt line number for the SMI error/done interrupt
|
||||
- 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
|
||||
PHY address on the MDIO bus.
|
||||
|
||||
Example at the SoC level without an interrupt property:
|
||||
|
||||
mdio {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
compatible = "marvell,orion-mdio";
|
||||
reg = <0xd0072004 0x4>;
|
||||
};
|
||||
|
||||
Example with an interrupt property:
|
||||
|
||||
mdio {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
compatible = "marvell,orion-mdio";
|
||||
reg = <0xd0072004 0x84>;
|
||||
interrupts = <30>;
|
||||
};
|
||||
|
||||
And at the board level:
|
||||
|
||||
mdio {
|
||||
phy0: ethernet-phy@0 {
|
||||
reg = <0>;
|
||||
};
|
||||
|
||||
phy1: ethernet-phy@1 {
|
||||
reg = <1>;
|
||||
};
|
||||
}
|
|
@ -0,0 +1,434 @@
|
|||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/net/mediatek,net.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: MediaTek Frame Engine Ethernet controller
|
||||
|
||||
maintainers:
|
||||
- Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
- Felix Fietkau <nbd@nbd.name>
|
||||
|
||||
description:
|
||||
The frame engine ethernet controller can be found on MediaTek SoCs. These SoCs
|
||||
have dual GMAC ports.
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
enum:
|
||||
- mediatek,mt2701-eth
|
||||
- mediatek,mt7623-eth
|
||||
- mediatek,mt7622-eth
|
||||
- mediatek,mt7629-eth
|
||||
- mediatek,mt7986-eth
|
||||
- ralink,rt5350-eth
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
interrupts:
|
||||
minItems: 3
|
||||
maxItems: 4
|
||||
|
||||
power-domains:
|
||||
maxItems: 1
|
||||
|
||||
resets:
|
||||
maxItems: 3
|
||||
|
||||
reset-names:
|
||||
items:
|
||||
- const: fe
|
||||
- const: gmac
|
||||
- const: ppe
|
||||
|
||||
mediatek,ethsys:
|
||||
$ref: /schemas/types.yaml#/definitions/phandle
|
||||
description:
|
||||
Phandle to the syscon node that handles the port setup.
|
||||
|
||||
cci-control-port: true
|
||||
|
||||
mediatek,hifsys:
|
||||
$ref: /schemas/types.yaml#/definitions/phandle
|
||||
description:
|
||||
Phandle to the mediatek hifsys controller used to provide various clocks
|
||||
and reset to the system.
|
||||
|
||||
mediatek,sgmiisys:
|
||||
$ref: /schemas/types.yaml#/definitions/phandle-array
|
||||
minItems: 1
|
||||
maxItems: 2
|
||||
items:
|
||||
maxItems: 1
|
||||
description:
|
||||
A list of phandle to the syscon node that handles the SGMII setup which is required for
|
||||
those SoCs equipped with SGMII.
|
||||
|
||||
dma-coherent: true
|
||||
|
||||
mdio-bus:
|
||||
$ref: mdio.yaml#
|
||||
unevaluatedProperties: false
|
||||
|
||||
"#address-cells":
|
||||
const: 1
|
||||
|
||||
"#size-cells":
|
||||
const: 0
|
||||
|
||||
allOf:
|
||||
- $ref: "ethernet-controller.yaml#"
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
enum:
|
||||
- mediatek,mt2701-eth
|
||||
- mediatek,mt7623-eth
|
||||
then:
|
||||
properties:
|
||||
interrupts:
|
||||
maxItems: 3
|
||||
|
||||
clocks:
|
||||
minItems: 4
|
||||
maxItems: 4
|
||||
|
||||
clock-names:
|
||||
items:
|
||||
- const: ethif
|
||||
- const: esw
|
||||
- const: gp1
|
||||
- const: gp2
|
||||
|
||||
mediatek,pctl:
|
||||
$ref: /schemas/types.yaml#/definitions/phandle
|
||||
description:
|
||||
Phandle to the syscon node that handles the ports slew rate and
|
||||
driver current.
|
||||
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
const: mediatek,mt7622-eth
|
||||
then:
|
||||
properties:
|
||||
interrupts:
|
||||
maxItems: 3
|
||||
|
||||
clocks:
|
||||
minItems: 11
|
||||
maxItems: 11
|
||||
|
||||
clock-names:
|
||||
items:
|
||||
- const: ethif
|
||||
- const: esw
|
||||
- const: gp0
|
||||
- const: gp1
|
||||
- const: gp2
|
||||
- const: sgmii_tx250m
|
||||
- const: sgmii_rx250m
|
||||
- const: sgmii_cdr_ref
|
||||
- const: sgmii_cdr_fb
|
||||
- const: sgmii_ck
|
||||
- const: eth2pll
|
||||
|
||||
mediatek,sgmiisys:
|
||||
minItems: 1
|
||||
maxItems: 1
|
||||
|
||||
mediatek,wed:
|
||||
$ref: /schemas/types.yaml#/definitions/phandle-array
|
||||
minItems: 2
|
||||
maxItems: 2
|
||||
items:
|
||||
maxItems: 1
|
||||
description:
|
||||
List of phandles to wireless ethernet dispatch nodes.
|
||||
|
||||
mediatek,pcie-mirror:
|
||||
$ref: /schemas/types.yaml#/definitions/phandle
|
||||
description:
|
||||
Phandle to the mediatek pcie-mirror controller.
|
||||
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
const: mediatek,mt7629-eth
|
||||
then:
|
||||
properties:
|
||||
interrupts:
|
||||
maxItems: 3
|
||||
|
||||
clocks:
|
||||
minItems: 17
|
||||
maxItems: 17
|
||||
|
||||
clock-names:
|
||||
items:
|
||||
- const: ethif
|
||||
- const: sgmiitop
|
||||
- const: esw
|
||||
- const: gp0
|
||||
- const: gp1
|
||||
- const: gp2
|
||||
- const: fe
|
||||
- const: sgmii_tx250m
|
||||
- const: sgmii_rx250m
|
||||
- const: sgmii_cdr_ref
|
||||
- const: sgmii_cdr_fb
|
||||
- const: sgmii2_tx250m
|
||||
- const: sgmii2_rx250m
|
||||
- const: sgmii2_cdr_ref
|
||||
- const: sgmii2_cdr_fb
|
||||
- const: sgmii_ck
|
||||
- const: eth2pll
|
||||
|
||||
mediatek,infracfg:
|
||||
$ref: /schemas/types.yaml#/definitions/phandle
|
||||
description:
|
||||
Phandle to the syscon node that handles the path from GMAC to
|
||||
PHY variants.
|
||||
|
||||
mediatek,sgmiisys:
|
||||
minItems: 2
|
||||
maxItems: 2
|
||||
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
const: mediatek,mt7986-eth
|
||||
then:
|
||||
properties:
|
||||
interrupts:
|
||||
minItems: 4
|
||||
|
||||
clocks:
|
||||
minItems: 15
|
||||
maxItems: 15
|
||||
|
||||
clock-names:
|
||||
items:
|
||||
- const: fe
|
||||
- const: gp2
|
||||
- const: gp1
|
||||
- const: wocpu1
|
||||
- const: wocpu0
|
||||
- const: sgmii_tx250m
|
||||
- const: sgmii_rx250m
|
||||
- const: sgmii_cdr_ref
|
||||
- const: sgmii_cdr_fb
|
||||
- const: sgmii2_tx250m
|
||||
- const: sgmii2_rx250m
|
||||
- const: sgmii2_cdr_ref
|
||||
- const: sgmii2_cdr_fb
|
||||
- const: netsys0
|
||||
- const: netsys1
|
||||
|
||||
mediatek,sgmiisys:
|
||||
minItems: 2
|
||||
maxItems: 2
|
||||
|
||||
patternProperties:
|
||||
"^mac@[0-1]$":
|
||||
type: object
|
||||
additionalProperties: false
|
||||
allOf:
|
||||
- $ref: ethernet-controller.yaml#
|
||||
description:
|
||||
Ethernet MAC node
|
||||
properties:
|
||||
compatible:
|
||||
const: mediatek,eth-mac
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
phy-handle: true
|
||||
|
||||
phy-mode: true
|
||||
|
||||
required:
|
||||
- reg
|
||||
- compatible
|
||||
- phy-handle
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- interrupts
|
||||
- clocks
|
||||
- clock-names
|
||||
- mediatek,ethsys
|
||||
|
||||
unevaluatedProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/interrupt-controller/arm-gic.h>
|
||||
#include <dt-bindings/interrupt-controller/irq.h>
|
||||
#include <dt-bindings/clock/mt7622-clk.h>
|
||||
#include <dt-bindings/power/mt7622-power.h>
|
||||
|
||||
soc {
|
||||
#address-cells = <2>;
|
||||
#size-cells = <2>;
|
||||
|
||||
ethernet: ethernet@1b100000 {
|
||||
compatible = "mediatek,mt7622-eth";
|
||||
reg = <0 0x1b100000 0 0x20000>;
|
||||
interrupts = <GIC_SPI 223 IRQ_TYPE_LEVEL_LOW>,
|
||||
<GIC_SPI 224 IRQ_TYPE_LEVEL_LOW>,
|
||||
<GIC_SPI 225 IRQ_TYPE_LEVEL_LOW>;
|
||||
clocks = <&topckgen CLK_TOP_ETH_SEL>,
|
||||
<ðsys CLK_ETH_ESW_EN>,
|
||||
<ðsys CLK_ETH_GP0_EN>,
|
||||
<ðsys CLK_ETH_GP1_EN>,
|
||||
<ðsys CLK_ETH_GP2_EN>,
|
||||
<&sgmiisys CLK_SGMII_TX250M_EN>,
|
||||
<&sgmiisys CLK_SGMII_RX250M_EN>,
|
||||
<&sgmiisys CLK_SGMII_CDR_REF>,
|
||||
<&sgmiisys CLK_SGMII_CDR_FB>,
|
||||
<&topckgen CLK_TOP_SGMIIPLL>,
|
||||
<&apmixedsys CLK_APMIXED_ETH2PLL>;
|
||||
clock-names = "ethif", "esw", "gp0", "gp1", "gp2",
|
||||
"sgmii_tx250m", "sgmii_rx250m",
|
||||
"sgmii_cdr_ref", "sgmii_cdr_fb", "sgmii_ck",
|
||||
"eth2pll";
|
||||
power-domains = <&scpsys MT7622_POWER_DOMAIN_ETHSYS>;
|
||||
mediatek,ethsys = <ðsys>;
|
||||
mediatek,sgmiisys = <&sgmiisys>;
|
||||
cci-control-port = <&cci_control2>;
|
||||
mediatek,pcie-mirror = <&pcie_mirror>;
|
||||
mediatek,hifsys = <&hifsys>;
|
||||
dma-coherent;
|
||||
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
mdio0: mdio-bus {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
phy0: ethernet-phy@0 {
|
||||
reg = <0>;
|
||||
};
|
||||
|
||||
phy1: ethernet-phy@1 {
|
||||
reg = <1>;
|
||||
};
|
||||
};
|
||||
|
||||
gmac0: mac@0 {
|
||||
compatible = "mediatek,eth-mac";
|
||||
phy-mode = "rgmii";
|
||||
phy-handle = <&phy0>;
|
||||
reg = <0>;
|
||||
};
|
||||
|
||||
gmac1: mac@1 {
|
||||
compatible = "mediatek,eth-mac";
|
||||
phy-mode = "rgmii";
|
||||
phy-handle = <&phy1>;
|
||||
reg = <1>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
- |
|
||||
#include <dt-bindings/interrupt-controller/arm-gic.h>
|
||||
#include <dt-bindings/interrupt-controller/irq.h>
|
||||
#include <dt-bindings/clock/mt7622-clk.h>
|
||||
|
||||
soc {
|
||||
#address-cells = <2>;
|
||||
#size-cells = <2>;
|
||||
|
||||
eth: ethernet@15100000 {
|
||||
#define CLK_ETH_FE_EN 0
|
||||
#define CLK_ETH_WOCPU1_EN 3
|
||||
#define CLK_ETH_WOCPU0_EN 4
|
||||
#define CLK_TOP_NETSYS_SEL 43
|
||||
#define CLK_TOP_NETSYS_500M_SEL 44
|
||||
#define CLK_TOP_NETSYS_2X_SEL 46
|
||||
#define CLK_TOP_SGM_325M_SEL 47
|
||||
#define CLK_APMIXED_NET2PLL 1
|
||||
#define CLK_APMIXED_SGMPLL 3
|
||||
|
||||
compatible = "mediatek,mt7986-eth";
|
||||
reg = <0 0x15100000 0 0x80000>;
|
||||
interrupts = <GIC_SPI 196 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 197 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 198 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 199 IRQ_TYPE_LEVEL_HIGH>;
|
||||
clocks = <ðsys CLK_ETH_FE_EN>,
|
||||
<ðsys CLK_ETH_GP2_EN>,
|
||||
<ðsys CLK_ETH_GP1_EN>,
|
||||
<ðsys CLK_ETH_WOCPU1_EN>,
|
||||
<ðsys CLK_ETH_WOCPU0_EN>,
|
||||
<&sgmiisys0 CLK_SGMII_TX250M_EN>,
|
||||
<&sgmiisys0 CLK_SGMII_RX250M_EN>,
|
||||
<&sgmiisys0 CLK_SGMII_CDR_REF>,
|
||||
<&sgmiisys0 CLK_SGMII_CDR_FB>,
|
||||
<&sgmiisys1 CLK_SGMII_TX250M_EN>,
|
||||
<&sgmiisys1 CLK_SGMII_RX250M_EN>,
|
||||
<&sgmiisys1 CLK_SGMII_CDR_REF>,
|
||||
<&sgmiisys1 CLK_SGMII_CDR_FB>,
|
||||
<&topckgen CLK_TOP_NETSYS_SEL>,
|
||||
<&topckgen CLK_TOP_NETSYS_SEL>;
|
||||
clock-names = "fe", "gp2", "gp1", "wocpu1", "wocpu0",
|
||||
"sgmii_tx250m", "sgmii_rx250m",
|
||||
"sgmii_cdr_ref", "sgmii_cdr_fb",
|
||||
"sgmii2_tx250m", "sgmii2_rx250m",
|
||||
"sgmii2_cdr_ref", "sgmii2_cdr_fb",
|
||||
"netsys0", "netsys1";
|
||||
mediatek,ethsys = <ðsys>;
|
||||
mediatek,sgmiisys = <&sgmiisys0>, <&sgmiisys1>;
|
||||
assigned-clocks = <&topckgen CLK_TOP_NETSYS_2X_SEL>,
|
||||
<&topckgen CLK_TOP_SGM_325M_SEL>;
|
||||
assigned-clock-parents = <&apmixedsys CLK_APMIXED_NET2PLL>,
|
||||
<&apmixedsys CLK_APMIXED_SGMPLL>;
|
||||
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
mdio: mdio-bus {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
phy5: ethernet-phy@0 {
|
||||
compatible = "ethernet-phy-id67c9.de0a";
|
||||
phy-mode = "2500base-x";
|
||||
reset-gpios = <&pio 6 1>;
|
||||
reset-deassert-us = <20000>;
|
||||
reg = <5>;
|
||||
};
|
||||
|
||||
phy6: ethernet-phy@1 {
|
||||
compatible = "ethernet-phy-id67c9.de0a";
|
||||
phy-mode = "2500base-x";
|
||||
reg = <6>;
|
||||
};
|
||||
};
|
||||
|
||||
mac0: mac@0 {
|
||||
compatible = "mediatek,eth-mac";
|
||||
phy-mode = "2500base-x";
|
||||
phy-handle = <&phy5>;
|
||||
reg = <0>;
|
||||
};
|
||||
|
||||
mac1: mac@1 {
|
||||
compatible = "mediatek,eth-mac";
|
||||
phy-mode = "2500base-x";
|
||||
phy-handle = <&phy6>;
|
||||
reg = <1>;
|
||||
};
|
||||
};
|
||||
};
|
|
@ -1,98 +0,0 @@
|
|||
MediaTek Frame Engine Ethernet controller
|
||||
=========================================
|
||||
|
||||
The frame engine ethernet controller can be found on MediaTek SoCs. These SoCs
|
||||
have dual GMAC each represented by a child node..
|
||||
|
||||
* Ethernet controller node
|
||||
|
||||
Required properties:
|
||||
- compatible: Should be
|
||||
"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
|
||||
"ralink,rt5350-eth": for Ralink Rt5350F and MT7628/88 SoC
|
||||
- reg: Address and length of the register set for the device
|
||||
- interrupts: Should contain the three frame engines interrupts in numeric
|
||||
order. These are fe_int0, fe_int1 and fe_int2.
|
||||
- clocks: the clock used by the core
|
||||
- clock-names: the names of the clock listed in the clocks property. These are
|
||||
"ethif", "esw", "gp2", "gp1" : 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,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
|
||||
|
||||
* Ethernet MAC node
|
||||
|
||||
Required properties:
|
||||
- compatible: Should be "mediatek,eth-mac"
|
||||
- reg: The number of the MAC
|
||||
- phy-handle: see ethernet.txt file in the same directory and
|
||||
the phy-mode "trgmii" required being provided when reg
|
||||
is equal to 0 and the MAC uses fixed-link to connect
|
||||
with internal switch such as MT7530.
|
||||
|
||||
Example:
|
||||
|
||||
eth: ethernet@1b100000 {
|
||||
compatible = "mediatek,mt7623-eth";
|
||||
reg = <0 0x1b100000 0 0x20000>;
|
||||
clocks = <&topckgen CLK_TOP_ETHIF_SEL>,
|
||||
<ðsys CLK_ETHSYS_ESW>,
|
||||
<ðsys CLK_ETHSYS_GP2>,
|
||||
<ðsys CLK_ETHSYS_GP1>;
|
||||
clock-names = "ethif", "esw", "gp2", "gp1";
|
||||
interrupts = <GIC_SPI 200 IRQ_TYPE_LEVEL_LOW
|
||||
GIC_SPI 199 IRQ_TYPE_LEVEL_LOW
|
||||
GIC_SPI 198 IRQ_TYPE_LEVEL_LOW>;
|
||||
power-domains = <&scpsys MT2701_POWER_DOMAIN_ETH>;
|
||||
resets = <ðsys MT2701_ETHSYS_ETH_RST>;
|
||||
reset-names = "eth";
|
||||
mediatek,ethsys = <ðsys>;
|
||||
mediatek,pctl = <&syscfg_pctl_a>;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
gmac1: mac@0 {
|
||||
compatible = "mediatek,eth-mac";
|
||||
reg = <0>;
|
||||
phy-handle = <&phy0>;
|
||||
};
|
||||
|
||||
gmac2: mac@1 {
|
||||
compatible = "mediatek,eth-mac";
|
||||
reg = <1>;
|
||||
phy-handle = <&phy1>;
|
||||
};
|
||||
|
||||
mdio-bus {
|
||||
phy0: ethernet-phy@0 {
|
||||
reg = <0>;
|
||||
phy-mode = "rgmii";
|
||||
};
|
||||
|
||||
phy1: ethernet-phy@1 {
|
||||
reg = <1>;
|
||||
phy-mode = "rgmii";
|
||||
};
|
||||
};
|
||||
};
|
|
@ -45,3 +45,12 @@ Optional properties:
|
|||
|
||||
In fiber mode, auto-negotiation is disabled and the PHY can only work in
|
||||
100base-fx (full and half duplex) modes.
|
||||
|
||||
- coma-mode-gpios: If present the given gpio will be deasserted when the
|
||||
PHY is probed.
|
||||
|
||||
Some PHYs have a COMA mode input pin which puts the PHY into
|
||||
isolate and power-down mode. On some boards this input is connected
|
||||
to a GPIO of the SoC.
|
||||
|
||||
Supported on the LAN8814.
|
||||
|
|
|
@ -39,6 +39,7 @@ properties:
|
|||
- description: frame dma based extraction
|
||||
- description: analyzer interrupt
|
||||
- description: ptp interrupt
|
||||
- description: ptp external interrupt
|
||||
|
||||
interrupt-names:
|
||||
minItems: 1
|
||||
|
@ -47,16 +48,15 @@ properties:
|
|||
- const: fdma
|
||||
- const: ana
|
||||
- const: ptp
|
||||
- const: ptp-ext
|
||||
|
||||
resets:
|
||||
items:
|
||||
- description: Reset controller used for switch core reset (soft reset)
|
||||
- description: Reset controller used for releasing the phy from reset
|
||||
|
||||
reset-names:
|
||||
items:
|
||||
- const: switch
|
||||
- const: phy
|
||||
|
||||
ethernet-ports:
|
||||
type: object
|
||||
|
@ -145,8 +145,8 @@ examples:
|
|||
reg-names = "cpu", "gcb";
|
||||
interrupts = <GIC_SPI 30 IRQ_TYPE_LEVEL_HIGH>;
|
||||
interrupt-names = "xtr";
|
||||
resets = <&switch_reset 0>, <&phy_reset 0>;
|
||||
reset-names = "switch", "phy";
|
||||
resets = <&switch_reset 0>;
|
||||
reset-names = "switch";
|
||||
ethernet-ports {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
|
|
@ -0,0 +1,61 @@
|
|||
# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/net/mscc,miim.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Microsemi MII Management Controller (MIIM)
|
||||
|
||||
maintainers:
|
||||
- Alexandre Belloni <alexandre.belloni@bootlin.com>
|
||||
|
||||
allOf:
|
||||
- $ref: "mdio.yaml#"
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
enum:
|
||||
- mscc,ocelot-miim
|
||||
- microchip,lan966x-miim
|
||||
|
||||
"#address-cells":
|
||||
const: 1
|
||||
|
||||
"#size-cells":
|
||||
const: 0
|
||||
|
||||
reg:
|
||||
items:
|
||||
- description: base address
|
||||
- description: associated reset register for internal PHYs
|
||||
minItems: 1
|
||||
|
||||
interrupts:
|
||||
maxItems: 1
|
||||
|
||||
clocks:
|
||||
maxItems: 1
|
||||
|
||||
clock-frequency: true
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- "#address-cells"
|
||||
- "#size-cells"
|
||||
|
||||
unevaluatedProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
mdio@107009c {
|
||||
compatible = "mscc,ocelot-miim";
|
||||
reg = <0x107009c 0x36>, <0x10700f0 0x8>;
|
||||
interrupts = <14>;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
phy0: ethernet-phy@0 {
|
||||
reg = <0>;
|
||||
};
|
||||
};
|
|
@ -1,26 +0,0 @@
|
|||
Microsemi MII Management Controller (MIIM) / MDIO
|
||||
=================================================
|
||||
|
||||
Properties:
|
||||
- compatible: must be "mscc,ocelot-miim" or "microchip,lan966x-miim"
|
||||
- reg: The base address of the MDIO bus controller register bank. Optionally, a
|
||||
second register bank can be defined if there is an associated reset register
|
||||
for internal PHYs
|
||||
- #address-cells: Must be <1>.
|
||||
- #size-cells: Must be <0>. MDIO addresses have no size component.
|
||||
- interrupts: interrupt specifier (refer to the interrupt binding)
|
||||
|
||||
Typically an MDIO bus might have several children.
|
||||
|
||||
Example:
|
||||
mdio@107009c {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
compatible = "mscc,ocelot-miim";
|
||||
reg = <0x107009c 0x36>, <0x10700f0 0x8>;
|
||||
interrupts = <14>;
|
||||
|
||||
phy0: ethernet-phy@0 {
|
||||
reg = <0>;
|
||||
};
|
||||
};
|
|
@ -43,6 +43,11 @@ properties:
|
|||
- renesas,etheravb-r8a779a0 # R-Car V3U
|
||||
- const: renesas,etheravb-rcar-gen3 # R-Car Gen3 and RZ/G2
|
||||
|
||||
- items:
|
||||
- enum:
|
||||
- renesas,etheravb-r9a09g011 # RZ/V2M
|
||||
- const: renesas,etheravb-rzv2m # RZ/V2M compatible
|
||||
|
||||
- items:
|
||||
- enum:
|
||||
- renesas,r9a07g043-gbeth # RZ/G2UL
|
||||
|
@ -160,16 +165,33 @@ allOf:
|
|||
- const: arp_ns
|
||||
rx-internal-delay-ps: false
|
||||
else:
|
||||
properties:
|
||||
interrupts:
|
||||
minItems: 25
|
||||
maxItems: 25
|
||||
interrupt-names:
|
||||
items:
|
||||
pattern: '^ch[0-9]+$'
|
||||
required:
|
||||
- interrupt-names
|
||||
- rx-internal-delay-ps
|
||||
if:
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
const: renesas,etheravb-rzv2m
|
||||
then:
|
||||
properties:
|
||||
interrupts:
|
||||
minItems: 29
|
||||
maxItems: 29
|
||||
interrupt-names:
|
||||
items:
|
||||
pattern: '^(ch(1?)[0-9])|ch20|ch21|dia|dib|err_a|err_b|mgmt_a|mgmt_b|line3$'
|
||||
rx-internal-delay-ps: false
|
||||
required:
|
||||
- interrupt-names
|
||||
else:
|
||||
properties:
|
||||
interrupts:
|
||||
minItems: 25
|
||||
maxItems: 25
|
||||
interrupt-names:
|
||||
items:
|
||||
pattern: '^ch[0-9]+$'
|
||||
required:
|
||||
- interrupt-names
|
||||
- rx-internal-delay-ps
|
||||
|
||||
- if:
|
||||
properties:
|
||||
|
@ -231,17 +253,35 @@ allOf:
|
|||
- const: chi
|
||||
- const: refclk
|
||||
else:
|
||||
properties:
|
||||
clocks:
|
||||
minItems: 1
|
||||
items:
|
||||
- description: AVB functional clock
|
||||
- description: Optional TXC reference clock
|
||||
clock-names:
|
||||
minItems: 1
|
||||
items:
|
||||
- const: fck
|
||||
- const: refclk
|
||||
if:
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
const: renesas,etheravb-rzv2m
|
||||
then:
|
||||
properties:
|
||||
clocks:
|
||||
items:
|
||||
- description: Main clock
|
||||
- description: Coherent Hub Interface clock
|
||||
- description: gPTP reference clock
|
||||
clock-names:
|
||||
items:
|
||||
- const: axi
|
||||
- const: chi
|
||||
- const: gptp
|
||||
else:
|
||||
properties:
|
||||
clocks:
|
||||
minItems: 1
|
||||
items:
|
||||
- description: AVB functional clock
|
||||
- description: Optional TXC reference clock
|
||||
clock-names:
|
||||
minItems: 1
|
||||
items:
|
||||
- const: fck
|
||||
- const: refclk
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
|
|
|
@ -0,0 +1,141 @@
|
|||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
# Copyright (C) Sunplus Co., Ltd. 2021
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/net/sunplus,sp7021-emac.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Sunplus SP7021 Dual Ethernet MAC Device Tree Bindings
|
||||
|
||||
maintainers:
|
||||
- Wells Lu <wellslutw@gmail.com>
|
||||
|
||||
description: |
|
||||
Sunplus SP7021 dual 10M/100M Ethernet MAC controller.
|
||||
Device node of the controller has following properties.
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
const: sunplus,sp7021-emac
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
interrupts:
|
||||
maxItems: 1
|
||||
|
||||
clocks:
|
||||
maxItems: 1
|
||||
|
||||
resets:
|
||||
maxItems: 1
|
||||
|
||||
ethernet-ports:
|
||||
type: object
|
||||
description: Ethernet ports to PHY
|
||||
|
||||
properties:
|
||||
"#address-cells":
|
||||
const: 1
|
||||
|
||||
"#size-cells":
|
||||
const: 0
|
||||
|
||||
patternProperties:
|
||||
"^port@[0-1]$":
|
||||
type: object
|
||||
description: Port to PHY
|
||||
|
||||
properties:
|
||||
reg:
|
||||
minimum: 0
|
||||
maximum: 1
|
||||
|
||||
phy-handle:
|
||||
maxItems: 1
|
||||
|
||||
phy-mode:
|
||||
maxItems: 1
|
||||
|
||||
nvmem-cells:
|
||||
items:
|
||||
- description: nvmem cell address of MAC address
|
||||
|
||||
nvmem-cell-names:
|
||||
description: names corresponding to the nvmem cells
|
||||
items:
|
||||
- const: mac-address
|
||||
|
||||
required:
|
||||
- reg
|
||||
- phy-handle
|
||||
- phy-mode
|
||||
- nvmem-cells
|
||||
- nvmem-cell-names
|
||||
|
||||
mdio:
|
||||
$ref: mdio.yaml#
|
||||
unevaluatedProperties: false
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- interrupts
|
||||
- clocks
|
||||
- resets
|
||||
- pinctrl-0
|
||||
- pinctrl-names
|
||||
- ethernet-ports
|
||||
- mdio
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/interrupt-controller/irq.h>
|
||||
|
||||
ethernet@9c108000 {
|
||||
compatible = "sunplus,sp7021-emac";
|
||||
reg = <0x9c108000 0x400>;
|
||||
interrupt-parent = <&intc>;
|
||||
interrupts = <66 IRQ_TYPE_LEVEL_HIGH>;
|
||||
clocks = <&clkc 0xa7>;
|
||||
resets = <&rstc 0x97>;
|
||||
pinctrl-0 = <&emac_demo_board_v3_pins>;
|
||||
pinctrl-names = "default";
|
||||
|
||||
ethernet-ports {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
port@0 {
|
||||
reg = <0>;
|
||||
phy-handle = <ð_phy0>;
|
||||
phy-mode = "rmii";
|
||||
nvmem-cells = <&mac_addr0>;
|
||||
nvmem-cell-names = "mac-address";
|
||||
};
|
||||
|
||||
port@1 {
|
||||
reg = <1>;
|
||||
phy-handle = <ð_phy1>;
|
||||
phy-mode = "rmii";
|
||||
nvmem-cells = <&mac_addr1>;
|
||||
nvmem-cell-names = "mac-address";
|
||||
};
|
||||
};
|
||||
|
||||
mdio {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
eth_phy0: ethernet-phy@0 {
|
||||
reg = <0>;
|
||||
};
|
||||
|
||||
eth_phy1: ethernet-phy@1 {
|
||||
reg = <1>;
|
||||
};
|
||||
};
|
||||
};
|
||||
...
|
|
@ -52,6 +52,7 @@ unevaluatedProperties: false
|
|||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/clock/toshiba,tmpv770x.h>
|
||||
#include <dt-bindings/interrupt-controller/arm-gic.h>
|
||||
|
||||
soc {
|
||||
|
@ -63,7 +64,7 @@ examples:
|
|||
reg = <0 0x28000000 0 0x10000>;
|
||||
interrupts = <GIC_SPI 156 IRQ_TYPE_LEVEL_HIGH>;
|
||||
interrupt-names = "macirq";
|
||||
clocks = <&clk300mhz>, <&clk125mhz>;
|
||||
clocks = <&pismu TMPV770X_CLK_PIETHER_BUS>, <&pismu TMPV770X_CLK_PIETHER_125M>;
|
||||
clock-names = "stmmaceth", "phy_ref_clk";
|
||||
snps,txpbl = <4>;
|
||||
snps,rxpbl = <4>;
|
||||
|
|
|
@ -20,120 +20,17 @@ properties:
|
|||
enum:
|
||||
- qcom,ipq8074-wifi
|
||||
- qcom,ipq6018-wifi
|
||||
- qcom,wcn6750-wifi
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
interrupts:
|
||||
items:
|
||||
- description: misc-pulse1 interrupt events
|
||||
- description: misc-latch interrupt events
|
||||
- description: sw exception interrupt events
|
||||
- description: watchdog interrupt events
|
||||
- description: interrupt event for ring CE0
|
||||
- description: interrupt event for ring CE1
|
||||
- description: interrupt event for ring CE2
|
||||
- description: interrupt event for ring CE3
|
||||
- description: interrupt event for ring CE4
|
||||
- description: interrupt event for ring CE5
|
||||
- description: interrupt event for ring CE6
|
||||
- description: interrupt event for ring CE7
|
||||
- description: interrupt event for ring CE8
|
||||
- description: interrupt event for ring CE9
|
||||
- description: interrupt event for ring CE10
|
||||
- description: interrupt event for ring CE11
|
||||
- description: interrupt event for ring host2wbm-desc-feed
|
||||
- description: interrupt event for ring host2reo-re-injection
|
||||
- description: interrupt event for ring host2reo-command
|
||||
- description: interrupt event for ring host2rxdma-monitor-ring3
|
||||
- description: interrupt event for ring host2rxdma-monitor-ring2
|
||||
- description: interrupt event for ring host2rxdma-monitor-ring1
|
||||
- description: interrupt event for ring reo2ost-exception
|
||||
- description: interrupt event for ring wbm2host-rx-release
|
||||
- description: interrupt event for ring reo2host-status
|
||||
- description: interrupt event for ring reo2host-destination-ring4
|
||||
- description: interrupt event for ring reo2host-destination-ring3
|
||||
- description: interrupt event for ring reo2host-destination-ring2
|
||||
- description: interrupt event for ring reo2host-destination-ring1
|
||||
- description: interrupt event for ring rxdma2host-monitor-destination-mac3
|
||||
- description: interrupt event for ring rxdma2host-monitor-destination-mac2
|
||||
- description: interrupt event for ring rxdma2host-monitor-destination-mac1
|
||||
- description: interrupt event for ring ppdu-end-interrupts-mac3
|
||||
- description: interrupt event for ring ppdu-end-interrupts-mac2
|
||||
- description: interrupt event for ring ppdu-end-interrupts-mac1
|
||||
- description: interrupt event for ring rxdma2host-monitor-status-ring-mac3
|
||||
- description: interrupt event for ring rxdma2host-monitor-status-ring-mac2
|
||||
- description: interrupt event for ring rxdma2host-monitor-status-ring-mac1
|
||||
- description: interrupt event for ring host2rxdma-host-buf-ring-mac3
|
||||
- description: interrupt event for ring host2rxdma-host-buf-ring-mac2
|
||||
- description: interrupt event for ring host2rxdma-host-buf-ring-mac1
|
||||
- description: interrupt event for ring rxdma2host-destination-ring-mac3
|
||||
- description: interrupt event for ring rxdma2host-destination-ring-mac2
|
||||
- description: interrupt event for ring rxdma2host-destination-ring-mac1
|
||||
- description: interrupt event for ring host2tcl-input-ring4
|
||||
- description: interrupt event for ring host2tcl-input-ring3
|
||||
- description: interrupt event for ring host2tcl-input-ring2
|
||||
- description: interrupt event for ring host2tcl-input-ring1
|
||||
- description: interrupt event for ring wbm2host-tx-completions-ring3
|
||||
- description: interrupt event for ring wbm2host-tx-completions-ring2
|
||||
- description: interrupt event for ring wbm2host-tx-completions-ring1
|
||||
- description: interrupt event for ring tcl2host-status-ring
|
||||
|
||||
minItems: 32
|
||||
maxItems: 52
|
||||
|
||||
interrupt-names:
|
||||
items:
|
||||
- const: misc-pulse1
|
||||
- const: misc-latch
|
||||
- const: sw-exception
|
||||
- const: watchdog
|
||||
- const: ce0
|
||||
- const: ce1
|
||||
- const: ce2
|
||||
- const: ce3
|
||||
- const: ce4
|
||||
- const: ce5
|
||||
- const: ce6
|
||||
- const: ce7
|
||||
- const: ce8
|
||||
- const: ce9
|
||||
- const: ce10
|
||||
- const: ce11
|
||||
- const: host2wbm-desc-feed
|
||||
- const: host2reo-re-injection
|
||||
- const: host2reo-command
|
||||
- const: host2rxdma-monitor-ring3
|
||||
- const: host2rxdma-monitor-ring2
|
||||
- const: host2rxdma-monitor-ring1
|
||||
- const: reo2ost-exception
|
||||
- const: wbm2host-rx-release
|
||||
- const: reo2host-status
|
||||
- const: reo2host-destination-ring4
|
||||
- const: reo2host-destination-ring3
|
||||
- const: reo2host-destination-ring2
|
||||
- const: reo2host-destination-ring1
|
||||
- const: rxdma2host-monitor-destination-mac3
|
||||
- const: rxdma2host-monitor-destination-mac2
|
||||
- const: rxdma2host-monitor-destination-mac1
|
||||
- const: ppdu-end-interrupts-mac3
|
||||
- const: ppdu-end-interrupts-mac2
|
||||
- const: ppdu-end-interrupts-mac1
|
||||
- const: rxdma2host-monitor-status-ring-mac3
|
||||
- const: rxdma2host-monitor-status-ring-mac2
|
||||
- const: rxdma2host-monitor-status-ring-mac1
|
||||
- const: host2rxdma-host-buf-ring-mac3
|
||||
- const: host2rxdma-host-buf-ring-mac2
|
||||
- const: host2rxdma-host-buf-ring-mac1
|
||||
- const: rxdma2host-destination-ring-mac3
|
||||
- const: rxdma2host-destination-ring-mac2
|
||||
- const: rxdma2host-destination-ring-mac1
|
||||
- const: host2tcl-input-ring4
|
||||
- const: host2tcl-input-ring3
|
||||
- const: host2tcl-input-ring2
|
||||
- const: host2tcl-input-ring1
|
||||
- const: wbm2host-tx-completions-ring3
|
||||
- const: wbm2host-tx-completions-ring2
|
||||
- const: wbm2host-tx-completions-ring1
|
||||
- const: tcl2host-status-ring
|
||||
maxItems: 52
|
||||
|
||||
qcom,rproc:
|
||||
$ref: /schemas/types.yaml#/definitions/phandle
|
||||
|
@ -151,20 +48,205 @@ properties:
|
|||
board-2.bin for designs with colliding bus and device specific ids
|
||||
|
||||
memory-region:
|
||||
maxItems: 1
|
||||
minItems: 1
|
||||
maxItems: 2
|
||||
description:
|
||||
phandle to a node describing reserved memory (System RAM memory)
|
||||
used by ath11k firmware (see bindings/reserved-memory/reserved-memory.txt)
|
||||
|
||||
iommus:
|
||||
minItems: 1
|
||||
maxItems: 2
|
||||
|
||||
wifi-firmware:
|
||||
type: object
|
||||
description: |
|
||||
WCN6750 wifi node can contain one optional firmware subnode.
|
||||
Firmware subnode is needed when the platform does not have Trustzone.
|
||||
required:
|
||||
- iommus
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- interrupts
|
||||
- interrupt-names
|
||||
- qcom,rproc
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
allOf:
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
enum:
|
||||
- qcom,ipq8074-wifi
|
||||
- qcom,ipq6018-wifi
|
||||
then:
|
||||
properties:
|
||||
interrupts:
|
||||
items:
|
||||
- description: misc-pulse1 interrupt events
|
||||
- description: misc-latch interrupt events
|
||||
- description: sw exception interrupt events
|
||||
- description: watchdog interrupt events
|
||||
- description: interrupt event for ring CE0
|
||||
- description: interrupt event for ring CE1
|
||||
- description: interrupt event for ring CE2
|
||||
- description: interrupt event for ring CE3
|
||||
- description: interrupt event for ring CE4
|
||||
- description: interrupt event for ring CE5
|
||||
- description: interrupt event for ring CE6
|
||||
- description: interrupt event for ring CE7
|
||||
- description: interrupt event for ring CE8
|
||||
- description: interrupt event for ring CE9
|
||||
- description: interrupt event for ring CE10
|
||||
- description: interrupt event for ring CE11
|
||||
- description: interrupt event for ring host2wbm-desc-feed
|
||||
- description: interrupt event for ring host2reo-re-injection
|
||||
- description: interrupt event for ring host2reo-command
|
||||
- description: interrupt event for ring host2rxdma-monitor-ring3
|
||||
- description: interrupt event for ring host2rxdma-monitor-ring2
|
||||
- description: interrupt event for ring host2rxdma-monitor-ring1
|
||||
- description: interrupt event for ring reo2ost-exception
|
||||
- description: interrupt event for ring wbm2host-rx-release
|
||||
- description: interrupt event for ring reo2host-status
|
||||
- description: interrupt event for ring reo2host-destination-ring4
|
||||
- description: interrupt event for ring reo2host-destination-ring3
|
||||
- description: interrupt event for ring reo2host-destination-ring2
|
||||
- description: interrupt event for ring reo2host-destination-ring1
|
||||
- description: interrupt event for ring rxdma2host-monitor-destination-mac3
|
||||
- description: interrupt event for ring rxdma2host-monitor-destination-mac2
|
||||
- description: interrupt event for ring rxdma2host-monitor-destination-mac1
|
||||
- description: interrupt event for ring ppdu-end-interrupts-mac3
|
||||
- description: interrupt event for ring ppdu-end-interrupts-mac2
|
||||
- description: interrupt event for ring ppdu-end-interrupts-mac1
|
||||
- description: interrupt event for ring rxdma2host-monitor-status-ring-mac3
|
||||
- description: interrupt event for ring rxdma2host-monitor-status-ring-mac2
|
||||
- description: interrupt event for ring rxdma2host-monitor-status-ring-mac1
|
||||
- description: interrupt event for ring host2rxdma-host-buf-ring-mac3
|
||||
- description: interrupt event for ring host2rxdma-host-buf-ring-mac2
|
||||
- description: interrupt event for ring host2rxdma-host-buf-ring-mac1
|
||||
- description: interrupt event for ring rxdma2host-destination-ring-mac3
|
||||
- description: interrupt event for ring rxdma2host-destination-ring-mac2
|
||||
- description: interrupt event for ring rxdma2host-destination-ring-mac1
|
||||
- description: interrupt event for ring host2tcl-input-ring4
|
||||
- description: interrupt event for ring host2tcl-input-ring3
|
||||
- description: interrupt event for ring host2tcl-input-ring2
|
||||
- description: interrupt event for ring host2tcl-input-ring1
|
||||
- description: interrupt event for ring wbm2host-tx-completions-ring3
|
||||
- description: interrupt event for ring wbm2host-tx-completions-ring2
|
||||
- description: interrupt event for ring wbm2host-tx-completions-ring1
|
||||
- description: interrupt event for ring tcl2host-status-ring
|
||||
interrupt-names:
|
||||
items:
|
||||
- const: misc-pulse1
|
||||
- const: misc-latch
|
||||
- const: sw-exception
|
||||
- const: watchdog
|
||||
- const: ce0
|
||||
- const: ce1
|
||||
- const: ce2
|
||||
- const: ce3
|
||||
- const: ce4
|
||||
- const: ce5
|
||||
- const: ce6
|
||||
- const: ce7
|
||||
- const: ce8
|
||||
- const: ce9
|
||||
- const: ce10
|
||||
- const: ce11
|
||||
- const: host2wbm-desc-feed
|
||||
- const: host2reo-re-injection
|
||||
- const: host2reo-command
|
||||
- const: host2rxdma-monitor-ring3
|
||||
- const: host2rxdma-monitor-ring2
|
||||
- const: host2rxdma-monitor-ring1
|
||||
- const: reo2ost-exception
|
||||
- const: wbm2host-rx-release
|
||||
- const: reo2host-status
|
||||
- const: reo2host-destination-ring4
|
||||
- const: reo2host-destination-ring3
|
||||
- const: reo2host-destination-ring2
|
||||
- const: reo2host-destination-ring1
|
||||
- const: rxdma2host-monitor-destination-mac3
|
||||
- const: rxdma2host-monitor-destination-mac2
|
||||
- const: rxdma2host-monitor-destination-mac1
|
||||
- const: ppdu-end-interrupts-mac3
|
||||
- const: ppdu-end-interrupts-mac2
|
||||
- const: ppdu-end-interrupts-mac1
|
||||
- const: rxdma2host-monitor-status-ring-mac3
|
||||
- const: rxdma2host-monitor-status-ring-mac2
|
||||
- const: rxdma2host-monitor-status-ring-mac1
|
||||
- const: host2rxdma-host-buf-ring-mac3
|
||||
- const: host2rxdma-host-buf-ring-mac2
|
||||
- const: host2rxdma-host-buf-ring-mac1
|
||||
- const: rxdma2host-destination-ring-mac3
|
||||
- const: rxdma2host-destination-ring-mac2
|
||||
- const: rxdma2host-destination-ring-mac1
|
||||
- const: host2tcl-input-ring4
|
||||
- const: host2tcl-input-ring3
|
||||
- const: host2tcl-input-ring2
|
||||
- const: host2tcl-input-ring1
|
||||
- const: wbm2host-tx-completions-ring3
|
||||
- const: wbm2host-tx-completions-ring2
|
||||
- const: wbm2host-tx-completions-ring1
|
||||
- const: tcl2host-status-ring
|
||||
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
enum:
|
||||
- qcom,ipq8074-wifi
|
||||
- qcom,ipq6018-wifi
|
||||
then:
|
||||
required:
|
||||
- interrupt-names
|
||||
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
enum:
|
||||
- qcom,wcn6750-wifi
|
||||
then:
|
||||
properties:
|
||||
interrupts:
|
||||
items:
|
||||
- description: interrupt event for ring CE1
|
||||
- description: interrupt event for ring CE2
|
||||
- description: interrupt event for ring CE3
|
||||
- description: interrupt event for ring CE4
|
||||
- description: interrupt event for ring CE5
|
||||
- description: interrupt event for ring CE6
|
||||
- description: interrupt event for ring CE7
|
||||
- description: interrupt event for ring CE8
|
||||
- description: interrupt event for ring CE9
|
||||
- description: interrupt event for ring CE10
|
||||
- description: interrupt event for ring DP1
|
||||
- description: interrupt event for ring DP2
|
||||
- description: interrupt event for ring DP3
|
||||
- description: interrupt event for ring DP4
|
||||
- description: interrupt event for ring DP5
|
||||
- description: interrupt event for ring DP6
|
||||
- description: interrupt event for ring DP7
|
||||
- description: interrupt event for ring DP8
|
||||
- description: interrupt event for ring DP9
|
||||
- description: interrupt event for ring DP10
|
||||
- description: interrupt event for ring DP11
|
||||
- description: interrupt event for ring DP12
|
||||
- description: interrupt event for ring DP13
|
||||
- description: interrupt event for ring DP14
|
||||
- description: interrupt event for ring DP15
|
||||
- description: interrupt event for ring DP16
|
||||
- description: interrupt event for ring DP17
|
||||
- description: interrupt event for ring DP18
|
||||
- description: interrupt event for ring DP19
|
||||
- description: interrupt event for ring DP20
|
||||
- description: interrupt event for ring DP21
|
||||
- description: interrupt event for ring DP22
|
||||
|
||||
examples:
|
||||
- |
|
||||
|
||||
|
@ -309,3 +391,64 @@ examples:
|
|||
};
|
||||
};
|
||||
};
|
||||
|
||||
- |
|
||||
#include <dt-bindings/interrupt-controller/arm-gic.h>
|
||||
|
||||
reserved-memory {
|
||||
#address-cells = <2>;
|
||||
#size-cells = <2>;
|
||||
|
||||
wlan_ce_mem: memory@4cd000 {
|
||||
no-map;
|
||||
reg = <0x0 0x004cd000 0x0 0x1000>;
|
||||
};
|
||||
|
||||
wlan_fw_mem: memory@80c00000 {
|
||||
no-map;
|
||||
reg = <0x0 0x80c00000 0x0 0xc00000>;
|
||||
};
|
||||
};
|
||||
|
||||
wifi: wifi@17a10040 {
|
||||
compatible = "qcom,wcn6750-wifi";
|
||||
reg = <0x17a10040 0x0>;
|
||||
iommus = <&apps_smmu 0x1c00 0x1>;
|
||||
interrupts = <GIC_SPI 768 IRQ_TYPE_EDGE_RISING>,
|
||||
<GIC_SPI 769 IRQ_TYPE_EDGE_RISING>,
|
||||
<GIC_SPI 770 IRQ_TYPE_EDGE_RISING>,
|
||||
<GIC_SPI 771 IRQ_TYPE_EDGE_RISING>,
|
||||
<GIC_SPI 772 IRQ_TYPE_EDGE_RISING>,
|
||||
<GIC_SPI 773 IRQ_TYPE_EDGE_RISING>,
|
||||
<GIC_SPI 774 IRQ_TYPE_EDGE_RISING>,
|
||||
<GIC_SPI 775 IRQ_TYPE_EDGE_RISING>,
|
||||
<GIC_SPI 776 IRQ_TYPE_EDGE_RISING>,
|
||||
<GIC_SPI 777 IRQ_TYPE_EDGE_RISING>,
|
||||
<GIC_SPI 778 IRQ_TYPE_EDGE_RISING>,
|
||||
<GIC_SPI 779 IRQ_TYPE_EDGE_RISING>,
|
||||
<GIC_SPI 780 IRQ_TYPE_EDGE_RISING>,
|
||||
<GIC_SPI 781 IRQ_TYPE_EDGE_RISING>,
|
||||
<GIC_SPI 782 IRQ_TYPE_EDGE_RISING>,
|
||||
<GIC_SPI 783 IRQ_TYPE_EDGE_RISING>,
|
||||
<GIC_SPI 784 IRQ_TYPE_EDGE_RISING>,
|
||||
<GIC_SPI 785 IRQ_TYPE_EDGE_RISING>,
|
||||
<GIC_SPI 786 IRQ_TYPE_EDGE_RISING>,
|
||||
<GIC_SPI 787 IRQ_TYPE_EDGE_RISING>,
|
||||
<GIC_SPI 788 IRQ_TYPE_EDGE_RISING>,
|
||||
<GIC_SPI 789 IRQ_TYPE_EDGE_RISING>,
|
||||
<GIC_SPI 790 IRQ_TYPE_EDGE_RISING>,
|
||||
<GIC_SPI 791 IRQ_TYPE_EDGE_RISING>,
|
||||
<GIC_SPI 792 IRQ_TYPE_EDGE_RISING>,
|
||||
<GIC_SPI 793 IRQ_TYPE_EDGE_RISING>,
|
||||
<GIC_SPI 794 IRQ_TYPE_EDGE_RISING>,
|
||||
<GIC_SPI 795 IRQ_TYPE_EDGE_RISING>,
|
||||
<GIC_SPI 796 IRQ_TYPE_EDGE_RISING>,
|
||||
<GIC_SPI 797 IRQ_TYPE_EDGE_RISING>,
|
||||
<GIC_SPI 798 IRQ_TYPE_EDGE_RISING>,
|
||||
<GIC_SPI 799 IRQ_TYPE_EDGE_RISING>;
|
||||
qcom,rproc = <&remoteproc_wpss>;
|
||||
memory-region = <&wlan_fw_mem>, <&wlan_ce_mem>;
|
||||
wifi-firmware {
|
||||
iommus = <&apps_smmu 0x1c02 0x1>;
|
||||
};
|
||||
};
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
%YAML 1.2
|
||||
---
|
||||
|
||||
$id: http://devicetree.org/schemas/staging/net/wireless/silabs,wfx.yaml#
|
||||
$id: http://devicetree.org/schemas/net/wireless/silabs,wfx.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Silicon Labs WFxxx devicetree bindings
|
|
@ -283,6 +283,8 @@ patternProperties:
|
|||
description: Shenzen Chuangsiqi Technology Co.,Ltd.
|
||||
"^ctera,.*":
|
||||
description: CTERA Networks Intl.
|
||||
"^ctu,.*":
|
||||
description: Czech Technical University in Prague
|
||||
"^cubietech,.*":
|
||||
description: Cubietech, Ltd.
|
||||
"^cui,.*":
|
||||
|
|
|
@ -9,7 +9,6 @@ Contents:
|
|||
:maxdepth: 2
|
||||
|
||||
cops
|
||||
ltpc
|
||||
|
||||
.. only:: subproject and html
|
||||
|
||||
|
|
|
@ -1,144 +0,0 @@
|
|||
.. SPDX-License-Identifier: GPL-2.0
|
||||
|
||||
===========
|
||||
LTPC Driver
|
||||
===========
|
||||
|
||||
This is the ALPHA version of the ltpc driver.
|
||||
|
||||
In order to use it, you will need at least version 1.3.3 of the
|
||||
netatalk package, and the Apple or Farallon LocalTalk PC card.
|
||||
There are a number of different LocalTalk cards for the PC; this
|
||||
driver applies only to the one with the 65c02 processor chip on it.
|
||||
|
||||
To include it in the kernel, select the CONFIG_LTPC switch in the
|
||||
configuration dialog. You can also compile it as a module.
|
||||
|
||||
While the driver will attempt to autoprobe the I/O port address, IRQ
|
||||
line, and DMA channel of the card, this does not always work. For
|
||||
this reason, you should be prepared to supply these parameters
|
||||
yourself. (see "Card Configuration" below for how to determine or
|
||||
change the settings on your card)
|
||||
|
||||
When the driver is compiled into the kernel, you can add a line such
|
||||
as the following to your /etc/lilo.conf::
|
||||
|
||||
append="ltpc=0x240,9,1"
|
||||
|
||||
where the parameters (in order) are the port address, IRQ, and DMA
|
||||
channel. The second and third values can be omitted, in which case
|
||||
the driver will try to determine them itself.
|
||||
|
||||
If you load the driver as a module, you can pass the parameters "io=",
|
||||
"irq=", and "dma=" on the command line with insmod or modprobe, or add
|
||||
them as options in a configuration file in /etc/modprobe.d/ directory::
|
||||
|
||||
alias lt0 ltpc # autoload the module when the interface is configured
|
||||
options ltpc io=0x240 irq=9 dma=1
|
||||
|
||||
Before starting up the netatalk demons (perhaps in rc.local), you
|
||||
need to add a line such as::
|
||||
|
||||
/sbin/ifconfig lt0 127.0.0.42
|
||||
|
||||
The address is unimportant - however, the card needs to be configured
|
||||
with ifconfig so that Netatalk can find it.
|
||||
|
||||
The appropriate netatalk configuration depends on whether you are
|
||||
attached to a network that includes AppleTalk routers or not. If,
|
||||
like me, you are simply connecting to your home Macintoshes and
|
||||
printers, you need to set up netatalk to "seed". The way I do this
|
||||
is to have the lines::
|
||||
|
||||
dummy -seed -phase 2 -net 2000 -addr 2000.26 -zone "1033"
|
||||
lt0 -seed -phase 1 -net 1033 -addr 1033.27 -zone "1033"
|
||||
|
||||
in my atalkd.conf. What is going on here is that I need to fool
|
||||
netatalk into thinking that there are two AppleTalk interfaces
|
||||
present; otherwise, it refuses to seed. This is a hack, and a more
|
||||
permanent solution would be to alter the netatalk code. Also, make
|
||||
sure you have the correct name for the dummy interface - If it's
|
||||
compiled as a module, you will need to refer to it as "dummy0" or some
|
||||
such.
|
||||
|
||||
If you are attached to an extended AppleTalk network, with routers on
|
||||
it, then you don't need to fool around with this -- the appropriate
|
||||
line in atalkd.conf is::
|
||||
|
||||
lt0 -phase 1
|
||||
|
||||
|
||||
Card Configuration
|
||||
==================
|
||||
|
||||
The interrupts and so forth are configured via the dipswitch on the
|
||||
board. Set the switches so as not to conflict with other hardware.
|
||||
|
||||
Interrupts -- set at most one. If none are set, the driver uses
|
||||
polled mode. Because the card was developed in the XT era, the
|
||||
original documentation refers to IRQ2. Since you'll be running
|
||||
this on an AT (or later) class machine, that really means IRQ9.
|
||||
|
||||
=== ===========================================================
|
||||
SW1 IRQ 4
|
||||
SW2 IRQ 3
|
||||
SW3 IRQ 9 (2 in original card documentation only applies to XT)
|
||||
=== ===========================================================
|
||||
|
||||
|
||||
DMA -- choose DMA 1 or 3, and set both corresponding switches.
|
||||
|
||||
=== =====
|
||||
SW4 DMA 3
|
||||
SW5 DMA 1
|
||||
SW6 DMA 3
|
||||
SW7 DMA 1
|
||||
=== =====
|
||||
|
||||
|
||||
I/O address -- choose one.
|
||||
|
||||
=== =========
|
||||
SW8 220 / 240
|
||||
=== =========
|
||||
|
||||
|
||||
IP
|
||||
==
|
||||
|
||||
Yes, it is possible to do IP over LocalTalk. However, you can't just
|
||||
treat the LocalTalk device like an ordinary Ethernet device, even if
|
||||
that's what it looks like to Netatalk.
|
||||
|
||||
Instead, you follow the same procedure as for doing IP in EtherTalk.
|
||||
See Documentation/networking/ipddp.rst for more information about the
|
||||
kernel driver and userspace tools needed.
|
||||
|
||||
|
||||
Bugs
|
||||
====
|
||||
|
||||
IRQ autoprobing often doesn't work on a cold boot. To get around
|
||||
this, either compile the driver as a module, or pass the parameters
|
||||
for the card to the kernel as described above.
|
||||
|
||||
Also, as usual, autoprobing is not recommended when you use the driver
|
||||
as a module. (though it usually works at boot time, at least)
|
||||
|
||||
Polled mode is *really* slow sometimes, but this seems to depend on
|
||||
the configuration of the network.
|
||||
|
||||
It may theoretically be possible to use two LTPC cards in the same
|
||||
machine, but this is unsupported, so if you really want to do this,
|
||||
you'll probably have to hack the initialization code a bit.
|
||||
|
||||
|
||||
Thanks
|
||||
======
|
||||
|
||||
Thanks to Alan Cox for helpful discussions early on in this
|
||||
work, and to Denis Hainsworth for doing the bleeding-edge testing.
|
||||
|
||||
Bradford Johnson <bradford@math.umn.edu>
|
||||
|
||||
Updated 11/09/1998 by David Huggins-Daines <dhd@debian.org>
|
|
@ -0,0 +1,639 @@
|
|||
.. SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
CTU CAN FD Driver
|
||||
=================
|
||||
|
||||
Author: Martin Jerabek <martin.jerabek01@gmail.com>
|
||||
|
||||
|
||||
About CTU CAN FD IP Core
|
||||
------------------------
|
||||
|
||||
`CTU CAN FD <https://gitlab.fel.cvut.cz/canbus/ctucanfd_ip_core>`_
|
||||
is an open source soft core written in VHDL.
|
||||
It originated in 2015 as Ondrej Ille's project
|
||||
at the `Department of Measurement <https://meas.fel.cvut.cz/>`_
|
||||
of `FEE <http://www.fel.cvut.cz/en/>`_ at `CTU <https://www.cvut.cz/en>`_.
|
||||
|
||||
The SocketCAN driver for Xilinx Zynq SoC based MicroZed board
|
||||
`Vivado integration <https://gitlab.fel.cvut.cz/canbus/zynq/zynq-can-sja1000-top>`_
|
||||
and Intel Cyclone V 5CSEMA4U23C6 based DE0-Nano-SoC Terasic board
|
||||
`QSys integration <https://gitlab.fel.cvut.cz/canbus/intel-soc-ctucanfd>`_
|
||||
has been developed as well as support for
|
||||
`PCIe integration <https://gitlab.fel.cvut.cz/canbus/pcie-ctucanfd>`_ of the core.
|
||||
|
||||
In the case of Zynq, the core is connected via the APB system bus, which does
|
||||
not have enumeration support, and the device must be specified in Device Tree.
|
||||
This kind of devices is called platform device in the kernel and is
|
||||
handled by a platform device driver.
|
||||
|
||||
The basic functional model of the CTU CAN FD peripheral has been
|
||||
accepted into QEMU mainline. See QEMU `CAN emulation support <https://www.qemu.org/docs/master/system/devices/can.html>`_
|
||||
for CAN FD buses, host connection and CTU CAN FD core emulation. The development
|
||||
version of emulation support can be cloned from ctu-canfd branch of QEMU local
|
||||
development `repository <https://gitlab.fel.cvut.cz/canbus/qemu-canbus>`_.
|
||||
|
||||
|
||||
About SocketCAN
|
||||
---------------
|
||||
|
||||
SocketCAN is a standard common interface for CAN devices in the Linux
|
||||
kernel. As the name suggests, the bus is accessed via sockets, similarly
|
||||
to common network devices. The reasoning behind this is in depth
|
||||
described in `Linux SocketCAN <https://www.kernel.org/doc/html/latest/networking/can.html>`_.
|
||||
In short, it offers a
|
||||
natural way to implement and work with higher layer protocols over CAN,
|
||||
in the same way as, e.g., UDP/IP over Ethernet.
|
||||
|
||||
Device probe
|
||||
~~~~~~~~~~~~
|
||||
|
||||
Before going into detail about the structure of a CAN bus device driver,
|
||||
let's reiterate how the kernel gets to know about the device at all.
|
||||
Some buses, like PCI or PCIe, support device enumeration. That is, when
|
||||
the system boots, it discovers all the devices on the bus and reads
|
||||
their configuration. The kernel identifies the device via its vendor ID
|
||||
and device ID, and if there is a driver registered for this identifier
|
||||
combination, its probe method is invoked to populate the driver's
|
||||
instance for the given hardware. A similar situation goes with USB, only
|
||||
it allows for device hot-plug.
|
||||
|
||||
The situation is different for peripherals which are directly embedded
|
||||
in the SoC and connected to an internal system bus (AXI, APB, Avalon,
|
||||
and others). These buses do not support enumeration, and thus the kernel
|
||||
has to learn about the devices from elsewhere. This is exactly what the
|
||||
Device Tree was made for.
|
||||
|
||||
Device tree
|
||||
~~~~~~~~~~~
|
||||
|
||||
An entry in device tree states that a device exists in the system, how
|
||||
it is reachable (on which bus it resides) and its configuration –
|
||||
registers address, interrupts and so on. An example of such a device
|
||||
tree is given in .
|
||||
|
||||
::
|
||||
|
||||
/ {
|
||||
/* ... */
|
||||
amba: amba {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
compatible = "simple-bus";
|
||||
|
||||
CTU_CAN_FD_0: CTU_CAN_FD@43c30000 {
|
||||
compatible = "ctu,ctucanfd";
|
||||
interrupt-parent = <&intc>;
|
||||
interrupts = <0 30 4>;
|
||||
clocks = <&clkc 15>;
|
||||
reg = <0x43c30000 0x10000>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
.. _sec:socketcan:drv:
|
||||
|
||||
Driver structure
|
||||
~~~~~~~~~~~~~~~~
|
||||
|
||||
The driver can be divided into two parts – platform-dependent device
|
||||
discovery and set up, and platform-independent CAN network device
|
||||
implementation.
|
||||
|
||||
.. _sec:socketcan:platdev:
|
||||
|
||||
Platform device driver
|
||||
^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
In the case of Zynq, the core is connected via the AXI system bus, which
|
||||
does not have enumeration support, and the device must be specified in
|
||||
Device Tree. This kind of devices is called *platform device* in the
|
||||
kernel and is handled by a *platform device driver*\ [1]_.
|
||||
|
||||
A platform device driver provides the following things:
|
||||
|
||||
- A *probe* function
|
||||
|
||||
- A *remove* function
|
||||
|
||||
- A table of *compatible* devices that the driver can handle
|
||||
|
||||
The *probe* function is called exactly once when the device appears (or
|
||||
the driver is loaded, whichever happens later). If there are more
|
||||
devices handled by the same driver, the *probe* function is called for
|
||||
each one of them. Its role is to allocate and initialize resources
|
||||
required for handling the device, as well as set up low-level functions
|
||||
for the platform-independent layer, e.g., *read_reg* and *write_reg*.
|
||||
After that, the driver registers the device to a higher layer, in our
|
||||
case as a *network device*.
|
||||
|
||||
The *remove* function is called when the device disappears, or the
|
||||
driver is about to be unloaded. It serves to free the resources
|
||||
allocated in *probe* and to unregister the device from higher layers.
|
||||
|
||||
Finally, the table of *compatible* devices states which devices the
|
||||
driver can handle. The Device Tree entry ``compatible`` is matched
|
||||
against the tables of all *platform drivers*.
|
||||
|
||||
.. code:: c
|
||||
|
||||
/* Match table for OF platform binding */
|
||||
static const struct of_device_id ctucan_of_match[] = {
|
||||
{ .compatible = "ctu,canfd-2", },
|
||||
{ .compatible = "ctu,ctucanfd", },
|
||||
{ /* end of list */ },
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, ctucan_of_match);
|
||||
|
||||
static int ctucan_probe(struct platform_device *pdev);
|
||||
static int ctucan_remove(struct platform_device *pdev);
|
||||
|
||||
static struct platform_driver ctucanfd_driver = {
|
||||
.probe = ctucan_probe,
|
||||
.remove = ctucan_remove,
|
||||
.driver = {
|
||||
.name = DRIVER_NAME,
|
||||
.of_match_table = ctucan_of_match,
|
||||
},
|
||||
};
|
||||
module_platform_driver(ctucanfd_driver);
|
||||
|
||||
|
||||
.. _sec:socketcan:netdev:
|
||||
|
||||
Network device driver
|
||||
^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Each network device must support at least these operations:
|
||||
|
||||
- Bring the device up: ``ndo_open``
|
||||
|
||||
- Bring the device down: ``ndo_close``
|
||||
|
||||
- Submit TX frames to the device: ``ndo_start_xmit``
|
||||
|
||||
- Signal TX completion and errors to the network subsystem: ISR
|
||||
|
||||
- Submit RX frames to the network subsystem: ISR and NAPI
|
||||
|
||||
There are two possible event sources: the device and the network
|
||||
subsystem. Device events are usually signaled via an interrupt, handled
|
||||
in an Interrupt Service Routine (ISR). Handlers for the events
|
||||
originating in the network subsystem are then specified in
|
||||
``struct net_device_ops``.
|
||||
|
||||
When the device is brought up, e.g., by calling ``ip link set can0 up``,
|
||||
the driver’s function ``ndo_open`` is called. It should validate the
|
||||
interface configuration and configure and enable the device. The
|
||||
analogous opposite is ``ndo_close``, called when the device is being
|
||||
brought down, be it explicitly or implicitly.
|
||||
|
||||
When the system should transmit a frame, it does so by calling
|
||||
``ndo_start_xmit``, which enqueues the frame into the device. If the
|
||||
device HW queue (FIFO, mailboxes or whatever the implementation is)
|
||||
becomes full, the ``ndo_start_xmit`` implementation informs the network
|
||||
subsystem that it should stop the TX queue (via ``netif_stop_queue``).
|
||||
It is then re-enabled later in ISR when the device has some space
|
||||
available again and is able to enqueue another frame.
|
||||
|
||||
All the device events are handled in ISR, namely:
|
||||
|
||||
#. **TX completion**. When the device successfully finishes transmitting
|
||||
a frame, the frame is echoed locally. On error, an informative error
|
||||
frame [2]_ is sent to the network subsystem instead. In both cases,
|
||||
the software TX queue is resumed so that more frames may be sent.
|
||||
|
||||
#. **Error condition**. If something goes wrong (e.g., the device goes
|
||||
bus-off or RX overrun happens), error counters are updated, and
|
||||
informative error frames are enqueued to SW RX queue.
|
||||
|
||||
#. **RX buffer not empty**. In this case, read the RX frames and enqueue
|
||||
them to SW RX queue. Usually NAPI is used as a middle layer (see ).
|
||||
|
||||
.. _sec:socketcan:napi:
|
||||
|
||||
NAPI
|
||||
~~~~
|
||||
|
||||
The frequency of incoming frames can be high and the overhead to invoke
|
||||
the interrupt service routine for each frame can cause significant
|
||||
system load. There are multiple mechanisms in the Linux kernel to deal
|
||||
with this situation. They evolved over the years of Linux kernel
|
||||
development and enhancements. For network devices, the current standard
|
||||
is NAPI – *the New API*. It is similar to classical top-half/bottom-half
|
||||
interrupt handling in that it only acknowledges the interrupt in the ISR
|
||||
and signals that the rest of the processing should be done in softirq
|
||||
context. On top of that, it offers the possibility to *poll* for new
|
||||
frames for a while. This has a potential to avoid the costly round of
|
||||
enabling interrupts, handling an incoming IRQ in ISR, re-enabling the
|
||||
softirq and switching context back to softirq.
|
||||
|
||||
More detailed documentation of NAPI may be found on the pages of Linux
|
||||
Foundation `<https://wiki.linuxfoundation.org/networking/napi>`_.
|
||||
|
||||
Integrating the core to Xilinx Zynq
|
||||
-----------------------------------
|
||||
|
||||
The core interfaces a simple subset of the Avalon
|
||||
(search for Intel **Avalon Interface Specifications**)
|
||||
bus as it was originally used on
|
||||
Alterra FPGA chips, yet Xilinx natively interfaces with AXI
|
||||
(search for ARM **AMBA AXI and ACE Protocol Specification AXI3,
|
||||
AXI4, and AXI4-Lite, ACE and ACE-Lite**).
|
||||
The most obvious solution would be to use
|
||||
an Avalon/AXI bridge or implement some simple conversion entity.
|
||||
However, the core’s interface is half-duplex with no handshake
|
||||
signaling, whereas AXI is full duplex with two-way signaling. Moreover,
|
||||
even AXI-Lite slave interface is quite resource-intensive, and the
|
||||
flexibility and speed of AXI are not required for a CAN core.
|
||||
|
||||
Thus a much simpler bus was chosen – APB (Advanced Peripheral Bus)
|
||||
(search for ARM **AMBA APB Protocol Specification**).
|
||||
APB-AXI bridge is directly available in
|
||||
Xilinx Vivado, and the interface adaptor entity is just a few simple
|
||||
combinatorial assignments.
|
||||
|
||||
Finally, to be able to include the core in a block diagram as a custom
|
||||
IP, the core, together with the APB interface, has been packaged as a
|
||||
Vivado component.
|
||||
|
||||
CTU CAN FD Driver design
|
||||
------------------------
|
||||
|
||||
The general structure of a CAN device driver has already been examined
|
||||
in . The next paragraphs provide a more detailed description of the CTU
|
||||
CAN FD core driver in particular.
|
||||
|
||||
Low-level driver
|
||||
~~~~~~~~~~~~~~~~
|
||||
|
||||
The core is not intended to be used solely with SocketCAN, and thus it
|
||||
is desirable to have an OS-independent low-level driver. This low-level
|
||||
driver can then be used in implementations of OS driver or directly
|
||||
either on bare metal or in a user-space application. Another advantage
|
||||
is that if the hardware slightly changes, only the low-level driver
|
||||
needs to be modified.
|
||||
|
||||
The code [3]_ is in part automatically generated and in part written
|
||||
manually by the core author, with contributions of the thesis’ author.
|
||||
The low-level driver supports operations such as: set bit timing, set
|
||||
controller mode, enable/disable, read RX frame, write TX frame, and so
|
||||
on.
|
||||
|
||||
Configuring bit timing
|
||||
~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
On CAN, each bit is divided into four segments: SYNC, PROP, PHASE1, and
|
||||
PHASE2. Their duration is expressed in multiples of a Time Quantum
|
||||
(details in `CAN Specification, Version 2.0 <http://esd.cs.ucr.edu/webres/can20.pdf>`_, chapter 8).
|
||||
When configuring
|
||||
bitrate, the durations of all the segments (and time quantum) must be
|
||||
computed from the bitrate and Sample Point. This is performed
|
||||
independently for both the Nominal bitrate and Data bitrate for CAN FD.
|
||||
|
||||
SocketCAN is fairly flexible and offers either highly customized
|
||||
configuration by setting all the segment durations manually, or a
|
||||
convenient configuration by setting just the bitrate and sample point
|
||||
(and even that is chosen automatically per Bosch recommendation if not
|
||||
specified). However, each CAN controller may have different base clock
|
||||
frequency and different width of segment duration registers. The
|
||||
algorithm thus needs the minimum and maximum values for the durations
|
||||
(and clock prescaler) and tries to optimize the numbers to fit both the
|
||||
constraints and the requested parameters.
|
||||
|
||||
.. code:: c
|
||||
|
||||
struct can_bittiming_const {
|
||||
char name[16]; /* Name of the CAN controller hardware */
|
||||
__u32 tseg1_min; /* Time segment 1 = prop_seg + phase_seg1 */
|
||||
__u32 tseg1_max;
|
||||
__u32 tseg2_min; /* Time segment 2 = phase_seg2 */
|
||||
__u32 tseg2_max;
|
||||
__u32 sjw_max; /* Synchronisation jump width */
|
||||
__u32 brp_min; /* Bit-rate prescaler */
|
||||
__u32 brp_max;
|
||||
__u32 brp_inc;
|
||||
};
|
||||
|
||||
|
||||
[lst:can_bittiming_const]
|
||||
|
||||
A curious reader will notice that the durations of the segments PROP_SEG
|
||||
and PHASE_SEG1 are not determined separately but rather combined and
|
||||
then, by default, the resulting TSEG1 is evenly divided between PROP_SEG
|
||||
and PHASE_SEG1. In practice, this has virtually no consequences as the
|
||||
sample point is between PHASE_SEG1 and PHASE_SEG2. In CTU CAN FD,
|
||||
however, the duration registers ``PROP`` and ``PH1`` have different
|
||||
widths (6 and 7 bits, respectively), so the auto-computed values might
|
||||
overflow the shorter register and must thus be redistributed among the
|
||||
two [4]_.
|
||||
|
||||
Handling RX
|
||||
~~~~~~~~~~~
|
||||
|
||||
Frame reception is handled in NAPI queue, which is enabled from ISR when
|
||||
the RXNE (RX FIFO Not Empty) bit is set. Frames are read one by one
|
||||
until either no frame is left in the RX FIFO or the maximum work quota
|
||||
has been reached for the NAPI poll run (see ). Each frame is then passed
|
||||
to the network interface RX queue.
|
||||
|
||||
An incoming frame may be either a CAN 2.0 frame or a CAN FD frame. The
|
||||
way to distinguish between these two in the kernel is to allocate either
|
||||
``struct can_frame`` or ``struct canfd_frame``, the two having different
|
||||
sizes. In the controller, the information about the frame type is stored
|
||||
in the first word of RX FIFO.
|
||||
|
||||
This brings us a chicken-egg problem: we want to allocate the ``skb``
|
||||
for the frame, and only if it succeeds, fetch the frame from FIFO;
|
||||
otherwise keep it there for later. But to be able to allocate the
|
||||
correct ``skb``, we have to fetch the first work of FIFO. There are
|
||||
several possible solutions:
|
||||
|
||||
#. Read the word, then allocate. If it fails, discard the rest of the
|
||||
frame. When the system is low on memory, the situation is bad anyway.
|
||||
|
||||
#. Always allocate ``skb`` big enough for an FD frame beforehand. Then
|
||||
tweak the ``skb`` internals to look like it has been allocated for
|
||||
the smaller CAN 2.0 frame.
|
||||
|
||||
#. Add option to peek into the FIFO instead of consuming the word.
|
||||
|
||||
#. If the allocation fails, store the read word into driver’s data. On
|
||||
the next try, use the stored word instead of reading it again.
|
||||
|
||||
Option 1 is simple enough, but not very satisfying if we could do
|
||||
better. Option 2 is not acceptable, as it would require modifying the
|
||||
private state of an integral kernel structure. The slightly higher
|
||||
memory consumption is just a virtual cherry on top of the “cake”. Option
|
||||
3 requires non-trivial HW changes and is not ideal from the HW point of
|
||||
view.
|
||||
|
||||
Option 4 seems like a good compromise, with its disadvantage being that
|
||||
a partial frame may stay in the FIFO for a prolonged time. Nonetheless,
|
||||
there may be just one owner of the RX FIFO, and thus no one else should
|
||||
see the partial frame (disregarding some exotic debugging scenarios).
|
||||
Basides, the driver resets the core on its initialization, so the
|
||||
partial frame cannot be “adopted” either. In the end, option 4 was
|
||||
selected [5]_.
|
||||
|
||||
.. _subsec:ctucanfd:rxtimestamp:
|
||||
|
||||
Timestamping RX frames
|
||||
^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
The CTU CAN FD core reports the exact timestamp when the frame has been
|
||||
received. The timestamp is by default captured at the sample point of
|
||||
the last bit of EOF but is configurable to be captured at the SOF bit.
|
||||
The timestamp source is external to the core and may be up to 64 bits
|
||||
wide. At the time of writing, passing the timestamp from kernel to
|
||||
userspace is not yet implemented, but is planned in the future.
|
||||
|
||||
Handling TX
|
||||
~~~~~~~~~~~
|
||||
|
||||
The CTU CAN FD core has 4 independent TX buffers, each with its own
|
||||
state and priority. When the core wants to transmit, a TX buffer in
|
||||
Ready state with the highest priority is selected.
|
||||
|
||||
The priorities are 3bit numbers in register TX_PRIORITY
|
||||
(nibble-aligned). This should be flexible enough for most use cases.
|
||||
SocketCAN, however, supports only one FIFO queue for outgoing
|
||||
frames [6]_. The buffer priorities may be used to simulate the FIFO
|
||||
behavior by assigning each buffer a distinct priority and *rotating* the
|
||||
priorities after a frame transmission is completed.
|
||||
|
||||
In addition to priority rotation, the SW must maintain head and tail
|
||||
pointers into the FIFO formed by the TX buffers to be able to determine
|
||||
which buffer should be used for next frame (``txb_head``) and which
|
||||
should be the first completed one (``txb_tail``). The actual buffer
|
||||
indices are (obviously) modulo 4 (number of TX buffers), but the
|
||||
pointers must be at least one bit wider to be able to distinguish
|
||||
between FIFO full and FIFO empty – in this situation,
|
||||
:math:`txb\_head \equiv txb\_tail\ (\textrm{mod}\ 4)`. An example of how
|
||||
the FIFO is maintained, together with priority rotation, is depicted in
|
||||
|
||||
|
|
||||
|
||||
+------+---+---+---+---+
|
||||
| TXB# | 0 | 1 | 2 | 3 |
|
||||
+======+===+===+===+===+
|
||||
| Seq | A | B | C | |
|
||||
+------+---+---+---+---+
|
||||
| Prio | 7 | 6 | 5 | 4 |
|
||||
+------+---+---+---+---+
|
||||
| | | T | | H |
|
||||
+------+---+---+---+---+
|
||||
|
||||
|
|
||||
|
||||
+------+---+---+---+---+
|
||||
| TXB# | 0 | 1 | 2 | 3 |
|
||||
+======+===+===+===+===+
|
||||
| Seq | | B | C | |
|
||||
+------+---+---+---+---+
|
||||
| Prio | 4 | 7 | 6 | 5 |
|
||||
+------+---+---+---+---+
|
||||
| | | T | | H |
|
||||
+------+---+---+---+---+
|
||||
|
||||
|
|
||||
|
||||
+------+---+---+---+---+----+
|
||||
| TXB# | 0 | 1 | 2 | 3 | 0’ |
|
||||
+======+===+===+===+===+====+
|
||||
| Seq | E | B | C | D | |
|
||||
+------+---+---+---+---+----+
|
||||
| Prio | 4 | 7 | 6 | 5 | |
|
||||
+------+---+---+---+---+----+
|
||||
| | | T | | | H |
|
||||
+------+---+---+---+---+----+
|
||||
|
||||
|
|
||||
|
||||
.. kernel-figure:: fsm_txt_buffer_user.svg
|
||||
|
||||
TX Buffer states with possible transitions
|
||||
|
||||
.. _subsec:ctucanfd:txtimestamp:
|
||||
|
||||
Timestamping TX frames
|
||||
^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
When submitting a frame to a TX buffer, one may specify the timestamp at
|
||||
which the frame should be transmitted. The frame transmission may start
|
||||
later, but not sooner. Note that the timestamp does not participate in
|
||||
buffer prioritization – that is decided solely by the mechanism
|
||||
described above.
|
||||
|
||||
Support for time-based packet transmission was recently merged to Linux
|
||||
v4.19 `Time-based packet transmission <https://lwn.net/Articles/748879/>`_,
|
||||
but it remains yet to be researched
|
||||
whether this functionality will be practical for CAN.
|
||||
|
||||
Also similarly to retrieving the timestamp of RX frames, the core
|
||||
supports retrieving the timestamp of TX frames – that is the time when
|
||||
the frame was successfully delivered. The particulars are very similar
|
||||
to timestamping RX frames and are described in .
|
||||
|
||||
Handling RX buffer overrun
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
When a received frame does no more fit into the hardware RX FIFO in its
|
||||
entirety, RX FIFO overrun flag (STATUS[DOR]) is set and Data Overrun
|
||||
Interrupt (DOI) is triggered. When servicing the interrupt, care must be
|
||||
taken first to clear the DOR flag (via COMMAND[CDO]) and after that
|
||||
clear the DOI interrupt flag. Otherwise, the interrupt would be
|
||||
immediately [7]_ rearmed.
|
||||
|
||||
**Note**: During development, it was discussed whether the internal HW
|
||||
pipelining cannot disrupt this clear sequence and whether an additional
|
||||
dummy cycle is necessary between clearing the flag and the interrupt. On
|
||||
the Avalon interface, it indeed proved to be the case, but APB being
|
||||
safe because it uses 2-cycle transactions. Essentially, the DOR flag
|
||||
would be cleared, but DOI register’s Preset input would still be high
|
||||
the cycle when the DOI clear request would also be applied (by setting
|
||||
the register’s Reset input high). As Set had higher priority than Reset,
|
||||
the DOI flag would not be reset. This has been already fixed by swapping
|
||||
the Set/Reset priority (see issue #187).
|
||||
|
||||
Reporting Error Passive and Bus Off conditions
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
It may be desirable to report when the node reaches *Error Passive*,
|
||||
*Error Warning*, and *Bus Off* conditions. The driver is notified about
|
||||
error state change by an interrupt (EPI, EWLI), and then proceeds to
|
||||
determine the core’s error state by reading its error counters.
|
||||
|
||||
There is, however, a slight race condition here – there is a delay
|
||||
between the time when the state transition occurs (and the interrupt is
|
||||
triggered) and when the error counters are read. When EPI is received,
|
||||
the node may be either *Error Passive* or *Bus Off*. If the node goes
|
||||
*Bus Off*, it obviously remains in the state until it is reset.
|
||||
Otherwise, the node is *or was* *Error Passive*. However, it may happen
|
||||
that the read state is *Error Warning* or even *Error Active*. It may be
|
||||
unclear whether and what exactly to report in that case, but I
|
||||
personally entertain the idea that the past error condition should still
|
||||
be reported. Similarly, when EWLI is received but the state is later
|
||||
detected to be *Error Passive*, *Error Passive* should be reported.
|
||||
|
||||
|
||||
CTU CAN FD Driver Sources Reference
|
||||
-----------------------------------
|
||||
|
||||
.. kernel-doc:: drivers/net/can/ctucanfd/ctucanfd.h
|
||||
:internal:
|
||||
|
||||
.. kernel-doc:: drivers/net/can/ctucanfd/ctucanfd_base.c
|
||||
:internal:
|
||||
|
||||
.. kernel-doc:: drivers/net/can/ctucanfd/ctucanfd_pci.c
|
||||
:internal:
|
||||
|
||||
.. kernel-doc:: drivers/net/can/ctucanfd/ctucanfd_platform.c
|
||||
:internal:
|
||||
|
||||
CTU CAN FD IP Core and Driver Development Acknowledgment
|
||||
---------------------------------------------------------
|
||||
|
||||
* Odrej Ille <ondrej.ille@gmail.com>
|
||||
|
||||
* started the project as student at Department of Measurement, FEE, CTU
|
||||
* invested great amount of personal time and enthusiasm to the project over years
|
||||
* worked on more funded tasks
|
||||
|
||||
* `Department of Measurement <https://meas.fel.cvut.cz/>`_,
|
||||
`Faculty of Electrical Engineering <http://www.fel.cvut.cz/en/>`_,
|
||||
`Czech Technical University <https://www.cvut.cz/en>`_
|
||||
|
||||
* is the main investor into the project over many years
|
||||
* uses project in their CAN/CAN FD diagnostics framework for `Skoda Auto <https://www.skoda-auto.cz/>`_
|
||||
|
||||
* `Digiteq Automotive <https://www.digiteqautomotive.com/en>`_
|
||||
|
||||
* funding of the project CAN FD Open Cores Support Linux Kernel Based Systems
|
||||
* negotiated and paid CTU to allow public access to the project
|
||||
* provided additional funding of the work
|
||||
|
||||
* `Department of Control Engineering <https://control.fel.cvut.cz/en>`_,
|
||||
`Faculty of Electrical Engineering <http://www.fel.cvut.cz/en/>`_,
|
||||
`Czech Technical University <https://www.cvut.cz/en>`_
|
||||
|
||||
* solving the project CAN FD Open Cores Support Linux Kernel Based Systems
|
||||
* providing GitLab management
|
||||
* virtual servers and computational power for continuous integration
|
||||
* providing hardware for HIL continuous integration tests
|
||||
|
||||
* `PiKRON Ltd. <http://pikron.com/>`_
|
||||
|
||||
* minor funding to initiate preparation of the project open-sourcing
|
||||
|
||||
* Petr Porazil <porazil@pikron.com>
|
||||
|
||||
* design of PCIe transceiver addon board and assembly of boards
|
||||
* design and assembly of MZ_APO baseboard for MicroZed/Zynq based system
|
||||
|
||||
* Martin Jerabek <martin.jerabek01@gmail.com>
|
||||
|
||||
* Linux driver development
|
||||
* continuous integration platform architect and GHDL updates
|
||||
* theses `Open-source and Open-hardware CAN FD Protocol Support <https://dspace.cvut.cz/bitstream/handle/10467/80366/F3-DP-2019-Jerabek-Martin-Jerabek-thesis-2019-canfd.pdf>`_
|
||||
|
||||
* Jiri Novak <jnovak@fel.cvut.cz>
|
||||
|
||||
* project initiation, management and use at Department of Measurement, FEE, CTU
|
||||
|
||||
* Pavel Pisa <pisa@cmp.felk.cvut.cz>
|
||||
|
||||
* initiate open-sourcing, project coordination, management at Department of Control Engineering, FEE, CTU
|
||||
|
||||
* Jaroslav Beran<jara.beran@gmail.com>
|
||||
|
||||
* system integration for Intel SoC, core and driver testing and updates
|
||||
|
||||
* Carsten Emde (`OSADL <https://www.osadl.org/>`_)
|
||||
|
||||
* provided OSADL expertise to discuss IP core licensing
|
||||
* pointed to possible deadlock for LGPL and CAN bus possible patent case which lead to relicense IP core design to BSD like license
|
||||
|
||||
* Reiner Zitzmann and Holger Zeltwanger (`CAN in Automation <https://www.can-cia.org/>`_)
|
||||
|
||||
* provided suggestions and help to inform community about the project and invited us to events focused on CAN bus future development directions
|
||||
|
||||
* Jan Charvat
|
||||
|
||||
* implemented CTU CAN FD functional model for QEMU which has been integrated into QEMU mainline (`docs/system/devices/can.rst <https://www.qemu.org/docs/master/system/devices/can.html>`_)
|
||||
* Bachelor theses Model of CAN FD Communication Controller for QEMU Emulator
|
||||
|
||||
Notes
|
||||
-----
|
||||
|
||||
|
||||
.. [1]
|
||||
Other buses have their own specific driver interface to set up the
|
||||
device.
|
||||
|
||||
.. [2]
|
||||
Not to be mistaken with CAN Error Frame. This is a ``can_frame`` with
|
||||
``CAN_ERR_FLAG`` set and some error info in its ``data`` field.
|
||||
|
||||
.. [3]
|
||||
Available in CTU CAN FD repository
|
||||
`<https://gitlab.fel.cvut.cz/canbus/ctucanfd_ip_core>`_
|
||||
|
||||
.. [4]
|
||||
As is done in the low-level driver functions
|
||||
``ctucan_hw_set_nom_bittiming`` and
|
||||
``ctucan_hw_set_data_bittiming``.
|
||||
|
||||
.. [5]
|
||||
At the time of writing this thesis, option 1 is still being used and
|
||||
the modification is queued in gitlab issue #222
|
||||
|
||||
.. [6]
|
||||
Strictly speaking, multiple CAN TX queues are supported since v4.19
|
||||
`can: enable multi-queue for SocketCAN devices <https://lore.kernel.org/patchwork/patch/913526/>`_ but no mainline driver is using
|
||||
them yet.
|
||||
|
||||
.. [7]
|
||||
Or rather in the next clock cycle
|
|
@ -0,0 +1,151 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg width="113.611mm" height="86.6873mm" version="1.1" viewBox="0 0 113.611 86.6873" xmlns="http://www.w3.org/2000/svg" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
|
||||
<defs>
|
||||
<marker id="marker3667" overflow="visible" orient="auto">
|
||||
<path transform="scale(-.6)" d="m8.71859 4.03374-10.9259-4.01772 10.9259-4.01772c-1.7455 2.37206-1.73544 5.61745-6e-7 8.03544z" fill="#28a4ff" fill-rule="evenodd" stroke="#28a4ff" stroke-linejoin="round" stroke-width=".625"/>
|
||||
</marker>
|
||||
<marker id="marker3517" overflow="visible" orient="auto">
|
||||
<path transform="scale(-.6)" d="m8.71859 4.03374-10.9259-4.01772 10.9259-4.01772c-1.7455 2.37206-1.73544 5.61745-6e-7 8.03544z" fill-rule="evenodd" stroke="#000" stroke-linejoin="round" stroke-width=".625"/>
|
||||
</marker>
|
||||
<marker id="marker3373" overflow="visible" orient="auto">
|
||||
<path transform="scale(-.6)" d="m8.71859 4.03374-10.9259-4.01772 10.9259-4.01772c-1.7455 2.37206-1.73544 5.61745-6e-7 8.03544z" fill-rule="evenodd" stroke="#000" stroke-linejoin="round" stroke-width=".625"/>
|
||||
</marker>
|
||||
<marker id="marker3199" overflow="visible" orient="auto">
|
||||
<path transform="scale(-.6)" d="m8.71859 4.03374-10.9259-4.01772 10.9259-4.01772c-1.7455 2.37206-1.73544 5.61745-6e-7 8.03544z" fill="#28a4ff" fill-rule="evenodd" stroke="#28a4ff" stroke-linejoin="round" stroke-width=".625"/>
|
||||
</marker>
|
||||
<marker id="marker3037" overflow="visible" orient="auto">
|
||||
<path transform="scale(-.6)" d="m8.71859 4.03374-10.9259-4.01772 10.9259-4.01772c-1.7455 2.37206-1.73544 5.61745-6e-7 8.03544z" fill="#28a4ff" fill-rule="evenodd" stroke="#28a4ff" stroke-linejoin="round" stroke-width=".625"/>
|
||||
</marker>
|
||||
<marker id="marker2779" overflow="visible" orient="auto">
|
||||
<path transform="scale(-.6)" d="m8.71859 4.03374-10.9259-4.01772 10.9259-4.01772c-1.7455 2.37206-1.73544 5.61745-6e-7 8.03544z" fill="#28a4ff" fill-rule="evenodd" stroke="#28a4ff" stroke-linejoin="round" stroke-width=".625"/>
|
||||
</marker>
|
||||
<marker id="marker2477" overflow="visible" orient="auto">
|
||||
<path transform="scale(.6) rotate(180) translate(0)" d="m8.71859 4.03374-10.9259-4.01772 10.9259-4.01772c-1.7455 2.37206-1.73544 5.61745-6e-7 8.03544z" fill="#28a4ff" fill-rule="evenodd" stroke="#28a4ff" stroke-linejoin="round" stroke-width=".625"/>
|
||||
</marker>
|
||||
<marker id="marker2074" overflow="visible" orient="auto">
|
||||
<path transform="scale(.6) rotate(180) translate(0)" d="m8.71859 4.03374-10.9259-4.01772 10.9259-4.01772c-1.7455 2.37206-1.73544 5.61745-6e-7 8.03544z" fill-rule="evenodd" stroke="#000" stroke-linejoin="round" stroke-width=".625"/>
|
||||
</marker>
|
||||
<marker id="marker1964" overflow="visible" orient="auto">
|
||||
<path transform="scale(.6) rotate(180) translate(0)" d="m8.71859 4.03374-10.9259-4.01772 10.9259-4.01772c-1.7455 2.37206-1.73544 5.61745-6e-7 8.03544z" fill-rule="evenodd" stroke="#000" stroke-linejoin="round" stroke-width=".625"/>
|
||||
</marker>
|
||||
<marker id="marker1856" overflow="visible" orient="auto">
|
||||
<path transform="scale(.6) rotate(180) translate(0)" d="m8.71859 4.03374-10.9259-4.01772 10.9259-4.01772c-1.7455 2.37206-1.73544 5.61745-6e-7 8.03544z" fill-rule="evenodd" stroke="#000" stroke-linejoin="round" stroke-width=".625"/>
|
||||
</marker>
|
||||
<marker id="Arrow2Mend" overflow="visible" orient="auto">
|
||||
<path transform="scale(.6) rotate(180) translate(0)" d="m8.71859 4.03374-10.9259-4.01772 10.9259-4.01772c-1.7455 2.37206-1.73544 5.61745-6e-7 8.03544z" fill-rule="evenodd" stroke="#000" stroke-linejoin="round" stroke-width=".625"/>
|
||||
</marker>
|
||||
<filter id="filter1204" x="-4.19953e-6" y="-5.60084e-6" width="1.00001" height="1.00001" color-interpolation-filters="sRGB">
|
||||
<feGaussianBlur stdDeviation="0.00018829868"/>
|
||||
</filter>
|
||||
<marker id="marker2074-3" overflow="visible" orient="auto">
|
||||
<path transform="scale(-.6)" d="m8.71859 4.03374-10.9259-4.01772 10.9259-4.01772c-1.7455 2.37206-1.73544 5.61745-6e-7 8.03544z" fill="#28a4ff" fill-rule="evenodd" stroke="#28a4ff" stroke-linejoin="round" stroke-width=".625"/>
|
||||
</marker>
|
||||
<filter id="filter1204-6" x="-4.19953e-6" y="-5.60084e-6" width="1.00001" height="1.00001" color-interpolation-filters="sRGB">
|
||||
<feGaussianBlur stdDeviation="0.00018829868"/>
|
||||
</filter>
|
||||
<filter id="filter1204-6-9" x="-4.19953e-6" y="-5.60084e-6" width="1.00001" height="1.00001" color-interpolation-filters="sRGB">
|
||||
<feGaussianBlur stdDeviation="0.00018829868"/>
|
||||
</filter>
|
||||
<filter id="filter1204-6-2" x="-4.19953e-6" y="-5.60084e-6" width="1.00001" height="1.00001" color-interpolation-filters="sRGB">
|
||||
<feGaussianBlur stdDeviation="0.00018829868"/>
|
||||
</filter>
|
||||
<filter id="filter1204-6-2-9" x="-4.19953e-6" y="-5.60084e-6" width="1.00001" height="1.00001" color-interpolation-filters="sRGB">
|
||||
<feGaussianBlur stdDeviation="0.00018829868"/>
|
||||
</filter>
|
||||
<filter id="filter1204-6-2-9-4" x="-4.19953e-6" y="-5.60084e-6" width="1.00001" height="1.00001" color-interpolation-filters="sRGB">
|
||||
<feGaussianBlur stdDeviation="0.00018829868"/>
|
||||
</filter>
|
||||
<filter id="filter1204-6-2-9-1" x="-4.19953e-6" y="-5.60084e-6" width="1.00001" height="1.00001" color-interpolation-filters="sRGB">
|
||||
<feGaussianBlur stdDeviation="0.00018829868"/>
|
||||
</filter>
|
||||
<filter id="filter1204-6-2-9-1-3" x="-4.19953e-6" y="-5.60084e-6" width="1.00001" height="1.00001" color-interpolation-filters="sRGB">
|
||||
<feGaussianBlur stdDeviation="0.00018829868"/>
|
||||
</filter>
|
||||
<filter id="filter1204-6-2-9-1-3-1" x="-4.19953e-6" y="-5.60084e-6" width="1.00001" height="1.00001" color-interpolation-filters="sRGB">
|
||||
<feGaussianBlur stdDeviation="0.00018829868"/>
|
||||
</filter>
|
||||
</defs>
|
||||
<metadata>
|
||||
<rdf:RDF>
|
||||
<cc:Work rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"/>
|
||||
<dc:title/>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g transform="translate(-49.0277 -104.823)">
|
||||
<g>
|
||||
<path d="m130.534 165.429h-71.1816v-17.5315" fill="none" marker-end="url(#marker2477)" stroke="#28a4ff" stroke-width=".6"/>
|
||||
<path d="m145.034 122.959v-11.5914h-43.1215" fill="none" marker-end="url(#marker3037)" stroke="#28a4ff" stroke-width=".6"/>
|
||||
<rect x="130.679" y="122.933" width="28.2965" height="45.2319" rx="0" ry="0" fill="#e5e5e5" stroke="#717171" stroke-linecap="square" stroke-width=".499999"/>
|
||||
<path d="m102.044 116.236h23.3126l-0.13388 18.8185h19.9383v3.66603" fill="none" marker-end="url(#marker3199)" stroke="#28a4ff" stroke-width=".6"/>
|
||||
<path d="m59.5006 138.391v-24.2517h20.6338" fill="none" marker-end="url(#marker2779)" stroke="#28a4ff" stroke-width=".6"/>
|
||||
<rect x="78.1389" y="126.411" width="28.0037" height="35.0443" rx="0" ry="0" fill="#e5e5e5" stroke="#717171" stroke-linecap="square" stroke-width=".5"/>
|
||||
</g>
|
||||
<g fill="#ffcb35" stroke="#000" stroke-linecap="square">
|
||||
<ellipse cx="92.1408" cy="114.239" rx="10.8866" ry="4.39308" stroke-width=".5"/>
|
||||
<ellipse cx="92.1408" cy="134.185" rx="10.8866" ry="4.39308" stroke-width=".499999"/>
|
||||
<ellipse cx="92.1408" cy="152.199" rx="10.8866" ry="4.39308" stroke-width=".499999"/>
|
||||
</g>
|
||||
<g fill="#28a4ff" stroke="#000" stroke-linecap="square" stroke-width=".499999">
|
||||
<ellipse cx="144.827" cy="143.316" rx="10.8866" ry="4.39308"/>
|
||||
<ellipse cx="144.827" cy="159.143" rx="10.8866" ry="4.39308"/>
|
||||
<ellipse cx="59.4364" cy="142.823" rx="7.36455" ry="4.39308"/>
|
||||
<ellipse cx="144.827" cy="129.196" rx="10.8866" ry="4.39308"/>
|
||||
<ellipse cx="143.077" cy="180.53" rx="10.8866" ry="4.39308"/>
|
||||
</g>
|
||||
<ellipse cx="110.386" cy="180.53" rx="10.8866" ry="4.39308" fill="#ffcb35" stroke="#000" stroke-linecap="square" stroke-width=".499999"/>
|
||||
<text x="110.90907" y="179.42688" font-size="3.175px" xml:space="preserve"><tspan x="110.90907" y="179.42688" dy="0.60000002" text-align="center" text-anchor="middle">Accessible</tspan><tspan x="110.90907" y="183.39563"><tspan font-size="3.175px" text-align="center" text-anchor="middle">for S</tspan>W</tspan></text>
|
||||
<text x="143.5869" y="179.52795" xml:space="preserve"><tspan x="143.5869" y="179.52795" dy="1 0 0 0 0 0" font-family="sans-serif" font-size="2.82222px" text-align="center" text-anchor="middle" style="font-variant-caps:normal;font-variant-east-asian:normal;font-variant-ligatures:normal;font-variant-numeric:normal">Inaccessible</tspan><tspan x="143.5869" y="183.36786" font-size="3.175px"><tspan font-size="3.175px" text-align="center" text-anchor="middle">for S</tspan>W</tspan></text>
|
||||
<g font-size="3.175px">
|
||||
<text x="91.95018" y="115.29005" xml:space="preserve"><tspan x="91.95018" y="115.29005" font-size="3.175px"><tspan font-size="3.175px" text-align="center" text-anchor="middle">Ready</tspan></tspan></text>
|
||||
<text x="145.25127" y="130.49019" xml:space="preserve"><tspan x="145.25127" y="130.49019" font-size="3.175px"><tspan font-size="3.175px" text-align="center" text-anchor="middle">TX OK</tspan></tspan></text>
|
||||
<text x="145.31845" y="144.43121" xml:space="preserve"><tspan x="145.31845" y="144.43121" font-size="3.175px"><tspan font-size="3.175px" text-align="center" text-anchor="middle">Aborted</tspan></tspan></text>
|
||||
<text x="145.40399" y="160.36035" xml:space="preserve"><tspan x="145.40399" y="160.36035" font-size="3.175px"><tspan font-size="3.175px" text-align="center" text-anchor="middle">TX failed</tspan></tspan></text>
|
||||
<text x="91.823967" y="133.53941" text-align="center" text-anchor="middle" style="line-height:0.9" xml:space="preserve"><tspan x="91.823967" y="133.53941" text-align="center"><tspan font-size="3.175px" text-align="center" text-anchor="middle">TX in</tspan></tspan><tspan x="91.823967" y="136.39691" text-align="center">progress</tspan></text>
|
||||
<text x="91.648918" y="151.84813" text-align="center" text-anchor="middle" style="line-height:0.9" xml:space="preserve"><tspan x="91.648918" y="151.84813" text-align="center"><tspan font-size="3.175px" text-align="center" text-anchor="middle">Abort in</tspan></tspan><tspan x="91.648918" y="154.70563" text-align="center">progress</tspan></text>
|
||||
<text x="59.456043" y="143.91658" xml:space="preserve"><tspan x="59.456043" y="143.91658" font-size="3.175px"><tspan font-size="3.175px" text-align="center" text-anchor="middle">Empty</tspan></tspan></text>
|
||||
</g>
|
||||
<g fill="none">
|
||||
<g stroke="#000">
|
||||
<rect x="52.3943" y="171.63" width="106.581" height="16.601" rx="0" ry="0" stroke-linecap="square" stroke-width=".499999"/>
|
||||
<g stroke-width=".6">
|
||||
<path d="m106.383 159.046h26.4967" marker-end="url(#Arrow2Mend)"/>
|
||||
<path d="m103.138 152.268h41.5564v-3.92426" marker-end="url(#marker1856)"/>
|
||||
<path d="m106.38 129.354h17.7785"/>
|
||||
<path d="m125.818 129.359h7.2418" marker-end="url(#marker1964)"/>
|
||||
</g>
|
||||
<path d="m124.169 129.354a0.959514 0.97091 0 0 1 0.47587-0.84557 0.959514 0.97091 0 0 1 0.96164-3e-3 0.959514 0.97091 0 0 1 0.48149 0.84231" stroke-linecap="square" stroke-width=".600001"/>
|
||||
<path d="m55.7026 180.832h34.8131" marker-end="url(#marker2074)" stroke-width=".6"/>
|
||||
</g>
|
||||
<g>
|
||||
<path d="m55.6464 185.744h34.8131" marker-end="url(#marker2074-3)" stroke="#28a4ff" stroke-width=".600001"/>
|
||||
<g stroke-width=".6">
|
||||
<path d="m94.0487 129.889v-10.6493" marker-end="url(#marker3373)" stroke="#000"/>
|
||||
<path d="m89.7534 118.621v10.662" marker-end="url(#marker3517)" stroke="#000"/>
|
||||
<path d="m92.119 138.812v7.9718" marker-end="url(#marker3667)" stroke="#28a4ff"/>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
<text transform="matrix(.264583 0 0 .264583 91.8919 139.964)" x="26.959213" y="9.11724" fill="#2aa1ff" filter="url(#filter1204-6-2-9-1-3-1)" font-size="12px" stroke-width="3.77953" text-align="center" text-anchor="middle" style="line-height:1.1" xml:space="preserve"><tspan x="26.959213" y="9.11724" text-align="center">Set</tspan><tspan x="26.959213" y="22.31724" text-align="center">abort</tspan></text>
|
||||
<text transform="translate(49.0277 104.823)" x="57.620724" y="16.855087" filter="url(#filter1204)" font-size="3.175px" text-align="center" text-anchor="middle" style="line-height:1.1" xml:space="preserve"><tspan x="57.620724" y="16.855087" text-align="center">Transmission</tspan><tspan x="57.620724" y="20.347588" text-align="center">unsuccesfull</tspan></text>
|
||||
<g font-size="12px" stroke-width="3.77953" text-anchor="middle">
|
||||
<text transform="matrix(.264583 0 0 .264583 68.5988 118.913)" x="38.824219" y="9.1171875" filter="url(#filter1204)" text-align="center" style="line-height:1.1" xml:space="preserve"><tspan x="38.824219" y="9.1171875" text-align="center">Transmission</tspan><tspan x="38.824219" y="22.317188" text-align="center">starts</tspan></text>
|
||||
<text transform="matrix(.264583 0 0 .264583 106.802 130.509)" x="38.824219" y="9.1171875" filter="url(#filter1204)" text-align="center" style="line-height:1.1" xml:space="preserve"><tspan x="38.824219" y="9.1171875" text-align="center">Transmission</tspan><tspan x="38.824219" y="22.317188" text-align="center">succesfull</tspan></text>
|
||||
<text transform="matrix(.264583 0 0 .264583 107.77 145.476)" x="38.824219" y="9.1171875" filter="url(#filter1204)" text-align="center" style="line-height:1.1" xml:space="preserve"><tspan x="38.824219" y="9.1171875" text-align="center">Transmission</tspan><tspan x="38.824219" y="22.317188" text-align="center">sborted</tspan></text>
|
||||
</g>
|
||||
<g stroke-width="3.77953" text-anchor="middle">
|
||||
<text transform="matrix(.264583 0 0 .264583 107.574 155.948)" x="38.824219" y="9.1171875" filter="url(#filter1204)" font-size="10.6667px" text-align="center" style="line-height:1.1" xml:space="preserve"><tspan x="38.824219" y="9.1171875" text-align="center">Retransmit</tspan><tspan x="38.824219" y="20.850557" text-align="center">limit reached or</tspan><tspan x="38.824219" y="32.583927" text-align="center">node went bus off</tspan><tspan x="38.824219" y="44.317299" text-align="center"/></text>
|
||||
<text transform="matrix(.264583 0 0 .264583 60.7127 177.384)" x="38.824539" y="9.1173134" filter="url(#filter1204-6)" font-size="12px" text-align="center" style="line-height:1.1" xml:space="preserve"><tspan x="38.824539" y="9.1173134" font-size="12px" stroke-width="3.77953" text-align="center" text-anchor="middle">Transmission result</tspan></text>
|
||||
<text transform="matrix(.264583 0 0 .264583 45.6885 173.226)" x="57.727047" y="9.11724" filter="url(#filter1204-6-9)" font-size="12px" text-align="center" style="line-height:1.1" xml:space="preserve"><tspan x="57.727047" y="9.11724" font-size="12px" stroke-width="3.77953" text-align="center" text-anchor="middle">Legend:</tspan></text>
|
||||
</g>
|
||||
<g fill="#2aa1ff" font-size="12px" stroke-width="3.77953" text-anchor="middle">
|
||||
<text transform="matrix(.264583 0 0 .264583 57.0045 182.079)" x="57.727047" y="9.11724" filter="url(#filter1204-6-2)" text-align="center" style="line-height:1.1" xml:space="preserve"><tspan x="57.727047" y="9.11724" fill="#2aa1ff" font-size="12px" stroke-width="3.77953" text-align="center" text-anchor="middle">SW command</tspan></text>
|
||||
<text transform="matrix(.264583 0 0 .264583 57.7865 110.104)" x="40.822609" y="9.11724" filter="url(#filter1204-6-2-9)" text-align="center" style="line-height:1.1" xml:space="preserve"><tspan x="40.822609" y="9.11724" fill="#2aa1ff" font-size="12px" stroke-width="3.77953" text-align="center" text-anchor="middle">Set ready</tspan></text>
|
||||
<text transform="matrix(.264583 0 0 .264583 116.893 107.491)" x="28.049065" y="9.1172523" filter="url(#filter1204-6-2-9-4)" text-align="center" style="line-height:1.1" xml:space="preserve"><tspan x="28.049065" y="9.1172523" fill="#2aa1ff" font-size="12px" stroke-width="3.77953" text-align="center" text-anchor="middle">Set ready</tspan></text>
|
||||
<text transform="matrix(.264583 0 0 .264583 87.5687 166.324)" x="28.049065" y="9.1172523" filter="url(#filter1204-6-2-9-1)" text-align="center" style="line-height:1.1" xml:space="preserve"><tspan x="28.049065" y="9.1172523" fill="#2aa1ff" font-size="12px" stroke-width="3.77953" text-align="center" text-anchor="middle">Set empty</tspan></text>
|
||||
<text transform="matrix(.264583 0 0 .264583 106.53 113.074)" x="30.228771" y="8.9063139" filter="url(#filter1204-6-2-9-1-3)" text-align="center" style="line-height:1.1" xml:space="preserve"><tspan x="30.228771" y="8.9063139" fill="#2aa1ff" font-size="12px" stroke-width="3.77953" text-align="center" text-anchor="middle">Set abort</tspan></text>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 16 KiB |
|
@ -10,6 +10,7 @@ Contents:
|
|||
.. toctree::
|
||||
:maxdepth: 2
|
||||
|
||||
ctu/ctucanfd-driver
|
||||
freescale/flexcan
|
||||
|
||||
.. only:: subproject and html
|
||||
|
|
|
@ -1,189 +0,0 @@
|
|||
.. SPDX-License-Identifier: GPL-2.0
|
||||
|
||||
===================================
|
||||
DEC EtherWORKS Ethernet De4x5 cards
|
||||
===================================
|
||||
|
||||
Originally, this driver was written for the Digital Equipment
|
||||
Corporation series of EtherWORKS Ethernet cards:
|
||||
|
||||
- DE425 TP/COAX EISA
|
||||
- DE434 TP PCI
|
||||
- DE435 TP/COAX/AUI PCI
|
||||
- DE450 TP/COAX/AUI PCI
|
||||
- DE500 10/100 PCI Fasternet
|
||||
|
||||
but it will now attempt to support all cards which conform to the
|
||||
Digital Semiconductor SROM Specification. The driver currently
|
||||
recognises the following chips:
|
||||
|
||||
- DC21040 (no SROM)
|
||||
- DC21041[A]
|
||||
- DC21140[A]
|
||||
- DC21142
|
||||
- DC21143
|
||||
|
||||
So far the driver is known to work with the following cards:
|
||||
|
||||
- KINGSTON
|
||||
- Linksys
|
||||
- ZNYX342
|
||||
- SMC8432
|
||||
- SMC9332 (w/new SROM)
|
||||
- ZNYX31[45]
|
||||
- ZNYX346 10/100 4 port (can act as a 10/100 bridge!)
|
||||
|
||||
The driver has been tested on a relatively busy network using the DE425,
|
||||
DE434, DE435 and DE500 cards and benchmarked with 'ttcp': it transferred
|
||||
16M of data to a DECstation 5000/200 as follows::
|
||||
|
||||
TCP UDP
|
||||
TX RX TX RX
|
||||
DE425 1030k 997k 1170k 1128k
|
||||
DE434 1063k 995k 1170k 1125k
|
||||
DE435 1063k 995k 1170k 1125k
|
||||
DE500 1063k 998k 1170k 1125k in 10Mb/s mode
|
||||
|
||||
All values are typical (in kBytes/sec) from a sample of 4 for each
|
||||
measurement. Their error is +/-20k on a quiet (private) network and also
|
||||
depend on what load the CPU has.
|
||||
|
||||
----------------------------------------------------------------------------
|
||||
|
||||
The ability to load this driver as a loadable module has been included
|
||||
and used extensively during the driver development (to save those long
|
||||
reboot sequences). Loadable module support under PCI and EISA has been
|
||||
achieved by letting the driver autoprobe as if it were compiled into the
|
||||
kernel. Do make sure you're not sharing interrupts with anything that
|
||||
cannot accommodate interrupt sharing!
|
||||
|
||||
To utilise this ability, you have to do 8 things:
|
||||
|
||||
0) have a copy of the loadable modules code installed on your system.
|
||||
1) copy de4x5.c from the /linux/drivers/net directory to your favourite
|
||||
temporary directory.
|
||||
2) for fixed autoprobes (not recommended), edit the source code near
|
||||
line 5594 to reflect the I/O address you're using, or assign these when
|
||||
loading by::
|
||||
|
||||
insmod de4x5 io=0xghh where g = bus number
|
||||
hh = device number
|
||||
|
||||
.. note::
|
||||
|
||||
autoprobing for modules is now supported by default. You may just
|
||||
use::
|
||||
|
||||
insmod de4x5
|
||||
|
||||
to load all available boards. For a specific board, still use
|
||||
the 'io=?' above.
|
||||
3) compile de4x5.c, but include -DMODULE in the command line to ensure
|
||||
that the correct bits are compiled (see end of source code).
|
||||
4) if you are wanting to add a new card, goto 5. Otherwise, recompile a
|
||||
kernel with the de4x5 configuration turned off and reboot.
|
||||
5) insmod de4x5 [io=0xghh]
|
||||
6) run the net startup bits for your new eth?? interface(s) manually
|
||||
(usually /etc/rc.inet[12] at boot time).
|
||||
7) enjoy!
|
||||
|
||||
To unload a module, turn off the associated interface(s)
|
||||
'ifconfig eth?? down' then 'rmmod de4x5'.
|
||||
|
||||
Automedia detection is included so that in principle you can disconnect
|
||||
from, e.g. TP, reconnect to BNC and things will still work (after a
|
||||
pause while the driver figures out where its media went). My tests
|
||||
using ping showed that it appears to work....
|
||||
|
||||
By default, the driver will now autodetect any DECchip based card.
|
||||
Should you have a need to restrict the driver to DIGITAL only cards, you
|
||||
can compile with a DEC_ONLY define, or if loading as a module, use the
|
||||
'dec_only=1' parameter.
|
||||
|
||||
I've changed the timing routines to use the kernel timer and scheduling
|
||||
functions so that the hangs and other assorted problems that occurred
|
||||
while autosensing the media should be gone. A bonus for the DC21040
|
||||
auto media sense algorithm is that it can now use one that is more in
|
||||
line with the rest (the DC21040 chip doesn't have a hardware timer).
|
||||
The downside is the 1 'jiffies' (10ms) resolution.
|
||||
|
||||
IEEE 802.3u MII interface code has been added in anticipation that some
|
||||
products may use it in the future.
|
||||
|
||||
The SMC9332 card has a non-compliant SROM which needs fixing - I have
|
||||
patched this driver to detect it because the SROM format used complies
|
||||
to a previous DEC-STD format.
|
||||
|
||||
I have removed the buffer copies needed for receive on Intels. I cannot
|
||||
remove them for Alphas since the Tulip hardware only does longword
|
||||
aligned DMA transfers and the Alphas get alignment traps with non
|
||||
longword aligned data copies (which makes them really slow). No comment.
|
||||
|
||||
I have added SROM decoding routines to make this driver work with any
|
||||
card that supports the Digital Semiconductor SROM spec. This will help
|
||||
all cards running the dc2114x series chips in particular. Cards using
|
||||
the dc2104x chips should run correctly with the basic driver. I'm in
|
||||
debt to <mjacob@feral.com> for the testing and feedback that helped get
|
||||
this feature working. So far we have tested KINGSTON, SMC8432, SMC9332
|
||||
(with the latest SROM complying with the SROM spec V3: their first was
|
||||
broken), ZNYX342 and LinkSys. ZNYX314 (dual 21041 MAC) and ZNYX 315
|
||||
(quad 21041 MAC) cards also appear to work despite their incorrectly
|
||||
wired IRQs.
|
||||
|
||||
I have added a temporary fix for interrupt problems when some SCSI cards
|
||||
share the same interrupt as the DECchip based cards. The problem occurs
|
||||
because the SCSI card wants to grab the interrupt as a fast interrupt
|
||||
(runs the service routine with interrupts turned off) vs. this card
|
||||
which really needs to run the service routine with interrupts turned on.
|
||||
This driver will now add the interrupt service routine as a fast
|
||||
interrupt if it is bounced from the slow interrupt. THIS IS NOT A
|
||||
RECOMMENDED WAY TO RUN THE DRIVER and has been done for a limited time
|
||||
until people sort out their compatibility issues and the kernel
|
||||
interrupt service code is fixed. YOU SHOULD SEPARATE OUT THE FAST
|
||||
INTERRUPT CARDS FROM THE SLOW INTERRUPT CARDS to ensure that they do not
|
||||
run on the same interrupt. PCMCIA/CardBus is another can of worms...
|
||||
|
||||
Finally, I think I have really fixed the module loading problem with
|
||||
more than one DECchip based card. As a side effect, I don't mess with
|
||||
the device structure any more which means that if more than 1 card in
|
||||
2.0.x is installed (4 in 2.1.x), the user will have to edit
|
||||
linux/drivers/net/Space.c to make room for them. Hence, module loading
|
||||
is the preferred way to use this driver, since it doesn't have this
|
||||
limitation.
|
||||
|
||||
Where SROM media detection is used and full duplex is specified in the
|
||||
SROM, the feature is ignored unless lp->params.fdx is set at compile
|
||||
time OR during a module load (insmod de4x5 args='eth??:fdx' [see
|
||||
below]). This is because there is no way to automatically detect full
|
||||
duplex links except through autonegotiation. When I include the
|
||||
autonegotiation feature in the SROM autoconf code, this detection will
|
||||
occur automatically for that case.
|
||||
|
||||
Command line arguments are now allowed, similar to passing arguments
|
||||
through LILO. This will allow a per adapter board set up of full duplex
|
||||
and media. The only lexical constraints are: the board name (dev->name)
|
||||
appears in the list before its parameters. The list of parameters ends
|
||||
either at the end of the parameter list or with another board name. The
|
||||
following parameters are allowed:
|
||||
|
||||
========= ===============================================
|
||||
fdx for full duplex
|
||||
autosense to set the media/speed; with the following
|
||||
sub-parameters:
|
||||
TP, TP_NW, BNC, AUI, BNC_AUI, 100Mb, 10Mb, AUTO
|
||||
========= ===============================================
|
||||
|
||||
Case sensitivity is important for the sub-parameters. They *must* be
|
||||
upper case. Examples::
|
||||
|
||||
insmod de4x5 args='eth1:fdx autosense=BNC eth0:autosense=100Mb'.
|
||||
|
||||
For a compiled in driver, in linux/drivers/net/CONFIG, place e.g.::
|
||||
|
||||
DE4X5_OPTS = -DDE4X5_PARM='"eth0:fdx autosense=AUI eth2:autosense=TP"'
|
||||
|
||||
Yes, I know full duplex isn't permissible on BNC or AUI; they're just
|
||||
examples. By default, full duplex is turned off and AUTO is the default
|
||||
autosense setting. In reality, I expect only the full duplex option to
|
||||
be used. Note the use of single quotes in the two examples above and the
|
||||
lack of commas to separate items.
|
|
@ -19,7 +19,6 @@ Contents:
|
|||
cirrus/cs89x0
|
||||
dlink/dl2k
|
||||
davicom/dm9000
|
||||
dec/de4x5
|
||||
dec/dmfe
|
||||
freescale/dpaa
|
||||
freescale/dpaa2/index
|
||||
|
@ -39,6 +38,7 @@ Contents:
|
|||
intel/iavf
|
||||
intel/ice
|
||||
marvell/octeontx2
|
||||
marvell/octeon_ep
|
||||
mellanox/mlx5
|
||||
microsoft/netvsc
|
||||
neterion/s2io
|
||||
|
|
|
@ -0,0 +1,35 @@
|
|||
.. SPDX-License-Identifier: GPL-2.0+
|
||||
|
||||
====================================================================
|
||||
Linux kernel networking driver for Marvell's Octeon PCI Endpoint NIC
|
||||
====================================================================
|
||||
|
||||
Network driver for Marvell's Octeon PCI EndPoint NIC.
|
||||
Copyright (c) 2020 Marvell International Ltd.
|
||||
|
||||
Contents
|
||||
========
|
||||
|
||||
- `Overview`_
|
||||
- `Supported Devices`_
|
||||
- `Interface Control`_
|
||||
|
||||
Overview
|
||||
========
|
||||
This driver implements networking functionality of Marvell's Octeon PCI
|
||||
EndPoint NIC.
|
||||
|
||||
Supported Devices
|
||||
=================
|
||||
Currently, this driver support following devices:
|
||||
* Network controller: Cavium, Inc. Device b200
|
||||
|
||||
Interface Control
|
||||
=================
|
||||
Network Interface control like changing mtu, link speed, link down/up are
|
||||
done by writing command to mailbox command queue, a mailbox interface
|
||||
implemented through a reserved region in BAR4.
|
||||
This driver writes the commands into the mailbox and the firmware on the
|
||||
Octeon device processes them. The firmware also sends unsolicited notifications
|
||||
to driver for events suchs as link change, through notification queue
|
||||
implemented as part of mailbox interface.
|
|
@ -17,7 +17,6 @@ Contents:
|
|||
fddi/index
|
||||
hamradio/index
|
||||
qlogic/index
|
||||
wan/index
|
||||
wifi/index
|
||||
wwan/index
|
||||
|
||||
|
|
|
@ -1,18 +0,0 @@
|
|||
.. SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
|
||||
Classic WAN Device Drivers
|
||||
==========================
|
||||
|
||||
Contents:
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 2
|
||||
|
||||
z8530book
|
||||
|
||||
.. only:: subproject and html
|
||||
|
||||
Indices
|
||||
=======
|
||||
|
||||
* :ref:`genindex`
|
|
@ -1,256 +0,0 @@
|
|||
=======================
|
||||
Z8530 Programming Guide
|
||||
=======================
|
||||
|
||||
:Author: Alan Cox
|
||||
|
||||
Introduction
|
||||
============
|
||||
|
||||
The Z85x30 family synchronous/asynchronous controller chips are used on
|
||||
a large number of cheap network interface cards. The kernel provides a
|
||||
core interface layer that is designed to make it easy to provide WAN
|
||||
services using this chip.
|
||||
|
||||
The current driver only support synchronous operation. Merging the
|
||||
asynchronous driver support into this code to allow any Z85x30 device to
|
||||
be used as both a tty interface and as a synchronous controller is a
|
||||
project for Linux post the 2.4 release
|
||||
|
||||
Driver Modes
|
||||
============
|
||||
|
||||
The Z85230 driver layer can drive Z8530, Z85C30 and Z85230 devices in
|
||||
three different modes. Each mode can be applied to an individual channel
|
||||
on the chip (each chip has two channels).
|
||||
|
||||
The PIO synchronous mode supports the most common Z8530 wiring. Here the
|
||||
chip is interface to the I/O and interrupt facilities of the host
|
||||
machine but not to the DMA subsystem. When running PIO the Z8530 has
|
||||
extremely tight timing requirements. Doing high speeds, even with a
|
||||
Z85230 will be tricky. Typically you should expect to achieve at best
|
||||
9600 baud with a Z8C530 and 64Kbits with a Z85230.
|
||||
|
||||
The DMA mode supports the chip when it is configured to use dual DMA
|
||||
channels on an ISA bus. The better cards tend to support this mode of
|
||||
operation for a single channel. With DMA running the Z85230 tops out
|
||||
when it starts to hit ISA DMA constraints at about 512Kbits. It is worth
|
||||
noting here that many PC machines hang or crash when the chip is driven
|
||||
fast enough to hold the ISA bus solid.
|
||||
|
||||
Transmit DMA mode uses a single DMA channel. The DMA channel is used for
|
||||
transmission as the transmit FIFO is smaller than the receive FIFO. it
|
||||
gives better performance than pure PIO mode but is nowhere near as ideal
|
||||
as pure DMA mode.
|
||||
|
||||
Using the Z85230 driver
|
||||
=======================
|
||||
|
||||
The Z85230 driver provides the back end interface to your board. To
|
||||
configure a Z8530 interface you need to detect the board and to identify
|
||||
its ports and interrupt resources. It is also your problem to verify the
|
||||
resources are available.
|
||||
|
||||
Having identified the chip you need to fill in a struct z8530_dev,
|
||||
which describes each chip. This object must exist until you finally
|
||||
shutdown the board. Firstly zero the active field. This ensures nothing
|
||||
goes off without you intending it. The irq field should be set to the
|
||||
interrupt number of the chip. (Each chip has a single interrupt source
|
||||
rather than each channel). You are responsible for allocating the
|
||||
interrupt line. The interrupt handler should be set to
|
||||
:c:func:`z8530_interrupt()`. The device id should be set to the
|
||||
z8530_dev structure pointer. Whether the interrupt can be shared or not
|
||||
is board dependent, and up to you to initialise.
|
||||
|
||||
The structure holds two channel structures. Initialise chanA.ctrlio and
|
||||
chanA.dataio with the address of the control and data ports. You can or
|
||||
this with Z8530_PORT_SLEEP to indicate your interface needs the 5uS
|
||||
delay for chip settling done in software. The PORT_SLEEP option is
|
||||
architecture specific. Other flags may become available on future
|
||||
platforms, eg for MMIO. Initialise the chanA.irqs to &z8530_nop to
|
||||
start the chip up as disabled and discarding interrupt events. This
|
||||
ensures that stray interrupts will be mopped up and not hang the bus.
|
||||
Set chanA.dev to point to the device structure itself. The private and
|
||||
name field you may use as you wish. The private field is unused by the
|
||||
Z85230 layer. The name is used for error reporting and it may thus make
|
||||
sense to make it match the network name.
|
||||
|
||||
Repeat the same operation with the B channel if your chip has both
|
||||
channels wired to something useful. This isn't always the case. If it is
|
||||
not wired then the I/O values do not matter, but you must initialise
|
||||
chanB.dev.
|
||||
|
||||
If your board has DMA facilities then initialise the txdma and rxdma
|
||||
fields for the relevant channels. You must also allocate the ISA DMA
|
||||
channels and do any necessary board level initialisation to configure
|
||||
them. The low level driver will do the Z8530 and DMA controller
|
||||
programming but not board specific magic.
|
||||
|
||||
Having initialised the device you can then call
|
||||
:c:func:`z8530_init()`. This will probe the chip and reset it into
|
||||
a known state. An identification sequence is then run to identify the
|
||||
chip type. If the checks fail to pass the function returns a non zero
|
||||
error code. Typically this indicates that the port given is not valid.
|
||||
After this call the type field of the z8530_dev structure is
|
||||
initialised to either Z8530, Z85C30 or Z85230 according to the chip
|
||||
found.
|
||||
|
||||
Once you have called z8530_init you can also make use of the utility
|
||||
function :c:func:`z8530_describe()`. This provides a consistent
|
||||
reporting format for the Z8530 devices, and allows all the drivers to
|
||||
provide consistent reporting.
|
||||
|
||||
Attaching Network Interfaces
|
||||
============================
|
||||
|
||||
If you wish to use the network interface facilities of the driver, then
|
||||
you need to attach a network device to each channel that is present and
|
||||
in use. In addition to use the generic HDLC you need to follow some
|
||||
additional plumbing rules. They may seem complex but a look at the
|
||||
example hostess_sv11 driver should reassure you.
|
||||
|
||||
The network device used for each channel should be pointed to by the
|
||||
netdevice field of each channel. The hdlc-> priv field of the network
|
||||
device points to your private data - you will need to be able to find
|
||||
your private data from this.
|
||||
|
||||
The way most drivers approach this particular problem is to create a
|
||||
structure holding the Z8530 device definition and put that into the
|
||||
private field of the network device. The network device fields of the
|
||||
channels then point back to the network devices.
|
||||
|
||||
If you wish to use the generic HDLC then you need to register the HDLC
|
||||
device.
|
||||
|
||||
Before you register your network device you will also need to provide
|
||||
suitable handlers for most of the network device callbacks. See the
|
||||
network device documentation for more details on this.
|
||||
|
||||
Configuring And Activating The Port
|
||||
===================================
|
||||
|
||||
The Z85230 driver provides helper functions and tables to load the port
|
||||
registers on the Z8530 chips. When programming the register settings for
|
||||
a channel be aware that the documentation recommends initialisation
|
||||
orders. Strange things happen when these are not followed.
|
||||
|
||||
:c:func:`z8530_channel_load()` takes an array of pairs of
|
||||
initialisation values in an array of u8 type. The first value is the
|
||||
Z8530 register number. Add 16 to indicate the alternate register bank on
|
||||
the later chips. The array is terminated by a 255.
|
||||
|
||||
The driver provides a pair of public tables. The z8530_hdlc_kilostream
|
||||
table is for the UK 'Kilostream' service and also happens to cover most
|
||||
other end host configurations. The z8530_hdlc_kilostream_85230 table
|
||||
is the same configuration using the enhancements of the 85230 chip. The
|
||||
configuration loaded is standard NRZ encoded synchronous data with HDLC
|
||||
bitstuffing. All of the timing is taken from the other end of the link.
|
||||
|
||||
When writing your own tables be aware that the driver internally tracks
|
||||
register values. It may need to reload values. You should therefore be
|
||||
sure to set registers 1-7, 9-11, 14 and 15 in all configurations. Where
|
||||
the register settings depend on DMA selection the driver will update the
|
||||
bits itself when you open or close. Loading a new table with the
|
||||
interface open is not recommended.
|
||||
|
||||
There are three standard configurations supported by the core code. In
|
||||
PIO mode the interface is programmed up to use interrupt driven PIO.
|
||||
This places high demands on the host processor to avoid latency. The
|
||||
driver is written to take account of latency issues but it cannot avoid
|
||||
latencies caused by other drivers, notably IDE in PIO mode. Because the
|
||||
drivers allocate buffers you must also prevent MTU changes while the
|
||||
port is open.
|
||||
|
||||
Once the port is open it will call the rx_function of each channel
|
||||
whenever a completed packet arrived. This is invoked from interrupt
|
||||
context and passes you the channel and a network buffer (struct
|
||||
sk_buff) holding the data. The data includes the CRC bytes so most
|
||||
users will want to trim the last two bytes before processing the data.
|
||||
This function is very timing critical. When you wish to simply discard
|
||||
data the support code provides the function
|
||||
:c:func:`z8530_null_rx()` to discard the data.
|
||||
|
||||
To active PIO mode sending and receiving the ``z8530_sync_open`` is called.
|
||||
This expects to be passed the network device and the channel. Typically
|
||||
this is called from your network device open callback. On a failure a
|
||||
non zero error status is returned.
|
||||
The :c:func:`z8530_sync_close()` function shuts down a PIO
|
||||
channel. This must be done before the channel is opened again and before
|
||||
the driver shuts down and unloads.
|
||||
|
||||
The ideal mode of operation is dual channel DMA mode. Here the kernel
|
||||
driver will configure the board for DMA in both directions. The driver
|
||||
also handles ISA DMA issues such as controller programming and the
|
||||
memory range limit for you. This mode is activated by calling the
|
||||
:c:func:`z8530_sync_dma_open()` function. On failure a non zero
|
||||
error value is returned. Once this mode is activated it can be shut down
|
||||
by calling the :c:func:`z8530_sync_dma_close()`. You must call
|
||||
the close function matching the open mode you used.
|
||||
|
||||
The final supported mode uses a single DMA channel to drive the transmit
|
||||
side. As the Z85C30 has a larger FIFO on the receive channel this tends
|
||||
to increase the maximum speed a little. This is activated by calling the
|
||||
``z8530_sync_txdma_open``. This returns a non zero error code on failure. The
|
||||
:c:func:`z8530_sync_txdma_close()` function closes down the Z8530
|
||||
interface from this mode.
|
||||
|
||||
Network Layer Functions
|
||||
=======================
|
||||
|
||||
The Z8530 layer provides functions to queue packets for transmission.
|
||||
The driver internally buffers the frame currently being transmitted and
|
||||
one further frame (in order to keep back to back transmission running).
|
||||
Any further buffering is up to the caller.
|
||||
|
||||
The function :c:func:`z8530_queue_xmit()` takes a network buffer
|
||||
in sk_buff format and queues it for transmission. The caller must
|
||||
provide the entire packet with the exception of the bitstuffing and CRC.
|
||||
This is normally done by the caller via the generic HDLC interface
|
||||
layer. It returns 0 if the buffer has been queued and non zero values
|
||||
for queue full. If the function accepts the buffer it becomes property
|
||||
of the Z8530 layer and the caller should not free it.
|
||||
|
||||
The function :c:func:`z8530_get_stats()` returns a pointer to an
|
||||
internally maintained per interface statistics block. This provides most
|
||||
of the interface code needed to implement the network layer get_stats
|
||||
callback.
|
||||
|
||||
Porting The Z8530 Driver
|
||||
========================
|
||||
|
||||
The Z8530 driver is written to be portable. In DMA mode it makes
|
||||
assumptions about the use of ISA DMA. These are probably warranted in
|
||||
most cases as the Z85230 in particular was designed to glue to PC type
|
||||
machines. The PIO mode makes no real assumptions.
|
||||
|
||||
Should you need to retarget the Z8530 driver to another architecture the
|
||||
only code that should need changing are the port I/O functions. At the
|
||||
moment these assume PC I/O port accesses. This may not be appropriate
|
||||
for all platforms. Replacing :c:func:`z8530_read_port()` and
|
||||
``z8530_write_port`` is intended to be all that is required to port
|
||||
this driver layer.
|
||||
|
||||
Known Bugs And Assumptions
|
||||
==========================
|
||||
|
||||
Interrupt Locking
|
||||
The locking in the driver is done via the global cli/sti lock. This
|
||||
makes for relatively poor SMP performance. Switching this to use a
|
||||
per device spin lock would probably materially improve performance.
|
||||
|
||||
Occasional Failures
|
||||
We have reports of occasional failures when run for very long
|
||||
periods of time and the driver starts to receive junk frames. At the
|
||||
moment the cause of this is not clear.
|
||||
|
||||
Public Functions Provided
|
||||
=========================
|
||||
|
||||
.. kernel-doc:: drivers/net/wan/z85230.c
|
||||
:export:
|
||||
|
||||
Internal Functions
|
||||
==================
|
||||
|
||||
.. kernel-doc:: drivers/net/wan/z85230.c
|
||||
:internal:
|
|
@ -9,6 +9,7 @@ Contents:
|
|||
:maxdepth: 2
|
||||
|
||||
iosm
|
||||
t7xx
|
||||
|
||||
.. only:: subproject and html
|
||||
|
||||
|
|
|
@ -0,0 +1,120 @@
|
|||
.. SPDX-License-Identifier: GPL-2.0-only
|
||||
|
||||
.. Copyright (C) 2020-21 Intel Corporation
|
||||
|
||||
.. _t7xx_driver_doc:
|
||||
|
||||
============================================
|
||||
t7xx driver for MTK PCIe based T700 5G modem
|
||||
============================================
|
||||
The t7xx driver is a WWAN PCIe host driver developed for linux or Chrome OS platforms
|
||||
for data exchange over PCIe interface between Host platform & MediaTek's T700 5G modem.
|
||||
The driver exposes an interface conforming to the MBIM protocol [1]. Any front end
|
||||
application (e.g. Modem Manager) could easily manage the MBIM interface to enable
|
||||
data communication towards WWAN. The driver also provides an interface to interact
|
||||
with the MediaTek's modem via AT commands.
|
||||
|
||||
Basic usage
|
||||
===========
|
||||
MBIM & AT functions are inactive when unmanaged. The t7xx driver provides
|
||||
WWAN port userspace interfaces representing MBIM & AT control channels and does
|
||||
not play any role in managing their functionality. It is the job of a userspace
|
||||
application to detect port enumeration and enable MBIM & AT functionalities.
|
||||
|
||||
Examples of few such userspace applications are:
|
||||
|
||||
- mbimcli (included with the libmbim [2] library), and
|
||||
- Modem Manager [3]
|
||||
|
||||
Management Applications to carry out below required actions for establishing
|
||||
MBIM IP session:
|
||||
|
||||
- open the MBIM control channel
|
||||
- configure network connection settings
|
||||
- connect to network
|
||||
- configure IP network interface
|
||||
|
||||
Management Applications to carry out below required actions for send an AT
|
||||
command and receive response:
|
||||
|
||||
- open the AT control channel using a UART tool or a special user tool
|
||||
|
||||
Management application development
|
||||
==================================
|
||||
The driver and userspace interfaces are described below. The MBIM protocol is
|
||||
described in [1] Mobile Broadband Interface Model v1.0 Errata-1.
|
||||
|
||||
MBIM control channel userspace ABI
|
||||
----------------------------------
|
||||
|
||||
/dev/wwan0mbim0 character device
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
The driver exposes an MBIM interface to the MBIM function by implementing
|
||||
MBIM WWAN Port. The userspace end of the control channel pipe is a
|
||||
/dev/wwan0mbim0 character device. Application shall use this interface for
|
||||
MBIM protocol communication.
|
||||
|
||||
Fragmentation
|
||||
~~~~~~~~~~~~~
|
||||
The userspace application is responsible for all control message fragmentation
|
||||
and defragmentation as per MBIM specification.
|
||||
|
||||
/dev/wwan0mbim0 write()
|
||||
~~~~~~~~~~~~~~~~~~~~~~~
|
||||
The MBIM control messages from the management application must not exceed the
|
||||
negotiated control message size.
|
||||
|
||||
/dev/wwan0mbim0 read()
|
||||
~~~~~~~~~~~~~~~~~~~~~~
|
||||
The management application must accept control messages of up the negotiated
|
||||
control message size.
|
||||
|
||||
MBIM data channel userspace ABI
|
||||
-------------------------------
|
||||
|
||||
wwan0-X network device
|
||||
~~~~~~~~~~~~~~~~~~~~~~
|
||||
The t7xx driver exposes IP link interface "wwan0-X" of type "wwan" for IP
|
||||
traffic. Iproute network utility is used for creating "wwan0-X" network
|
||||
interface and for associating it with MBIM IP session.
|
||||
|
||||
The userspace management application is responsible for creating new IP link
|
||||
prior to establishing MBIM IP session where the SessionId is greater than 0.
|
||||
|
||||
For example, creating new IP link for a MBIM IP session with SessionId 1:
|
||||
|
||||
ip link add dev wwan0-1 parentdev wwan0 type wwan linkid 1
|
||||
|
||||
The driver will automatically map the "wwan0-1" network device to MBIM IP
|
||||
session 1.
|
||||
|
||||
AT port userspace ABI
|
||||
----------------------------------
|
||||
|
||||
/dev/wwan0at0 character device
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
The driver exposes an AT port by implementing AT WWAN Port.
|
||||
The userspace end of the control port is a /dev/wwan0at0 character
|
||||
device. Application shall use this interface to issue AT commands.
|
||||
|
||||
The MediaTek's T700 modem supports the 3GPP TS 27.007 [4] specification.
|
||||
|
||||
References
|
||||
==========
|
||||
[1] *MBIM (Mobile Broadband Interface Model) Errata-1*
|
||||
|
||||
- https://www.usb.org/document-library/
|
||||
|
||||
[2] *libmbim "a glib-based library for talking to WWAN modems and devices which
|
||||
speak the Mobile Interface Broadband Model (MBIM) protocol"*
|
||||
|
||||
- http://www.freedesktop.org/wiki/Software/libmbim/
|
||||
|
||||
[3] *Modem Manager "a DBus-activated daemon which controls mobile broadband
|
||||
(2G/3G/4G/5G) devices and connections"*
|
||||
|
||||
- http://www.freedesktop.org/wiki/Software/ModemManager/
|
||||
|
||||
[4] *Specification # 27.007 - 3GPP*
|
||||
|
||||
- https://www.3gpp.org/DynaReport/27007.htm
|
|
@ -0,0 +1,122 @@
|
|||
.. SPDX-License-Identifier: GPL-2.0
|
||||
|
||||
=================
|
||||
Devlink Line card
|
||||
=================
|
||||
|
||||
Background
|
||||
==========
|
||||
|
||||
The ``devlink-linecard`` mechanism is targeted for manipulation of
|
||||
line cards that serve as a detachable PHY modules for modular switch
|
||||
system. Following operations are provided:
|
||||
|
||||
* Get a list of supported line card types.
|
||||
* Provision of a slot with specific line card type.
|
||||
* Get and monitor of line card state and its change.
|
||||
|
||||
Line card according to the type may contain one or more gearboxes
|
||||
to mux the lanes with certain speed to multiple ports with lanes
|
||||
of different speed. Line card ensures N:M mapping between
|
||||
the switch ASIC modules and physical front panel ports.
|
||||
|
||||
Overview
|
||||
========
|
||||
|
||||
Each line card devlink object is created by device driver,
|
||||
according to the physical line card slots available on the device.
|
||||
|
||||
Similar to splitter cable, where the device might have no way
|
||||
of detection of the splitter cable geometry, the device
|
||||
might not have a way to detect line card type. For that devices,
|
||||
concept of provisioning is introduced. It allows the user to:
|
||||
|
||||
* Provision a line card slot with certain line card type
|
||||
|
||||
- Device driver would instruct the ASIC to prepare all
|
||||
resources accordingly. The device driver would
|
||||
create all instances, namely devlink port and netdevices
|
||||
that reside on the line card, according to the line card type
|
||||
* Manipulate of line card entities even without line card
|
||||
being physically connected or powered-up
|
||||
* Setup splitter cable on line card ports
|
||||
|
||||
- As on the ordinary ports, user may provision a splitter
|
||||
cable of a certain type, without the need to
|
||||
be physically connected to the port
|
||||
* Configure devlink ports and netdevices
|
||||
|
||||
Netdevice carrier is decided as follows:
|
||||
|
||||
* Line card is not inserted or powered-down
|
||||
|
||||
- The carrier is always down
|
||||
* Line card is inserted and powered up
|
||||
|
||||
- The carrier is decided as for ordinary port netdevice
|
||||
|
||||
Line card state
|
||||
===============
|
||||
|
||||
The ``devlink-linecard`` mechanism supports the following line card states:
|
||||
|
||||
* ``unprovisioned``: Line card is not provisioned on the slot.
|
||||
* ``unprovisioning``: Line card slot is currently being unprovisioned.
|
||||
* ``provisioning``: Line card slot is currently in a process of being provisioned
|
||||
with a line card type.
|
||||
* ``provisioning_failed``: Provisioning was not successful.
|
||||
* ``provisioned``: Line card slot is provisioned with a type.
|
||||
* ``active``: Line card is powered-up and active.
|
||||
|
||||
The following diagram provides a general overview of ``devlink-linecard``
|
||||
state transitions::
|
||||
|
||||
+-------------------------+
|
||||
| |
|
||||
+----------------------------------> unprovisioned |
|
||||
| | |
|
||||
| +--------|-------^--------+
|
||||
| | |
|
||||
| | |
|
||||
| +--------v-------|--------+
|
||||
| | |
|
||||
| | provisioning |
|
||||
| | |
|
||||
| +------------|------------+
|
||||
| |
|
||||
| +-----------------------------+
|
||||
| | |
|
||||
| +------------v------------+ +------------v------------+ +-------------------------+
|
||||
| | | | ----> |
|
||||
+----- provisioning_failed | | provisioned | | active |
|
||||
| | | | <---- |
|
||||
| +------------^------------+ +------------|------------+ +-------------------------+
|
||||
| | |
|
||||
| | |
|
||||
| | +------------v------------+
|
||||
| | | |
|
||||
| | | unprovisioning |
|
||||
| | | |
|
||||
| | +------------|------------+
|
||||
| | |
|
||||
| +-----------------------------+
|
||||
| |
|
||||
+-----------------------------------------------+
|
||||
|
||||
|
||||
Example usage
|
||||
=============
|
||||
|
||||
.. code:: shell
|
||||
|
||||
$ devlink lc show [ DEV [ lc LC_INDEX ] ]
|
||||
$ devlink lc set DEV lc LC_INDEX [ { type LC_TYPE | notype } ]
|
||||
|
||||
# Show current line card configuration and status for all slots:
|
||||
$ devlink lc
|
||||
|
||||
# Set slot 8 to be provisioned with type "16x100G":
|
||||
$ devlink lc set pci/0000:01:00.0 lc 8 type 16x100G
|
||||
|
||||
# Set slot 8 to be unprovisioned:
|
||||
$ devlink lc set pci/0000:01:00.0 lc 8 notype
|
|
@ -39,6 +39,7 @@ general.
|
|||
devlink-resource
|
||||
devlink-reload
|
||||
devlink-trap
|
||||
devlink-linecard
|
||||
|
||||
Driver-specific documentation
|
||||
-----------------------------
|
||||
|
|
|
@ -193,6 +193,23 @@ protocol. If not all packets are of equal size, the tagger can implement the
|
|||
default behavior by specifying the correct offset incurred by each individual
|
||||
RX packet. Tail taggers do not cause issues to the flow dissector.
|
||||
|
||||
Checksum offload should work with category 1 and 2 taggers when the DSA master
|
||||
driver declares NETIF_F_HW_CSUM in vlan_features and looks at csum_start and
|
||||
csum_offset. For those cases, DSA will shift the checksum start and offset by
|
||||
the tag size. If the DSA master driver still uses the legacy NETIF_F_IP_CSUM
|
||||
or NETIF_F_IPV6_CSUM in vlan_features, the offload might only work if the
|
||||
offload hardware already expects that specific tag (perhaps due to matching
|
||||
vendors). DSA slaves inherit those flags from the master port, and it is up to
|
||||
the driver to correctly fall back to software checksum when the IP header is not
|
||||
where the hardware expects. If that check is ineffective, the packets might go
|
||||
to the network without a proper checksum (the checksum field will have the
|
||||
pseudo IP header sum). For category 3, when the offload hardware does not
|
||||
already expect the switch tag in use, the checksum must be calculated before any
|
||||
tag is inserted (i.e. inside the tagger). Otherwise, the DSA master would
|
||||
include the tail tag in the (software or hardware) checksum calculation. Then,
|
||||
when the tag gets stripped by the switch during transmission, it will leave an
|
||||
incorrect IP checksum in place.
|
||||
|
||||
Due to various reasons (most common being category 1 taggers being associated
|
||||
with DSA-unaware masters, mangling what the master perceives as MAC DA), the
|
||||
tagging protocol may require the DSA master to operate in promiscuous mode, to
|
||||
|
|
|
@ -862,6 +862,7 @@ Kernel response contents:
|
|||
``ETHTOOL_A_RINGS_RX_BUF_LEN`` u32 size of buffers on the ring
|
||||
``ETHTOOL_A_RINGS_TCP_DATA_SPLIT`` u8 TCP header / data split
|
||||
``ETHTOOL_A_RINGS_CQE_SIZE`` u32 Size of TX/RX CQE
|
||||
``ETHTOOL_A_RINGS_TX_PUSH`` u8 flag of TX Push mode
|
||||
==================================== ====== ===========================
|
||||
|
||||
``ETHTOOL_A_RINGS_TCP_DATA_SPLIT`` indicates whether the device is usable with
|
||||
|
@ -871,6 +872,12 @@ separate buffers. The device configuration must make it possible to receive
|
|||
full memory pages of data, for example because MTU is high enough or through
|
||||
HW-GRO.
|
||||
|
||||
``ETHTOOL_A_RINGS_TX_PUSH`` flag is used to enable descriptor fast
|
||||
path to send packets. In ordinary path, driver fills descriptors in DRAM and
|
||||
notifies NIC hardware. In fast path, driver pushes descriptors to the device
|
||||
through MMIO writes, thus reducing the latency. However, enabling this feature
|
||||
may increase the CPU cost. Drivers may enforce additional per-packet
|
||||
eligibility checks (e.g. on packet size).
|
||||
|
||||
RINGS_SET
|
||||
=========
|
||||
|
@ -887,6 +894,7 @@ Request contents:
|
|||
``ETHTOOL_A_RINGS_TX`` u32 size of TX ring
|
||||
``ETHTOOL_A_RINGS_RX_BUF_LEN`` u32 size of buffers on the ring
|
||||
``ETHTOOL_A_RINGS_CQE_SIZE`` u32 Size of TX/RX CQE
|
||||
``ETHTOOL_A_RINGS_TX_PUSH`` u8 flag of TX Push mode
|
||||
==================================== ====== ===========================
|
||||
|
||||
Kernel checks that requested ring sizes do not exceed limits reported by
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
Linux Networking Documentation
|
||||
==============================
|
||||
Networking
|
||||
==========
|
||||
|
||||
Refer to :ref:`netdev-FAQ` for a guide on netdev development process specifics.
|
||||
|
||||
|
@ -97,6 +97,7 @@ Contents:
|
|||
sctp
|
||||
secid
|
||||
seg6-sysctl
|
||||
skbuff
|
||||
smc-sysctl
|
||||
statistics
|
||||
strparser
|
||||
|
|
|
@ -2474,6 +2474,33 @@ drop_unsolicited_na - BOOLEAN
|
|||
|
||||
By default this is turned off.
|
||||
|
||||
accept_unsolicited_na - BOOLEAN
|
||||
Add a new neighbour cache entry in STALE state for routers on receiving an
|
||||
unsolicited neighbour advertisement with target link-layer address option
|
||||
specified. This is as per router-side behavior documented in RFC9131.
|
||||
This has lower precedence than drop_unsolicited_na.
|
||||
|
||||
==== ====== ====== ==============================================
|
||||
drop accept fwding behaviour
|
||||
---- ------ ------ ----------------------------------------------
|
||||
1 X X Drop NA packet and don't pass up the stack
|
||||
0 0 X Pass NA packet up the stack, don't update NC
|
||||
0 1 0 Pass NA packet up the stack, don't update NC
|
||||
0 1 1 Pass NA packet up the stack, and add a STALE
|
||||
NC entry
|
||||
==== ====== ====== ==============================================
|
||||
|
||||
This will optimize the return path for the initial off-link communication
|
||||
that is initiated by a directly connected host, by ensuring that
|
||||
the first-hop router which turns on this setting doesn't have to
|
||||
buffer the initial return packets to do neighbour-solicitation.
|
||||
The prerequisite is that the host is configured to send
|
||||
unsolicited neighbour advertisements on interface bringup.
|
||||
This setting should be used in conjunction with the ndisc_notify setting
|
||||
on the host to satisfy this prerequisite.
|
||||
|
||||
By default this is turned off.
|
||||
|
||||
enhanced_dad - BOOLEAN
|
||||
Include a nonce option in the IPv6 neighbor solicitation messages used for
|
||||
duplicate address detection per RFC7527. A received DAD NS will only signal
|
||||
|
|
|
@ -46,6 +46,24 @@ allow_join_initial_addr_port - BOOLEAN
|
|||
|
||||
Default: 1
|
||||
|
||||
pm_type - INTEGER
|
||||
|
||||
Set the default path manager type to use for each new MPTCP
|
||||
socket. In-kernel path management will control subflow
|
||||
connections and address advertisements according to
|
||||
per-namespace values configured over the MPTCP netlink
|
||||
API. Userspace path management puts per-MPTCP-connection subflow
|
||||
connection decisions and address advertisements under control of
|
||||
a privileged userspace program, at the cost of more netlink
|
||||
traffic to propagate all of the related events and commands.
|
||||
|
||||
This is a per-namespace sysctl.
|
||||
|
||||
* 0 - In-kernel path manager
|
||||
* 1 - Userspace path manager
|
||||
|
||||
Default: 0
|
||||
|
||||
stale_loss_cnt - INTEGER
|
||||
The number of MPTCP-level retransmission intervals with no traffic and
|
||||
pending outstanding data on a given subflow required to declare it stale.
|
||||
|
|
|
@ -34,10 +34,13 @@ nf_conntrack_count - INTEGER (read-only)
|
|||
|
||||
nf_conntrack_events - BOOLEAN
|
||||
- 0 - disabled
|
||||
- not 0 - enabled (default)
|
||||
- 1 - enabled
|
||||
- 2 - auto (default)
|
||||
|
||||
If this option is enabled, the connection tracking code will
|
||||
provide userspace with connection tracking events via ctnetlink.
|
||||
The default allocates the extension if a userspace program is
|
||||
listening to ctnetlink events.
|
||||
|
||||
nf_conntrack_expect_max - INTEGER
|
||||
Maximum size of expectation table. Default value is
|
||||
|
|
|
@ -0,0 +1,37 @@
|
|||
.. SPDX-License-Identifier: GPL-2.0
|
||||
|
||||
struct sk_buff
|
||||
==============
|
||||
|
||||
:c:type:`sk_buff` is the main networking structure representing
|
||||
a packet.
|
||||
|
||||
Basic sk_buff geometry
|
||||
----------------------
|
||||
|
||||
.. kernel-doc:: include/linux/skbuff.h
|
||||
:doc: Basic sk_buff geometry
|
||||
|
||||
Shared skbs and skb clones
|
||||
--------------------------
|
||||
|
||||
:c:member:`sk_buff.users` is a simple refcount allowing multiple entities
|
||||
to keep a struct sk_buff alive. skbs with a ``sk_buff.users != 1`` are referred
|
||||
to as shared skbs (see skb_shared()).
|
||||
|
||||
skb_clone() allows for fast duplication of skbs. None of the data buffers
|
||||
get copied, but caller gets a new metadata struct (struct sk_buff).
|
||||
&skb_shared_info.refcount indicates the number of skbs pointing at the same
|
||||
packet data (i.e. clones).
|
||||
|
||||
dataref and headerless skbs
|
||||
---------------------------
|
||||
|
||||
.. kernel-doc:: include/linux/skbuff.h
|
||||
:doc: dataref and headerless skbs
|
||||
|
||||
Checksum information
|
||||
--------------------
|
||||
|
||||
.. kernel-doc:: include/linux/skbuff.h
|
||||
:doc: skb checksums
|
63
MAINTAINERS
63
MAINTAINERS
|
@ -4386,7 +4386,6 @@ F: drivers/net/can/
|
|||
F: drivers/phy/phy-can-transceiver.c
|
||||
F: include/linux/can/bittiming.h
|
||||
F: include/linux/can/dev.h
|
||||
F: include/linux/can/led.h
|
||||
F: include/linux/can/length.h
|
||||
F: include/linux/can/platform/
|
||||
F: include/linux/can/rx-offload.h
|
||||
|
@ -5064,12 +5063,6 @@ S: Maintained
|
|||
F: Documentation/hwmon/corsair-psu.rst
|
||||
F: drivers/hwmon/corsair-psu.c
|
||||
|
||||
COSA/SRP SYNC SERIAL DRIVER
|
||||
M: Jan "Yenya" Kasprzak <kas@fi.muni.cz>
|
||||
S: Maintained
|
||||
W: http://www.fi.muni.cz/~kas/cosa/
|
||||
F: drivers/net/wan/cosa*
|
||||
|
||||
COUNTER SUBSYSTEM
|
||||
M: William Breathitt Gray <vilhelm.gray@gmail.com>
|
||||
L: linux-iio@vger.kernel.org
|
||||
|
@ -5251,6 +5244,14 @@ T: git git://linuxtv.org/media_tree.git
|
|||
F: Documentation/devicetree/bindings/media/allwinner,sun6i-a31-csi.yaml
|
||||
F: drivers/media/platform/sunxi/sun6i-csi/
|
||||
|
||||
CTU CAN FD DRIVER
|
||||
M: Pavel Pisa <pisa@cmp.felk.cvut.cz>
|
||||
M: Ondrej Ille <ondrej.ille@gmail.com>
|
||||
L: linux-can@vger.kernel.org
|
||||
S: Maintained
|
||||
F: Documentation/devicetree/bindings/net/can/ctu,ctucanfd.yaml
|
||||
F: drivers/net/can/ctucanfd/
|
||||
|
||||
CW1200 WLAN driver
|
||||
M: Solomon Peachy <pizza@shaftnet.org>
|
||||
S: Maintained
|
||||
|
@ -8795,7 +8796,6 @@ F: kernel/time/timer_*.c
|
|||
HIGH-SPEED SCC DRIVER FOR AX.25
|
||||
L: linux-hams@vger.kernel.org
|
||||
S: Orphan
|
||||
F: drivers/net/hamradio/dmascc.c
|
||||
F: drivers/net/hamradio/scc.c
|
||||
|
||||
HIGHPOINT ROCKETRAID 3xxx RAID DRIVER
|
||||
|
@ -11876,6 +11876,13 @@ S: Supported
|
|||
F: Documentation/devicetree/bindings/mmc/marvell,xenon-sdhci.yaml
|
||||
F: drivers/mmc/host/sdhci-xenon*
|
||||
|
||||
MARVELL OCTEON ENDPOINT DRIVER
|
||||
M: Veerasenareddy Burru <vburru@marvell.com>
|
||||
M: Abhijit Ayarekar <aayarekar@marvell.com>
|
||||
L: netdev@vger.kernel.org
|
||||
S: Supported
|
||||
F: drivers/net/ethernet/marvell/octeon_ep
|
||||
|
||||
MATROX FRAMEBUFFER DRIVER
|
||||
L: linux-fbdev@vger.kernel.org
|
||||
S: Orphan
|
||||
|
@ -12524,6 +12531,17 @@ S: Maintained
|
|||
F: drivers/net/dsa/mt7530.*
|
||||
F: net/dsa/tag_mtk.c
|
||||
|
||||
MEDIATEK T7XX 5G WWAN MODEM DRIVER
|
||||
M: Chandrashekar Devegowda <chandrashekar.devegowda@intel.com>
|
||||
M: Intel Corporation <linuxwwan@intel.com>
|
||||
R: Chiranjeevi Rapolu <chiranjeevi.rapolu@linux.intel.com>
|
||||
R: Liu Haijun <haijun.liu@mediatek.com>
|
||||
R: M Chetan Kumar <m.chetan.kumar@linux.intel.com>
|
||||
R: Ricardo Martinez <ricardo.martinez@linux.intel.com>
|
||||
L: netdev@vger.kernel.org
|
||||
S: Supported
|
||||
F: drivers/net/wwan/t7xx/
|
||||
|
||||
MEDIATEK USB3 DRD IP DRIVER
|
||||
M: Chunfeng Yun <chunfeng.yun@mediatek.com>
|
||||
L: linux-usb@vger.kernel.org
|
||||
|
@ -12953,6 +12971,13 @@ F: drivers/net/dsa/microchip/*
|
|||
F: include/linux/platform_data/microchip-ksz.h
|
||||
F: net/dsa/tag_ksz.c
|
||||
|
||||
MICROCHIP LAN87xx/LAN937x T1 PHY DRIVER
|
||||
M: Arun Ramadoss <arun.ramadoss@microchip.com>
|
||||
R: UNGLinuxDriver@microchip.com
|
||||
L: netdev@vger.kernel.org
|
||||
S: Maintained
|
||||
F: drivers/net/phy/microchip_t1.c
|
||||
|
||||
MICROCHIP LAN743X ETHERNET DRIVER
|
||||
M: Bryan Whitehead <bryan.whitehead@microchip.com>
|
||||
M: UNGLinuxDriver@microchip.com
|
||||
|
@ -13825,6 +13850,7 @@ F: include/net/mptcp.h
|
|||
F: include/trace/events/mptcp.h
|
||||
F: include/uapi/linux/mptcp.h
|
||||
F: net/mptcp/
|
||||
F: tools/testing/selftests/bpf/*/*mptcp*.c
|
||||
F: tools/testing/selftests/net/mptcp/
|
||||
|
||||
NETWORKING [TCP]
|
||||
|
@ -16047,6 +16073,12 @@ T: git git://linuxtv.org/media_tree.git
|
|||
F: Documentation/admin-guide/media/pulse8-cec.rst
|
||||
F: drivers/media/cec/usb/pulse8/
|
||||
|
||||
PURELIFI PLFXLC DRIVER
|
||||
M: Srinivasan Raju <srini.raju@purelifi.com>
|
||||
L: linux-wireless@vger.kernel.org
|
||||
S: Supported
|
||||
F: drivers/net/wireless/purelifi/plfxlc/
|
||||
|
||||
PVRUSB2 VIDEO4LINUX DRIVER
|
||||
M: Mike Isely <isely@pobox.com>
|
||||
L: pvrusb2@isely.net (subscribers-only)
|
||||
|
@ -18058,8 +18090,8 @@ F: drivers/platform/x86/touchscreen_dmi.c
|
|||
SILICON LABS WIRELESS DRIVERS (for WFxxx series)
|
||||
M: Jérôme Pouiller <jerome.pouiller@silabs.com>
|
||||
S: Supported
|
||||
F: Documentation/devicetree/bindings/staging/net/wireless/silabs,wfx.yaml
|
||||
F: drivers/staging/wfx/
|
||||
F: Documentation/devicetree/bindings/net/wireless/silabs,wfx.yaml
|
||||
F: drivers/net/wireless/silabs/wfx/
|
||||
|
||||
SILICON MOTION SM712 FRAME BUFFER DRIVER
|
||||
M: Sudip Mukherjee <sudipm.mukherjee@gmail.com>
|
||||
|
@ -18946,6 +18978,14 @@ L: netdev@vger.kernel.org
|
|||
S: Maintained
|
||||
F: drivers/net/ethernet/dlink/sundance.c
|
||||
|
||||
SUNPLUS ETHERNET DRIVER
|
||||
M: Wells Lu <wellslutw@gmail.com>
|
||||
L: netdev@vger.kernel.org
|
||||
S: Maintained
|
||||
W: https://sunplus.atlassian.net/wiki/spaces/doc/overview
|
||||
F: Documentation/devicetree/bindings/net/sunplus,sp7021-emac.yaml
|
||||
F: drivers/net/ethernet/sunplus/
|
||||
|
||||
SUNPLUS OCOTP DRIVER
|
||||
M: Vincent Shih <vincent.sunplus@gmail.com>
|
||||
S: Maintained
|
||||
|
@ -21582,6 +21622,7 @@ K: (?:\b|_)xdp(?:\b|_)
|
|||
XDP SOCKETS (AF_XDP)
|
||||
M: Björn Töpel <bjorn@kernel.org>
|
||||
M: Magnus Karlsson <magnus.karlsson@intel.com>
|
||||
M: Maciej Fijalkowski <maciej.fijalkowski@intel.com>
|
||||
R: Jonathan Lemon <jonathan.lemon@gmail.com>
|
||||
L: netdev@vger.kernel.org
|
||||
L: bpf@vger.kernel.org
|
||||
|
@ -21715,7 +21756,7 @@ M: Appana Durga Kedareswara rao <appana.durga.rao@xilinx.com>
|
|||
R: Naga Sureshkumar Relli <naga.sureshkumar.relli@xilinx.com>
|
||||
L: linux-can@vger.kernel.org
|
||||
S: Maintained
|
||||
F: Documentation/devicetree/bindings/net/can/xilinx_can.txt
|
||||
F: Documentation/devicetree/bindings/net/can/xilinx,can.yaml
|
||||
F: drivers/net/can/xilinx_can.c
|
||||
|
||||
XILINX GPIO DRIVER
|
||||
|
|
|
@ -135,6 +135,8 @@
|
|||
|
||||
#define SO_TXREHASH 74
|
||||
|
||||
#define SO_RCVMARK 75
|
||||
|
||||
#if !defined(__KERNEL__)
|
||||
|
||||
#if __BITS_PER_LONG == 64
|
||||
|
|
|
@ -181,6 +181,7 @@
|
|||
status = "disabled";
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&pinctrl_mdio1_default>;
|
||||
resets = <&syscon ASPEED_RESET_MII>;
|
||||
};
|
||||
|
||||
mdio1: mdio@1e650008 {
|
||||
|
@ -191,6 +192,7 @@
|
|||
status = "disabled";
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&pinctrl_mdio2_default>;
|
||||
resets = <&syscon ASPEED_RESET_MII>;
|
||||
};
|
||||
|
||||
mdio2: mdio@1e650010 {
|
||||
|
@ -201,6 +203,7 @@
|
|||
status = "disabled";
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&pinctrl_mdio3_default>;
|
||||
resets = <&syscon ASPEED_RESET_MII>;
|
||||
};
|
||||
|
||||
mdio3: mdio@1e650018 {
|
||||
|
@ -211,6 +214,7 @@
|
|||
status = "disabled";
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&pinctrl_mdio4_default>;
|
||||
resets = <&syscon ASPEED_RESET_MII>;
|
||||
};
|
||||
|
||||
mac0: ftgmac@1e660000 {
|
||||
|
|
|
@ -83,6 +83,16 @@
|
|||
qca,clk-out-frequency = <125000000>;
|
||||
qca,smarteee-tw-us-1g = <24>;
|
||||
};
|
||||
|
||||
/*
|
||||
* ADIN1300 (som rev 1.9 or later) is always at address 1. It
|
||||
* will be enabled automatically by U-Boot if detected.
|
||||
*/
|
||||
ethernet-phy@1 {
|
||||
reg = <1>;
|
||||
adi,phy-output-clock = "125mhz-free-running";
|
||||
status = "disabled";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
|
|
|
@ -303,7 +303,7 @@
|
|||
/* switch nodes are enabled by U-Boot if modules are present */
|
||||
switch0@10 {
|
||||
compatible = "marvell,mv88e6190";
|
||||
reg = <0x10 0>;
|
||||
reg = <0x10>;
|
||||
dsa,member = <0 0>;
|
||||
interrupt-parent = <&moxtet>;
|
||||
interrupts = <MOXTET_IRQ_PERIDOT(0)>;
|
||||
|
@ -428,7 +428,7 @@
|
|||
|
||||
switch0@2 {
|
||||
compatible = "marvell,mv88e6085";
|
||||
reg = <0x2 0>;
|
||||
reg = <0x2>;
|
||||
dsa,member = <0 0>;
|
||||
interrupt-parent = <&moxtet>;
|
||||
interrupts = <MOXTET_IRQ_TOPAZ>;
|
||||
|
@ -495,7 +495,7 @@
|
|||
|
||||
switch1@11 {
|
||||
compatible = "marvell,mv88e6190";
|
||||
reg = <0x11 0>;
|
||||
reg = <0x11>;
|
||||
dsa,member = <0 1>;
|
||||
interrupt-parent = <&moxtet>;
|
||||
interrupts = <MOXTET_IRQ_PERIDOT(1)>;
|
||||
|
@ -620,7 +620,7 @@
|
|||
|
||||
switch1@2 {
|
||||
compatible = "marvell,mv88e6085";
|
||||
reg = <0x2 0>;
|
||||
reg = <0x2>;
|
||||
dsa,member = <0 1>;
|
||||
interrupt-parent = <&moxtet>;
|
||||
interrupts = <MOXTET_IRQ_TOPAZ>;
|
||||
|
@ -687,7 +687,7 @@
|
|||
|
||||
switch2@12 {
|
||||
compatible = "marvell,mv88e6190";
|
||||
reg = <0x12 0>;
|
||||
reg = <0x12>;
|
||||
dsa,member = <0 2>;
|
||||
interrupt-parent = <&moxtet>;
|
||||
interrupts = <MOXTET_IRQ_PERIDOT(2)>;
|
||||
|
@ -803,7 +803,7 @@
|
|||
|
||||
switch2@2 {
|
||||
compatible = "marvell,mv88e6085";
|
||||
reg = <0x2 0>;
|
||||
reg = <0x2>;
|
||||
dsa,member = <0 2>;
|
||||
interrupt-parent = <&moxtet>;
|
||||
interrupts = <MOXTET_IRQ_TOPAZ>;
|
||||
|
|
|
@ -357,7 +357,7 @@
|
|||
};
|
||||
|
||||
cci_control2: slave-if@5000 {
|
||||
compatible = "arm,cci-400-ctrl-if";
|
||||
compatible = "arm,cci-400-ctrl-if", "syscon";
|
||||
interface-type = "ace";
|
||||
reg = <0x5000 0x1000>;
|
||||
};
|
||||
|
@ -901,6 +901,11 @@
|
|||
};
|
||||
};
|
||||
|
||||
hifsys: syscon@1af00000 {
|
||||
compatible = "mediatek,mt7622-hifsys", "syscon";
|
||||
reg = <0 0x1af00000 0 0x70>;
|
||||
};
|
||||
|
||||
ethsys: syscon@1b000000 {
|
||||
compatible = "mediatek,mt7622-ethsys",
|
||||
"syscon";
|
||||
|
@ -919,6 +924,26 @@
|
|||
#dma-cells = <1>;
|
||||
};
|
||||
|
||||
pcie_mirror: pcie-mirror@10000400 {
|
||||
compatible = "mediatek,mt7622-pcie-mirror",
|
||||
"syscon";
|
||||
reg = <0 0x10000400 0 0x10>;
|
||||
};
|
||||
|
||||
wed0: wed@1020a000 {
|
||||
compatible = "mediatek,mt7622-wed",
|
||||
"syscon";
|
||||
reg = <0 0x1020a000 0 0x1000>;
|
||||
interrupts = <GIC_SPI 214 IRQ_TYPE_LEVEL_LOW>;
|
||||
};
|
||||
|
||||
wed1: wed@1020b000 {
|
||||
compatible = "mediatek,mt7622-wed",
|
||||
"syscon";
|
||||
reg = <0 0x1020b000 0 0x1000>;
|
||||
interrupts = <GIC_SPI 215 IRQ_TYPE_LEVEL_LOW>;
|
||||
};
|
||||
|
||||
eth: ethernet@1b100000 {
|
||||
compatible = "mediatek,mt7622-eth",
|
||||
"mediatek,mt2701-eth",
|
||||
|
@ -945,6 +970,11 @@
|
|||
power-domains = <&scpsys MT7622_POWER_DOMAIN_ETHSYS>;
|
||||
mediatek,ethsys = <ðsys>;
|
||||
mediatek,sgmiisys = <&sgmiisys>;
|
||||
cci-control-port = <&cci_control2>;
|
||||
mediatek,wed = <&wed0>, <&wed1>;
|
||||
mediatek,pcie-mirror = <&pcie_mirror>;
|
||||
mediatek,hifsys = <&hifsys>;
|
||||
dma-coherent;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
status = "disabled";
|
||||
|
|
|
@ -25,6 +25,80 @@
|
|||
};
|
||||
};
|
||||
|
||||
ð {
|
||||
status = "okay";
|
||||
|
||||
gmac0: mac@0 {
|
||||
compatible = "mediatek,eth-mac";
|
||||
reg = <0>;
|
||||
phy-mode = "2500base-x";
|
||||
|
||||
fixed-link {
|
||||
speed = <2500>;
|
||||
full-duplex;
|
||||
pause;
|
||||
};
|
||||
};
|
||||
|
||||
mdio: mdio-bus {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
};
|
||||
};
|
||||
|
||||
&mdio {
|
||||
switch: switch@0 {
|
||||
compatible = "mediatek,mt7531";
|
||||
reg = <31>;
|
||||
reset-gpios = <&pio 5 0>;
|
||||
};
|
||||
};
|
||||
|
||||
&switch {
|
||||
ports {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
port@0 {
|
||||
reg = <0>;
|
||||
label = "lan0";
|
||||
};
|
||||
|
||||
port@1 {
|
||||
reg = <1>;
|
||||
label = "lan1";
|
||||
};
|
||||
|
||||
port@2 {
|
||||
reg = <2>;
|
||||
label = "lan2";
|
||||
};
|
||||
|
||||
port@3 {
|
||||
reg = <3>;
|
||||
label = "lan3";
|
||||
};
|
||||
|
||||
port@4 {
|
||||
reg = <4>;
|
||||
label = "lan4";
|
||||
};
|
||||
|
||||
port@6 {
|
||||
reg = <6>;
|
||||
label = "cpu";
|
||||
ethernet = <&gmac0>;
|
||||
phy-mode = "2500base-x";
|
||||
|
||||
fixed-link {
|
||||
speed = <2500>;
|
||||
full-duplex;
|
||||
pause;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
&uart0 {
|
||||
status = "okay";
|
||||
};
|
||||
|
|
|
@ -222,6 +222,45 @@
|
|||
#reset-cells = <1>;
|
||||
};
|
||||
|
||||
eth: ethernet@15100000 {
|
||||
compatible = "mediatek,mt7986-eth";
|
||||
reg = <0 0x15100000 0 0x80000>;
|
||||
interrupts = <GIC_SPI 196 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 197 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 198 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 199 IRQ_TYPE_LEVEL_HIGH>;
|
||||
clocks = <ðsys CLK_ETH_FE_EN>,
|
||||
<ðsys CLK_ETH_GP2_EN>,
|
||||
<ðsys CLK_ETH_GP1_EN>,
|
||||
<ðsys CLK_ETH_WOCPU1_EN>,
|
||||
<ðsys CLK_ETH_WOCPU0_EN>,
|
||||
<&sgmiisys0 CLK_SGMII0_TX250M_EN>,
|
||||
<&sgmiisys0 CLK_SGMII0_RX250M_EN>,
|
||||
<&sgmiisys0 CLK_SGMII0_CDR_REF>,
|
||||
<&sgmiisys0 CLK_SGMII0_CDR_FB>,
|
||||
<&sgmiisys1 CLK_SGMII1_TX250M_EN>,
|
||||
<&sgmiisys1 CLK_SGMII1_RX250M_EN>,
|
||||
<&sgmiisys1 CLK_SGMII1_CDR_REF>,
|
||||
<&sgmiisys1 CLK_SGMII1_CDR_FB>,
|
||||
<&topckgen CLK_TOP_NETSYS_SEL>,
|
||||
<&topckgen CLK_TOP_NETSYS_500M_SEL>;
|
||||
clock-names = "fe", "gp2", "gp1", "wocpu1", "wocpu0",
|
||||
"sgmii_tx250m", "sgmii_rx250m",
|
||||
"sgmii_cdr_ref", "sgmii_cdr_fb",
|
||||
"sgmii2_tx250m", "sgmii2_rx250m",
|
||||
"sgmii2_cdr_ref", "sgmii2_cdr_fb",
|
||||
"netsys0", "netsys1";
|
||||
assigned-clocks = <&topckgen CLK_TOP_NETSYS_2X_SEL>,
|
||||
<&topckgen CLK_TOP_SGM_325M_SEL>;
|
||||
assigned-clock-parents = <&apmixedsys CLK_APMIXED_NET2PLL>,
|
||||
<&apmixedsys CLK_APMIXED_SGMPLL>;
|
||||
mediatek,ethsys = <ðsys>;
|
||||
mediatek,sgmiisys = <&sgmiisys0>, <&sgmiisys1>;
|
||||
#reset-cells = <1>;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
status = "disabled";
|
||||
};
|
||||
};
|
||||
|
||||
};
|
||||
|
|
|
@ -28,3 +28,73 @@
|
|||
&uart0 {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
ð {
|
||||
status = "okay";
|
||||
|
||||
gmac0: mac@0 {
|
||||
compatible = "mediatek,eth-mac";
|
||||
reg = <0>;
|
||||
phy-mode = "2500base-x";
|
||||
|
||||
fixed-link {
|
||||
speed = <2500>;
|
||||
full-duplex;
|
||||
pause;
|
||||
};
|
||||
};
|
||||
|
||||
mdio: mdio-bus {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
switch@0 {
|
||||
compatible = "mediatek,mt7531";
|
||||
reg = <31>;
|
||||
reset-gpios = <&pio 5 0>;
|
||||
|
||||
ports {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
port@0 {
|
||||
reg = <0>;
|
||||
label = "lan0";
|
||||
};
|
||||
|
||||
port@1 {
|
||||
reg = <1>;
|
||||
label = "lan1";
|
||||
};
|
||||
|
||||
port@2 {
|
||||
reg = <2>;
|
||||
label = "lan2";
|
||||
};
|
||||
|
||||
port@3 {
|
||||
reg = <3>;
|
||||
label = "lan3";
|
||||
};
|
||||
|
||||
port@4 {
|
||||
reg = <4>;
|
||||
label = "lan4";
|
||||
};
|
||||
|
||||
port@6 {
|
||||
reg = <6>;
|
||||
label = "cpu";
|
||||
ethernet = <&gmac0>;
|
||||
phy-mode = "2500base-x";
|
||||
|
||||
fixed-link {
|
||||
speed = <2500>;
|
||||
full-duplex;
|
||||
pause;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
|
|
@ -201,6 +201,8 @@ enum aarch64_insn_size_type {
|
|||
enum aarch64_insn_ldst_type {
|
||||
AARCH64_INSN_LDST_LOAD_REG_OFFSET,
|
||||
AARCH64_INSN_LDST_STORE_REG_OFFSET,
|
||||
AARCH64_INSN_LDST_LOAD_IMM_OFFSET,
|
||||
AARCH64_INSN_LDST_STORE_IMM_OFFSET,
|
||||
AARCH64_INSN_LDST_LOAD_PAIR_PRE_INDEX,
|
||||
AARCH64_INSN_LDST_STORE_PAIR_PRE_INDEX,
|
||||
AARCH64_INSN_LDST_LOAD_PAIR_POST_INDEX,
|
||||
|
@ -335,6 +337,7 @@ __AARCH64_INSN_FUNCS(load_pre, 0x3FE00C00, 0x38400C00)
|
|||
__AARCH64_INSN_FUNCS(store_post, 0x3FE00C00, 0x38000400)
|
||||
__AARCH64_INSN_FUNCS(load_post, 0x3FE00C00, 0x38400400)
|
||||
__AARCH64_INSN_FUNCS(str_reg, 0x3FE0EC00, 0x38206800)
|
||||
__AARCH64_INSN_FUNCS(str_imm, 0x3FC00000, 0x39000000)
|
||||
__AARCH64_INSN_FUNCS(ldadd, 0x3F20FC00, 0x38200000)
|
||||
__AARCH64_INSN_FUNCS(ldclr, 0x3F20FC00, 0x38201000)
|
||||
__AARCH64_INSN_FUNCS(ldeor, 0x3F20FC00, 0x38202000)
|
||||
|
@ -342,6 +345,7 @@ __AARCH64_INSN_FUNCS(ldset, 0x3F20FC00, 0x38203000)
|
|||
__AARCH64_INSN_FUNCS(swp, 0x3F20FC00, 0x38208000)
|
||||
__AARCH64_INSN_FUNCS(cas, 0x3FA07C00, 0x08A07C00)
|
||||
__AARCH64_INSN_FUNCS(ldr_reg, 0x3FE0EC00, 0x38606800)
|
||||
__AARCH64_INSN_FUNCS(ldr_imm, 0x3FC00000, 0x39400000)
|
||||
__AARCH64_INSN_FUNCS(ldr_lit, 0xBF000000, 0x18000000)
|
||||
__AARCH64_INSN_FUNCS(ldrsw_lit, 0xFF000000, 0x98000000)
|
||||
__AARCH64_INSN_FUNCS(exclusive, 0x3F800000, 0x08000000)
|
||||
|
@ -501,6 +505,11 @@ u32 aarch64_insn_gen_load_store_reg(enum aarch64_insn_register reg,
|
|||
enum aarch64_insn_register offset,
|
||||
enum aarch64_insn_size_type size,
|
||||
enum aarch64_insn_ldst_type type);
|
||||
u32 aarch64_insn_gen_load_store_imm(enum aarch64_insn_register reg,
|
||||
enum aarch64_insn_register base,
|
||||
unsigned int imm,
|
||||
enum aarch64_insn_size_type size,
|
||||
enum aarch64_insn_ldst_type type);
|
||||
u32 aarch64_insn_gen_load_store_pair(enum aarch64_insn_register reg1,
|
||||
enum aarch64_insn_register reg2,
|
||||
enum aarch64_insn_register base,
|
||||
|
|
|
@ -299,29 +299,24 @@ static u32 aarch64_insn_encode_register(enum aarch64_insn_register_type type,
|
|||
return insn;
|
||||
}
|
||||
|
||||
static const u32 aarch64_insn_ldst_size[] = {
|
||||
[AARCH64_INSN_SIZE_8] = 0,
|
||||
[AARCH64_INSN_SIZE_16] = 1,
|
||||
[AARCH64_INSN_SIZE_32] = 2,
|
||||
[AARCH64_INSN_SIZE_64] = 3,
|
||||
};
|
||||
|
||||
static u32 aarch64_insn_encode_ldst_size(enum aarch64_insn_size_type type,
|
||||
u32 insn)
|
||||
{
|
||||
u32 size;
|
||||
|
||||
switch (type) {
|
||||
case AARCH64_INSN_SIZE_8:
|
||||
size = 0;
|
||||
break;
|
||||
case AARCH64_INSN_SIZE_16:
|
||||
size = 1;
|
||||
break;
|
||||
case AARCH64_INSN_SIZE_32:
|
||||
size = 2;
|
||||
break;
|
||||
case AARCH64_INSN_SIZE_64:
|
||||
size = 3;
|
||||
break;
|
||||
default:
|
||||
if (type < AARCH64_INSN_SIZE_8 || type > AARCH64_INSN_SIZE_64) {
|
||||
pr_err("%s: unknown size encoding %d\n", __func__, type);
|
||||
return AARCH64_BREAK_FAULT;
|
||||
}
|
||||
|
||||
size = aarch64_insn_ldst_size[type];
|
||||
insn &= ~GENMASK(31, 30);
|
||||
insn |= size << 30;
|
||||
|
||||
|
@ -504,6 +499,50 @@ u32 aarch64_insn_gen_load_store_reg(enum aarch64_insn_register reg,
|
|||
offset);
|
||||
}
|
||||
|
||||
u32 aarch64_insn_gen_load_store_imm(enum aarch64_insn_register reg,
|
||||
enum aarch64_insn_register base,
|
||||
unsigned int imm,
|
||||
enum aarch64_insn_size_type size,
|
||||
enum aarch64_insn_ldst_type type)
|
||||
{
|
||||
u32 insn;
|
||||
u32 shift;
|
||||
|
||||
if (size < AARCH64_INSN_SIZE_8 || size > AARCH64_INSN_SIZE_64) {
|
||||
pr_err("%s: unknown size encoding %d\n", __func__, type);
|
||||
return AARCH64_BREAK_FAULT;
|
||||
}
|
||||
|
||||
shift = aarch64_insn_ldst_size[size];
|
||||
if (imm & ~(BIT(12 + shift) - BIT(shift))) {
|
||||
pr_err("%s: invalid imm: %d\n", __func__, imm);
|
||||
return AARCH64_BREAK_FAULT;
|
||||
}
|
||||
|
||||
imm >>= shift;
|
||||
|
||||
switch (type) {
|
||||
case AARCH64_INSN_LDST_LOAD_IMM_OFFSET:
|
||||
insn = aarch64_insn_get_ldr_imm_value();
|
||||
break;
|
||||
case AARCH64_INSN_LDST_STORE_IMM_OFFSET:
|
||||
insn = aarch64_insn_get_str_imm_value();
|
||||
break;
|
||||
default:
|
||||
pr_err("%s: unknown load/store encoding %d\n", __func__, type);
|
||||
return AARCH64_BREAK_FAULT;
|
||||
}
|
||||
|
||||
insn = aarch64_insn_encode_ldst_size(size, insn);
|
||||
|
||||
insn = aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RT, insn, reg);
|
||||
|
||||
insn = aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RN, insn,
|
||||
base);
|
||||
|
||||
return aarch64_insn_encode_immediate(AARCH64_INSN_IMM_12, insn, imm);
|
||||
}
|
||||
|
||||
u32 aarch64_insn_gen_load_store_pair(enum aarch64_insn_register reg1,
|
||||
enum aarch64_insn_register reg2,
|
||||
enum aarch64_insn_register base,
|
||||
|
|
|
@ -66,6 +66,20 @@
|
|||
#define A64_STR64(Xt, Xn, Xm) A64_LS_REG(Xt, Xn, Xm, 64, STORE)
|
||||
#define A64_LDR64(Xt, Xn, Xm) A64_LS_REG(Xt, Xn, Xm, 64, LOAD)
|
||||
|
||||
/* Load/store register (immediate offset) */
|
||||
#define A64_LS_IMM(Rt, Rn, imm, size, type) \
|
||||
aarch64_insn_gen_load_store_imm(Rt, Rn, imm, \
|
||||
AARCH64_INSN_SIZE_##size, \
|
||||
AARCH64_INSN_LDST_##type##_IMM_OFFSET)
|
||||
#define A64_STRBI(Wt, Xn, imm) A64_LS_IMM(Wt, Xn, imm, 8, STORE)
|
||||
#define A64_LDRBI(Wt, Xn, imm) A64_LS_IMM(Wt, Xn, imm, 8, LOAD)
|
||||
#define A64_STRHI(Wt, Xn, imm) A64_LS_IMM(Wt, Xn, imm, 16, STORE)
|
||||
#define A64_LDRHI(Wt, Xn, imm) A64_LS_IMM(Wt, Xn, imm, 16, LOAD)
|
||||
#define A64_STR32I(Wt, Xn, imm) A64_LS_IMM(Wt, Xn, imm, 32, STORE)
|
||||
#define A64_LDR32I(Wt, Xn, imm) A64_LS_IMM(Wt, Xn, imm, 32, LOAD)
|
||||
#define A64_STR64I(Xt, Xn, imm) A64_LS_IMM(Xt, Xn, imm, 64, STORE)
|
||||
#define A64_LDR64I(Xt, Xn, imm) A64_LS_IMM(Xt, Xn, imm, 64, LOAD)
|
||||
|
||||
/* Load/store register pair */
|
||||
#define A64_LS_PAIR(Rt, Rt2, Rn, offset, ls, type) \
|
||||
aarch64_insn_gen_load_store_pair(Rt, Rt2, Rn, offset, \
|
||||
|
@ -249,6 +263,9 @@
|
|||
/* HINTs */
|
||||
#define A64_HINT(x) aarch64_insn_gen_hint(x)
|
||||
|
||||
#define A64_PACIASP A64_HINT(AARCH64_INSN_HINT_PACIASP)
|
||||
#define A64_AUTIASP A64_HINT(AARCH64_INSN_HINT_AUTIASP)
|
||||
|
||||
/* BTI */
|
||||
#define A64_BTI_C A64_HINT(AARCH64_INSN_HINT_BTIC)
|
||||
#define A64_BTI_J A64_HINT(AARCH64_INSN_HINT_BTIJ)
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
#define TMP_REG_2 (MAX_BPF_JIT_REG + 1)
|
||||
#define TCALL_CNT (MAX_BPF_JIT_REG + 2)
|
||||
#define TMP_REG_3 (MAX_BPF_JIT_REG + 3)
|
||||
#define FP_BOTTOM (MAX_BPF_JIT_REG + 4)
|
||||
|
||||
#define check_imm(bits, imm) do { \
|
||||
if ((((imm) > 0) && ((imm) >> (bits))) || \
|
||||
|
@ -63,6 +64,7 @@ static const int bpf2a64[] = {
|
|||
[TCALL_CNT] = A64_R(26),
|
||||
/* temporary register for blinding constants */
|
||||
[BPF_REG_AX] = A64_R(9),
|
||||
[FP_BOTTOM] = A64_R(27),
|
||||
};
|
||||
|
||||
struct jit_ctx {
|
||||
|
@ -73,6 +75,7 @@ struct jit_ctx {
|
|||
int exentry_idx;
|
||||
__le32 *image;
|
||||
u32 stack_size;
|
||||
int fpb_offset;
|
||||
};
|
||||
|
||||
static inline void emit(const u32 insn, struct jit_ctx *ctx)
|
||||
|
@ -191,11 +194,53 @@ static bool is_addsub_imm(u32 imm)
|
|||
return !(imm & ~0xfff) || !(imm & ~0xfff000);
|
||||
}
|
||||
|
||||
/*
|
||||
* There are 3 types of AArch64 LDR/STR (immediate) instruction:
|
||||
* Post-index, Pre-index, Unsigned offset.
|
||||
*
|
||||
* For BPF ldr/str, the "unsigned offset" type is sufficient.
|
||||
*
|
||||
* "Unsigned offset" type LDR(immediate) format:
|
||||
*
|
||||
* 3 2 1 0
|
||||
* 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
|
||||
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
* |x x|1 1 1 0 0 1 0 1| imm12 | Rn | Rt |
|
||||
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
* scale
|
||||
*
|
||||
* "Unsigned offset" type STR(immediate) format:
|
||||
* 3 2 1 0
|
||||
* 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
|
||||
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
* |x x|1 1 1 0 0 1 0 0| imm12 | Rn | Rt |
|
||||
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
* scale
|
||||
*
|
||||
* The offset is calculated from imm12 and scale in the following way:
|
||||
*
|
||||
* offset = (u64)imm12 << scale
|
||||
*/
|
||||
static bool is_lsi_offset(int offset, int scale)
|
||||
{
|
||||
if (offset < 0)
|
||||
return false;
|
||||
|
||||
if (offset > (0xFFF << scale))
|
||||
return false;
|
||||
|
||||
if (offset & ((1 << scale) - 1))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Tail call offset to jump into */
|
||||
#if IS_ENABLED(CONFIG_ARM64_BTI_KERNEL)
|
||||
#define PROLOGUE_OFFSET 8
|
||||
#if IS_ENABLED(CONFIG_ARM64_BTI_KERNEL) || \
|
||||
IS_ENABLED(CONFIG_ARM64_PTR_AUTH_KERNEL)
|
||||
#define PROLOGUE_OFFSET 9
|
||||
#else
|
||||
#define PROLOGUE_OFFSET 7
|
||||
#define PROLOGUE_OFFSET 8
|
||||
#endif
|
||||
|
||||
static int build_prologue(struct jit_ctx *ctx, bool ebpf_from_cbpf)
|
||||
|
@ -207,6 +252,7 @@ static int build_prologue(struct jit_ctx *ctx, bool ebpf_from_cbpf)
|
|||
const u8 r9 = bpf2a64[BPF_REG_9];
|
||||
const u8 fp = bpf2a64[BPF_REG_FP];
|
||||
const u8 tcc = bpf2a64[TCALL_CNT];
|
||||
const u8 fpb = bpf2a64[FP_BOTTOM];
|
||||
const int idx0 = ctx->idx;
|
||||
int cur_offset;
|
||||
|
||||
|
@ -233,8 +279,11 @@ static int build_prologue(struct jit_ctx *ctx, bool ebpf_from_cbpf)
|
|||
*
|
||||
*/
|
||||
|
||||
/* Sign lr */
|
||||
if (IS_ENABLED(CONFIG_ARM64_PTR_AUTH_KERNEL))
|
||||
emit(A64_PACIASP, ctx);
|
||||
/* BTI landing pad */
|
||||
if (IS_ENABLED(CONFIG_ARM64_BTI_KERNEL))
|
||||
else if (IS_ENABLED(CONFIG_ARM64_BTI_KERNEL))
|
||||
emit(A64_BTI_C, ctx);
|
||||
|
||||
/* Save FP and LR registers to stay align with ARM64 AAPCS */
|
||||
|
@ -245,6 +294,7 @@ static int build_prologue(struct jit_ctx *ctx, bool ebpf_from_cbpf)
|
|||
emit(A64_PUSH(r6, r7, A64_SP), ctx);
|
||||
emit(A64_PUSH(r8, r9, A64_SP), ctx);
|
||||
emit(A64_PUSH(fp, tcc, A64_SP), ctx);
|
||||
emit(A64_PUSH(fpb, A64_R(28), A64_SP), ctx);
|
||||
|
||||
/* Set up BPF prog stack base register */
|
||||
emit(A64_MOV(1, fp, A64_SP), ctx);
|
||||
|
@ -265,6 +315,8 @@ static int build_prologue(struct jit_ctx *ctx, bool ebpf_from_cbpf)
|
|||
emit(A64_BTI_J, ctx);
|
||||
}
|
||||
|
||||
emit(A64_SUB_I(1, fpb, fp, ctx->fpb_offset), ctx);
|
||||
|
||||
/* Stack must be multiples of 16B */
|
||||
ctx->stack_size = round_up(prog->aux->stack_depth, 16);
|
||||
|
||||
|
@ -512,10 +564,13 @@ static void build_epilogue(struct jit_ctx *ctx)
|
|||
const u8 r8 = bpf2a64[BPF_REG_8];
|
||||
const u8 r9 = bpf2a64[BPF_REG_9];
|
||||
const u8 fp = bpf2a64[BPF_REG_FP];
|
||||
const u8 fpb = bpf2a64[FP_BOTTOM];
|
||||
|
||||
/* We're done with BPF stack */
|
||||
emit(A64_ADD_I(1, A64_SP, A64_SP, ctx->stack_size), ctx);
|
||||
|
||||
/* Restore x27 and x28 */
|
||||
emit(A64_POP(fpb, A64_R(28), A64_SP), ctx);
|
||||
/* Restore fs (x25) and x26 */
|
||||
emit(A64_POP(fp, A64_R(26), A64_SP), ctx);
|
||||
|
||||
|
@ -529,6 +584,10 @@ static void build_epilogue(struct jit_ctx *ctx)
|
|||
/* Set return value */
|
||||
emit(A64_MOV(1, A64_R(0), r0), ctx);
|
||||
|
||||
/* Authenticate lr */
|
||||
if (IS_ENABLED(CONFIG_ARM64_PTR_AUTH_KERNEL))
|
||||
emit(A64_AUTIASP, ctx);
|
||||
|
||||
emit(A64_RET(A64_LR), ctx);
|
||||
}
|
||||
|
||||
|
@ -609,6 +668,8 @@ static int build_insn(const struct bpf_insn *insn, struct jit_ctx *ctx,
|
|||
const u8 src = bpf2a64[insn->src_reg];
|
||||
const u8 tmp = bpf2a64[TMP_REG_1];
|
||||
const u8 tmp2 = bpf2a64[TMP_REG_2];
|
||||
const u8 fp = bpf2a64[BPF_REG_FP];
|
||||
const u8 fpb = bpf2a64[FP_BOTTOM];
|
||||
const s16 off = insn->off;
|
||||
const s32 imm = insn->imm;
|
||||
const int i = insn - ctx->prog->insnsi;
|
||||
|
@ -617,6 +678,9 @@ static int build_insn(const struct bpf_insn *insn, struct jit_ctx *ctx,
|
|||
u8 jmp_cond;
|
||||
s32 jmp_offset;
|
||||
u32 a64_insn;
|
||||
u8 src_adj;
|
||||
u8 dst_adj;
|
||||
int off_adj;
|
||||
int ret;
|
||||
|
||||
switch (code) {
|
||||
|
@ -971,19 +1035,45 @@ emit_cond_jmp:
|
|||
case BPF_LDX | BPF_PROBE_MEM | BPF_W:
|
||||
case BPF_LDX | BPF_PROBE_MEM | BPF_H:
|
||||
case BPF_LDX | BPF_PROBE_MEM | BPF_B:
|
||||
emit_a64_mov_i(1, tmp, off, ctx);
|
||||
if (ctx->fpb_offset > 0 && src == fp) {
|
||||
src_adj = fpb;
|
||||
off_adj = off + ctx->fpb_offset;
|
||||
} else {
|
||||
src_adj = src;
|
||||
off_adj = off;
|
||||
}
|
||||
switch (BPF_SIZE(code)) {
|
||||
case BPF_W:
|
||||
emit(A64_LDR32(dst, src, tmp), ctx);
|
||||
if (is_lsi_offset(off_adj, 2)) {
|
||||
emit(A64_LDR32I(dst, src_adj, off_adj), ctx);
|
||||
} else {
|
||||
emit_a64_mov_i(1, tmp, off, ctx);
|
||||
emit(A64_LDR32(dst, src, tmp), ctx);
|
||||
}
|
||||
break;
|
||||
case BPF_H:
|
||||
emit(A64_LDRH(dst, src, tmp), ctx);
|
||||
if (is_lsi_offset(off_adj, 1)) {
|
||||
emit(A64_LDRHI(dst, src_adj, off_adj), ctx);
|
||||
} else {
|
||||
emit_a64_mov_i(1, tmp, off, ctx);
|
||||
emit(A64_LDRH(dst, src, tmp), ctx);
|
||||
}
|
||||
break;
|
||||
case BPF_B:
|
||||
emit(A64_LDRB(dst, src, tmp), ctx);
|
||||
if (is_lsi_offset(off_adj, 0)) {
|
||||
emit(A64_LDRBI(dst, src_adj, off_adj), ctx);
|
||||
} else {
|
||||
emit_a64_mov_i(1, tmp, off, ctx);
|
||||
emit(A64_LDRB(dst, src, tmp), ctx);
|
||||
}
|
||||
break;
|
||||
case BPF_DW:
|
||||
emit(A64_LDR64(dst, src, tmp), ctx);
|
||||
if (is_lsi_offset(off_adj, 3)) {
|
||||
emit(A64_LDR64I(dst, src_adj, off_adj), ctx);
|
||||
} else {
|
||||
emit_a64_mov_i(1, tmp, off, ctx);
|
||||
emit(A64_LDR64(dst, src, tmp), ctx);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -1010,21 +1100,47 @@ emit_cond_jmp:
|
|||
case BPF_ST | BPF_MEM | BPF_H:
|
||||
case BPF_ST | BPF_MEM | BPF_B:
|
||||
case BPF_ST | BPF_MEM | BPF_DW:
|
||||
if (ctx->fpb_offset > 0 && dst == fp) {
|
||||
dst_adj = fpb;
|
||||
off_adj = off + ctx->fpb_offset;
|
||||
} else {
|
||||
dst_adj = dst;
|
||||
off_adj = off;
|
||||
}
|
||||
/* Load imm to a register then store it */
|
||||
emit_a64_mov_i(1, tmp2, off, ctx);
|
||||
emit_a64_mov_i(1, tmp, imm, ctx);
|
||||
switch (BPF_SIZE(code)) {
|
||||
case BPF_W:
|
||||
emit(A64_STR32(tmp, dst, tmp2), ctx);
|
||||
if (is_lsi_offset(off_adj, 2)) {
|
||||
emit(A64_STR32I(tmp, dst_adj, off_adj), ctx);
|
||||
} else {
|
||||
emit_a64_mov_i(1, tmp2, off, ctx);
|
||||
emit(A64_STR32(tmp, dst, tmp2), ctx);
|
||||
}
|
||||
break;
|
||||
case BPF_H:
|
||||
emit(A64_STRH(tmp, dst, tmp2), ctx);
|
||||
if (is_lsi_offset(off_adj, 1)) {
|
||||
emit(A64_STRHI(tmp, dst_adj, off_adj), ctx);
|
||||
} else {
|
||||
emit_a64_mov_i(1, tmp2, off, ctx);
|
||||
emit(A64_STRH(tmp, dst, tmp2), ctx);
|
||||
}
|
||||
break;
|
||||
case BPF_B:
|
||||
emit(A64_STRB(tmp, dst, tmp2), ctx);
|
||||
if (is_lsi_offset(off_adj, 0)) {
|
||||
emit(A64_STRBI(tmp, dst_adj, off_adj), ctx);
|
||||
} else {
|
||||
emit_a64_mov_i(1, tmp2, off, ctx);
|
||||
emit(A64_STRB(tmp, dst, tmp2), ctx);
|
||||
}
|
||||
break;
|
||||
case BPF_DW:
|
||||
emit(A64_STR64(tmp, dst, tmp2), ctx);
|
||||
if (is_lsi_offset(off_adj, 3)) {
|
||||
emit(A64_STR64I(tmp, dst_adj, off_adj), ctx);
|
||||
} else {
|
||||
emit_a64_mov_i(1, tmp2, off, ctx);
|
||||
emit(A64_STR64(tmp, dst, tmp2), ctx);
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
@ -1034,19 +1150,45 @@ emit_cond_jmp:
|
|||
case BPF_STX | BPF_MEM | BPF_H:
|
||||
case BPF_STX | BPF_MEM | BPF_B:
|
||||
case BPF_STX | BPF_MEM | BPF_DW:
|
||||
emit_a64_mov_i(1, tmp, off, ctx);
|
||||
if (ctx->fpb_offset > 0 && dst == fp) {
|
||||
dst_adj = fpb;
|
||||
off_adj = off + ctx->fpb_offset;
|
||||
} else {
|
||||
dst_adj = dst;
|
||||
off_adj = off;
|
||||
}
|
||||
switch (BPF_SIZE(code)) {
|
||||
case BPF_W:
|
||||
emit(A64_STR32(src, dst, tmp), ctx);
|
||||
if (is_lsi_offset(off_adj, 2)) {
|
||||
emit(A64_STR32I(src, dst_adj, off_adj), ctx);
|
||||
} else {
|
||||
emit_a64_mov_i(1, tmp, off, ctx);
|
||||
emit(A64_STR32(src, dst, tmp), ctx);
|
||||
}
|
||||
break;
|
||||
case BPF_H:
|
||||
emit(A64_STRH(src, dst, tmp), ctx);
|
||||
if (is_lsi_offset(off_adj, 1)) {
|
||||
emit(A64_STRHI(src, dst_adj, off_adj), ctx);
|
||||
} else {
|
||||
emit_a64_mov_i(1, tmp, off, ctx);
|
||||
emit(A64_STRH(src, dst, tmp), ctx);
|
||||
}
|
||||
break;
|
||||
case BPF_B:
|
||||
emit(A64_STRB(src, dst, tmp), ctx);
|
||||
if (is_lsi_offset(off_adj, 0)) {
|
||||
emit(A64_STRBI(src, dst_adj, off_adj), ctx);
|
||||
} else {
|
||||
emit_a64_mov_i(1, tmp, off, ctx);
|
||||
emit(A64_STRB(src, dst, tmp), ctx);
|
||||
}
|
||||
break;
|
||||
case BPF_DW:
|
||||
emit(A64_STR64(src, dst, tmp), ctx);
|
||||
if (is_lsi_offset(off_adj, 3)) {
|
||||
emit(A64_STR64I(src, dst_adj, off_adj), ctx);
|
||||
} else {
|
||||
emit_a64_mov_i(1, tmp, off, ctx);
|
||||
emit(A64_STR64(src, dst, tmp), ctx);
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
@ -1069,6 +1211,79 @@ emit_cond_jmp:
|
|||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Return 0 if FP may change at runtime, otherwise find the minimum negative
|
||||
* offset to FP, converts it to positive number, and align down to 8 bytes.
|
||||
*/
|
||||
static int find_fpb_offset(struct bpf_prog *prog)
|
||||
{
|
||||
int i;
|
||||
int offset = 0;
|
||||
|
||||
for (i = 0; i < prog->len; i++) {
|
||||
const struct bpf_insn *insn = &prog->insnsi[i];
|
||||
const u8 class = BPF_CLASS(insn->code);
|
||||
const u8 mode = BPF_MODE(insn->code);
|
||||
const u8 src = insn->src_reg;
|
||||
const u8 dst = insn->dst_reg;
|
||||
const s32 imm = insn->imm;
|
||||
const s16 off = insn->off;
|
||||
|
||||
switch (class) {
|
||||
case BPF_STX:
|
||||
case BPF_ST:
|
||||
/* fp holds atomic operation result */
|
||||
if (class == BPF_STX && mode == BPF_ATOMIC &&
|
||||
((imm == BPF_XCHG ||
|
||||
imm == (BPF_FETCH | BPF_ADD) ||
|
||||
imm == (BPF_FETCH | BPF_AND) ||
|
||||
imm == (BPF_FETCH | BPF_XOR) ||
|
||||
imm == (BPF_FETCH | BPF_OR)) &&
|
||||
src == BPF_REG_FP))
|
||||
return 0;
|
||||
|
||||
if (mode == BPF_MEM && dst == BPF_REG_FP &&
|
||||
off < offset)
|
||||
offset = insn->off;
|
||||
break;
|
||||
|
||||
case BPF_JMP32:
|
||||
case BPF_JMP:
|
||||
break;
|
||||
|
||||
case BPF_LDX:
|
||||
case BPF_LD:
|
||||
/* fp holds load result */
|
||||
if (dst == BPF_REG_FP)
|
||||
return 0;
|
||||
|
||||
if (class == BPF_LDX && mode == BPF_MEM &&
|
||||
src == BPF_REG_FP && off < offset)
|
||||
offset = off;
|
||||
break;
|
||||
|
||||
case BPF_ALU:
|
||||
case BPF_ALU64:
|
||||
default:
|
||||
/* fp holds ALU result */
|
||||
if (dst == BPF_REG_FP)
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (offset < 0) {
|
||||
/*
|
||||
* safely be converted to a positive 'int', since insn->off
|
||||
* is 's16'
|
||||
*/
|
||||
offset = -offset;
|
||||
/* align down to 8 bytes */
|
||||
offset = ALIGN_DOWN(offset, 8);
|
||||
}
|
||||
|
||||
return offset;
|
||||
}
|
||||
|
||||
static int build_body(struct jit_ctx *ctx, bool extra_pass)
|
||||
{
|
||||
const struct bpf_prog *prog = ctx->prog;
|
||||
|
@ -1190,6 +1405,8 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *prog)
|
|||
goto out_off;
|
||||
}
|
||||
|
||||
ctx.fpb_offset = find_fpb_offset(prog);
|
||||
|
||||
/*
|
||||
* 1. Initial fake pass to compute ctx->idx and ctx->offset.
|
||||
*
|
||||
|
|
|
@ -178,12 +178,8 @@ CONFIG_NETCONSOLE=m
|
|||
CONFIG_ATM_TCP=m
|
||||
CONFIG_ATM_LANAI=m
|
||||
CONFIG_ATM_ENI=m
|
||||
CONFIG_ATM_FIRESTREAM=m
|
||||
CONFIG_ATM_ZATM=m
|
||||
CONFIG_ATM_NICSTAR=m
|
||||
CONFIG_ATM_IDT77252=m
|
||||
CONFIG_ATM_AMBASSADOR=m
|
||||
CONFIG_ATM_HORIZON=m
|
||||
CONFIG_ATM_IA=m
|
||||
CONFIG_ATM_FORE200E=m
|
||||
CONFIG_ATM_HE=m
|
||||
|
@ -214,7 +210,6 @@ CONFIG_ATH_DEBUG=y
|
|||
CONFIG_ATH5K=y
|
||||
CONFIG_ATH5K_DEBUG=y
|
||||
CONFIG_WAN=y
|
||||
CONFIG_LANMEDIA=m
|
||||
CONFIG_HDLC=m
|
||||
CONFIG_HDLC_RAW=m
|
||||
CONFIG_HDLC_RAW_ETH=m
|
||||
|
|
|
@ -255,12 +255,8 @@ CONFIG_ARCNET_COM20020_CS=m
|
|||
CONFIG_ATM_TCP=m
|
||||
CONFIG_ATM_LANAI=m
|
||||
CONFIG_ATM_ENI=m
|
||||
CONFIG_ATM_FIRESTREAM=m
|
||||
CONFIG_ATM_ZATM=m
|
||||
CONFIG_ATM_NICSTAR=m
|
||||
CONFIG_ATM_IDT77252=m
|
||||
CONFIG_ATM_AMBASSADOR=m
|
||||
CONFIG_ATM_HORIZON=m
|
||||
CONFIG_ATM_IA=m
|
||||
CONFIG_ATM_FORE200E=m
|
||||
CONFIG_ATM_HE=m
|
||||
|
@ -281,7 +277,6 @@ CONFIG_CHELSIO_T1=m
|
|||
CONFIG_NET_TULIP=y
|
||||
CONFIG_DE2104X=m
|
||||
CONFIG_TULIP=m
|
||||
CONFIG_DE4X5=m
|
||||
CONFIG_WINBOND_840=m
|
||||
CONFIG_DM9102=m
|
||||
CONFIG_ULI526X=m
|
||||
|
@ -363,7 +358,6 @@ CONFIG_USB_AN2720=y
|
|||
CONFIG_USB_EPSON2888=y
|
||||
CONFIG_USB_SIERRA_NET=m
|
||||
CONFIG_WAN=y
|
||||
CONFIG_LANMEDIA=m
|
||||
CONFIG_HDLC=m
|
||||
CONFIG_HDLC_RAW=m
|
||||
CONFIG_HDLC_RAW_ETH=m
|
||||
|
|
|
@ -146,6 +146,8 @@
|
|||
|
||||
#define SO_TXREHASH 74
|
||||
|
||||
#define SO_RCVMARK 75
|
||||
|
||||
#if !defined(__KERNEL__)
|
||||
|
||||
#if __BITS_PER_LONG == 64
|
||||
|
|
|
@ -127,6 +127,8 @@
|
|||
|
||||
#define SO_TXREHASH 0x4048
|
||||
|
||||
#define SO_RCVMARK 0x4049
|
||||
|
||||
#if !defined(__KERNEL__)
|
||||
|
||||
#if __BITS_PER_LONG == 64
|
||||
|
|
|
@ -53,7 +53,6 @@ CONFIG_ATA_GENERIC=y
|
|||
CONFIG_NETDEVICES=y
|
||||
CONFIG_PCNET32=y
|
||||
CONFIG_NET_TULIP=y
|
||||
CONFIG_DE4X5=y
|
||||
CONFIG_MV643XX_ETH=y
|
||||
CONFIG_8139CP=y
|
||||
CONFIG_8139TOO=y
|
||||
|
|
|
@ -444,7 +444,6 @@ CONFIG_NET_TULIP=y
|
|||
CONFIG_DE2104X=m
|
||||
CONFIG_TULIP=m
|
||||
CONFIG_TULIP_MMIO=y
|
||||
CONFIG_DE4X5=m
|
||||
CONFIG_WINBOND_840=m
|
||||
CONFIG_DM9102=m
|
||||
CONFIG_ULI526X=m
|
||||
|
|
|
@ -535,6 +535,43 @@ static inline u32 rv_amoadd_w(u8 rd, u8 rs2, u8 rs1, u8 aq, u8 rl)
|
|||
return rv_amo_insn(0, aq, rl, rs2, rs1, 2, rd, 0x2f);
|
||||
}
|
||||
|
||||
static inline u32 rv_amoand_w(u8 rd, u8 rs2, u8 rs1, u8 aq, u8 rl)
|
||||
{
|
||||
return rv_amo_insn(0xc, aq, rl, rs2, rs1, 2, rd, 0x2f);
|
||||
}
|
||||
|
||||
static inline u32 rv_amoor_w(u8 rd, u8 rs2, u8 rs1, u8 aq, u8 rl)
|
||||
{
|
||||
return rv_amo_insn(0x8, aq, rl, rs2, rs1, 2, rd, 0x2f);
|
||||
}
|
||||
|
||||
static inline u32 rv_amoxor_w(u8 rd, u8 rs2, u8 rs1, u8 aq, u8 rl)
|
||||
{
|
||||
return rv_amo_insn(0x4, aq, rl, rs2, rs1, 2, rd, 0x2f);
|
||||
}
|
||||
|
||||
static inline u32 rv_amoswap_w(u8 rd, u8 rs2, u8 rs1, u8 aq, u8 rl)
|
||||
{
|
||||
return rv_amo_insn(0x1, aq, rl, rs2, rs1, 2, rd, 0x2f);
|
||||
}
|
||||
|
||||
static inline u32 rv_lr_w(u8 rd, u8 rs2, u8 rs1, u8 aq, u8 rl)
|
||||
{
|
||||
return rv_amo_insn(0x2, aq, rl, rs2, rs1, 2, rd, 0x2f);
|
||||
}
|
||||
|
||||
static inline u32 rv_sc_w(u8 rd, u8 rs2, u8 rs1, u8 aq, u8 rl)
|
||||
{
|
||||
return rv_amo_insn(0x3, aq, rl, rs2, rs1, 2, rd, 0x2f);
|
||||
}
|
||||
|
||||
static inline u32 rv_fence(u8 pred, u8 succ)
|
||||
{
|
||||
u16 imm11_0 = pred << 4 | succ;
|
||||
|
||||
return rv_i_insn(imm11_0, 0, 0, 0, 0xf);
|
||||
}
|
||||
|
||||
/* RVC instrutions. */
|
||||
|
||||
static inline u16 rvc_addi4spn(u8 rd, u32 imm10)
|
||||
|
@ -753,6 +790,36 @@ static inline u32 rv_amoadd_d(u8 rd, u8 rs2, u8 rs1, u8 aq, u8 rl)
|
|||
return rv_amo_insn(0, aq, rl, rs2, rs1, 3, rd, 0x2f);
|
||||
}
|
||||
|
||||
static inline u32 rv_amoand_d(u8 rd, u8 rs2, u8 rs1, u8 aq, u8 rl)
|
||||
{
|
||||
return rv_amo_insn(0xc, aq, rl, rs2, rs1, 3, rd, 0x2f);
|
||||
}
|
||||
|
||||
static inline u32 rv_amoor_d(u8 rd, u8 rs2, u8 rs1, u8 aq, u8 rl)
|
||||
{
|
||||
return rv_amo_insn(0x8, aq, rl, rs2, rs1, 3, rd, 0x2f);
|
||||
}
|
||||
|
||||
static inline u32 rv_amoxor_d(u8 rd, u8 rs2, u8 rs1, u8 aq, u8 rl)
|
||||
{
|
||||
return rv_amo_insn(0x4, aq, rl, rs2, rs1, 3, rd, 0x2f);
|
||||
}
|
||||
|
||||
static inline u32 rv_amoswap_d(u8 rd, u8 rs2, u8 rs1, u8 aq, u8 rl)
|
||||
{
|
||||
return rv_amo_insn(0x1, aq, rl, rs2, rs1, 3, rd, 0x2f);
|
||||
}
|
||||
|
||||
static inline u32 rv_lr_d(u8 rd, u8 rs2, u8 rs1, u8 aq, u8 rl)
|
||||
{
|
||||
return rv_amo_insn(0x2, aq, rl, rs2, rs1, 3, rd, 0x2f);
|
||||
}
|
||||
|
||||
static inline u32 rv_sc_d(u8 rd, u8 rs2, u8 rs1, u8 aq, u8 rl)
|
||||
{
|
||||
return rv_amo_insn(0x3, aq, rl, rs2, rs1, 3, rd, 0x2f);
|
||||
}
|
||||
|
||||
/* RV64-only RVC instructions. */
|
||||
|
||||
static inline u16 rvc_ld(u8 rd, u32 imm8, u8 rs1)
|
||||
|
|
|
@ -455,6 +455,90 @@ static int emit_call(bool fixed, u64 addr, struct rv_jit_context *ctx)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void emit_atomic(u8 rd, u8 rs, s16 off, s32 imm, bool is64,
|
||||
struct rv_jit_context *ctx)
|
||||
{
|
||||
u8 r0;
|
||||
int jmp_offset;
|
||||
|
||||
if (off) {
|
||||
if (is_12b_int(off)) {
|
||||
emit_addi(RV_REG_T1, rd, off, ctx);
|
||||
} else {
|
||||
emit_imm(RV_REG_T1, off, ctx);
|
||||
emit_add(RV_REG_T1, RV_REG_T1, rd, ctx);
|
||||
}
|
||||
rd = RV_REG_T1;
|
||||
}
|
||||
|
||||
switch (imm) {
|
||||
/* lock *(u32/u64 *)(dst_reg + off16) <op>= src_reg */
|
||||
case BPF_ADD:
|
||||
emit(is64 ? rv_amoadd_d(RV_REG_ZERO, rs, rd, 0, 0) :
|
||||
rv_amoadd_w(RV_REG_ZERO, rs, rd, 0, 0), ctx);
|
||||
break;
|
||||
case BPF_AND:
|
||||
emit(is64 ? rv_amoand_d(RV_REG_ZERO, rs, rd, 0, 0) :
|
||||
rv_amoand_w(RV_REG_ZERO, rs, rd, 0, 0), ctx);
|
||||
break;
|
||||
case BPF_OR:
|
||||
emit(is64 ? rv_amoor_d(RV_REG_ZERO, rs, rd, 0, 0) :
|
||||
rv_amoor_w(RV_REG_ZERO, rs, rd, 0, 0), ctx);
|
||||
break;
|
||||
case BPF_XOR:
|
||||
emit(is64 ? rv_amoxor_d(RV_REG_ZERO, rs, rd, 0, 0) :
|
||||
rv_amoxor_w(RV_REG_ZERO, rs, rd, 0, 0), ctx);
|
||||
break;
|
||||
/* src_reg = atomic_fetch_<op>(dst_reg + off16, src_reg) */
|
||||
case BPF_ADD | BPF_FETCH:
|
||||
emit(is64 ? rv_amoadd_d(rs, rs, rd, 0, 0) :
|
||||
rv_amoadd_w(rs, rs, rd, 0, 0), ctx);
|
||||
if (!is64)
|
||||
emit_zext_32(rs, ctx);
|
||||
break;
|
||||
case BPF_AND | BPF_FETCH:
|
||||
emit(is64 ? rv_amoand_d(rs, rs, rd, 0, 0) :
|
||||
rv_amoand_w(rs, rs, rd, 0, 0), ctx);
|
||||
if (!is64)
|
||||
emit_zext_32(rs, ctx);
|
||||
break;
|
||||
case BPF_OR | BPF_FETCH:
|
||||
emit(is64 ? rv_amoor_d(rs, rs, rd, 0, 0) :
|
||||
rv_amoor_w(rs, rs, rd, 0, 0), ctx);
|
||||
if (!is64)
|
||||
emit_zext_32(rs, ctx);
|
||||
break;
|
||||
case BPF_XOR | BPF_FETCH:
|
||||
emit(is64 ? rv_amoxor_d(rs, rs, rd, 0, 0) :
|
||||
rv_amoxor_w(rs, rs, rd, 0, 0), ctx);
|
||||
if (!is64)
|
||||
emit_zext_32(rs, ctx);
|
||||
break;
|
||||
/* src_reg = atomic_xchg(dst_reg + off16, src_reg); */
|
||||
case BPF_XCHG:
|
||||
emit(is64 ? rv_amoswap_d(rs, rs, rd, 0, 0) :
|
||||
rv_amoswap_w(rs, rs, rd, 0, 0), ctx);
|
||||
if (!is64)
|
||||
emit_zext_32(rs, ctx);
|
||||
break;
|
||||
/* r0 = atomic_cmpxchg(dst_reg + off16, r0, src_reg); */
|
||||
case BPF_CMPXCHG:
|
||||
r0 = bpf_to_rv_reg(BPF_REG_0, ctx);
|
||||
emit(is64 ? rv_addi(RV_REG_T2, r0, 0) :
|
||||
rv_addiw(RV_REG_T2, r0, 0), ctx);
|
||||
emit(is64 ? rv_lr_d(r0, 0, rd, 0, 0) :
|
||||
rv_lr_w(r0, 0, rd, 0, 0), ctx);
|
||||
jmp_offset = ninsns_rvoff(8);
|
||||
emit(rv_bne(RV_REG_T2, r0, jmp_offset >> 1), ctx);
|
||||
emit(is64 ? rv_sc_d(RV_REG_T3, rs, rd, 0, 0) :
|
||||
rv_sc_w(RV_REG_T3, rs, rd, 0, 0), ctx);
|
||||
jmp_offset = ninsns_rvoff(-6);
|
||||
emit(rv_bne(RV_REG_T3, 0, jmp_offset >> 1), ctx);
|
||||
emit(rv_fence(0x3, 0x3), ctx);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
#define BPF_FIXUP_OFFSET_MASK GENMASK(26, 0)
|
||||
#define BPF_FIXUP_REG_MASK GENMASK(31, 27)
|
||||
|
||||
|
@ -1146,30 +1230,8 @@ out_be:
|
|||
break;
|
||||
case BPF_STX | BPF_ATOMIC | BPF_W:
|
||||
case BPF_STX | BPF_ATOMIC | BPF_DW:
|
||||
if (insn->imm != BPF_ADD) {
|
||||
pr_err("bpf-jit: not supported: atomic operation %02x ***\n",
|
||||
insn->imm);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* atomic_add: lock *(u32 *)(dst + off) += src
|
||||
* atomic_add: lock *(u64 *)(dst + off) += src
|
||||
*/
|
||||
|
||||
if (off) {
|
||||
if (is_12b_int(off)) {
|
||||
emit_addi(RV_REG_T1, rd, off, ctx);
|
||||
} else {
|
||||
emit_imm(RV_REG_T1, off, ctx);
|
||||
emit_add(RV_REG_T1, RV_REG_T1, rd, ctx);
|
||||
}
|
||||
|
||||
rd = RV_REG_T1;
|
||||
}
|
||||
|
||||
emit(BPF_SIZE(code) == BPF_W ?
|
||||
rv_amoadd_w(RV_REG_ZERO, rs, rd, 0, 0) :
|
||||
rv_amoadd_d(RV_REG_ZERO, rs, rd, 0, 0), ctx);
|
||||
emit_atomic(rd, rs, off, imm,
|
||||
BPF_SIZE(code) == BPF_DW, ctx);
|
||||
break;
|
||||
default:
|
||||
pr_err("bpf-jit: unknown opcode %02x\n", code);
|
||||
|
|
|
@ -1809,7 +1809,7 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *fp)
|
|||
/*
|
||||
* Three initial passes:
|
||||
* - 1/2: Determine clobbered registers
|
||||
* - 3: Calculate program size and addrs arrray
|
||||
* - 3: Calculate program size and addrs array
|
||||
*/
|
||||
for (pass = 1; pass <= 3; pass++) {
|
||||
if (bpf_jit_prog(&jit, fp, extra_pass, stack_depth)) {
|
||||
|
|
|
@ -128,6 +128,7 @@
|
|||
|
||||
#define SO_TXREHASH 0x0053
|
||||
|
||||
#define SO_RCVMARK 0x0054
|
||||
|
||||
#if !defined(__KERNEL__)
|
||||
|
||||
|
|
|
@ -1255,7 +1255,8 @@ static int vector_net_open(struct net_device *dev)
|
|||
goto out_close;
|
||||
}
|
||||
|
||||
netif_napi_add(vp->dev, &vp->napi, vector_poll, get_depth(vp->parsed));
|
||||
netif_napi_add_weight(vp->dev, &vp->napi, vector_poll,
|
||||
get_depth(vp->parsed));
|
||||
napi_enable(&vp->napi);
|
||||
|
||||
/* READ IRQ */
|
||||
|
|
|
@ -45,6 +45,7 @@ extern void *text_poke(void *addr, const void *opcode, size_t len);
|
|||
extern void text_poke_sync(void);
|
||||
extern void *text_poke_kgdb(void *addr, const void *opcode, size_t len);
|
||||
extern void *text_poke_copy(void *addr, const void *opcode, size_t len);
|
||||
extern void *text_poke_set(void *addr, int c, size_t len);
|
||||
extern int poke_int3_handler(struct pt_regs *regs);
|
||||
extern void text_poke_bp(void *addr, const void *opcode, size_t len, const void *emulate);
|
||||
|
||||
|
|
|
@ -994,7 +994,21 @@ static inline void unuse_temporary_mm(temp_mm_state_t prev_state)
|
|||
__ro_after_init struct mm_struct *poking_mm;
|
||||
__ro_after_init unsigned long poking_addr;
|
||||
|
||||
static void *__text_poke(void *addr, const void *opcode, size_t len)
|
||||
static void text_poke_memcpy(void *dst, const void *src, size_t len)
|
||||
{
|
||||
memcpy(dst, src, len);
|
||||
}
|
||||
|
||||
static void text_poke_memset(void *dst, const void *src, size_t len)
|
||||
{
|
||||
int c = *(const int *)src;
|
||||
|
||||
memset(dst, c, len);
|
||||
}
|
||||
|
||||
typedef void text_poke_f(void *dst, const void *src, size_t len);
|
||||
|
||||
static void *__text_poke(text_poke_f func, void *addr, const void *src, size_t len)
|
||||
{
|
||||
bool cross_page_boundary = offset_in_page(addr) + len > PAGE_SIZE;
|
||||
struct page *pages[2] = {NULL};
|
||||
|
@ -1059,7 +1073,7 @@ static void *__text_poke(void *addr, const void *opcode, size_t len)
|
|||
prev = use_temporary_mm(poking_mm);
|
||||
|
||||
kasan_disable_current();
|
||||
memcpy((u8 *)poking_addr + offset_in_page(addr), opcode, len);
|
||||
func((u8 *)poking_addr + offset_in_page(addr), src, len);
|
||||
kasan_enable_current();
|
||||
|
||||
/*
|
||||
|
@ -1087,11 +1101,13 @@ static void *__text_poke(void *addr, const void *opcode, size_t len)
|
|||
(cross_page_boundary ? 2 : 1) * PAGE_SIZE,
|
||||
PAGE_SHIFT, false);
|
||||
|
||||
/*
|
||||
* If the text does not match what we just wrote then something is
|
||||
* fundamentally screwy; there's nothing we can really do about that.
|
||||
*/
|
||||
BUG_ON(memcmp(addr, opcode, len));
|
||||
if (func == text_poke_memcpy) {
|
||||
/*
|
||||
* If the text does not match what we just wrote then something is
|
||||
* fundamentally screwy; there's nothing we can really do about that.
|
||||
*/
|
||||
BUG_ON(memcmp(addr, src, len));
|
||||
}
|
||||
|
||||
local_irq_restore(flags);
|
||||
pte_unmap_unlock(ptep, ptl);
|
||||
|
@ -1118,7 +1134,7 @@ void *text_poke(void *addr, const void *opcode, size_t len)
|
|||
{
|
||||
lockdep_assert_held(&text_mutex);
|
||||
|
||||
return __text_poke(addr, opcode, len);
|
||||
return __text_poke(text_poke_memcpy, addr, opcode, len);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1137,7 +1153,7 @@ void *text_poke(void *addr, const void *opcode, size_t len)
|
|||
*/
|
||||
void *text_poke_kgdb(void *addr, const void *opcode, size_t len)
|
||||
{
|
||||
return __text_poke(addr, opcode, len);
|
||||
return __text_poke(text_poke_memcpy, addr, opcode, len);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1167,7 +1183,38 @@ void *text_poke_copy(void *addr, const void *opcode, size_t len)
|
|||
|
||||
s = min_t(size_t, PAGE_SIZE * 2 - offset_in_page(ptr), len - patched);
|
||||
|
||||
__text_poke((void *)ptr, opcode + patched, s);
|
||||
__text_poke(text_poke_memcpy, (void *)ptr, opcode + patched, s);
|
||||
patched += s;
|
||||
}
|
||||
mutex_unlock(&text_mutex);
|
||||
return addr;
|
||||
}
|
||||
|
||||
/**
|
||||
* text_poke_set - memset into (an unused part of) RX memory
|
||||
* @addr: address to modify
|
||||
* @c: the byte to fill the area with
|
||||
* @len: length to copy, could be more than 2x PAGE_SIZE
|
||||
*
|
||||
* This is useful to overwrite unused regions of RX memory with illegal
|
||||
* instructions.
|
||||
*/
|
||||
void *text_poke_set(void *addr, int c, size_t len)
|
||||
{
|
||||
unsigned long start = (unsigned long)addr;
|
||||
size_t patched = 0;
|
||||
|
||||
if (WARN_ON_ONCE(core_kernel_text(start)))
|
||||
return NULL;
|
||||
|
||||
mutex_lock(&text_mutex);
|
||||
while (patched < len) {
|
||||
unsigned long ptr = start + patched;
|
||||
size_t s;
|
||||
|
||||
s = min_t(size_t, PAGE_SIZE * 2 - offset_in_page(ptr), len - patched);
|
||||
|
||||
__text_poke(text_poke_memset, (void *)ptr, (void *)&c, s);
|
||||
patched += s;
|
||||
}
|
||||
mutex_unlock(&text_mutex);
|
||||
|
|
|
@ -228,6 +228,11 @@ static void jit_fill_hole(void *area, unsigned int size)
|
|||
memset(area, 0xcc, size);
|
||||
}
|
||||
|
||||
int bpf_arch_text_invalidate(void *dst, size_t len)
|
||||
{
|
||||
return IS_ERR_OR_NULL(text_poke_set(dst, 0xcc, len));
|
||||
}
|
||||
|
||||
struct jit_context {
|
||||
int cleanup_addr; /* Epilogue code offset */
|
||||
|
||||
|
@ -1762,13 +1767,32 @@ static void restore_regs(const struct btf_func_model *m, u8 **prog, int nr_args,
|
|||
}
|
||||
|
||||
static int invoke_bpf_prog(const struct btf_func_model *m, u8 **pprog,
|
||||
struct bpf_prog *p, int stack_size, bool save_ret)
|
||||
struct bpf_tramp_link *l, int stack_size,
|
||||
int run_ctx_off, bool save_ret)
|
||||
{
|
||||
u8 *prog = *pprog;
|
||||
u8 *jmp_insn;
|
||||
int ctx_cookie_off = offsetof(struct bpf_tramp_run_ctx, bpf_cookie);
|
||||
struct bpf_prog *p = l->link.prog;
|
||||
u64 cookie = l->cookie;
|
||||
|
||||
/* mov rdi, cookie */
|
||||
emit_mov_imm64(&prog, BPF_REG_1, (long) cookie >> 32, (u32) (long) cookie);
|
||||
|
||||
/* Prepare struct bpf_tramp_run_ctx.
|
||||
*
|
||||
* bpf_tramp_run_ctx is already preserved by
|
||||
* arch_prepare_bpf_trampoline().
|
||||
*
|
||||
* mov QWORD PTR [rbp - run_ctx_off + ctx_cookie_off], rdi
|
||||
*/
|
||||
emit_stx(&prog, BPF_DW, BPF_REG_FP, BPF_REG_1, -run_ctx_off + ctx_cookie_off);
|
||||
|
||||
/* arg1: mov rdi, progs[i] */
|
||||
emit_mov_imm64(&prog, BPF_REG_1, (long) p >> 32, (u32) (long) p);
|
||||
/* arg2: lea rsi, [rbp - ctx_cookie_off] */
|
||||
EMIT4(0x48, 0x8D, 0x75, -run_ctx_off);
|
||||
|
||||
if (emit_call(&prog,
|
||||
p->aux->sleepable ? __bpf_prog_enter_sleepable :
|
||||
__bpf_prog_enter, prog))
|
||||
|
@ -1814,6 +1838,8 @@ static int invoke_bpf_prog(const struct btf_func_model *m, u8 **pprog,
|
|||
emit_mov_imm64(&prog, BPF_REG_1, (long) p >> 32, (u32) (long) p);
|
||||
/* arg2: mov rsi, rbx <- start time in nsec */
|
||||
emit_mov_reg(&prog, true, BPF_REG_2, BPF_REG_6);
|
||||
/* arg3: lea rdx, [rbp - run_ctx_off] */
|
||||
EMIT4(0x48, 0x8D, 0x55, -run_ctx_off);
|
||||
if (emit_call(&prog,
|
||||
p->aux->sleepable ? __bpf_prog_exit_sleepable :
|
||||
__bpf_prog_exit, prog))
|
||||
|
@ -1850,15 +1876,15 @@ static int emit_cond_near_jump(u8 **pprog, void *func, void *ip, u8 jmp_cond)
|
|||
}
|
||||
|
||||
static int invoke_bpf(const struct btf_func_model *m, u8 **pprog,
|
||||
struct bpf_tramp_progs *tp, int stack_size,
|
||||
bool save_ret)
|
||||
struct bpf_tramp_links *tl, int stack_size,
|
||||
int run_ctx_off, bool save_ret)
|
||||
{
|
||||
int i;
|
||||
u8 *prog = *pprog;
|
||||
|
||||
for (i = 0; i < tp->nr_progs; i++) {
|
||||
if (invoke_bpf_prog(m, &prog, tp->progs[i], stack_size,
|
||||
save_ret))
|
||||
for (i = 0; i < tl->nr_links; i++) {
|
||||
if (invoke_bpf_prog(m, &prog, tl->links[i], stack_size,
|
||||
run_ctx_off, save_ret))
|
||||
return -EINVAL;
|
||||
}
|
||||
*pprog = prog;
|
||||
|
@ -1866,8 +1892,8 @@ static int invoke_bpf(const struct btf_func_model *m, u8 **pprog,
|
|||
}
|
||||
|
||||
static int invoke_bpf_mod_ret(const struct btf_func_model *m, u8 **pprog,
|
||||
struct bpf_tramp_progs *tp, int stack_size,
|
||||
u8 **branches)
|
||||
struct bpf_tramp_links *tl, int stack_size,
|
||||
int run_ctx_off, u8 **branches)
|
||||
{
|
||||
u8 *prog = *pprog;
|
||||
int i;
|
||||
|
@ -1877,8 +1903,8 @@ static int invoke_bpf_mod_ret(const struct btf_func_model *m, u8 **pprog,
|
|||
*/
|
||||
emit_mov_imm32(&prog, false, BPF_REG_0, 0);
|
||||
emit_stx(&prog, BPF_DW, BPF_REG_FP, BPF_REG_0, -8);
|
||||
for (i = 0; i < tp->nr_progs; i++) {
|
||||
if (invoke_bpf_prog(m, &prog, tp->progs[i], stack_size, true))
|
||||
for (i = 0; i < tl->nr_links; i++) {
|
||||
if (invoke_bpf_prog(m, &prog, tl->links[i], stack_size, run_ctx_off, true))
|
||||
return -EINVAL;
|
||||
|
||||
/* mod_ret prog stored return value into [rbp - 8]. Emit:
|
||||
|
@ -1980,14 +2006,14 @@ static bool is_valid_bpf_tramp_flags(unsigned int flags)
|
|||
*/
|
||||
int arch_prepare_bpf_trampoline(struct bpf_tramp_image *im, void *image, void *image_end,
|
||||
const struct btf_func_model *m, u32 flags,
|
||||
struct bpf_tramp_progs *tprogs,
|
||||
struct bpf_tramp_links *tlinks,
|
||||
void *orig_call)
|
||||
{
|
||||
int ret, i, nr_args = m->nr_args;
|
||||
int regs_off, ip_off, args_off, stack_size = nr_args * 8;
|
||||
struct bpf_tramp_progs *fentry = &tprogs[BPF_TRAMP_FENTRY];
|
||||
struct bpf_tramp_progs *fexit = &tprogs[BPF_TRAMP_FEXIT];
|
||||
struct bpf_tramp_progs *fmod_ret = &tprogs[BPF_TRAMP_MODIFY_RETURN];
|
||||
int regs_off, ip_off, args_off, stack_size = nr_args * 8, run_ctx_off;
|
||||
struct bpf_tramp_links *fentry = &tlinks[BPF_TRAMP_FENTRY];
|
||||
struct bpf_tramp_links *fexit = &tlinks[BPF_TRAMP_FEXIT];
|
||||
struct bpf_tramp_links *fmod_ret = &tlinks[BPF_TRAMP_MODIFY_RETURN];
|
||||
u8 **branches = NULL;
|
||||
u8 *prog;
|
||||
bool save_ret;
|
||||
|
@ -2014,6 +2040,8 @@ int arch_prepare_bpf_trampoline(struct bpf_tramp_image *im, void *image, void *i
|
|||
* RBP - args_off [ args count ] always
|
||||
*
|
||||
* RBP - ip_off [ traced function ] BPF_TRAMP_F_IP_ARG flag
|
||||
*
|
||||
* RBP - run_ctx_off [ bpf_tramp_run_ctx ]
|
||||
*/
|
||||
|
||||
/* room for return value of orig_call or fentry prog */
|
||||
|
@ -2032,6 +2060,9 @@ int arch_prepare_bpf_trampoline(struct bpf_tramp_image *im, void *image, void *i
|
|||
|
||||
ip_off = stack_size;
|
||||
|
||||
stack_size += (sizeof(struct bpf_tramp_run_ctx) + 7) & ~0x7;
|
||||
run_ctx_off = stack_size;
|
||||
|
||||
if (flags & BPF_TRAMP_F_SKIP_FRAME) {
|
||||
/* skip patched call instruction and point orig_call to actual
|
||||
* body of the kernel function.
|
||||
|
@ -2078,19 +2109,19 @@ int arch_prepare_bpf_trampoline(struct bpf_tramp_image *im, void *image, void *i
|
|||
}
|
||||
}
|
||||
|
||||
if (fentry->nr_progs)
|
||||
if (invoke_bpf(m, &prog, fentry, regs_off,
|
||||
if (fentry->nr_links)
|
||||
if (invoke_bpf(m, &prog, fentry, regs_off, run_ctx_off,
|
||||
flags & BPF_TRAMP_F_RET_FENTRY_RET))
|
||||
return -EINVAL;
|
||||
|
||||
if (fmod_ret->nr_progs) {
|
||||
branches = kcalloc(fmod_ret->nr_progs, sizeof(u8 *),
|
||||
if (fmod_ret->nr_links) {
|
||||
branches = kcalloc(fmod_ret->nr_links, sizeof(u8 *),
|
||||
GFP_KERNEL);
|
||||
if (!branches)
|
||||
return -ENOMEM;
|
||||
|
||||
if (invoke_bpf_mod_ret(m, &prog, fmod_ret, regs_off,
|
||||
branches)) {
|
||||
run_ctx_off, branches)) {
|
||||
ret = -EINVAL;
|
||||
goto cleanup;
|
||||
}
|
||||
|
@ -2111,7 +2142,7 @@ int arch_prepare_bpf_trampoline(struct bpf_tramp_image *im, void *image, void *i
|
|||
prog += X86_PATCH_SIZE;
|
||||
}
|
||||
|
||||
if (fmod_ret->nr_progs) {
|
||||
if (fmod_ret->nr_links) {
|
||||
/* From Intel 64 and IA-32 Architectures Optimization
|
||||
* Reference Manual, 3.4.1.4 Code Alignment, Assembly/Compiler
|
||||
* Coding Rule 11: All branch targets should be 16-byte
|
||||
|
@ -2121,13 +2152,13 @@ int arch_prepare_bpf_trampoline(struct bpf_tramp_image *im, void *image, void *i
|
|||
/* Update the branches saved in invoke_bpf_mod_ret with the
|
||||
* aligned address of do_fexit.
|
||||
*/
|
||||
for (i = 0; i < fmod_ret->nr_progs; i++)
|
||||
for (i = 0; i < fmod_ret->nr_links; i++)
|
||||
emit_cond_near_jump(&branches[i], prog, branches[i],
|
||||
X86_JNE);
|
||||
}
|
||||
|
||||
if (fexit->nr_progs)
|
||||
if (invoke_bpf(m, &prog, fexit, regs_off, false)) {
|
||||
if (fexit->nr_links)
|
||||
if (invoke_bpf(m, &prog, fexit, regs_off, run_ctx_off, false)) {
|
||||
ret = -EINVAL;
|
||||
goto cleanup;
|
||||
}
|
||||
|
|
|
@ -146,36 +146,6 @@ config ATM_ENI_BURST_RX_2W
|
|||
try this if you have disabled 4W and 8W bursts. Enabling 2W if 4W or
|
||||
8W are also set may or may not improve throughput.
|
||||
|
||||
config ATM_FIRESTREAM
|
||||
tristate "Fujitsu FireStream (FS50/FS155) "
|
||||
depends on PCI && VIRT_TO_BUS
|
||||
help
|
||||
Driver for the Fujitsu FireStream 155 (MB86697) and
|
||||
FireStream 50 (MB86695) ATM PCI chips.
|
||||
|
||||
To compile this driver as a module, choose M here: the module will
|
||||
be called firestream.
|
||||
|
||||
config ATM_ZATM
|
||||
tristate "ZeitNet ZN1221/ZN1225"
|
||||
depends on PCI && VIRT_TO_BUS
|
||||
help
|
||||
Driver for the ZeitNet ZN1221 (MMF) and ZN1225 (UTP-5) 155 Mbps ATM
|
||||
adapters.
|
||||
|
||||
To compile this driver as a module, choose M here: the module will
|
||||
be called zatm.
|
||||
|
||||
config ATM_ZATM_DEBUG
|
||||
bool "Enable extended debugging"
|
||||
depends on ATM_ZATM
|
||||
help
|
||||
Extended debugging records various events and displays that list
|
||||
when an inconsistency is detected. This mechanism is faster than
|
||||
generally using printks, but still has some impact on performance.
|
||||
Note that extended debugging may create certain race conditions
|
||||
itself. Enable this ONLY if you suspect problems with the driver.
|
||||
|
||||
config ATM_NICSTAR
|
||||
tristate "IDT 77201 (NICStAR) (ForeRunnerLE)"
|
||||
depends on PCI
|
||||
|
@ -244,55 +214,6 @@ config ATM_IDT77252_USE_SUNI
|
|||
depends on ATM_IDT77252
|
||||
default y
|
||||
|
||||
config ATM_AMBASSADOR
|
||||
tristate "Madge Ambassador (Collage PCI 155 Server)"
|
||||
depends on PCI && VIRT_TO_BUS
|
||||
select BITREVERSE
|
||||
help
|
||||
This is a driver for ATMizer based ATM card produced by Madge
|
||||
Networks Ltd. Say Y (or M to compile as a module named ambassador)
|
||||
here if you have one of these cards.
|
||||
|
||||
config ATM_AMBASSADOR_DEBUG
|
||||
bool "Enable debugging messages"
|
||||
depends on ATM_AMBASSADOR
|
||||
help
|
||||
Somewhat useful debugging messages are available. The choice of
|
||||
messages is controlled by a bitmap. This may be specified as a
|
||||
module argument (kernel command line argument as well?), changed
|
||||
dynamically using an ioctl (not yet) or changed by sending the
|
||||
string "Dxxxx" to VCI 1023 (where x is a hex digit). See the file
|
||||
<file:drivers/atm/ambassador.h> for the meanings of the bits in the
|
||||
mask.
|
||||
|
||||
When active, these messages can have a significant impact on the
|
||||
speed of the driver, and the size of your syslog files! When
|
||||
inactive, they will have only a modest impact on performance.
|
||||
|
||||
config ATM_HORIZON
|
||||
tristate "Madge Horizon [Ultra] (Collage PCI 25 and Collage PCI 155 Client)"
|
||||
depends on PCI && VIRT_TO_BUS
|
||||
help
|
||||
This is a driver for the Horizon chipset ATM adapter cards once
|
||||
produced by Madge Networks Ltd. Say Y (or M to compile as a module
|
||||
named horizon) here if you have one of these cards.
|
||||
|
||||
config ATM_HORIZON_DEBUG
|
||||
bool "Enable debugging messages"
|
||||
depends on ATM_HORIZON
|
||||
help
|
||||
Somewhat useful debugging messages are available. The choice of
|
||||
messages is controlled by a bitmap. This may be specified as a
|
||||
module argument (kernel command line argument as well?), changed
|
||||
dynamically using an ioctl (not yet) or changed by sending the
|
||||
string "Dxxxx" to VCI 1023 (where x is a hex digit). See the file
|
||||
<file:drivers/atm/horizon.h> for the meanings of the bits in the
|
||||
mask.
|
||||
|
||||
When active, these messages can have a significant impact on the
|
||||
speed of the driver, and the size of your syslog files! When
|
||||
inactive, they will have only a modest impact on performance.
|
||||
|
||||
config ATM_IA
|
||||
tristate "Interphase ATM PCI x575/x525/x531"
|
||||
depends on PCI
|
||||
|
|
|
@ -5,10 +5,7 @@
|
|||
|
||||
fore_200e-y := fore200e.o
|
||||
|
||||
obj-$(CONFIG_ATM_ZATM) += zatm.o uPD98402.o
|
||||
obj-$(CONFIG_ATM_NICSTAR) += nicstar.o
|
||||
obj-$(CONFIG_ATM_AMBASSADOR) += ambassador.o
|
||||
obj-$(CONFIG_ATM_HORIZON) += horizon.o
|
||||
obj-$(CONFIG_ATM_IA) += iphase.o suni.o
|
||||
obj-$(CONFIG_ATM_FORE200E) += fore_200e.o
|
||||
obj-$(CONFIG_ATM_ENI) += eni.o suni.o
|
||||
|
@ -27,7 +24,6 @@ endif
|
|||
|
||||
obj-$(CONFIG_ATM_DUMMY) += adummy.o
|
||||
obj-$(CONFIG_ATM_TCP) += atmtcp.o
|
||||
obj-$(CONFIG_ATM_FIRESTREAM) += firestream.o
|
||||
obj-$(CONFIG_ATM_LANAI) += lanai.o
|
||||
|
||||
obj-$(CONFIG_ATM_HE) += he.o
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,648 +0,0 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
/*
|
||||
Madge Ambassador ATM Adapter driver.
|
||||
Copyright (C) 1995-1999 Madge Networks Ltd.
|
||||
|
||||
*/
|
||||
|
||||
#ifndef AMBASSADOR_H
|
||||
#define AMBASSADOR_H
|
||||
|
||||
|
||||
#ifdef CONFIG_ATM_AMBASSADOR_DEBUG
|
||||
#define DEBUG_AMBASSADOR
|
||||
#endif
|
||||
|
||||
#define DEV_LABEL "amb"
|
||||
|
||||
#ifndef PCI_VENDOR_ID_MADGE
|
||||
#define PCI_VENDOR_ID_MADGE 0x10B6
|
||||
#endif
|
||||
#ifndef PCI_VENDOR_ID_MADGE_AMBASSADOR
|
||||
#define PCI_DEVICE_ID_MADGE_AMBASSADOR 0x1001
|
||||
#endif
|
||||
#ifndef PCI_VENDOR_ID_MADGE_AMBASSADOR_BAD
|
||||
#define PCI_DEVICE_ID_MADGE_AMBASSADOR_BAD 0x1002
|
||||
#endif
|
||||
|
||||
// diagnostic output
|
||||
|
||||
#define PRINTK(severity,format,args...) \
|
||||
printk(severity DEV_LABEL ": " format "\n" , ## args)
|
||||
|
||||
#ifdef DEBUG_AMBASSADOR
|
||||
|
||||
#define DBG_ERR 0x0001
|
||||
#define DBG_WARN 0x0002
|
||||
#define DBG_INFO 0x0004
|
||||
#define DBG_INIT 0x0008
|
||||
#define DBG_LOAD 0x0010
|
||||
#define DBG_VCC 0x0020
|
||||
#define DBG_QOS 0x0040
|
||||
#define DBG_CMD 0x0080
|
||||
#define DBG_TX 0x0100
|
||||
#define DBG_RX 0x0200
|
||||
#define DBG_SKB 0x0400
|
||||
#define DBG_POOL 0x0800
|
||||
#define DBG_IRQ 0x1000
|
||||
#define DBG_FLOW 0x2000
|
||||
#define DBG_REGS 0x4000
|
||||
#define DBG_DATA 0x8000
|
||||
#define DBG_MASK 0xffff
|
||||
|
||||
/* the ## prevents the annoying double expansion of the macro arguments */
|
||||
/* KERN_INFO is used since KERN_DEBUG often does not make it to the console */
|
||||
#define PRINTDB(bits,format,args...) \
|
||||
( (debug & (bits)) ? printk (KERN_INFO DEV_LABEL ": " format , ## args) : 1 )
|
||||
#define PRINTDM(bits,format,args...) \
|
||||
( (debug & (bits)) ? printk (format , ## args) : 1 )
|
||||
#define PRINTDE(bits,format,args...) \
|
||||
( (debug & (bits)) ? printk (format "\n" , ## args) : 1 )
|
||||
#define PRINTD(bits,format,args...) \
|
||||
( (debug & (bits)) ? printk (KERN_INFO DEV_LABEL ": " format "\n" , ## args) : 1 )
|
||||
|
||||
#else
|
||||
|
||||
#define PRINTD(bits,format,args...)
|
||||
#define PRINTDB(bits,format,args...)
|
||||
#define PRINTDM(bits,format,args...)
|
||||
#define PRINTDE(bits,format,args...)
|
||||
|
||||
#endif
|
||||
|
||||
#define PRINTDD(bits,format,args...)
|
||||
#define PRINTDDB(sec,fmt,args...)
|
||||
#define PRINTDDM(sec,fmt,args...)
|
||||
#define PRINTDDE(sec,fmt,args...)
|
||||
|
||||
// tunable values (?)
|
||||
|
||||
/* MUST be powers of two -- why ? */
|
||||
#define COM_Q_ENTRIES 8
|
||||
#define TX_Q_ENTRIES 32
|
||||
#define RX_Q_ENTRIES 64
|
||||
|
||||
// fixed values
|
||||
|
||||
// guessing
|
||||
#define AMB_EXTENT 0x80
|
||||
|
||||
// Minimum allowed size for an Ambassador queue
|
||||
#define MIN_QUEUE_SIZE 2
|
||||
|
||||
// Ambassador microcode allows 1 to 4 pools, we use 4 (simpler)
|
||||
#define NUM_RX_POOLS 4
|
||||
|
||||
// minimum RX buffers required to cope with replenishing delay
|
||||
#define MIN_RX_BUFFERS 1
|
||||
|
||||
// minimum PCI latency we will tolerate (32 IS TOO SMALL)
|
||||
#define MIN_PCI_LATENCY 64 // 255
|
||||
|
||||
// VCs supported by card (VPI always 0)
|
||||
#define NUM_VPI_BITS 0
|
||||
#define NUM_VCI_BITS 10
|
||||
#define NUM_VCS 1024
|
||||
|
||||
/* The status field bits defined so far. */
|
||||
#define RX_ERR 0x8000 // always present if there is an error (hmm)
|
||||
#define CRC_ERR 0x4000 // AAL5 CRC error
|
||||
#define LEN_ERR 0x2000 // overlength frame
|
||||
#define ABORT_ERR 0x1000 // zero length field in received frame
|
||||
#define UNUSED_ERR 0x0800 // buffer returned unused
|
||||
|
||||
// Adaptor commands
|
||||
|
||||
#define SRB_OPEN_VC 0
|
||||
/* par_0: dwordswap(VC_number) */
|
||||
/* par_1: dwordswap(flags<<16) or wordswap(flags)*/
|
||||
/* flags: */
|
||||
|
||||
/* LANE: 0x0004 */
|
||||
/* NOT_UBR: 0x0008 */
|
||||
/* ABR: 0x0010 */
|
||||
|
||||
/* RxPool0: 0x0000 */
|
||||
/* RxPool1: 0x0020 */
|
||||
/* RxPool2: 0x0040 */
|
||||
/* RxPool3: 0x0060 */
|
||||
|
||||
/* par_2: dwordswap(fp_rate<<16) or wordswap(fp_rate) */
|
||||
|
||||
#define SRB_CLOSE_VC 1
|
||||
/* par_0: dwordswap(VC_number) */
|
||||
|
||||
#define SRB_GET_BIA 2
|
||||
/* returns */
|
||||
/* par_0: dwordswap(half BIA) */
|
||||
/* par_1: dwordswap(half BIA) */
|
||||
|
||||
#define SRB_GET_SUNI_STATS 3
|
||||
/* par_0: dwordswap(physical_host_address) */
|
||||
|
||||
#define SRB_SET_BITS_8 4
|
||||
#define SRB_SET_BITS_16 5
|
||||
#define SRB_SET_BITS_32 6
|
||||
#define SRB_CLEAR_BITS_8 7
|
||||
#define SRB_CLEAR_BITS_16 8
|
||||
#define SRB_CLEAR_BITS_32 9
|
||||
/* par_0: dwordswap(ATMizer address) */
|
||||
/* par_1: dwordswap(mask) */
|
||||
|
||||
#define SRB_SET_8 10
|
||||
#define SRB_SET_16 11
|
||||
#define SRB_SET_32 12
|
||||
/* par_0: dwordswap(ATMizer address) */
|
||||
/* par_1: dwordswap(data) */
|
||||
|
||||
#define SRB_GET_32 13
|
||||
/* par_0: dwordswap(ATMizer address) */
|
||||
/* returns */
|
||||
/* par_1: dwordswap(ATMizer data) */
|
||||
|
||||
#define SRB_GET_VERSION 14
|
||||
/* returns */
|
||||
/* par_0: dwordswap(Major Version) */
|
||||
/* par_1: dwordswap(Minor Version) */
|
||||
|
||||
#define SRB_FLUSH_BUFFER_Q 15
|
||||
/* Only flags to define which buffer pool; all others must be zero */
|
||||
/* par_0: dwordswap(flags<<16) or wordswap(flags)*/
|
||||
|
||||
#define SRB_GET_DMA_SPEEDS 16
|
||||
/* returns */
|
||||
/* par_0: dwordswap(Read speed (bytes/sec)) */
|
||||
/* par_1: dwordswap(Write speed (bytes/sec)) */
|
||||
|
||||
#define SRB_MODIFY_VC_RATE 17
|
||||
/* par_0: dwordswap(VC_number) */
|
||||
/* par_1: dwordswap(fp_rate<<16) or wordswap(fp_rate) */
|
||||
|
||||
#define SRB_MODIFY_VC_FLAGS 18
|
||||
/* par_0: dwordswap(VC_number) */
|
||||
/* par_1: dwordswap(flags<<16) or wordswap(flags)*/
|
||||
|
||||
/* flags: */
|
||||
|
||||
/* LANE: 0x0004 */
|
||||
/* NOT_UBR: 0x0008 */
|
||||
/* ABR: 0x0010 */
|
||||
|
||||
/* RxPool0: 0x0000 */
|
||||
/* RxPool1: 0x0020 */
|
||||
/* RxPool2: 0x0040 */
|
||||
/* RxPool3: 0x0060 */
|
||||
|
||||
#define SRB_RATE_SHIFT 16
|
||||
#define SRB_POOL_SHIFT (SRB_FLAGS_SHIFT+5)
|
||||
#define SRB_FLAGS_SHIFT 16
|
||||
|
||||
#define SRB_STOP_TASKING 19
|
||||
#define SRB_START_TASKING 20
|
||||
#define SRB_SHUT_DOWN 21
|
||||
#define MAX_SRB 21
|
||||
|
||||
#define SRB_COMPLETE 0xffffffff
|
||||
|
||||
#define TX_FRAME 0x80000000
|
||||
|
||||
// number of types of SRB MUST be a power of two -- why?
|
||||
#define NUM_OF_SRB 32
|
||||
|
||||
// number of bits of period info for rate
|
||||
#define MAX_RATE_BITS 6
|
||||
|
||||
#define TX_UBR 0x0000
|
||||
#define TX_UBR_CAPPED 0x0008
|
||||
#define TX_ABR 0x0018
|
||||
#define TX_FRAME_NOTCAP 0x0000
|
||||
#define TX_FRAME_CAPPED 0x8000
|
||||
|
||||
#define FP_155_RATE 0x24b1
|
||||
#define FP_25_RATE 0x1f9d
|
||||
|
||||
/* #define VERSION_NUMBER 0x01000000 // initial release */
|
||||
/* #define VERSION_NUMBER 0x01010000 // fixed startup probs PLX MB0 not cleared */
|
||||
/* #define VERSION_NUMBER 0x01020000 // changed SUNI reset timings; allowed r/w onchip */
|
||||
|
||||
/* #define VERSION_NUMBER 0x01030000 // clear local doorbell int reg on reset */
|
||||
/* #define VERSION_NUMBER 0x01040000 // PLX bug work around version PLUS */
|
||||
/* remove race conditions on basic interface */
|
||||
/* indicate to the host that diagnostics */
|
||||
/* have finished; if failed, how and what */
|
||||
/* failed */
|
||||
/* fix host memory test to fix PLX bug */
|
||||
/* allow flash upgrade and BIA upgrade directly */
|
||||
/* */
|
||||
#define VERSION_NUMBER 0x01050025 /* Jason's first hacked version. */
|
||||
/* Change in download algorithm */
|
||||
|
||||
#define DMA_VALID 0xb728e149 /* completely random */
|
||||
|
||||
#define FLASH_BASE 0xa0c00000
|
||||
#define FLASH_SIZE 0x00020000 /* 128K */
|
||||
#define BIA_BASE (FLASH_BASE+0x0001c000) /* Flash Sector 7 */
|
||||
#define BIA_ADDRESS ((void *)0xa0c1c000)
|
||||
#define PLX_BASE 0xe0000000
|
||||
|
||||
typedef enum {
|
||||
host_memory_test = 1,
|
||||
read_adapter_memory,
|
||||
write_adapter_memory,
|
||||
adapter_start,
|
||||
get_version_number,
|
||||
interrupt_host,
|
||||
flash_erase_sector,
|
||||
adap_download_block = 0x20,
|
||||
adap_erase_flash,
|
||||
adap_run_in_iram,
|
||||
adap_end_download
|
||||
} loader_command;
|
||||
|
||||
#define BAD_COMMAND (-1)
|
||||
#define COMMAND_IN_PROGRESS 1
|
||||
#define COMMAND_PASSED_TEST 2
|
||||
#define COMMAND_FAILED_TEST 3
|
||||
#define COMMAND_READ_DATA_OK 4
|
||||
#define COMMAND_READ_BAD_ADDRESS 5
|
||||
#define COMMAND_WRITE_DATA_OK 6
|
||||
#define COMMAND_WRITE_BAD_ADDRESS 7
|
||||
#define COMMAND_WRITE_FLASH_FAILURE 8
|
||||
#define COMMAND_COMPLETE 9
|
||||
#define COMMAND_FLASH_ERASE_FAILURE 10
|
||||
#define COMMAND_WRITE_BAD_DATA 11
|
||||
|
||||
/* bit fields for mailbox[0] return values */
|
||||
|
||||
#define GPINT_TST_FAILURE 0x00000001
|
||||
#define SUNI_DATA_PATTERN_FAILURE 0x00000002
|
||||
#define SUNI_DATA_BITS_FAILURE 0x00000004
|
||||
#define SUNI_UTOPIA_FAILURE 0x00000008
|
||||
#define SUNI_FIFO_FAILURE 0x00000010
|
||||
#define SRAM_FAILURE 0x00000020
|
||||
#define SELF_TEST_FAILURE 0x0000003f
|
||||
|
||||
/* mailbox[1] = 0 in progress, -1 on completion */
|
||||
/* mailbox[2] = current test 00 00 test(8 bit) phase(8 bit) */
|
||||
/* mailbox[3] = last failure, 00 00 test(8 bit) phase(8 bit) */
|
||||
/* mailbox[4],mailbox[5],mailbox[6] random failure values */
|
||||
|
||||
/* PLX/etc. memory map including command structure */
|
||||
|
||||
/* These registers may also be memory mapped in PCI memory */
|
||||
|
||||
#define UNUSED_LOADER_MAILBOXES 6
|
||||
|
||||
typedef struct {
|
||||
u32 stuff[16];
|
||||
union {
|
||||
struct {
|
||||
u32 result;
|
||||
u32 ready;
|
||||
u32 stuff[UNUSED_LOADER_MAILBOXES];
|
||||
} loader;
|
||||
struct {
|
||||
u32 cmd_address;
|
||||
u32 tx_address;
|
||||
u32 rx_address[NUM_RX_POOLS];
|
||||
u32 gen_counter;
|
||||
u32 spare;
|
||||
} adapter;
|
||||
} mb;
|
||||
u32 doorbell;
|
||||
u32 interrupt;
|
||||
u32 interrupt_control;
|
||||
u32 reset_control;
|
||||
} amb_mem;
|
||||
|
||||
/* RESET bit, IRQ (card to host) and doorbell (host to card) enable bits */
|
||||
#define AMB_RESET_BITS 0x40000000
|
||||
#define AMB_INTERRUPT_BITS 0x00000300
|
||||
#define AMB_DOORBELL_BITS 0x00030000
|
||||
|
||||
/* loader commands */
|
||||
|
||||
#define MAX_COMMAND_DATA 13
|
||||
#define MAX_TRANSFER_DATA 11
|
||||
|
||||
typedef struct {
|
||||
__be32 address;
|
||||
__be32 count;
|
||||
__be32 data[MAX_TRANSFER_DATA];
|
||||
} transfer_block;
|
||||
|
||||
typedef struct {
|
||||
__be32 result;
|
||||
__be32 command;
|
||||
union {
|
||||
transfer_block transfer;
|
||||
__be32 version;
|
||||
__be32 start;
|
||||
__be32 data[MAX_COMMAND_DATA];
|
||||
} payload;
|
||||
__be32 valid;
|
||||
} loader_block;
|
||||
|
||||
/* command queue */
|
||||
|
||||
/* Again all data are BIG ENDIAN */
|
||||
|
||||
typedef struct {
|
||||
union {
|
||||
struct {
|
||||
__be32 vc;
|
||||
__be32 flags;
|
||||
__be32 rate;
|
||||
} open;
|
||||
struct {
|
||||
__be32 vc;
|
||||
__be32 rate;
|
||||
} modify_rate;
|
||||
struct {
|
||||
__be32 vc;
|
||||
__be32 flags;
|
||||
} modify_flags;
|
||||
struct {
|
||||
__be32 vc;
|
||||
} close;
|
||||
struct {
|
||||
__be32 lower4;
|
||||
__be32 upper2;
|
||||
} bia;
|
||||
struct {
|
||||
__be32 address;
|
||||
} suni;
|
||||
struct {
|
||||
__be32 major;
|
||||
__be32 minor;
|
||||
} version;
|
||||
struct {
|
||||
__be32 read;
|
||||
__be32 write;
|
||||
} speed;
|
||||
struct {
|
||||
__be32 flags;
|
||||
} flush;
|
||||
struct {
|
||||
__be32 address;
|
||||
__be32 data;
|
||||
} memory;
|
||||
__be32 par[3];
|
||||
} args;
|
||||
__be32 request;
|
||||
} command;
|
||||
|
||||
/* transmit queues and associated structures */
|
||||
|
||||
/* The hosts transmit structure. All BIG ENDIAN; host address
|
||||
restricted to first 1GByte, but address passed to the card must
|
||||
have the top MS bit or'ed in. -- check this */
|
||||
|
||||
/* TX is described by 1+ tx_frags followed by a tx_frag_end */
|
||||
|
||||
typedef struct {
|
||||
__be32 bytes;
|
||||
__be32 address;
|
||||
} tx_frag;
|
||||
|
||||
/* apart from handle the fields here are for the adapter to play with
|
||||
and should be set to zero */
|
||||
|
||||
typedef struct {
|
||||
u32 handle;
|
||||
u16 vc;
|
||||
u16 next_descriptor_length;
|
||||
u32 next_descriptor;
|
||||
#ifdef AMB_NEW_MICROCODE
|
||||
u8 cpcs_uu;
|
||||
u8 cpi;
|
||||
u16 pad;
|
||||
#endif
|
||||
} tx_frag_end;
|
||||
|
||||
typedef struct {
|
||||
tx_frag tx_frag;
|
||||
tx_frag_end tx_frag_end;
|
||||
struct sk_buff * skb;
|
||||
} tx_simple;
|
||||
|
||||
#if 0
|
||||
typedef union {
|
||||
tx_frag fragment;
|
||||
tx_frag_end end_of_list;
|
||||
} tx_descr;
|
||||
#endif
|
||||
|
||||
/* this "points" to the sequence of fragments and trailer */
|
||||
|
||||
typedef struct {
|
||||
__be16 vc;
|
||||
__be16 tx_descr_length;
|
||||
__be32 tx_descr_addr;
|
||||
} tx_in;
|
||||
|
||||
/* handle is the handle from tx_in */
|
||||
|
||||
typedef struct {
|
||||
u32 handle;
|
||||
} tx_out;
|
||||
|
||||
/* receive frame structure */
|
||||
|
||||
/* All BIG ENDIAN; handle is as passed from host; length is zero for
|
||||
aborted frames, and frames with errors. Header is actually VC
|
||||
number, lec-id is NOT yet supported. */
|
||||
|
||||
typedef struct {
|
||||
u32 handle;
|
||||
__be16 vc;
|
||||
__be16 lec_id; // unused
|
||||
__be16 status;
|
||||
__be16 length;
|
||||
} rx_out;
|
||||
|
||||
/* buffer supply structure */
|
||||
|
||||
typedef struct {
|
||||
u32 handle;
|
||||
__be32 host_address;
|
||||
} rx_in;
|
||||
|
||||
/* This first structure is the area in host memory where the adapter
|
||||
writes its pointer values. These pointer values are BIG ENDIAN and
|
||||
reside in the same 4MB 'page' as this structure. The host gives the
|
||||
adapter the address of this block by sending a doorbell interrupt
|
||||
to the adapter after downloading the code and setting it going. The
|
||||
addresses have the top 10 bits set to 1010000010b -- really?
|
||||
|
||||
The host must initialise these before handing the block to the
|
||||
adapter. */
|
||||
|
||||
typedef struct {
|
||||
__be32 command_start; /* SRB commands completions */
|
||||
__be32 command_end; /* SRB commands completions */
|
||||
__be32 tx_start;
|
||||
__be32 tx_end;
|
||||
__be32 txcom_start; /* tx completions */
|
||||
__be32 txcom_end; /* tx completions */
|
||||
struct {
|
||||
__be32 buffer_start;
|
||||
__be32 buffer_end;
|
||||
u32 buffer_q_get;
|
||||
u32 buffer_q_end;
|
||||
u32 buffer_aptr;
|
||||
__be32 rx_start; /* rx completions */
|
||||
__be32 rx_end;
|
||||
u32 rx_ptr;
|
||||
__be32 buffer_size; /* size of host buffer */
|
||||
} rec_struct[NUM_RX_POOLS];
|
||||
#ifdef AMB_NEW_MICROCODE
|
||||
u16 init_flags;
|
||||
u16 talk_block_spare;
|
||||
#endif
|
||||
} adap_talk_block;
|
||||
|
||||
/* This structure must be kept in line with the vcr image in sarmain.h
|
||||
|
||||
This is the structure in the host filled in by the adapter by
|
||||
GET_SUNI_STATS */
|
||||
|
||||
typedef struct {
|
||||
u8 racp_chcs;
|
||||
u8 racp_uhcs;
|
||||
u16 spare;
|
||||
u32 racp_rcell;
|
||||
u32 tacp_tcell;
|
||||
u32 flags;
|
||||
u32 dropped_cells;
|
||||
u32 dropped_frames;
|
||||
} suni_stats;
|
||||
|
||||
typedef enum {
|
||||
dead
|
||||
} amb_flags;
|
||||
|
||||
#define NEXTQ(current,start,limit) \
|
||||
( (current)+1 < (limit) ? (current)+1 : (start) )
|
||||
|
||||
typedef struct {
|
||||
command * start;
|
||||
command * in;
|
||||
command * out;
|
||||
command * limit;
|
||||
} amb_cq_ptrs;
|
||||
|
||||
typedef struct {
|
||||
spinlock_t lock;
|
||||
unsigned int pending;
|
||||
unsigned int high;
|
||||
unsigned int filled;
|
||||
unsigned int maximum; // size - 1 (q implementation)
|
||||
amb_cq_ptrs ptrs;
|
||||
} amb_cq;
|
||||
|
||||
typedef struct {
|
||||
spinlock_t lock;
|
||||
unsigned int pending;
|
||||
unsigned int high;
|
||||
unsigned int filled;
|
||||
unsigned int maximum; // size - 1 (q implementation)
|
||||
struct {
|
||||
tx_in * start;
|
||||
tx_in * ptr;
|
||||
tx_in * limit;
|
||||
} in;
|
||||
struct {
|
||||
tx_out * start;
|
||||
tx_out * ptr;
|
||||
tx_out * limit;
|
||||
} out;
|
||||
} amb_txq;
|
||||
|
||||
typedef struct {
|
||||
spinlock_t lock;
|
||||
unsigned int pending;
|
||||
unsigned int low;
|
||||
unsigned int emptied;
|
||||
unsigned int maximum; // size - 1 (q implementation)
|
||||
struct {
|
||||
rx_in * start;
|
||||
rx_in * ptr;
|
||||
rx_in * limit;
|
||||
} in;
|
||||
struct {
|
||||
rx_out * start;
|
||||
rx_out * ptr;
|
||||
rx_out * limit;
|
||||
} out;
|
||||
unsigned int buffers_wanted;
|
||||
unsigned int buffer_size;
|
||||
} amb_rxq;
|
||||
|
||||
typedef struct {
|
||||
unsigned long tx_ok;
|
||||
struct {
|
||||
unsigned long ok;
|
||||
unsigned long error;
|
||||
unsigned long badcrc;
|
||||
unsigned long toolong;
|
||||
unsigned long aborted;
|
||||
unsigned long unused;
|
||||
} rx;
|
||||
} amb_stats;
|
||||
|
||||
// a single struct pointed to by atm_vcc->dev_data
|
||||
|
||||
typedef struct {
|
||||
u8 tx_vc_bits:7;
|
||||
u8 tx_present:1;
|
||||
} amb_tx_info;
|
||||
|
||||
typedef struct {
|
||||
unsigned char pool;
|
||||
} amb_rx_info;
|
||||
|
||||
typedef struct {
|
||||
amb_rx_info rx_info;
|
||||
u16 tx_frame_bits;
|
||||
unsigned int tx_rate;
|
||||
unsigned int rx_rate;
|
||||
} amb_vcc;
|
||||
|
||||
struct amb_dev {
|
||||
u8 irq;
|
||||
unsigned long flags;
|
||||
u32 iobase;
|
||||
u32 * membase;
|
||||
|
||||
amb_cq cq;
|
||||
amb_txq txq;
|
||||
amb_rxq rxq[NUM_RX_POOLS];
|
||||
|
||||
struct mutex vcc_sf;
|
||||
amb_tx_info txer[NUM_VCS];
|
||||
struct atm_vcc * rxer[NUM_VCS];
|
||||
unsigned int tx_avail;
|
||||
unsigned int rx_avail;
|
||||
|
||||
amb_stats stats;
|
||||
|
||||
struct atm_dev * atm_dev;
|
||||
struct pci_dev * pci_dev;
|
||||
struct timer_list housekeeping;
|
||||
};
|
||||
|
||||
typedef struct amb_dev amb_dev;
|
||||
|
||||
#define AMB_DEV(atm_dev) ((amb_dev *) (atm_dev)->dev_data)
|
||||
#define AMB_VCC(atm_vcc) ((amb_vcc *) (atm_vcc)->dev_data)
|
||||
|
||||
/* rate rounding */
|
||||
|
||||
typedef enum {
|
||||
round_up,
|
||||
round_down,
|
||||
round_nearest
|
||||
} rounding;
|
||||
|
||||
#endif
|
File diff suppressed because it is too large
Load Diff
|
@ -1,502 +0,0 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
/* drivers/atm/firestream.h - FireStream 155 (MB86697) and
|
||||
* FireStream 50 (MB86695) device driver
|
||||
*/
|
||||
|
||||
/* Written & (C) 2000 by R.E.Wolff@BitWizard.nl
|
||||
* Copied snippets from zatm.c by Werner Almesberger, EPFL LRC/ICA
|
||||
* and ambassador.c Copyright (C) 1995-1999 Madge Networks Ltd
|
||||
*/
|
||||
|
||||
/*
|
||||
*/
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* first the defines for the chip. *
|
||||
***********************************************************************/
|
||||
|
||||
|
||||
/********************* General chip parameters. ************************/
|
||||
|
||||
#define FS_NR_FREE_POOLS 8
|
||||
#define FS_NR_RX_QUEUES 4
|
||||
|
||||
|
||||
/********************* queues and queue access macros ******************/
|
||||
|
||||
|
||||
/* A queue entry. */
|
||||
struct FS_QENTRY {
|
||||
u32 cmd;
|
||||
u32 p0, p1, p2;
|
||||
};
|
||||
|
||||
|
||||
/* A freepool entry. */
|
||||
struct FS_BPENTRY {
|
||||
u32 flags;
|
||||
u32 next;
|
||||
u32 bsa;
|
||||
u32 aal_bufsize;
|
||||
|
||||
/* The hardware doesn't look at this, but we need the SKB somewhere... */
|
||||
struct sk_buff *skb;
|
||||
struct freepool *fp;
|
||||
struct fs_dev *dev;
|
||||
};
|
||||
|
||||
|
||||
#define STATUS_CODE(qe) ((qe->cmd >> 22) & 0x3f)
|
||||
|
||||
|
||||
/* OFFSETS against the base of a QUEUE... */
|
||||
#define QSA 0x00
|
||||
#define QEA 0x04
|
||||
#define QRP 0x08
|
||||
#define QWP 0x0c
|
||||
#define QCNF 0x10 /* Only for Release queues! */
|
||||
/* Not for the transmit pending queue. */
|
||||
|
||||
|
||||
/* OFFSETS against the base of a FREE POOL... */
|
||||
#define FPCNF 0x00
|
||||
#define FPSA 0x04
|
||||
#define FPEA 0x08
|
||||
#define FPCNT 0x0c
|
||||
#define FPCTU 0x10
|
||||
|
||||
#define Q_SA(b) (b + QSA )
|
||||
#define Q_EA(b) (b + QEA )
|
||||
#define Q_RP(b) (b + QRP )
|
||||
#define Q_WP(b) (b + QWP )
|
||||
#define Q_CNF(b) (b + QCNF)
|
||||
|
||||
#define FP_CNF(b) (b + FPCNF)
|
||||
#define FP_SA(b) (b + FPSA)
|
||||
#define FP_EA(b) (b + FPEA)
|
||||
#define FP_CNT(b) (b + FPCNT)
|
||||
#define FP_CTU(b) (b + FPCTU)
|
||||
|
||||
/* bits in a queue register. */
|
||||
#define Q_FULL 0x1
|
||||
#define Q_EMPTY 0x2
|
||||
#define Q_INCWRAP 0x4
|
||||
#define Q_ADDR_MASK 0xfffffff0
|
||||
|
||||
/* bits in a FreePool config register */
|
||||
#define RBFP_RBS (0x1 << 16)
|
||||
#define RBFP_RBSVAL (0x1 << 15)
|
||||
#define RBFP_CME (0x1 << 12)
|
||||
#define RBFP_DLP (0x1 << 11)
|
||||
#define RBFP_BFPWT (0x1 << 0)
|
||||
|
||||
|
||||
|
||||
|
||||
/* FireStream commands. */
|
||||
#define QE_CMD_NULL (0x00 << 22)
|
||||
#define QE_CMD_REG_RD (0x01 << 22)
|
||||
#define QE_CMD_REG_RDM (0x02 << 22)
|
||||
#define QE_CMD_REG_WR (0x03 << 22)
|
||||
#define QE_CMD_REG_WRM (0x04 << 22)
|
||||
#define QE_CMD_CONFIG_TX (0x05 << 22)
|
||||
#define QE_CMD_CONFIG_RX (0x06 << 22)
|
||||
#define QE_CMD_PRP_RD (0x07 << 22)
|
||||
#define QE_CMD_PRP_RDM (0x2a << 22)
|
||||
#define QE_CMD_PRP_WR (0x09 << 22)
|
||||
#define QE_CMD_PRP_WRM (0x2b << 22)
|
||||
#define QE_CMD_RX_EN (0x0a << 22)
|
||||
#define QE_CMD_RX_PURGE (0x0b << 22)
|
||||
#define QE_CMD_RX_PURGE_INH (0x0c << 22)
|
||||
#define QE_CMD_TX_EN (0x0d << 22)
|
||||
#define QE_CMD_TX_PURGE (0x0e << 22)
|
||||
#define QE_CMD_TX_PURGE_INH (0x0f << 22)
|
||||
#define QE_CMD_RST_CG (0x10 << 22)
|
||||
#define QE_CMD_SET_CG (0x11 << 22)
|
||||
#define QE_CMD_RST_CLP (0x12 << 22)
|
||||
#define QE_CMD_SET_CLP (0x13 << 22)
|
||||
#define QE_CMD_OVERRIDE (0x14 << 22)
|
||||
#define QE_CMD_ADD_BFP (0x15 << 22)
|
||||
#define QE_CMD_DUMP_TX (0x16 << 22)
|
||||
#define QE_CMD_DUMP_RX (0x17 << 22)
|
||||
#define QE_CMD_LRAM_RD (0x18 << 22)
|
||||
#define QE_CMD_LRAM_RDM (0x28 << 22)
|
||||
#define QE_CMD_LRAM_WR (0x19 << 22)
|
||||
#define QE_CMD_LRAM_WRM (0x29 << 22)
|
||||
#define QE_CMD_LRAM_BSET (0x1a << 22)
|
||||
#define QE_CMD_LRAM_BCLR (0x1b << 22)
|
||||
#define QE_CMD_CONFIG_SEGM (0x1c << 22)
|
||||
#define QE_CMD_READ_SEGM (0x1d << 22)
|
||||
#define QE_CMD_CONFIG_ROUT (0x1e << 22)
|
||||
#define QE_CMD_READ_ROUT (0x1f << 22)
|
||||
#define QE_CMD_CONFIG_TM (0x20 << 22)
|
||||
#define QE_CMD_READ_TM (0x21 << 22)
|
||||
#define QE_CMD_CONFIG_TXBM (0x22 << 22)
|
||||
#define QE_CMD_READ_TXBM (0x23 << 22)
|
||||
#define QE_CMD_CONFIG_RXBM (0x24 << 22)
|
||||
#define QE_CMD_READ_RXBM (0x25 << 22)
|
||||
#define QE_CMD_CONFIG_REAS (0x26 << 22)
|
||||
#define QE_CMD_READ_REAS (0x27 << 22)
|
||||
|
||||
#define QE_TRANSMIT_DE (0x0 << 30)
|
||||
#define QE_CMD_LINKED (0x1 << 30)
|
||||
#define QE_CMD_IMM (0x2 << 30)
|
||||
#define QE_CMD_IMM_INQ (0x3 << 30)
|
||||
|
||||
#define TD_EPI (0x1 << 27)
|
||||
#define TD_COMMAND (0x1 << 28)
|
||||
|
||||
#define TD_DATA (0x0 << 29)
|
||||
#define TD_RM_CELL (0x1 << 29)
|
||||
#define TD_OAM_CELL (0x2 << 29)
|
||||
#define TD_OAM_CELL_SEGMENT (0x3 << 29)
|
||||
|
||||
#define TD_BPI (0x1 << 20)
|
||||
|
||||
#define FP_FLAGS_EPI (0x1 << 27)
|
||||
|
||||
|
||||
#define TX_PQ(i) (0x00 + (i) * 0x10)
|
||||
#define TXB_RQ (0x20)
|
||||
#define ST_Q (0x48)
|
||||
#define RXB_FP(i) (0x90 + (i) * 0x14)
|
||||
#define RXB_RQ(i) (0x134 + (i) * 0x14)
|
||||
|
||||
|
||||
#define TXQ_HP 0
|
||||
#define TXQ_LP 1
|
||||
|
||||
/* Phew. You don't want to know how many revisions these simple queue
|
||||
* address macros went through before I got them nice and compact as
|
||||
* they are now. -- REW
|
||||
*/
|
||||
|
||||
|
||||
/* And now for something completely different:
|
||||
* The rest of the registers... */
|
||||
|
||||
|
||||
#define CMDR0 0x34
|
||||
#define CMDR1 0x38
|
||||
#define CMDR2 0x3c
|
||||
#define CMDR3 0x40
|
||||
|
||||
|
||||
#define SARMODE0 0x5c
|
||||
|
||||
#define SARMODE0_TXVCS_0 (0x0 << 0)
|
||||
#define SARMODE0_TXVCS_1k (0x1 << 0)
|
||||
#define SARMODE0_TXVCS_2k (0x2 << 0)
|
||||
#define SARMODE0_TXVCS_4k (0x3 << 0)
|
||||
#define SARMODE0_TXVCS_8k (0x4 << 0)
|
||||
#define SARMODE0_TXVCS_16k (0x5 << 0)
|
||||
#define SARMODE0_TXVCS_32k (0x6 << 0)
|
||||
#define SARMODE0_TXVCS_64k (0x7 << 0)
|
||||
#define SARMODE0_TXVCS_32 (0x8 << 0)
|
||||
|
||||
#define SARMODE0_ABRVCS_0 (0x0 << 4)
|
||||
#define SARMODE0_ABRVCS_512 (0x1 << 4)
|
||||
#define SARMODE0_ABRVCS_1k (0x2 << 4)
|
||||
#define SARMODE0_ABRVCS_2k (0x3 << 4)
|
||||
#define SARMODE0_ABRVCS_4k (0x4 << 4)
|
||||
#define SARMODE0_ABRVCS_8k (0x5 << 4)
|
||||
#define SARMODE0_ABRVCS_16k (0x6 << 4)
|
||||
#define SARMODE0_ABRVCS_32k (0x7 << 4)
|
||||
#define SARMODE0_ABRVCS_32 (0x9 << 4) /* The others are "8", this one really has to
|
||||
be 9. Tell me you don't believe me. -- REW */
|
||||
|
||||
#define SARMODE0_RXVCS_0 (0x0 << 8)
|
||||
#define SARMODE0_RXVCS_1k (0x1 << 8)
|
||||
#define SARMODE0_RXVCS_2k (0x2 << 8)
|
||||
#define SARMODE0_RXVCS_4k (0x3 << 8)
|
||||
#define SARMODE0_RXVCS_8k (0x4 << 8)
|
||||
#define SARMODE0_RXVCS_16k (0x5 << 8)
|
||||
#define SARMODE0_RXVCS_32k (0x6 << 8)
|
||||
#define SARMODE0_RXVCS_64k (0x7 << 8)
|
||||
#define SARMODE0_RXVCS_32 (0x8 << 8)
|
||||
|
||||
#define SARMODE0_CALSUP_1 (0x0 << 12)
|
||||
#define SARMODE0_CALSUP_2 (0x1 << 12)
|
||||
#define SARMODE0_CALSUP_3 (0x2 << 12)
|
||||
#define SARMODE0_CALSUP_4 (0x3 << 12)
|
||||
|
||||
#define SARMODE0_PRPWT_FS50_0 (0x0 << 14)
|
||||
#define SARMODE0_PRPWT_FS50_2 (0x1 << 14)
|
||||
#define SARMODE0_PRPWT_FS50_5 (0x2 << 14)
|
||||
#define SARMODE0_PRPWT_FS50_11 (0x3 << 14)
|
||||
|
||||
#define SARMODE0_PRPWT_FS155_0 (0x0 << 14)
|
||||
#define SARMODE0_PRPWT_FS155_1 (0x1 << 14)
|
||||
#define SARMODE0_PRPWT_FS155_2 (0x2 << 14)
|
||||
#define SARMODE0_PRPWT_FS155_3 (0x3 << 14)
|
||||
|
||||
#define SARMODE0_SRTS0 (0x1 << 23)
|
||||
#define SARMODE0_SRTS1 (0x1 << 24)
|
||||
|
||||
#define SARMODE0_RUN (0x1 << 25)
|
||||
|
||||
#define SARMODE0_UNLOCK (0x1 << 26)
|
||||
#define SARMODE0_CWRE (0x1 << 27)
|
||||
|
||||
|
||||
#define SARMODE0_INTMODE_READCLEAR (0x0 << 28)
|
||||
#define SARMODE0_INTMODE_READNOCLEAR (0x1 << 28)
|
||||
#define SARMODE0_INTMODE_READNOCLEARINHIBIT (0x2 << 28)
|
||||
#define SARMODE0_INTMODE_READCLEARINHIBIT (0x3 << 28) /* Tell me you don't believe me. */
|
||||
|
||||
#define SARMODE0_GINT (0x1 << 30)
|
||||
#define SARMODE0_SHADEN (0x1 << 31)
|
||||
|
||||
|
||||
#define SARMODE1 0x60
|
||||
|
||||
|
||||
#define SARMODE1_TRTL_SHIFT 0 /* Program to 0 */
|
||||
#define SARMODE1_RRTL_SHIFT 4 /* Program to 0 */
|
||||
|
||||
#define SARMODE1_TAGM (0x1 << 8) /* Program to 0 */
|
||||
|
||||
#define SARMODE1_HECM0 (0x1 << 9)
|
||||
#define SARMODE1_HECM1 (0x1 << 10)
|
||||
#define SARMODE1_HECM2 (0x1 << 11)
|
||||
|
||||
#define SARMODE1_GFCE (0x1 << 14)
|
||||
#define SARMODE1_GFCR (0x1 << 15)
|
||||
#define SARMODE1_PMS (0x1 << 18)
|
||||
#define SARMODE1_GPRI (0x1 << 19)
|
||||
#define SARMODE1_GPAS (0x1 << 20)
|
||||
#define SARMODE1_GVAS (0x1 << 21)
|
||||
#define SARMODE1_GNAM (0x1 << 22)
|
||||
#define SARMODE1_GPLEN (0x1 << 23)
|
||||
#define SARMODE1_DUMPE (0x1 << 24)
|
||||
#define SARMODE1_OAMCRC (0x1 << 25)
|
||||
#define SARMODE1_DCOAM (0x1 << 26)
|
||||
#define SARMODE1_DCRM (0x1 << 27)
|
||||
#define SARMODE1_TSTLP (0x1 << 28)
|
||||
#define SARMODE1_DEFHEC (0x1 << 29)
|
||||
|
||||
|
||||
#define ISR 0x64
|
||||
#define IUSR 0x68
|
||||
#define IMR 0x6c
|
||||
|
||||
#define ISR_LPCO (0x1 << 0)
|
||||
#define ISR_DPCO (0x1 << 1)
|
||||
#define ISR_RBRQ0_W (0x1 << 2)
|
||||
#define ISR_RBRQ1_W (0x1 << 3)
|
||||
#define ISR_RBRQ2_W (0x1 << 4)
|
||||
#define ISR_RBRQ3_W (0x1 << 5)
|
||||
#define ISR_RBRQ0_NF (0x1 << 6)
|
||||
#define ISR_RBRQ1_NF (0x1 << 7)
|
||||
#define ISR_RBRQ2_NF (0x1 << 8)
|
||||
#define ISR_RBRQ3_NF (0x1 << 9)
|
||||
#define ISR_BFP_SC (0x1 << 10)
|
||||
#define ISR_INIT (0x1 << 11)
|
||||
#define ISR_INIT_ERR (0x1 << 12) /* Documented as "reserved" */
|
||||
#define ISR_USCEO (0x1 << 13)
|
||||
#define ISR_UPEC0 (0x1 << 14)
|
||||
#define ISR_VPFCO (0x1 << 15)
|
||||
#define ISR_CRCCO (0x1 << 16)
|
||||
#define ISR_HECO (0x1 << 17)
|
||||
#define ISR_TBRQ_W (0x1 << 18)
|
||||
#define ISR_TBRQ_NF (0x1 << 19)
|
||||
#define ISR_CTPQ_E (0x1 << 20)
|
||||
#define ISR_GFC_C0 (0x1 << 21)
|
||||
#define ISR_PCI_FTL (0x1 << 22)
|
||||
#define ISR_CSQ_W (0x1 << 23)
|
||||
#define ISR_CSQ_NF (0x1 << 24)
|
||||
#define ISR_EXT_INT (0x1 << 25)
|
||||
#define ISR_RXDMA_S (0x1 << 26)
|
||||
|
||||
|
||||
#define TMCONF 0x78
|
||||
/* Bits? */
|
||||
|
||||
|
||||
#define CALPRESCALE 0x7c
|
||||
/* Bits? */
|
||||
|
||||
#define CELLOSCONF 0x84
|
||||
#define CELLOSCONF_COTS (0x1 << 28)
|
||||
#define CELLOSCONF_CEN (0x1 << 27)
|
||||
#define CELLOSCONF_SC8 (0x3 << 24)
|
||||
#define CELLOSCONF_SC4 (0x2 << 24)
|
||||
#define CELLOSCONF_SC2 (0x1 << 24)
|
||||
#define CELLOSCONF_SC1 (0x0 << 24)
|
||||
|
||||
#define CELLOSCONF_COBS (0x1 << 16)
|
||||
#define CELLOSCONF_COPK (0x1 << 8)
|
||||
#define CELLOSCONF_COST (0x1 << 0)
|
||||
/* Bits? */
|
||||
|
||||
#define RAS0 0x1bc
|
||||
#define RAS0_DCD_XHLT (0x1 << 31)
|
||||
|
||||
#define RAS0_VPSEL (0x1 << 16)
|
||||
#define RAS0_VCSEL (0x1 << 0)
|
||||
|
||||
#define RAS1 0x1c0
|
||||
#define RAS1_UTREG (0x1 << 5)
|
||||
|
||||
|
||||
#define DMAMR 0x1cc
|
||||
#define DMAMR_TX_MODE_FULL (0x0 << 0)
|
||||
#define DMAMR_TX_MODE_PART (0x1 << 0)
|
||||
#define DMAMR_TX_MODE_NONE (0x2 << 0) /* And 3 */
|
||||
|
||||
|
||||
|
||||
#define RAS2 0x280
|
||||
|
||||
#define RAS2_NNI (0x1 << 0)
|
||||
#define RAS2_USEL (0x1 << 1)
|
||||
#define RAS2_UBS (0x1 << 2)
|
||||
|
||||
|
||||
|
||||
struct fs_transmit_config {
|
||||
u32 flags;
|
||||
u32 atm_hdr;
|
||||
u32 TMC[4];
|
||||
u32 spec;
|
||||
u32 rtag[3];
|
||||
};
|
||||
|
||||
#define TC_FLAGS_AAL5 (0x0 << 29)
|
||||
#define TC_FLAGS_TRANSPARENT_PAYLOAD (0x1 << 29)
|
||||
#define TC_FLAGS_TRANSPARENT_CELL (0x2 << 29)
|
||||
#define TC_FLAGS_STREAMING (0x1 << 28)
|
||||
#define TC_FLAGS_PACKET (0x0)
|
||||
#define TC_FLAGS_TYPE_ABR (0x0 << 22)
|
||||
#define TC_FLAGS_TYPE_CBR (0x1 << 22)
|
||||
#define TC_FLAGS_TYPE_VBR (0x2 << 22)
|
||||
#define TC_FLAGS_TYPE_UBR (0x3 << 22)
|
||||
#define TC_FLAGS_CAL0 (0x0 << 20)
|
||||
#define TC_FLAGS_CAL1 (0x1 << 20)
|
||||
#define TC_FLAGS_CAL2 (0x2 << 20)
|
||||
#define TC_FLAGS_CAL3 (0x3 << 20)
|
||||
|
||||
|
||||
#define RC_FLAGS_NAM (0x1 << 13)
|
||||
#define RC_FLAGS_RXBM_PSB (0x0 << 14)
|
||||
#define RC_FLAGS_RXBM_CIF (0x1 << 14)
|
||||
#define RC_FLAGS_RXBM_PMB (0x2 << 14)
|
||||
#define RC_FLAGS_RXBM_STR (0x4 << 14)
|
||||
#define RC_FLAGS_RXBM_SAF (0x6 << 14)
|
||||
#define RC_FLAGS_RXBM_POS (0x6 << 14)
|
||||
#define RC_FLAGS_BFPS (0x1 << 17)
|
||||
|
||||
#define RC_FLAGS_BFPS_BFP (0x1 << 17)
|
||||
|
||||
#define RC_FLAGS_BFPS_BFP0 (0x0 << 17)
|
||||
#define RC_FLAGS_BFPS_BFP1 (0x1 << 17)
|
||||
#define RC_FLAGS_BFPS_BFP2 (0x2 << 17)
|
||||
#define RC_FLAGS_BFPS_BFP3 (0x3 << 17)
|
||||
#define RC_FLAGS_BFPS_BFP4 (0x4 << 17)
|
||||
#define RC_FLAGS_BFPS_BFP5 (0x5 << 17)
|
||||
#define RC_FLAGS_BFPS_BFP6 (0x6 << 17)
|
||||
#define RC_FLAGS_BFPS_BFP7 (0x7 << 17)
|
||||
#define RC_FLAGS_BFPS_BFP01 (0x8 << 17)
|
||||
#define RC_FLAGS_BFPS_BFP23 (0x9 << 17)
|
||||
#define RC_FLAGS_BFPS_BFP45 (0xa << 17)
|
||||
#define RC_FLAGS_BFPS_BFP67 (0xb << 17)
|
||||
#define RC_FLAGS_BFPS_BFP07 (0xc << 17)
|
||||
#define RC_FLAGS_BFPS_BFP27 (0xd << 17)
|
||||
#define RC_FLAGS_BFPS_BFP47 (0xe << 17)
|
||||
|
||||
#define RC_FLAGS_BFPP (0x1 << 21)
|
||||
#define RC_FLAGS_TEVC (0x1 << 22)
|
||||
#define RC_FLAGS_TEP (0x1 << 23)
|
||||
#define RC_FLAGS_AAL5 (0x0 << 24)
|
||||
#define RC_FLAGS_TRANSP (0x1 << 24)
|
||||
#define RC_FLAGS_TRANSC (0x2 << 24)
|
||||
#define RC_FLAGS_ML (0x1 << 27)
|
||||
#define RC_FLAGS_TRBRM (0x1 << 28)
|
||||
#define RC_FLAGS_PRI (0x1 << 29)
|
||||
#define RC_FLAGS_HOAM (0x1 << 30)
|
||||
#define RC_FLAGS_CRC10 (0x1 << 31)
|
||||
|
||||
|
||||
#define RAC 0x1c8
|
||||
#define RAM 0x1c4
|
||||
|
||||
|
||||
|
||||
/************************************************************************
|
||||
* Then the datastructures that the DRIVER uses. *
|
||||
************************************************************************/
|
||||
|
||||
#define TXQ_NENTRIES 32
|
||||
#define RXRQ_NENTRIES 1024
|
||||
|
||||
|
||||
struct fs_vcc {
|
||||
int channo;
|
||||
wait_queue_head_t close_wait;
|
||||
struct sk_buff *last_skb;
|
||||
};
|
||||
|
||||
|
||||
struct queue {
|
||||
struct FS_QENTRY *sa, *ea;
|
||||
int offset;
|
||||
};
|
||||
|
||||
struct freepool {
|
||||
int offset;
|
||||
int bufsize;
|
||||
int nr_buffers;
|
||||
int n;
|
||||
};
|
||||
|
||||
|
||||
struct fs_dev {
|
||||
struct fs_dev *next; /* other FS devices */
|
||||
int flags;
|
||||
|
||||
unsigned char irq; /* IRQ */
|
||||
struct pci_dev *pci_dev; /* PCI stuff */
|
||||
struct atm_dev *atm_dev;
|
||||
struct timer_list timer;
|
||||
|
||||
unsigned long hw_base; /* mem base address */
|
||||
void __iomem *base; /* Mapping of base address */
|
||||
int channo;
|
||||
unsigned long channel_mask;
|
||||
|
||||
struct queue hp_txq, lp_txq, tx_relq, st_q;
|
||||
struct freepool rx_fp[FS_NR_FREE_POOLS];
|
||||
struct queue rx_rq[FS_NR_RX_QUEUES];
|
||||
|
||||
int nchannels;
|
||||
struct atm_vcc **atm_vccs;
|
||||
void *tx_inuse;
|
||||
int ntxpckts;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
/* Number of channesl that the FS50 supports. */
|
||||
#define FS50_CHANNEL_BITS 5
|
||||
#define FS50_NR_CHANNELS (1 << FS50_CHANNEL_BITS)
|
||||
|
||||
|
||||
#define FS_DEV(atm_dev) ((struct fs_dev *) (atm_dev)->dev_data)
|
||||
#define FS_VCC(atm_vcc) ((struct fs_vcc *) (atm_vcc)->dev_data)
|
||||
|
||||
|
||||
#define FS_IS50 0x1
|
||||
#define FS_IS155 0x2
|
||||
|
||||
#define IS_FS50(dev) (dev->flags & FS_IS50)
|
||||
#define IS_FS155(dev) (dev->flags & FS_IS155)
|
||||
|
||||
/* Within limits this is user-configurable. */
|
||||
/* Note: Currently the sum (10 -> 1k channels) is hardcoded in the driver. */
|
||||
#define FS155_VPI_BITS 4
|
||||
#define FS155_VCI_BITS 6
|
||||
|
||||
#define FS155_CHANNEL_BITS (FS155_VPI_BITS + FS155_VCI_BITS)
|
||||
#define FS155_NR_CHANNELS (1 << FS155_CHANNEL_BITS)
|
File diff suppressed because it is too large
Load Diff
|
@ -1,492 +0,0 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
/*
|
||||
Madge Horizon ATM Adapter driver.
|
||||
Copyright (C) 1995-1999 Madge Networks Ltd.
|
||||
|
||||
*/
|
||||
|
||||
/*
|
||||
IMPORTANT NOTE: Madge Networks no longer makes the adapters
|
||||
supported by this driver and makes no commitment to maintain it.
|
||||
*/
|
||||
|
||||
/* too many macros - change to inline functions */
|
||||
|
||||
#ifndef DRIVER_ATM_HORIZON_H
|
||||
#define DRIVER_ATM_HORIZON_H
|
||||
|
||||
|
||||
#ifdef CONFIG_ATM_HORIZON_DEBUG
|
||||
#define DEBUG_HORIZON
|
||||
#endif
|
||||
|
||||
#define DEV_LABEL "hrz"
|
||||
|
||||
#ifndef PCI_VENDOR_ID_MADGE
|
||||
#define PCI_VENDOR_ID_MADGE 0x10B6
|
||||
#endif
|
||||
#ifndef PCI_DEVICE_ID_MADGE_HORIZON
|
||||
#define PCI_DEVICE_ID_MADGE_HORIZON 0x1000
|
||||
#endif
|
||||
|
||||
// diagnostic output
|
||||
|
||||
#define PRINTK(severity,format,args...) \
|
||||
printk(severity DEV_LABEL ": " format "\n" , ## args)
|
||||
|
||||
#ifdef DEBUG_HORIZON
|
||||
|
||||
#define DBG_ERR 0x0001
|
||||
#define DBG_WARN 0x0002
|
||||
#define DBG_INFO 0x0004
|
||||
#define DBG_VCC 0x0008
|
||||
#define DBG_QOS 0x0010
|
||||
#define DBG_TX 0x0020
|
||||
#define DBG_RX 0x0040
|
||||
#define DBG_SKB 0x0080
|
||||
#define DBG_IRQ 0x0100
|
||||
#define DBG_FLOW 0x0200
|
||||
#define DBG_BUS 0x0400
|
||||
#define DBG_REGS 0x0800
|
||||
#define DBG_DATA 0x1000
|
||||
#define DBG_MASK 0x1fff
|
||||
|
||||
/* the ## prevents the annoying double expansion of the macro arguments */
|
||||
/* KERN_INFO is used since KERN_DEBUG often does not make it to the console */
|
||||
#define PRINTDB(bits,format,args...) \
|
||||
( (debug & (bits)) ? printk (KERN_INFO DEV_LABEL ": " format , ## args) : 1 )
|
||||
#define PRINTDM(bits,format,args...) \
|
||||
( (debug & (bits)) ? printk (format , ## args) : 1 )
|
||||
#define PRINTDE(bits,format,args...) \
|
||||
( (debug & (bits)) ? printk (format "\n" , ## args) : 1 )
|
||||
#define PRINTD(bits,format,args...) \
|
||||
( (debug & (bits)) ? printk (KERN_INFO DEV_LABEL ": " format "\n" , ## args) : 1 )
|
||||
|
||||
#else
|
||||
|
||||
#define PRINTD(bits,format,args...)
|
||||
#define PRINTDB(bits,format,args...)
|
||||
#define PRINTDM(bits,format,args...)
|
||||
#define PRINTDE(bits,format,args...)
|
||||
|
||||
#endif
|
||||
|
||||
#define PRINTDD(sec,fmt,args...)
|
||||
#define PRINTDDB(sec,fmt,args...)
|
||||
#define PRINTDDM(sec,fmt,args...)
|
||||
#define PRINTDDE(sec,fmt,args...)
|
||||
|
||||
// fixed constants
|
||||
|
||||
#define SPARE_BUFFER_POOL_SIZE MAX_VCS
|
||||
#define HRZ_MAX_VPI 4
|
||||
#define MIN_PCI_LATENCY 48 // 24 IS TOO SMALL
|
||||
|
||||
/* Horizon specific bits */
|
||||
/* Register offsets */
|
||||
|
||||
#define HRZ_IO_EXTENT 0x80
|
||||
|
||||
#define DATA_PORT_OFF 0x00
|
||||
#define TX_CHANNEL_PORT_OFF 0x04
|
||||
#define TX_DESCRIPTOR_PORT_OFF 0x08
|
||||
#define MEMORY_PORT_OFF 0x0C
|
||||
#define MEM_WR_ADDR_REG_OFF 0x14
|
||||
#define MEM_RD_ADDR_REG_OFF 0x18
|
||||
#define CONTROL_0_REG 0x1C
|
||||
#define INT_SOURCE_REG_OFF 0x20
|
||||
#define INT_ENABLE_REG_OFF 0x24
|
||||
#define MASTER_RX_ADDR_REG_OFF 0x28
|
||||
#define MASTER_RX_COUNT_REG_OFF 0x2C
|
||||
#define MASTER_TX_ADDR_REG_OFF 0x30
|
||||
#define MASTER_TX_COUNT_REG_OFF 0x34
|
||||
#define TX_DESCRIPTOR_REG_OFF 0x38
|
||||
#define TX_CHANNEL_CONFIG_COMMAND_OFF 0x40
|
||||
#define TX_CHANNEL_CONFIG_DATA_OFF 0x44
|
||||
#define TX_FREE_BUFFER_COUNT_OFF 0x48
|
||||
#define RX_FREE_BUFFER_COUNT_OFF 0x4C
|
||||
#define TX_CONFIG_OFF 0x50
|
||||
#define TX_STATUS_OFF 0x54
|
||||
#define RX_CONFIG_OFF 0x58
|
||||
#define RX_LINE_CONFIG_OFF 0x5C
|
||||
#define RX_QUEUE_RD_PTR_OFF 0x60
|
||||
#define RX_QUEUE_WR_PTR_OFF 0x64
|
||||
#define MAX_AAL5_CELL_COUNT_OFF 0x68
|
||||
#define RX_CHANNEL_PORT_OFF 0x6C
|
||||
#define TX_CELL_COUNT_OFF 0x70
|
||||
#define RX_CELL_COUNT_OFF 0x74
|
||||
#define HEC_ERROR_COUNT_OFF 0x78
|
||||
#define UNASSIGNED_CELL_COUNT_OFF 0x7C
|
||||
|
||||
/* Register bit definitions */
|
||||
|
||||
/* Control 0 register */
|
||||
|
||||
#define SEEPROM_DO 0x00000001
|
||||
#define SEEPROM_DI 0x00000002
|
||||
#define SEEPROM_SK 0x00000004
|
||||
#define SEEPROM_CS 0x00000008
|
||||
#define DEBUG_BIT_0 0x00000010
|
||||
#define DEBUG_BIT_1 0x00000020
|
||||
#define DEBUG_BIT_2 0x00000040
|
||||
// RESERVED 0x00000080
|
||||
#define DEBUG_BIT_0_OE 0x00000100
|
||||
#define DEBUG_BIT_1_OE 0x00000200
|
||||
#define DEBUG_BIT_2_OE 0x00000400
|
||||
// RESERVED 0x00000800
|
||||
#define DEBUG_BIT_0_STATE 0x00001000
|
||||
#define DEBUG_BIT_1_STATE 0x00002000
|
||||
#define DEBUG_BIT_2_STATE 0x00004000
|
||||
// RESERVED 0x00008000
|
||||
#define GENERAL_BIT_0 0x00010000
|
||||
#define GENERAL_BIT_1 0x00020000
|
||||
#define GENERAL_BIT_2 0x00040000
|
||||
#define GENERAL_BIT_3 0x00080000
|
||||
#define RESET_HORIZON 0x00100000
|
||||
#define RESET_ATM 0x00200000
|
||||
#define RESET_RX 0x00400000
|
||||
#define RESET_TX 0x00800000
|
||||
#define RESET_HOST 0x01000000
|
||||
// RESERVED 0x02000000
|
||||
#define TARGET_RETRY_DISABLE 0x04000000
|
||||
#define ATM_LAYER_SELECT 0x08000000
|
||||
#define ATM_LAYER_STATUS 0x10000000
|
||||
// RESERVED 0xE0000000
|
||||
|
||||
/* Interrupt source and enable registers */
|
||||
|
||||
#define RX_DATA_AV 0x00000001
|
||||
#define RX_DISABLED 0x00000002
|
||||
#define TIMING_MARKER 0x00000004
|
||||
#define FORCED 0x00000008
|
||||
#define RX_BUS_MASTER_COMPLETE 0x00000010
|
||||
#define TX_BUS_MASTER_COMPLETE 0x00000020
|
||||
#define ABR_TX_CELL_COUNT_INT 0x00000040
|
||||
#define DEBUG_INT 0x00000080
|
||||
// RESERVED 0xFFFFFF00
|
||||
|
||||
/* PIO and Bus Mastering */
|
||||
|
||||
#define MAX_PIO_COUNT 0x000000ff // 255 - make tunable?
|
||||
// 8188 is a hard limit for bus mastering
|
||||
#define MAX_TRANSFER_COUNT 0x00001ffc // 8188
|
||||
#define MASTER_TX_AUTO_APPEND_DESC 0x80000000
|
||||
|
||||
/* TX channel config command port */
|
||||
|
||||
#define PCR_TIMER_ACCESS 0x0000
|
||||
#define SCR_TIMER_ACCESS 0x0001
|
||||
#define BUCKET_CAPACITY_ACCESS 0x0002
|
||||
#define BUCKET_FULLNESS_ACCESS 0x0003
|
||||
#define RATE_TYPE_ACCESS 0x0004
|
||||
// UNUSED 0x00F8
|
||||
#define TX_CHANNEL_CONFIG_MULT 0x0100
|
||||
// UNUSED 0xF800
|
||||
#define BUCKET_MAX_SIZE 0x003f
|
||||
|
||||
/* TX channel config data port */
|
||||
|
||||
#define CLOCK_SELECT_SHIFT 4
|
||||
#define CLOCK_DISABLE 0x00ff
|
||||
|
||||
#define IDLE_RATE_TYPE 0x0
|
||||
#define ABR_RATE_TYPE 0x1
|
||||
#define VBR_RATE_TYPE 0x2
|
||||
#define CBR_RATE_TYPE 0x3
|
||||
|
||||
/* TX config register */
|
||||
|
||||
#define DRVR_DRVRBAR_ENABLE 0x0001
|
||||
#define TXCLK_MUX_SELECT_RCLK 0x0002
|
||||
#define TRANSMIT_TIMING_MARKER 0x0004
|
||||
#define LOOPBACK_TIMING_MARKER 0x0008
|
||||
#define TX_TEST_MODE_16MHz 0x0000
|
||||
#define TX_TEST_MODE_8MHz 0x0010
|
||||
#define TX_TEST_MODE_5_33MHz 0x0020
|
||||
#define TX_TEST_MODE_4MHz 0x0030
|
||||
#define TX_TEST_MODE_3_2MHz 0x0040
|
||||
#define TX_TEST_MODE_2_66MHz 0x0050
|
||||
#define TX_TEST_MODE_2_29MHz 0x0060
|
||||
#define TX_NORMAL_OPERATION 0x0070
|
||||
#define ABR_ROUND_ROBIN 0x0080
|
||||
|
||||
/* TX status register */
|
||||
|
||||
#define IDLE_CHANNELS_MASK 0x00FF
|
||||
#define ABR_CELL_COUNT_REACHED_MULT 0x0100
|
||||
#define ABR_CELL_COUNT_REACHED_MASK 0xFF
|
||||
|
||||
/* RX config register */
|
||||
|
||||
#define NON_USER_CELLS_IN_ONE_CHANNEL 0x0008
|
||||
#define RX_ENABLE 0x0010
|
||||
#define IGNORE_UNUSED_VPI_VCI_BITS_SET 0x0000
|
||||
#define NON_USER_UNUSED_VPI_VCI_BITS_SET 0x0020
|
||||
#define DISCARD_UNUSED_VPI_VCI_BITS_SET 0x0040
|
||||
|
||||
/* RX line config register */
|
||||
|
||||
#define SIGNAL_LOSS 0x0001
|
||||
#define FREQUENCY_DETECT_ERROR 0x0002
|
||||
#define LOCK_DETECT_ERROR 0x0004
|
||||
#define SELECT_INTERNAL_LOOPBACK 0x0008
|
||||
#define LOCK_DETECT_ENABLE 0x0010
|
||||
#define FREQUENCY_DETECT_ENABLE 0x0020
|
||||
#define USER_FRAQ 0x0040
|
||||
#define GXTALOUT_SELECT_DIV4 0x0080
|
||||
#define GXTALOUT_SELECT_NO_GATING 0x0100
|
||||
#define TIMING_MARKER_RECEIVED 0x0200
|
||||
|
||||
/* RX channel port */
|
||||
|
||||
#define RX_CHANNEL_MASK 0x03FF
|
||||
// UNUSED 0x3C00
|
||||
#define FLUSH_CHANNEL 0x4000
|
||||
#define RX_CHANNEL_UPDATE_IN_PROGRESS 0x8000
|
||||
|
||||
/* Receive queue entry */
|
||||
|
||||
#define RX_Q_ENTRY_LENGTH_MASK 0x0000FFFF
|
||||
#define RX_Q_ENTRY_CHANNEL_SHIFT 16
|
||||
#define SIMONS_DODGEY_MARKER 0x08000000
|
||||
#define RX_CONGESTION_EXPERIENCED 0x10000000
|
||||
#define RX_CRC_10_OK 0x20000000
|
||||
#define RX_CRC_32_OK 0x40000000
|
||||
#define RX_COMPLETE_FRAME 0x80000000
|
||||
|
||||
/* Offsets and constants for use with the buffer memory */
|
||||
|
||||
/* Buffer pointers and channel types */
|
||||
|
||||
#define BUFFER_PTR_MASK 0x0000FFFF
|
||||
#define RX_INT_THRESHOLD_MULT 0x00010000
|
||||
#define RX_INT_THRESHOLD_MASK 0x07FF
|
||||
#define INT_EVERY_N_CELLS 0x08000000
|
||||
#define CONGESTION_EXPERIENCED 0x10000000
|
||||
#define FIRST_CELL_OF_AAL5_FRAME 0x20000000
|
||||
#define CHANNEL_TYPE_AAL5 0x00000000
|
||||
#define CHANNEL_TYPE_RAW_CELLS 0x40000000
|
||||
#define CHANNEL_TYPE_AAL3_4 0x80000000
|
||||
|
||||
/* Buffer status stuff */
|
||||
|
||||
#define BUFF_STATUS_MASK 0x00030000
|
||||
#define BUFF_STATUS_EMPTY 0x00000000
|
||||
#define BUFF_STATUS_CELL_AV 0x00010000
|
||||
#define BUFF_STATUS_LAST_CELL_AV 0x00020000
|
||||
|
||||
/* Transmit channel stuff */
|
||||
|
||||
/* Receive channel stuff */
|
||||
|
||||
#define RX_CHANNEL_DISABLED 0x00000000
|
||||
#define RX_CHANNEL_IDLE 0x00000001
|
||||
|
||||
/* General things */
|
||||
|
||||
#define INITIAL_CRC 0xFFFFFFFF
|
||||
|
||||
// A Horizon u32, a byte! Really nasty. Horizon pointers are (32 bit)
|
||||
// word addresses and so standard C pointer operations break (as they
|
||||
// assume byte addresses); so we pretend that Horizon words (and word
|
||||
// pointers) are bytes (and byte pointers) for the purposes of having
|
||||
// a memory map that works.
|
||||
|
||||
typedef u8 HDW;
|
||||
|
||||
typedef struct cell_buf {
|
||||
HDW payload[12];
|
||||
HDW next;
|
||||
HDW cell_count; // AAL5 rx bufs
|
||||
HDW res;
|
||||
union {
|
||||
HDW partial_crc; // AAL5 rx bufs
|
||||
HDW cell_header; // RAW bufs
|
||||
} u;
|
||||
} cell_buf;
|
||||
|
||||
typedef struct tx_ch_desc {
|
||||
HDW rd_buf_type;
|
||||
HDW wr_buf_type;
|
||||
HDW partial_crc;
|
||||
HDW cell_header;
|
||||
} tx_ch_desc;
|
||||
|
||||
typedef struct rx_ch_desc {
|
||||
HDW wr_buf_type;
|
||||
HDW rd_buf_type;
|
||||
} rx_ch_desc;
|
||||
|
||||
typedef struct rx_q_entry {
|
||||
HDW entry;
|
||||
} rx_q_entry;
|
||||
|
||||
#define TX_CHANS 8
|
||||
#define RX_CHANS 1024
|
||||
#define RX_QS 1024
|
||||
#define MAX_VCS RX_CHANS
|
||||
|
||||
/* Horizon buffer memory map */
|
||||
|
||||
// TX Channel Descriptors 2
|
||||
// TX Initial Buffers 8 // TX_CHANS
|
||||
#define BUFN1_SIZE 118 // (126 - TX_CHANS)
|
||||
// RX/TX Start/End Buffers 4
|
||||
#define BUFN2_SIZE 124
|
||||
// RX Queue Entries 64
|
||||
#define BUFN3_SIZE 192
|
||||
// RX Channel Descriptors 128
|
||||
#define BUFN4_SIZE 1408
|
||||
// TOTAL cell_buff chunks 2048
|
||||
|
||||
// cell_buf bufs[2048];
|
||||
// HDW dws[32768];
|
||||
|
||||
typedef struct MEMMAP {
|
||||
tx_ch_desc tx_descs[TX_CHANS]; // 8 * 4 = 32 , 0x0020
|
||||
cell_buf inittxbufs[TX_CHANS]; // these are really
|
||||
cell_buf bufn1[BUFN1_SIZE]; // part of this pool
|
||||
cell_buf txfreebufstart;
|
||||
cell_buf txfreebufend;
|
||||
cell_buf rxfreebufstart;
|
||||
cell_buf rxfreebufend; // 8+118+1+1+1+1+124 = 254
|
||||
cell_buf bufn2[BUFN2_SIZE]; // 16 * 254 = 4064 , 0x1000
|
||||
rx_q_entry rx_q_entries[RX_QS]; // 1 * 1024 = 1024 , 0x1400
|
||||
cell_buf bufn3[BUFN3_SIZE]; // 16 * 192 = 3072 , 0x2000
|
||||
rx_ch_desc rx_descs[MAX_VCS]; // 2 * 1024 = 2048 , 0x2800
|
||||
cell_buf bufn4[BUFN4_SIZE]; // 16 * 1408 = 22528 , 0x8000
|
||||
} MEMMAP;
|
||||
|
||||
#define memmap ((MEMMAP *)0)
|
||||
|
||||
/* end horizon specific bits */
|
||||
|
||||
typedef enum {
|
||||
aal0,
|
||||
aal34,
|
||||
aal5
|
||||
} hrz_aal;
|
||||
|
||||
typedef enum {
|
||||
tx_busy,
|
||||
rx_busy,
|
||||
ultra
|
||||
} hrz_flags;
|
||||
|
||||
// a single struct pointed to by atm_vcc->dev_data
|
||||
|
||||
typedef struct {
|
||||
unsigned int tx_rate;
|
||||
unsigned int rx_rate;
|
||||
u16 channel;
|
||||
u16 tx_xbr_bits;
|
||||
u16 tx_pcr_bits;
|
||||
#if 0
|
||||
u16 tx_scr_bits;
|
||||
u16 tx_bucket_bits;
|
||||
#endif
|
||||
hrz_aal aal;
|
||||
} hrz_vcc;
|
||||
|
||||
struct hrz_dev {
|
||||
|
||||
u32 iobase;
|
||||
u32 * membase;
|
||||
|
||||
struct sk_buff * rx_skb; // skb being RXed
|
||||
unsigned int rx_bytes; // bytes remaining to RX within region
|
||||
void * rx_addr; // addr to send bytes to (for PIO)
|
||||
unsigned int rx_channel; // channel that the skb is going out on
|
||||
|
||||
struct sk_buff * tx_skb; // skb being TXed
|
||||
unsigned int tx_bytes; // bytes remaining to TX within region
|
||||
void * tx_addr; // addr to send bytes from (for PIO)
|
||||
struct iovec * tx_iovec; // remaining regions
|
||||
unsigned int tx_regions; // number of remaining regions
|
||||
|
||||
spinlock_t mem_lock;
|
||||
wait_queue_head_t tx_queue;
|
||||
|
||||
u8 irq;
|
||||
unsigned long flags;
|
||||
u8 tx_last;
|
||||
u8 tx_idle;
|
||||
|
||||
rx_q_entry * rx_q_reset;
|
||||
rx_q_entry * rx_q_entry;
|
||||
rx_q_entry * rx_q_wrap;
|
||||
|
||||
struct atm_dev * atm_dev;
|
||||
|
||||
u32 last_vc;
|
||||
|
||||
int noof_spare_buffers;
|
||||
u16 spare_buffers[SPARE_BUFFER_POOL_SIZE];
|
||||
|
||||
u16 tx_channel_record[TX_CHANS];
|
||||
|
||||
// this is what we follow when we get incoming data
|
||||
u32 txer[MAX_VCS/32];
|
||||
struct atm_vcc * rxer[MAX_VCS];
|
||||
|
||||
// cell rate allocation
|
||||
spinlock_t rate_lock;
|
||||
unsigned int rx_avail;
|
||||
unsigned int tx_avail;
|
||||
|
||||
// dev stats
|
||||
unsigned long tx_cell_count;
|
||||
unsigned long rx_cell_count;
|
||||
unsigned long hec_error_count;
|
||||
unsigned long unassigned_cell_count;
|
||||
|
||||
struct pci_dev * pci_dev;
|
||||
struct timer_list housekeeping;
|
||||
};
|
||||
|
||||
typedef struct hrz_dev hrz_dev;
|
||||
|
||||
/* macros for use later */
|
||||
|
||||
#define BUF_PTR(cbptr) ((cbptr) - (cell_buf *) 0)
|
||||
|
||||
#define INTERESTING_INTERRUPTS \
|
||||
(RX_DATA_AV | RX_DISABLED | TX_BUS_MASTER_COMPLETE | RX_BUS_MASTER_COMPLETE)
|
||||
|
||||
// 190 cells by default (192 TX buffers - 2 elbow room, see docs)
|
||||
#define TX_AAL5_LIMIT (190*ATM_CELL_PAYLOAD-ATM_AAL5_TRAILER) // 9112
|
||||
|
||||
// Have enough RX buffers (unless we allow other buffer splits)
|
||||
#define RX_AAL5_LIMIT ATM_MAX_AAL5_PDU
|
||||
|
||||
/* multi-statement macro protector */
|
||||
#define DW(x) do{ x } while(0)
|
||||
|
||||
#define HRZ_DEV(atm_dev) ((hrz_dev *) (atm_dev)->dev_data)
|
||||
#define HRZ_VCC(atm_vcc) ((hrz_vcc *) (atm_vcc)->dev_data)
|
||||
|
||||
/* Turn the LEDs on and off */
|
||||
// The LEDs bits are upside down in that setting the bit in the debug
|
||||
// register will turn the appropriate LED off.
|
||||
|
||||
#define YELLOW_LED DEBUG_BIT_0
|
||||
#define GREEN_LED DEBUG_BIT_1
|
||||
#define YELLOW_LED_OE DEBUG_BIT_0_OE
|
||||
#define GREEN_LED_OE DEBUG_BIT_1_OE
|
||||
|
||||
#define GREEN_LED_OFF(dev) \
|
||||
wr_regl (dev, CONTROL_0_REG, rd_regl (dev, CONTROL_0_REG) | GREEN_LED)
|
||||
#define GREEN_LED_ON(dev) \
|
||||
wr_regl (dev, CONTROL_0_REG, rd_regl (dev, CONTROL_0_REG) &~ GREEN_LED)
|
||||
#define YELLOW_LED_OFF(dev) \
|
||||
wr_regl (dev, CONTROL_0_REG, rd_regl (dev, CONTROL_0_REG) | YELLOW_LED)
|
||||
#define YELLOW_LED_ON(dev) \
|
||||
wr_regl (dev, CONTROL_0_REG, rd_regl (dev, CONTROL_0_REG) &~ YELLOW_LED)
|
||||
|
||||
typedef enum {
|
||||
round_up,
|
||||
round_down,
|
||||
round_nearest
|
||||
} rounding;
|
||||
|
||||
#endif /* DRIVER_ATM_HORIZON_H */
|
|
@ -14,11 +14,6 @@ typedef void __iomem *virt_addr_t;
|
|||
|
||||
#define CYCLE_DELAY 5
|
||||
|
||||
/*
|
||||
This was the original definition
|
||||
#define osp_MicroDelay(microsec) \
|
||||
do { int _i = 4*microsec; while (--_i > 0) { __SLOW_DOWN_IO; }} while (0)
|
||||
*/
|
||||
#define osp_MicroDelay(microsec) {unsigned long useconds = (microsec); \
|
||||
udelay((useconds));}
|
||||
/*
|
||||
|
|
|
@ -1,293 +0,0 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/* drivers/atm/uPD98401.h - NEC uPD98401 (SAR) declarations */
|
||||
|
||||
/* Written 1995 by Werner Almesberger, EPFL LRC */
|
||||
|
||||
|
||||
#ifndef DRIVERS_ATM_uPD98401_H
|
||||
#define DRIVERS_ATM_uPD98401_H
|
||||
|
||||
|
||||
#define MAX_CRAM_SIZE (1 << 18) /* 2^18 words */
|
||||
#define RAM_INCREMENT 1024 /* check in 4 kB increments */
|
||||
|
||||
#define uPD98401_PORTS 0x24 /* probably more ? */
|
||||
|
||||
|
||||
/*
|
||||
* Commands
|
||||
*/
|
||||
|
||||
#define uPD98401_OPEN_CHAN 0x20000000 /* open channel */
|
||||
#define uPD98401_CHAN_ADDR 0x0003fff8 /* channel address */
|
||||
#define uPD98401_CHAN_ADDR_SHIFT 3
|
||||
#define uPD98401_CLOSE_CHAN 0x24000000 /* close channel */
|
||||
#define uPD98401_CHAN_RT 0x02000000 /* RX/TX (0 TX, 1 RX) */
|
||||
#define uPD98401_DEACT_CHAN 0x28000000 /* deactivate channel */
|
||||
#define uPD98401_TX_READY 0x30000000 /* TX ready */
|
||||
#define uPD98401_ADD_BAT 0x34000000 /* add batches */
|
||||
#define uPD98401_POOL 0x000f0000 /* pool number */
|
||||
#define uPD98401_POOL_SHIFT 16
|
||||
#define uPD98401_POOL_NUMBAT 0x0000ffff /* number of batches */
|
||||
#define uPD98401_NOP 0x3f000000 /* NOP */
|
||||
#define uPD98401_IND_ACC 0x00000000 /* Indirect Access */
|
||||
#define uPD98401_IA_RW 0x10000000 /* Read/Write (0 W, 1 R) */
|
||||
#define uPD98401_IA_B3 0x08000000 /* Byte select, 1 enable */
|
||||
#define uPD98401_IA_B2 0x04000000
|
||||
#define uPD98401_IA_B1 0x02000000
|
||||
#define uPD98401_IA_B0 0x01000000
|
||||
#define uPD98401_IA_BALL 0x0f000000 /* whole longword */
|
||||
#define uPD98401_IA_TGT 0x000c0000 /* Target */
|
||||
#define uPD98401_IA_TGT_SHIFT 18
|
||||
#define uPD98401_IA_TGT_CM 0 /* - Control Memory */
|
||||
#define uPD98401_IA_TGT_SAR 1 /* - uPD98401 registers */
|
||||
#define uPD98401_IA_TGT_PHY 3 /* - PHY device */
|
||||
#define uPD98401_IA_ADDR 0x0003ffff
|
||||
|
||||
/*
|
||||
* Command Register Status
|
||||
*/
|
||||
|
||||
#define uPD98401_BUSY 0x80000000 /* SAR is busy */
|
||||
#define uPD98401_LOCKED 0x40000000 /* SAR is locked by other CPU */
|
||||
|
||||
/*
|
||||
* Indications
|
||||
*/
|
||||
|
||||
/* Normal (AAL5) Receive Indication */
|
||||
#define uPD98401_AAL5_UINFO 0xffff0000 /* user-supplied information */
|
||||
#define uPD98401_AAL5_UINFO_SHIFT 16
|
||||
#define uPD98401_AAL5_SIZE 0x0000ffff /* PDU size (in _CELLS_ !!) */
|
||||
#define uPD98401_AAL5_CHAN 0x7fff0000 /* Channel number */
|
||||
#define uPD98401_AAL5_CHAN_SHIFT 16
|
||||
#define uPD98401_AAL5_ERR 0x00008000 /* Error indication */
|
||||
#define uPD98401_AAL5_CI 0x00004000 /* Congestion Indication */
|
||||
#define uPD98401_AAL5_CLP 0x00002000 /* CLP (>= 1 cell had CLP=1) */
|
||||
#define uPD98401_AAL5_ES 0x00000f00 /* Error Status */
|
||||
#define uPD98401_AAL5_ES_SHIFT 8
|
||||
#define uPD98401_AAL5_ES_NONE 0 /* No error */
|
||||
#define uPD98401_AAL5_ES_FREE 1 /* Receiver free buf underflow */
|
||||
#define uPD98401_AAL5_ES_FIFO 2 /* Receiver FIFO overrun */
|
||||
#define uPD98401_AAL5_ES_TOOBIG 3 /* Maximum length violation */
|
||||
#define uPD98401_AAL5_ES_CRC 4 /* CRC error */
|
||||
#define uPD98401_AAL5_ES_ABORT 5 /* User abort */
|
||||
#define uPD98401_AAL5_ES_LENGTH 6 /* Length violation */
|
||||
#define uPD98401_AAL5_ES_T1 7 /* T1 error (timeout) */
|
||||
#define uPD98401_AAL5_ES_DEACT 8 /* Deactivated with DEACT_CHAN */
|
||||
#define uPD98401_AAL5_POOL 0x0000001f /* Free buffer pool number */
|
||||
|
||||
/* Raw Cell Indication */
|
||||
#define uPD98401_RAW_UINFO uPD98401_AAL5_UINFO
|
||||
#define uPD98401_RAW_UINFO_SHIFT uPD98401_AAL5_UINFO_SHIFT
|
||||
#define uPD98401_RAW_HEC 0x000000ff /* HEC */
|
||||
#define uPD98401_RAW_CHAN uPD98401_AAL5_CHAN
|
||||
#define uPD98401_RAW_CHAN_SHIFT uPD98401_AAL5_CHAN_SHIFT
|
||||
|
||||
/* Transmit Indication */
|
||||
#define uPD98401_TXI_CONN 0x7fff0000 /* Connection Number */
|
||||
#define uPD98401_TXI_CONN_SHIFT 16
|
||||
#define uPD98401_TXI_ACTIVE 0x00008000 /* Channel remains active */
|
||||
#define uPD98401_TXI_PQP 0x00007fff /* Packet Queue Pointer */
|
||||
|
||||
/*
|
||||
* Directly Addressable Registers
|
||||
*/
|
||||
|
||||
#define uPD98401_GMR 0x00 /* General Mode Register */
|
||||
#define uPD98401_GSR 0x01 /* General Status Register */
|
||||
#define uPD98401_IMR 0x02 /* Interrupt Mask Register */
|
||||
#define uPD98401_RQU 0x03 /* Receive Queue Underrun */
|
||||
#define uPD98401_RQA 0x04 /* Receive Queue Alert */
|
||||
#define uPD98401_ADDR 0x05 /* Last Burst Address */
|
||||
#define uPD98401_VER 0x06 /* Version Number */
|
||||
#define uPD98401_SWR 0x07 /* Software Reset */
|
||||
#define uPD98401_CMR 0x08 /* Command Register */
|
||||
#define uPD98401_CMR_L 0x09 /* Command Register and Lock/Unlock */
|
||||
#define uPD98401_CER 0x0a /* Command Extension Register */
|
||||
#define uPD98401_CER_L 0x0b /* Command Ext Reg and Lock/Unlock */
|
||||
|
||||
#define uPD98401_MSH(n) (0x10+(n)) /* Mailbox n Start Address High */
|
||||
#define uPD98401_MSL(n) (0x14+(n)) /* Mailbox n Start Address High */
|
||||
#define uPD98401_MBA(n) (0x18+(n)) /* Mailbox n Bottom Address */
|
||||
#define uPD98401_MTA(n) (0x1c+(n)) /* Mailbox n Tail Address */
|
||||
#define uPD98401_MWA(n) (0x20+(n)) /* Mailbox n Write Address */
|
||||
|
||||
/* GMR is at 0x00 */
|
||||
#define uPD98401_GMR_ONE 0x80000000 /* Must be set to one */
|
||||
#define uPD98401_GMR_SLM 0x40000000 /* Address mode (0 word, 1 byte) */
|
||||
#define uPD98401_GMR_CPE 0x00008000 /* Control Memory Parity Enable */
|
||||
#define uPD98401_GMR_LP 0x00004000 /* Loopback */
|
||||
#define uPD98401_GMR_WA 0x00002000 /* Early Bus Write Abort/RDY */
|
||||
#define uPD98401_GMR_RA 0x00001000 /* Early Read Abort/RDY */
|
||||
#define uPD98401_GMR_SZ 0x00000f00 /* Burst Size Enable */
|
||||
#define uPD98401_BURST16 0x00000800 /* 16-word burst */
|
||||
#define uPD98401_BURST8 0x00000400 /* 8-word burst */
|
||||
#define uPD98401_BURST4 0x00000200 /* 4-word burst */
|
||||
#define uPD98401_BURST2 0x00000100 /* 2-word burst */
|
||||
#define uPD98401_GMR_AD 0x00000080 /* Address (burst resolution) Disable */
|
||||
#define uPD98401_GMR_BO 0x00000040 /* Byte Order (0 little, 1 big) */
|
||||
#define uPD98401_GMR_PM 0x00000020 /* Bus Parity Mode (0 byte, 1 word)*/
|
||||
#define uPD98401_GMR_PC 0x00000010 /* Bus Parity Control (0even,1odd) */
|
||||
#define uPD98401_GMR_BPE 0x00000008 /* Bus Parity Enable */
|
||||
#define uPD98401_GMR_DR 0x00000004 /* Receive Drop Mode (0drop,1don't)*/
|
||||
#define uPD98401_GMR_SE 0x00000002 /* Shapers Enable */
|
||||
#define uPD98401_GMR_RE 0x00000001 /* Receiver Enable */
|
||||
|
||||
/* GSR is at 0x01, IMR is at 0x02 */
|
||||
#define uPD98401_INT_PI 0x80000000 /* PHY interrupt */
|
||||
#define uPD98401_INT_RQA 0x40000000 /* Receive Queue Alert */
|
||||
#define uPD98401_INT_RQU 0x20000000 /* Receive Queue Underrun */
|
||||
#define uPD98401_INT_RD 0x10000000 /* Receiver Deactivated */
|
||||
#define uPD98401_INT_SPE 0x08000000 /* System Parity Error */
|
||||
#define uPD98401_INT_CPE 0x04000000 /* Control Memory Parity Error */
|
||||
#define uPD98401_INT_SBE 0x02000000 /* System Bus Error */
|
||||
#define uPD98401_INT_IND 0x01000000 /* Initialization Done */
|
||||
#define uPD98401_INT_RCR 0x0000ff00 /* Raw Cell Received */
|
||||
#define uPD98401_INT_RCR_SHIFT 8
|
||||
#define uPD98401_INT_MF 0x000000f0 /* Mailbox Full */
|
||||
#define uPD98401_INT_MF_SHIFT 4
|
||||
#define uPD98401_INT_MM 0x0000000f /* Mailbox Modified */
|
||||
|
||||
/* VER is at 0x06 */
|
||||
#define uPD98401_MAJOR 0x0000ff00 /* Major revision */
|
||||
#define uPD98401_MAJOR_SHIFT 8
|
||||
#define uPD98401_MINOR 0x000000ff /* Minor revision */
|
||||
|
||||
/*
|
||||
* Indirectly Addressable Registers
|
||||
*/
|
||||
|
||||
#define uPD98401_IM(n) (0x40000+(n)) /* Scheduler n I and M */
|
||||
#define uPD98401_X(n) (0x40010+(n)) /* Scheduler n X */
|
||||
#define uPD98401_Y(n) (0x40020+(n)) /* Scheduler n Y */
|
||||
#define uPD98401_PC(n) (0x40030+(n)) /* Scheduler n P, C, p and c */
|
||||
#define uPD98401_PS(n) (0x40040+(n)) /* Scheduler n priority and status */
|
||||
|
||||
/* IM contents */
|
||||
#define uPD98401_IM_I 0xff000000 /* I */
|
||||
#define uPD98401_IM_I_SHIFT 24
|
||||
#define uPD98401_IM_M 0x00ffffff /* M */
|
||||
|
||||
/* PC contents */
|
||||
#define uPD98401_PC_P 0xff000000 /* P */
|
||||
#define uPD98401_PC_P_SHIFT 24
|
||||
#define uPD98401_PC_C 0x00ff0000 /* C */
|
||||
#define uPD98401_PC_C_SHIFT 16
|
||||
#define uPD98401_PC_p 0x0000ff00 /* p */
|
||||
#define uPD98401_PC_p_SHIFT 8
|
||||
#define uPD98401_PC_c 0x000000ff /* c */
|
||||
|
||||
/* PS contents */
|
||||
#define uPD98401_PS_PRIO 0xf0 /* Priority level (0 high, 15 low) */
|
||||
#define uPD98401_PS_PRIO_SHIFT 4
|
||||
#define uPD98401_PS_S 0x08 /* Scan - must be 0 (internal) */
|
||||
#define uPD98401_PS_R 0x04 /* Round Robin (internal) */
|
||||
#define uPD98401_PS_A 0x02 /* Active (internal) */
|
||||
#define uPD98401_PS_E 0x01 /* Enabled */
|
||||
|
||||
#define uPD98401_TOS 0x40100 /* Top of Stack Control Memory Address */
|
||||
#define uPD98401_SMA 0x40200 /* Shapers Control Memory Start Address */
|
||||
#define uPD98401_PMA 0x40201 /* Receive Pool Control Memory Start Address */
|
||||
#define uPD98401_T1R 0x40300 /* T1 Register */
|
||||
#define uPD98401_VRR 0x40301 /* VPI/VCI Reduction Register/Recv. Shutdown */
|
||||
#define uPD98401_TSR 0x40302 /* Time-Stamp Register */
|
||||
|
||||
/* VRR is at 0x40301 */
|
||||
#define uPD98401_VRR_SDM 0x80000000 /* Shutdown Mode */
|
||||
#define uPD98401_VRR_SHIFT 0x000f0000 /* VPI/VCI Shift */
|
||||
#define uPD98401_VRR_SHIFT_SHIFT 16
|
||||
#define uPD98401_VRR_MASK 0x0000ffff /* VPI/VCI mask */
|
||||
|
||||
/*
|
||||
* TX packet descriptor
|
||||
*/
|
||||
|
||||
#define uPD98401_TXPD_SIZE 16 /* descriptor size (in bytes) */
|
||||
|
||||
#define uPD98401_TXPD_V 0x80000000 /* Valid bit */
|
||||
#define uPD98401_TXPD_DP 0x40000000 /* Descriptor (1) or Pointer (0) */
|
||||
#define uPD98401_TXPD_SM 0x20000000 /* Single (1) or Multiple (0) */
|
||||
#define uPD98401_TXPD_CLPM 0x18000000 /* CLP mode */
|
||||
#define uPD98401_CLPM_0 0 /* 00 CLP = 0 */
|
||||
#define uPD98401_CLPM_1 3 /* 11 CLP = 1 */
|
||||
#define uPD98401_CLPM_LAST 1 /* 01 CLP unless last cell */
|
||||
#define uPD98401_TXPD_CLPM_SHIFT 27
|
||||
#define uPD98401_TXPD_PTI 0x07000000 /* PTI pattern */
|
||||
#define uPD98401_TXPD_PTI_SHIFT 24
|
||||
#define uPD98401_TXPD_GFC 0x00f00000 /* GFC pattern */
|
||||
#define uPD98401_TXPD_GFC_SHIFT 20
|
||||
#define uPD98401_TXPD_C10 0x00040000 /* insert CRC-10 */
|
||||
#define uPD98401_TXPD_AAL5 0x00020000 /* AAL5 processing */
|
||||
#define uPD98401_TXPD_MB 0x00010000 /* TX mailbox number */
|
||||
#define uPD98401_TXPD_UU 0x0000ff00 /* CPCS-UU */
|
||||
#define uPD98401_TXPD_UU_SHIFT 8
|
||||
#define uPD98401_TXPD_CPI 0x000000ff /* CPI */
|
||||
|
||||
/*
|
||||
* TX buffer descriptor
|
||||
*/
|
||||
|
||||
#define uPD98401_TXBD_SIZE 8 /* descriptor size (in bytes) */
|
||||
|
||||
#define uPD98401_TXBD_LAST 0x80000000 /* last buffer in packet */
|
||||
|
||||
/*
|
||||
* TX VC table
|
||||
*/
|
||||
|
||||
/* 1st word has the same structure as in a TX packet descriptor */
|
||||
#define uPD98401_TXVC_L 0x80000000 /* last buffer */
|
||||
#define uPD98401_TXVC_SHP 0x0f000000 /* shaper number */
|
||||
#define uPD98401_TXVC_SHP_SHIFT 24
|
||||
#define uPD98401_TXVC_VPI 0x00ff0000 /* VPI */
|
||||
#define uPD98401_TXVC_VPI_SHIFT 16
|
||||
#define uPD98401_TXVC_VCI 0x0000ffff /* VCI */
|
||||
#define uPD98401_TXVC_QRP 6 /* Queue Read Pointer is in word 6 */
|
||||
|
||||
/*
|
||||
* RX free buffer pools descriptor
|
||||
*/
|
||||
|
||||
#define uPD98401_RXFP_ALERT 0x70000000 /* low water mark */
|
||||
#define uPD98401_RXFP_ALERT_SHIFT 28
|
||||
#define uPD98401_RXFP_BFSZ 0x0f000000 /* buffer size, 64*2^n */
|
||||
#define uPD98401_RXFP_BFSZ_SHIFT 24
|
||||
#define uPD98401_RXFP_BTSZ 0x00ff0000 /* batch size, n+1 */
|
||||
#define uPD98401_RXFP_BTSZ_SHIFT 16
|
||||
#define uPD98401_RXFP_REMAIN 0x0000ffff /* remaining batches in pool */
|
||||
|
||||
/*
|
||||
* RX VC table
|
||||
*/
|
||||
|
||||
#define uPD98401_RXVC_BTSZ 0xff000000 /* remaining free buffers in batch */
|
||||
#define uPD98401_RXVC_BTSZ_SHIFT 24
|
||||
#define uPD98401_RXVC_MB 0x00200000 /* RX mailbox number */
|
||||
#define uPD98401_RXVC_POOL 0x001f0000 /* free buffer pool number */
|
||||
#define uPD98401_RXVC_POOL_SHIFT 16
|
||||
#define uPD98401_RXVC_UINFO 0x0000ffff /* user-supplied information */
|
||||
#define uPD98401_RXVC_T1 0xffff0000 /* T1 timestamp */
|
||||
#define uPD98401_RXVC_T1_SHIFT 16
|
||||
#define uPD98401_RXVC_PR 0x00008000 /* Packet Reception, 1 if busy */
|
||||
#define uPD98401_RXVC_DR 0x00004000 /* FIFO Drop */
|
||||
#define uPD98401_RXVC_OD 0x00001000 /* Drop OAM cells */
|
||||
#define uPD98401_RXVC_AR 0x00000800 /* AAL5 or raw cell; 1 if AAL5 */
|
||||
#define uPD98401_RXVC_MAXSEG 0x000007ff /* max number of segments per PDU */
|
||||
#define uPD98401_RXVC_REM 0xfffe0000 /* remaining words in curr buffer */
|
||||
#define uPD98401_RXVC_REM_SHIFT 17
|
||||
#define uPD98401_RXVC_CLP 0x00010000 /* CLP received */
|
||||
#define uPD98401_RXVC_BFA 0x00008000 /* Buffer Assigned */
|
||||
#define uPD98401_RXVC_BTA 0x00004000 /* Batch Assigned */
|
||||
#define uPD98401_RXVC_CI 0x00002000 /* Congestion Indication */
|
||||
#define uPD98401_RXVC_DD 0x00001000 /* Dropping incoming cells */
|
||||
#define uPD98401_RXVC_DP 0x00000800 /* like PR ? */
|
||||
#define uPD98401_RXVC_CURSEG 0x000007ff /* Current Segment count */
|
||||
|
||||
/*
|
||||
* RX lookup table
|
||||
*/
|
||||
|
||||
#define uPD98401_RXLT_ENBL 0x8000 /* Enable */
|
||||
|
||||
#endif
|
|
@ -1,266 +0,0 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/* drivers/atm/uPD98402.c - NEC uPD98402 (PHY) declarations */
|
||||
|
||||
/* Written 1995-2000 by Werner Almesberger, EPFL LRC/ICA */
|
||||
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/mm.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/atmdev.h>
|
||||
#include <linux/sonet.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/uaccess.h>
|
||||
#include <linux/atomic.h>
|
||||
|
||||
#include "uPD98402.h"
|
||||
|
||||
|
||||
#if 0
|
||||
#define DPRINTK(format,args...) printk(KERN_DEBUG format,##args)
|
||||
#else
|
||||
#define DPRINTK(format,args...)
|
||||
#endif
|
||||
|
||||
|
||||
struct uPD98402_priv {
|
||||
struct k_sonet_stats sonet_stats;/* link diagnostics */
|
||||
unsigned char framing; /* SONET/SDH framing */
|
||||
int loop_mode; /* loopback mode */
|
||||
spinlock_t lock;
|
||||
};
|
||||
|
||||
|
||||
#define PRIV(dev) ((struct uPD98402_priv *) dev->phy_data)
|
||||
|
||||
#define PUT(val,reg) dev->ops->phy_put(dev,val,uPD98402_##reg)
|
||||
#define GET(reg) dev->ops->phy_get(dev,uPD98402_##reg)
|
||||
|
||||
|
||||
static int fetch_stats(struct atm_dev *dev,struct sonet_stats __user *arg,int zero)
|
||||
{
|
||||
struct sonet_stats tmp;
|
||||
int error = 0;
|
||||
|
||||
atomic_add(GET(HECCT),&PRIV(dev)->sonet_stats.uncorr_hcs);
|
||||
sonet_copy_stats(&PRIV(dev)->sonet_stats,&tmp);
|
||||
if (arg) error = copy_to_user(arg,&tmp,sizeof(tmp));
|
||||
if (zero && !error) {
|
||||
/* unused fields are reported as -1, but we must not "adjust"
|
||||
them */
|
||||
tmp.corr_hcs = tmp.tx_cells = tmp.rx_cells = 0;
|
||||
sonet_subtract_stats(&PRIV(dev)->sonet_stats,&tmp);
|
||||
}
|
||||
return error ? -EFAULT : 0;
|
||||
}
|
||||
|
||||
|
||||
static int set_framing(struct atm_dev *dev,unsigned char framing)
|
||||
{
|
||||
static const unsigned char sonet[] = { 1,2,3,0 };
|
||||
static const unsigned char sdh[] = { 1,0,0,2 };
|
||||
const char *set;
|
||||
unsigned long flags;
|
||||
|
||||
switch (framing) {
|
||||
case SONET_FRAME_SONET:
|
||||
set = sonet;
|
||||
break;
|
||||
case SONET_FRAME_SDH:
|
||||
set = sdh;
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
spin_lock_irqsave(&PRIV(dev)->lock, flags);
|
||||
PUT(set[0],C11T);
|
||||
PUT(set[1],C12T);
|
||||
PUT(set[2],C13T);
|
||||
PUT((GET(MDR) & ~uPD98402_MDR_SS_MASK) | (set[3] <<
|
||||
uPD98402_MDR_SS_SHIFT),MDR);
|
||||
spin_unlock_irqrestore(&PRIV(dev)->lock, flags);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int get_sense(struct atm_dev *dev,u8 __user *arg)
|
||||
{
|
||||
unsigned long flags;
|
||||
unsigned char s[3];
|
||||
|
||||
spin_lock_irqsave(&PRIV(dev)->lock, flags);
|
||||
s[0] = GET(C11R);
|
||||
s[1] = GET(C12R);
|
||||
s[2] = GET(C13R);
|
||||
spin_unlock_irqrestore(&PRIV(dev)->lock, flags);
|
||||
return (put_user(s[0], arg) || put_user(s[1], arg+1) ||
|
||||
put_user(s[2], arg+2) || put_user(0xff, arg+3) ||
|
||||
put_user(0xff, arg+4) || put_user(0xff, arg+5)) ? -EFAULT : 0;
|
||||
}
|
||||
|
||||
|
||||
static int set_loopback(struct atm_dev *dev,int mode)
|
||||
{
|
||||
unsigned char mode_reg;
|
||||
|
||||
mode_reg = GET(MDR) & ~(uPD98402_MDR_TPLP | uPD98402_MDR_ALP |
|
||||
uPD98402_MDR_RPLP);
|
||||
switch (__ATM_LM_XTLOC(mode)) {
|
||||
case __ATM_LM_NONE:
|
||||
break;
|
||||
case __ATM_LM_PHY:
|
||||
mode_reg |= uPD98402_MDR_TPLP;
|
||||
break;
|
||||
case __ATM_LM_ATM:
|
||||
mode_reg |= uPD98402_MDR_ALP;
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
switch (__ATM_LM_XTRMT(mode)) {
|
||||
case __ATM_LM_NONE:
|
||||
break;
|
||||
case __ATM_LM_PHY:
|
||||
mode_reg |= uPD98402_MDR_RPLP;
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
PUT(mode_reg,MDR);
|
||||
PRIV(dev)->loop_mode = mode;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int uPD98402_ioctl(struct atm_dev *dev,unsigned int cmd,void __user *arg)
|
||||
{
|
||||
switch (cmd) {
|
||||
|
||||
case SONET_GETSTATZ:
|
||||
case SONET_GETSTAT:
|
||||
return fetch_stats(dev,arg, cmd == SONET_GETSTATZ);
|
||||
case SONET_SETFRAMING:
|
||||
return set_framing(dev, (int)(unsigned long)arg);
|
||||
case SONET_GETFRAMING:
|
||||
return put_user(PRIV(dev)->framing,(int __user *)arg) ?
|
||||
-EFAULT : 0;
|
||||
case SONET_GETFRSENSE:
|
||||
return get_sense(dev,arg);
|
||||
case ATM_SETLOOP:
|
||||
return set_loopback(dev, (int)(unsigned long)arg);
|
||||
case ATM_GETLOOP:
|
||||
return put_user(PRIV(dev)->loop_mode,(int __user *)arg) ?
|
||||
-EFAULT : 0;
|
||||
case ATM_QUERYLOOP:
|
||||
return put_user(ATM_LM_LOC_PHY | ATM_LM_LOC_ATM |
|
||||
ATM_LM_RMT_PHY,(int __user *)arg) ? -EFAULT : 0;
|
||||
default:
|
||||
return -ENOIOCTLCMD;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#define ADD_LIMITED(s,v) \
|
||||
{ atomic_add(GET(v),&PRIV(dev)->sonet_stats.s); \
|
||||
if (atomic_read(&PRIV(dev)->sonet_stats.s) < 0) \
|
||||
atomic_set(&PRIV(dev)->sonet_stats.s,INT_MAX); }
|
||||
|
||||
|
||||
static void stat_event(struct atm_dev *dev)
|
||||
{
|
||||
unsigned char events;
|
||||
|
||||
events = GET(PCR);
|
||||
if (events & uPD98402_PFM_PFEB) ADD_LIMITED(path_febe,PFECB);
|
||||
if (events & uPD98402_PFM_LFEB) ADD_LIMITED(line_febe,LECCT);
|
||||
if (events & uPD98402_PFM_B3E) ADD_LIMITED(path_bip,B3ECT);
|
||||
if (events & uPD98402_PFM_B2E) ADD_LIMITED(line_bip,B2ECT);
|
||||
if (events & uPD98402_PFM_B1E) ADD_LIMITED(section_bip,B1ECT);
|
||||
}
|
||||
|
||||
|
||||
#undef ADD_LIMITED
|
||||
|
||||
|
||||
static void uPD98402_int(struct atm_dev *dev)
|
||||
{
|
||||
static unsigned long silence = 0;
|
||||
unsigned char reason;
|
||||
|
||||
while ((reason = GET(PICR))) {
|
||||
if (reason & uPD98402_INT_LOS)
|
||||
printk(KERN_NOTICE "%s(itf %d): signal lost\n",
|
||||
dev->type,dev->number);
|
||||
if (reason & uPD98402_INT_PFM) stat_event(dev);
|
||||
if (reason & uPD98402_INT_PCO) {
|
||||
(void) GET(PCOCR); /* clear interrupt cause */
|
||||
atomic_add(GET(HECCT),
|
||||
&PRIV(dev)->sonet_stats.uncorr_hcs);
|
||||
}
|
||||
if ((reason & uPD98402_INT_RFO) &&
|
||||
(time_after(jiffies, silence) || silence == 0)) {
|
||||
printk(KERN_WARNING "%s(itf %d): uPD98402 receive "
|
||||
"FIFO overflow\n",dev->type,dev->number);
|
||||
silence = (jiffies+HZ/2)|1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static int uPD98402_start(struct atm_dev *dev)
|
||||
{
|
||||
DPRINTK("phy_start\n");
|
||||
if (!(dev->phy_data = kmalloc(sizeof(struct uPD98402_priv),GFP_KERNEL)))
|
||||
return -ENOMEM;
|
||||
spin_lock_init(&PRIV(dev)->lock);
|
||||
memset(&PRIV(dev)->sonet_stats,0,sizeof(struct k_sonet_stats));
|
||||
(void) GET(PCR); /* clear performance events */
|
||||
PUT(uPD98402_PFM_FJ,PCMR); /* ignore frequency adj */
|
||||
(void) GET(PCOCR); /* clear overflows */
|
||||
PUT(~uPD98402_PCO_HECC,PCOMR);
|
||||
(void) GET(PICR); /* clear interrupts */
|
||||
PUT(~(uPD98402_INT_PFM | uPD98402_INT_ALM | uPD98402_INT_RFO |
|
||||
uPD98402_INT_LOS),PIMR); /* enable them */
|
||||
(void) fetch_stats(dev,NULL,1); /* clear kernel counters */
|
||||
atomic_set(&PRIV(dev)->sonet_stats.corr_hcs,-1);
|
||||
atomic_set(&PRIV(dev)->sonet_stats.tx_cells,-1);
|
||||
atomic_set(&PRIV(dev)->sonet_stats.rx_cells,-1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int uPD98402_stop(struct atm_dev *dev)
|
||||
{
|
||||
/* let SAR driver worry about stopping interrupts */
|
||||
kfree(PRIV(dev));
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static const struct atmphy_ops uPD98402_ops = {
|
||||
.start = uPD98402_start,
|
||||
.ioctl = uPD98402_ioctl,
|
||||
.interrupt = uPD98402_int,
|
||||
.stop = uPD98402_stop,
|
||||
};
|
||||
|
||||
|
||||
int uPD98402_init(struct atm_dev *dev)
|
||||
{
|
||||
DPRINTK("phy_init\n");
|
||||
dev->phy = &uPD98402_ops;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
|
||||
EXPORT_SYMBOL(uPD98402_init);
|
||||
|
||||
static __init int uPD98402_module_init(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
module_init(uPD98402_module_init);
|
||||
/* module_exit not defined so not unloadable */
|
|
@ -1,107 +0,0 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/* drivers/atm/uPD98402.h - NEC uPD98402 (PHY) declarations */
|
||||
|
||||
/* Written 1995 by Werner Almesberger, EPFL LRC */
|
||||
|
||||
|
||||
#ifndef DRIVERS_ATM_uPD98402_H
|
||||
#define DRIVERS_ATM_uPD98402_H
|
||||
|
||||
/*
|
||||
* Registers
|
||||
*/
|
||||
|
||||
#define uPD98402_CMR 0x00 /* Command Register */
|
||||
#define uPD98402_MDR 0x01 /* Mode Register */
|
||||
#define uPD98402_PICR 0x02 /* PHY Interrupt Cause Register */
|
||||
#define uPD98402_PIMR 0x03 /* PHY Interrupt Mask Register */
|
||||
#define uPD98402_ACR 0x04 /* Alarm Cause Register */
|
||||
#define uPD98402_ACMR 0x05 /* Alarm Cause Mask Register */
|
||||
#define uPD98402_PCR 0x06 /* Performance Cause Register */
|
||||
#define uPD98402_PCMR 0x07 /* Performance Cause Mask Register */
|
||||
#define uPD98402_IACM 0x08 /* Internal Alarm Cause Mask Register */
|
||||
#define uPD98402_B1ECT 0x09 /* B1 Error Count Register */
|
||||
#define uPD98402_B2ECT 0x0a /* B2 Error Count Register */
|
||||
#define uPD98402_B3ECT 0x0b /* B3 Error Count Regster */
|
||||
#define uPD98402_PFECB 0x0c /* Path FEBE Count Register */
|
||||
#define uPD98402_LECCT 0x0d /* Line FEBE Count Register */
|
||||
#define uPD98402_HECCT 0x0e /* HEC Error Count Register */
|
||||
#define uPD98402_FJCT 0x0f /* Frequence Justification Count Reg */
|
||||
#define uPD98402_PCOCR 0x10 /* Perf. Counter Overflow Cause Reg */
|
||||
#define uPD98402_PCOMR 0x11 /* Perf. Counter Overflow Mask Reg */
|
||||
#define uPD98402_C11T 0x20 /* C11T Data Register */
|
||||
#define uPD98402_C12T 0x21 /* C12T Data Register */
|
||||
#define uPD98402_C13T 0x22 /* C13T Data Register */
|
||||
#define uPD98402_F1T 0x23 /* F1T Data Register */
|
||||
#define uPD98402_K2T 0x25 /* K2T Data Register */
|
||||
#define uPD98402_C2T 0x26 /* C2T Data Register */
|
||||
#define uPD98402_F2T 0x27 /* F2T Data Register */
|
||||
#define uPD98402_C11R 0x30 /* C11T Data Register */
|
||||
#define uPD98402_C12R 0x31 /* C12T Data Register */
|
||||
#define uPD98402_C13R 0x32 /* C13T Data Register */
|
||||
#define uPD98402_F1R 0x33 /* F1T Data Register */
|
||||
#define uPD98402_K2R 0x35 /* K2T Data Register */
|
||||
#define uPD98402_C2R 0x36 /* C2T Data Register */
|
||||
#define uPD98402_F2R 0x37 /* F2T Data Register */
|
||||
|
||||
/* CMR is at 0x00 */
|
||||
#define uPD98402_CMR_PFRF 0x01 /* Send path FERF */
|
||||
#define uPD98402_CMR_LFRF 0x02 /* Send line FERF */
|
||||
#define uPD98402_CMR_PAIS 0x04 /* Send path AIS */
|
||||
#define uPD98402_CMR_LAIS 0x08 /* Send line AIS */
|
||||
|
||||
/* MDR is at 0x01 */
|
||||
#define uPD98402_MDR_ALP 0x01 /* ATM layer loopback */
|
||||
#define uPD98402_MDR_TPLP 0x02 /* PMD loopback, to host */
|
||||
#define uPD98402_MDR_RPLP 0x04 /* PMD loopback, to network */
|
||||
#define uPD98402_MDR_SS0 0x08 /* SS0 */
|
||||
#define uPD98402_MDR_SS1 0x10 /* SS1 */
|
||||
#define uPD98402_MDR_SS_MASK 0x18 /* mask */
|
||||
#define uPD98402_MDR_SS_SHIFT 3 /* shift */
|
||||
#define uPD98402_MDR_HEC 0x20 /* disable HEC inbound processing */
|
||||
#define uPD98402_MDR_FSR 0x40 /* disable frame scrambler */
|
||||
#define uPD98402_MDR_CSR 0x80 /* disable cell scrambler */
|
||||
|
||||
/* PICR is at 0x02, PIMR is at 0x03 */
|
||||
#define uPD98402_INT_PFM 0x01 /* performance counter has changed */
|
||||
#define uPD98402_INT_ALM 0x02 /* line fault */
|
||||
#define uPD98402_INT_RFO 0x04 /* receive FIFO overflow */
|
||||
#define uPD98402_INT_PCO 0x08 /* performance counter overflow */
|
||||
#define uPD98402_INT_OTD 0x20 /* OTD has occurred */
|
||||
#define uPD98402_INT_LOS 0x40 /* Loss Of Signal */
|
||||
#define uPD98402_INT_LOF 0x80 /* Loss Of Frame */
|
||||
|
||||
/* ACR is as 0x04, ACMR is at 0x05 */
|
||||
#define uPD98402_ALM_PFRF 0x01 /* path FERF */
|
||||
#define uPD98402_ALM_LFRF 0x02 /* line FERF */
|
||||
#define uPD98402_ALM_PAIS 0x04 /* path AIS */
|
||||
#define uPD98402_ALM_LAIS 0x08 /* line AIS */
|
||||
#define uPD98402_ALM_LOD 0x10 /* loss of delineation */
|
||||
#define uPD98402_ALM_LOP 0x20 /* loss of pointer */
|
||||
#define uPD98402_ALM_OOF 0x40 /* out of frame */
|
||||
|
||||
/* PCR is at 0x06, PCMR is at 0x07 */
|
||||
#define uPD98402_PFM_PFEB 0x01 /* path FEBE */
|
||||
#define uPD98402_PFM_LFEB 0x02 /* line FEBE */
|
||||
#define uPD98402_PFM_B3E 0x04 /* B3 error */
|
||||
#define uPD98402_PFM_B2E 0x08 /* B2 error */
|
||||
#define uPD98402_PFM_B1E 0x10 /* B1 error */
|
||||
#define uPD98402_PFM_FJ 0x20 /* frequency justification */
|
||||
|
||||
/* IACM is at 0x08 */
|
||||
#define uPD98402_IACM_PFRF 0x01 /* don't generate path FERF */
|
||||
#define uPD98402_IACM_LFRF 0x02 /* don't generate line FERF */
|
||||
|
||||
/* PCOCR is at 0x010, PCOMR is at 0x11 */
|
||||
#define uPD98402_PCO_B1EC 0x01 /* B1ECT overflow */
|
||||
#define uPD98402_PCO_B2EC 0x02 /* B2ECT overflow */
|
||||
#define uPD98402_PCO_B3EC 0x04 /* B3ECT overflow */
|
||||
#define uPD98402_PCO_PFBC 0x08 /* PFEBC overflow */
|
||||
#define uPD98402_PCO_LFBC 0x10 /* LFEVC overflow */
|
||||
#define uPD98402_PCO_HECC 0x20 /* HECCT overflow */
|
||||
#define uPD98402_PCO_FJC 0x40 /* FJCT overflow */
|
||||
|
||||
|
||||
int uPD98402_init(struct atm_dev *dev);
|
||||
|
||||
#endif
|
1652
drivers/atm/zatm.c
1652
drivers/atm/zatm.c
File diff suppressed because it is too large
Load Diff
|
@ -1,104 +0,0 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/* drivers/atm/zatm.h - ZeitNet ZN122x device driver declarations */
|
||||
|
||||
/* Written 1995-1998 by Werner Almesberger, EPFL LRC/ICA */
|
||||
|
||||
|
||||
#ifndef DRIVER_ATM_ZATM_H
|
||||
#define DRIVER_ATM_ZATM_H
|
||||
|
||||
#include <linux/skbuff.h>
|
||||
#include <linux/atm.h>
|
||||
#include <linux/atmdev.h>
|
||||
#include <linux/sonet.h>
|
||||
#include <linux/pci.h>
|
||||
|
||||
|
||||
#define DEV_LABEL "zatm"
|
||||
|
||||
#define MAX_AAL5_PDU 10240 /* allocate for AAL5 PDUs of this size */
|
||||
#define MAX_RX_SIZE_LD 14 /* ceil(log2((MAX_AAL5_PDU+47)/48)) */
|
||||
|
||||
#define LOW_MARK 12 /* start adding new buffers if less than 12 */
|
||||
#define HIGH_MARK 30 /* stop adding buffers after reaching 30 */
|
||||
#define OFF_CNG_THRES 5 /* threshold for offset changes */
|
||||
|
||||
#define RX_SIZE 2 /* RX lookup entry size (in bytes) */
|
||||
#define NR_POOLS 32 /* number of free buffer pointers */
|
||||
#define POOL_SIZE 8 /* buffer entry size (in bytes) */
|
||||
#define NR_SHAPERS 16 /* number of shapers */
|
||||
#define SHAPER_SIZE 4 /* shaper entry size (in bytes) */
|
||||
#define VC_SIZE 32 /* VC dsc (TX or RX) size (in bytes) */
|
||||
|
||||
#define RING_ENTRIES 32 /* ring entries (without back pointer) */
|
||||
#define RING_WORDS 4 /* ring element size */
|
||||
#define RING_SIZE (sizeof(unsigned long)*(RING_ENTRIES+1)*RING_WORDS)
|
||||
|
||||
#define NR_MBX 4 /* four mailboxes */
|
||||
#define MBX_RX_0 0 /* mailbox indices */
|
||||
#define MBX_RX_1 1
|
||||
#define MBX_TX_0 2
|
||||
#define MBX_TX_1 3
|
||||
|
||||
struct zatm_vcc {
|
||||
/*-------------------------------- RX part */
|
||||
int rx_chan; /* RX channel, 0 if none */
|
||||
int pool; /* free buffer pool */
|
||||
/*-------------------------------- TX part */
|
||||
int tx_chan; /* TX channel, 0 if none */
|
||||
int shaper; /* shaper, <0 if none */
|
||||
struct sk_buff_head tx_queue; /* list of buffers in transit */
|
||||
wait_queue_head_t tx_wait; /* for close */
|
||||
u32 *ring; /* transmit ring */
|
||||
int ring_curr; /* current write position */
|
||||
int txing; /* number of transmits in progress */
|
||||
struct sk_buff_head backlog; /* list of buffers waiting for ring */
|
||||
};
|
||||
|
||||
struct zatm_dev {
|
||||
/*-------------------------------- TX part */
|
||||
int tx_bw; /* remaining bandwidth */
|
||||
u32 free_shapers; /* bit set */
|
||||
int ubr; /* UBR shaper; -1 if none */
|
||||
int ubr_ref_cnt; /* number of VCs using UBR shaper */
|
||||
/*-------------------------------- RX part */
|
||||
int pool_ref[NR_POOLS]; /* free buffer pool usage counters */
|
||||
volatile struct sk_buff *last_free[NR_POOLS];
|
||||
/* last entry in respective pool */
|
||||
struct sk_buff_head pool[NR_POOLS];/* free buffer pools */
|
||||
struct zatm_pool_info pool_info[NR_POOLS]; /* pool information */
|
||||
/*-------------------------------- maps */
|
||||
struct atm_vcc **tx_map; /* TX VCCs */
|
||||
struct atm_vcc **rx_map; /* RX VCCs */
|
||||
int chans; /* map size, must be 2^n */
|
||||
/*-------------------------------- mailboxes */
|
||||
unsigned long mbx_start[NR_MBX];/* start addresses */
|
||||
dma_addr_t mbx_dma[NR_MBX];
|
||||
u16 mbx_end[NR_MBX]; /* end offset (in bytes) */
|
||||
/*-------------------------------- other pointers */
|
||||
u32 pool_base; /* Free buffer pool dsc (word addr) */
|
||||
/*-------------------------------- ZATM links */
|
||||
struct atm_dev *more; /* other ZATM devices */
|
||||
/*-------------------------------- general information */
|
||||
int mem; /* RAM on board (in bytes) */
|
||||
int khz; /* timer clock */
|
||||
int copper; /* PHY type */
|
||||
unsigned char irq; /* IRQ */
|
||||
unsigned int base; /* IO base address */
|
||||
struct pci_dev *pci_dev; /* PCI stuff */
|
||||
spinlock_t lock;
|
||||
};
|
||||
|
||||
|
||||
#define ZATM_DEV(d) ((struct zatm_dev *) (d)->dev_data)
|
||||
#define ZATM_VCC(d) ((struct zatm_vcc *) (d)->dev_data)
|
||||
|
||||
|
||||
struct zatm_skb_prv {
|
||||
struct atm_skb_data _; /* reserved */
|
||||
u32 *dsc; /* pointer to skb's descriptor */
|
||||
};
|
||||
|
||||
#define ZATM_PRV_DSC(skb) (((struct zatm_skb_prv *) (skb)->cb)->dsc)
|
||||
|
||||
#endif
|
|
@ -11,6 +11,8 @@
|
|||
#include <linux/gpio/driver.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/export.h>
|
||||
#include <linux/property.h>
|
||||
|
||||
#include <linux/bcma/bcma.h>
|
||||
|
||||
#include "bcma_private.h"
|
||||
|
@ -182,9 +184,8 @@ int bcma_gpio_init(struct bcma_drv_cc *cc)
|
|||
chip->direction_input = bcma_gpio_direction_input;
|
||||
chip->direction_output = bcma_gpio_direction_output;
|
||||
chip->parent = bus->dev;
|
||||
#if IS_BUILTIN(CONFIG_OF)
|
||||
chip->of_node = cc->core->dev.of_node;
|
||||
#endif
|
||||
chip->fwnode = dev_fwnode(&cc->core->dev);
|
||||
|
||||
switch (bus->chipinfo.id) {
|
||||
case BCMA_CHIP_ID_BCM4707:
|
||||
case BCMA_CHIP_ID_BCM5357:
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
#include <linux/module.h>
|
||||
#include <linux/firmware.h>
|
||||
#include <linux/dmi.h>
|
||||
#include <linux/of.h>
|
||||
#include <asm/unaligned.h>
|
||||
|
||||
#include <net/bluetooth/bluetooth.h>
|
||||
|
@ -29,7 +30,7 @@
|
|||
#define BDADDR_BCM43341B (&(bdaddr_t) {{0xac, 0x1f, 0x00, 0x1b, 0x34, 0x43}})
|
||||
|
||||
#define BCM_FW_NAME_LEN 64
|
||||
#define BCM_FW_NAME_COUNT_MAX 2
|
||||
#define BCM_FW_NAME_COUNT_MAX 4
|
||||
/* For kmalloc-ing the fw-name array instead of putting it on the stack */
|
||||
typedef char bcm_fw_name[BCM_FW_NAME_LEN];
|
||||
|
||||
|
@ -457,6 +458,7 @@ static const struct bcm_subver_table bcm_uart_subver_table[] = {
|
|||
{ 0x6106, "BCM4359C0" }, /* 003.001.006 */
|
||||
{ 0x4106, "BCM4335A0" }, /* 002.001.006 */
|
||||
{ 0x410c, "BCM43430B0" }, /* 002.001.012 */
|
||||
{ 0x2119, "BCM4373A0" }, /* 001.001.025 */
|
||||
{ }
|
||||
};
|
||||
|
||||
|
@ -476,6 +478,42 @@ static const struct bcm_subver_table bcm_usb_subver_table[] = {
|
|||
{ }
|
||||
};
|
||||
|
||||
/*
|
||||
* This currently only looks up the device tree board appendix,
|
||||
* but can be expanded to other mechanisms.
|
||||
*/
|
||||
static const char *btbcm_get_board_name(struct device *dev)
|
||||
{
|
||||
#ifdef CONFIG_OF
|
||||
struct device_node *root;
|
||||
char *board_type;
|
||||
const char *tmp;
|
||||
int len;
|
||||
int i;
|
||||
|
||||
root = of_find_node_by_path("/");
|
||||
if (!root)
|
||||
return NULL;
|
||||
|
||||
if (of_property_read_string_index(root, "compatible", 0, &tmp))
|
||||
return NULL;
|
||||
|
||||
/* get rid of any '/' in the compatible string */
|
||||
len = strlen(tmp) + 1;
|
||||
board_type = devm_kzalloc(dev, len, GFP_KERNEL);
|
||||
strscpy(board_type, tmp, len);
|
||||
for (i = 0; i < board_type[i]; i++) {
|
||||
if (board_type[i] == '/')
|
||||
board_type[i] = '-';
|
||||
}
|
||||
of_node_put(root);
|
||||
|
||||
return board_type;
|
||||
#else
|
||||
return NULL;
|
||||
#endif
|
||||
}
|
||||
|
||||
int btbcm_initialize(struct hci_dev *hdev, bool *fw_load_done)
|
||||
{
|
||||
u16 subver, rev, pid, vid;
|
||||
|
@ -483,12 +521,15 @@ int btbcm_initialize(struct hci_dev *hdev, bool *fw_load_done)
|
|||
struct hci_rp_read_local_version *ver;
|
||||
const struct bcm_subver_table *bcm_subver_table;
|
||||
const char *hw_name = NULL;
|
||||
const char *board_name;
|
||||
char postfix[16] = "";
|
||||
int fw_name_count = 0;
|
||||
bcm_fw_name *fw_name;
|
||||
const struct firmware *fw;
|
||||
int i, err;
|
||||
|
||||
board_name = btbcm_get_board_name(&hdev->dev);
|
||||
|
||||
/* Reset */
|
||||
err = btbcm_reset(hdev);
|
||||
if (err)
|
||||
|
@ -549,11 +590,21 @@ int btbcm_initialize(struct hci_dev *hdev, bool *fw_load_done)
|
|||
return -ENOMEM;
|
||||
|
||||
if (hw_name) {
|
||||
if (board_name) {
|
||||
snprintf(fw_name[fw_name_count], BCM_FW_NAME_LEN,
|
||||
"brcm/%s%s.%s.hcd", hw_name, postfix, board_name);
|
||||
fw_name_count++;
|
||||
}
|
||||
snprintf(fw_name[fw_name_count], BCM_FW_NAME_LEN,
|
||||
"brcm/%s%s.hcd", hw_name, postfix);
|
||||
fw_name_count++;
|
||||
}
|
||||
|
||||
if (board_name) {
|
||||
snprintf(fw_name[fw_name_count], BCM_FW_NAME_LEN,
|
||||
"brcm/BCM%s.%s.hcd", postfix, board_name);
|
||||
fw_name_count++;
|
||||
}
|
||||
snprintf(fw_name[fw_name_count], BCM_FW_NAME_LEN,
|
||||
"brcm/BCM%s.hcd", postfix);
|
||||
fw_name_count++;
|
||||
|
|
|
@ -794,7 +794,7 @@ static void regmap_ibt_free_context(void *context)
|
|||
kfree(context);
|
||||
}
|
||||
|
||||
static struct regmap_bus regmap_ibt = {
|
||||
static const struct regmap_bus regmap_ibt = {
|
||||
.read = regmap_ibt_read,
|
||||
.write = regmap_ibt_write,
|
||||
.gather_write = regmap_ibt_gather_write,
|
||||
|
|
|
@ -379,6 +379,7 @@ static int btmtksdio_recv_event(struct hci_dev *hdev, struct sk_buff *skb)
|
|||
{
|
||||
struct btmtksdio_dev *bdev = hci_get_drvdata(hdev);
|
||||
struct hci_event_hdr *hdr = (void *)skb->data;
|
||||
u8 evt = hdr->evt;
|
||||
int err;
|
||||
|
||||
/* When someone waits for the WMT event, the skb is being cloned
|
||||
|
@ -396,7 +397,7 @@ static int btmtksdio_recv_event(struct hci_dev *hdev, struct sk_buff *skb)
|
|||
if (err < 0)
|
||||
goto err_free_skb;
|
||||
|
||||
if (hdr->evt == HCI_EV_WMT) {
|
||||
if (evt == HCI_EV_WMT) {
|
||||
if (test_and_clear_bit(BTMTKSDIO_TX_WAIT_VND_EVT,
|
||||
&bdev->tx_state)) {
|
||||
/* Barrier to sync with other CPUs */
|
||||
|
@ -863,6 +864,14 @@ static int mt79xx_setup(struct hci_dev *hdev, const char *fwname)
|
|||
return err;
|
||||
}
|
||||
|
||||
err = btmtksdio_fw_pmctrl(bdev);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
err = btmtksdio_drv_pmctrl(bdev);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
/* Enable Bluetooth protocol */
|
||||
wmt_params.op = BTMTK_WMT_FUNC_CTRL;
|
||||
wmt_params.flag = 0;
|
||||
|
@ -961,7 +970,7 @@ static int btmtksdio_get_codec_config_data(struct hci_dev *hdev,
|
|||
}
|
||||
|
||||
*ven_data = kmalloc(sizeof(__u8), GFP_KERNEL);
|
||||
if (!ven_data) {
|
||||
if (!*ven_data) {
|
||||
err = -ENOMEM;
|
||||
goto error;
|
||||
}
|
||||
|
@ -1108,14 +1117,6 @@ static int btmtksdio_setup(struct hci_dev *hdev)
|
|||
if (err < 0)
|
||||
return err;
|
||||
|
||||
err = btmtksdio_fw_pmctrl(bdev);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
err = btmtksdio_drv_pmctrl(bdev);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
/* Enable SCO over I2S/PCM */
|
||||
err = btmtksdio_sco_setting(hdev);
|
||||
if (err < 0) {
|
||||
|
@ -1188,6 +1189,10 @@ static int btmtksdio_shutdown(struct hci_dev *hdev)
|
|||
*/
|
||||
pm_runtime_get_sync(bdev->dev);
|
||||
|
||||
/* wmt command only works until the reset is complete */
|
||||
if (test_bit(BTMTKSDIO_HW_RESET_ACTIVE, &bdev->tx_state))
|
||||
goto ignore_wmt_cmd;
|
||||
|
||||
/* Disable the device */
|
||||
wmt_params.op = BTMTK_WMT_FUNC_CTRL;
|
||||
wmt_params.flag = 0;
|
||||
|
@ -1201,6 +1206,7 @@ static int btmtksdio_shutdown(struct hci_dev *hdev)
|
|||
return err;
|
||||
}
|
||||
|
||||
ignore_wmt_cmd:
|
||||
pm_runtime_put_noidle(bdev->dev);
|
||||
pm_runtime_disable(bdev->dev);
|
||||
|
||||
|
|
|
@ -50,6 +50,7 @@ enum btrtl_chip_id {
|
|||
CHIP_ID_8761B,
|
||||
CHIP_ID_8852A = 18,
|
||||
CHIP_ID_8852B = 20,
|
||||
CHIP_ID_8852C = 25,
|
||||
};
|
||||
|
||||
struct id_table {
|
||||
|
@ -196,6 +197,14 @@ static const struct id_table ic_id_table[] = {
|
|||
.has_msft_ext = true,
|
||||
.fw_name = "rtl_bt/rtl8852bu_fw.bin",
|
||||
.cfg_name = "rtl_bt/rtl8852bu_config" },
|
||||
|
||||
/* 8852C */
|
||||
{ IC_INFO(RTL_ROM_LMP_8852A, 0xc, 0xc, HCI_USB),
|
||||
.config_needed = false,
|
||||
.has_rom_version = true,
|
||||
.has_msft_ext = true,
|
||||
.fw_name = "rtl_bt/rtl8852cu_fw.bin",
|
||||
.cfg_name = "rtl_bt/rtl8852cu_config" },
|
||||
};
|
||||
|
||||
static const struct id_table *btrtl_match_ic(u16 lmp_subver, u16 hci_rev,
|
||||
|
@ -305,6 +314,7 @@ static int rtlbt_parse_firmware(struct hci_dev *hdev,
|
|||
{ RTL_ROM_LMP_8761A, 14 }, /* 8761B */
|
||||
{ RTL_ROM_LMP_8852A, 18 }, /* 8852A */
|
||||
{ RTL_ROM_LMP_8852A, 20 }, /* 8852B */
|
||||
{ RTL_ROM_LMP_8852A, 25 }, /* 8852C */
|
||||
};
|
||||
|
||||
min_size = sizeof(struct rtl_epatch_header) + sizeof(extension_sig) + 3;
|
||||
|
@ -768,6 +778,7 @@ void btrtl_set_quirks(struct hci_dev *hdev, struct btrtl_device_info *btrtl_dev)
|
|||
case CHIP_ID_8822C:
|
||||
case CHIP_ID_8852A:
|
||||
case CHIP_ID_8852B:
|
||||
case CHIP_ID_8852C:
|
||||
set_bit(HCI_QUIRK_VALID_LE_STATES, &hdev->quirks);
|
||||
set_bit(HCI_QUIRK_WIDEBAND_SPEECH_SUPPORTED, &hdev->quirks);
|
||||
hci_set_aosp_capable(hdev);
|
||||
|
@ -947,3 +958,5 @@ MODULE_FIRMWARE("rtl_bt/rtl8852au_fw.bin");
|
|||
MODULE_FIRMWARE("rtl_bt/rtl8852au_config.bin");
|
||||
MODULE_FIRMWARE("rtl_bt/rtl8852bu_fw.bin");
|
||||
MODULE_FIRMWARE("rtl_bt/rtl8852bu_config.bin");
|
||||
MODULE_FIRMWARE("rtl_bt/rtl8852cu_fw.bin");
|
||||
MODULE_FIRMWARE("rtl_bt/rtl8852cu_config.bin");
|
||||
|
|
|
@ -317,6 +317,11 @@ static const struct usb_device_id blacklist_table[] = {
|
|||
BTUSB_WIDEBAND_SPEECH |
|
||||
BTUSB_VALID_LE_STATES },
|
||||
|
||||
/* QCA WCN785x chipset */
|
||||
{ USB_DEVICE(0x0cf3, 0xe700), .driver_info = BTUSB_QCA_WCN6855 |
|
||||
BTUSB_WIDEBAND_SPEECH |
|
||||
BTUSB_VALID_LE_STATES },
|
||||
|
||||
/* Broadcom BCM2035 */
|
||||
{ USB_DEVICE(0x0a5c, 0x2009), .driver_info = BTUSB_BCM92035 },
|
||||
{ USB_DEVICE(0x0a5c, 0x200a), .driver_info = BTUSB_WRONG_SCO_MTU },
|
||||
|
@ -446,6 +451,9 @@ static const struct usb_device_id blacklist_table[] = {
|
|||
BTUSB_VALID_LE_STATES },
|
||||
|
||||
/* Additional MediaTek MT7921 Bluetooth devices */
|
||||
{ USB_DEVICE(0x0489, 0xe0c8), .driver_info = BTUSB_MEDIATEK |
|
||||
BTUSB_WIDEBAND_SPEECH |
|
||||
BTUSB_VALID_LE_STATES },
|
||||
{ USB_DEVICE(0x04ca, 0x3802), .driver_info = BTUSB_MEDIATEK |
|
||||
BTUSB_WIDEBAND_SPEECH |
|
||||
BTUSB_VALID_LE_STATES },
|
||||
|
@ -500,6 +508,10 @@ static const struct usb_device_id blacklist_table[] = {
|
|||
{ USB_DEVICE(0x2550, 0x8761), .driver_info = BTUSB_REALTEK |
|
||||
BTUSB_WIDEBAND_SPEECH },
|
||||
|
||||
/* Additional Realtek 8761BUV Bluetooth devices */
|
||||
{ USB_DEVICE(0x0bda, 0x8771), .driver_info = BTUSB_REALTEK |
|
||||
BTUSB_WIDEBAND_SPEECH },
|
||||
|
||||
/* Additional Realtek 8821AE Bluetooth devices */
|
||||
{ USB_DEVICE(0x0b05, 0x17dc), .driver_info = BTUSB_REALTEK },
|
||||
{ USB_DEVICE(0x13d3, 0x3414), .driver_info = BTUSB_REALTEK },
|
||||
|
@ -3037,6 +3049,7 @@ static const struct qca_device_info qca_devices_table[] = {
|
|||
{ 0x00130100, 40, 4, 16 }, /* WCN6855 1.0 */
|
||||
{ 0x00130200, 40, 4, 16 }, /* WCN6855 2.0 */
|
||||
{ 0x00130201, 40, 4, 16 }, /* WCN6855 2.1 */
|
||||
{ 0x00190200, 40, 4, 16 }, /* WCN785x 2.0 */
|
||||
};
|
||||
|
||||
static int btusb_qca_send_vendor_req(struct usb_device *udev, u8 request,
|
||||
|
@ -3327,14 +3340,20 @@ static int btusb_setup_qca(struct hci_dev *hdev)
|
|||
if (err < 0)
|
||||
return err;
|
||||
|
||||
/* WCN6855 2.1 will reset to apply firmware downloaded here, so
|
||||
/* WCN6855 2.1 and later will reset to apply firmware downloaded here, so
|
||||
* wait ~100ms for reset Done then go ahead, otherwise, it maybe
|
||||
* cause potential enable failure.
|
||||
*/
|
||||
if (info->rom_version == 0x00130201)
|
||||
if (info->rom_version >= 0x00130201)
|
||||
msleep(QCA_BT_RESET_WAIT_MS);
|
||||
}
|
||||
|
||||
/* Mark HCI_OP_ENHANCED_SETUP_SYNC_CONN as broken as it doesn't seem to
|
||||
* work with the likes of HSP/HFP mSBC.
|
||||
*/
|
||||
set_bit(HCI_QUIRK_BROKEN_ENHANCED_SETUP_SYNC_CONN, &hdev->quirks);
|
||||
set_bit(HCI_QUIRK_BROKEN_ERR_DATA_REPORTING, &hdev->quirks);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -696,9 +696,9 @@ static int qca_close(struct hci_uart *hu)
|
|||
skb_queue_purge(&qca->tx_wait_q);
|
||||
skb_queue_purge(&qca->txq);
|
||||
skb_queue_purge(&qca->rx_memdump_q);
|
||||
del_timer(&qca->tx_idle_timer);
|
||||
del_timer(&qca->wake_retrans_timer);
|
||||
destroy_workqueue(qca->workqueue);
|
||||
del_timer_sync(&qca->tx_idle_timer);
|
||||
del_timer_sync(&qca->wake_retrans_timer);
|
||||
qca->hu = NULL;
|
||||
|
||||
kfree_skb(qca->rx_skb);
|
||||
|
|
|
@ -197,7 +197,7 @@ static int tee_bnxt_fw_probe(struct device *dev)
|
|||
return -ENODEV;
|
||||
|
||||
/* Open session with Bnxt load Trusted App */
|
||||
memcpy(sess_arg.uuid, bnxt_device->id.uuid.b, TEE_IOCTL_UUID_LEN);
|
||||
export_uuid(sess_arg.uuid, &bnxt_device->id.uuid);
|
||||
sess_arg.clnt_login = TEE_IOCTL_LOGIN_PUBLIC;
|
||||
sess_arg.num_params = 0;
|
||||
|
||||
|
|
|
@ -2613,7 +2613,6 @@ void ib_set_device_ops(struct ib_device *dev, const struct ib_device_ops *ops)
|
|||
SET_DEVICE_OP(dev_ops, create_counters);
|
||||
SET_DEVICE_OP(dev_ops, create_cq);
|
||||
SET_DEVICE_OP(dev_ops, create_flow);
|
||||
SET_DEVICE_OP(dev_ops, create_flow_action_esp);
|
||||
SET_DEVICE_OP(dev_ops, create_qp);
|
||||
SET_DEVICE_OP(dev_ops, create_rwq_ind_table);
|
||||
SET_DEVICE_OP(dev_ops, create_srq);
|
||||
|
@ -2676,7 +2675,6 @@ void ib_set_device_ops(struct ib_device *dev, const struct ib_device_ops *ops)
|
|||
SET_DEVICE_OP(dev_ops, modify_ah);
|
||||
SET_DEVICE_OP(dev_ops, modify_cq);
|
||||
SET_DEVICE_OP(dev_ops, modify_device);
|
||||
SET_DEVICE_OP(dev_ops, modify_flow_action_esp);
|
||||
SET_DEVICE_OP(dev_ops, modify_hw_stat);
|
||||
SET_DEVICE_OP(dev_ops, modify_port);
|
||||
SET_DEVICE_OP(dev_ops, modify_qp);
|
||||
|
|
|
@ -46,385 +46,6 @@ static int uverbs_free_flow_action(struct ib_uobject *uobject,
|
|||
return action->device->ops.destroy_flow_action(action);
|
||||
}
|
||||
|
||||
static u64 esp_flags_uverbs_to_verbs(struct uverbs_attr_bundle *attrs,
|
||||
u32 flags, bool is_modify)
|
||||
{
|
||||
u64 verbs_flags = flags;
|
||||
|
||||
if (uverbs_attr_is_valid(attrs, UVERBS_ATTR_FLOW_ACTION_ESP_ESN))
|
||||
verbs_flags |= IB_FLOW_ACTION_ESP_FLAGS_ESN_TRIGGERED;
|
||||
|
||||
if (is_modify && uverbs_attr_is_valid(attrs,
|
||||
UVERBS_ATTR_FLOW_ACTION_ESP_ATTRS))
|
||||
verbs_flags |= IB_FLOW_ACTION_ESP_FLAGS_MOD_ESP_ATTRS;
|
||||
|
||||
return verbs_flags;
|
||||
};
|
||||
|
||||
static int validate_flow_action_esp_keymat_aes_gcm(struct ib_flow_action_attrs_esp_keymats *keymat)
|
||||
{
|
||||
struct ib_uverbs_flow_action_esp_keymat_aes_gcm *aes_gcm =
|
||||
&keymat->keymat.aes_gcm;
|
||||
|
||||
if (aes_gcm->iv_algo > IB_UVERBS_FLOW_ACTION_IV_ALGO_SEQ)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
if (aes_gcm->key_len != 32 &&
|
||||
aes_gcm->key_len != 24 &&
|
||||
aes_gcm->key_len != 16)
|
||||
return -EINVAL;
|
||||
|
||||
if (aes_gcm->icv_len != 16 &&
|
||||
aes_gcm->icv_len != 8 &&
|
||||
aes_gcm->icv_len != 12)
|
||||
return -EINVAL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int (* const flow_action_esp_keymat_validate[])(struct ib_flow_action_attrs_esp_keymats *keymat) = {
|
||||
[IB_UVERBS_FLOW_ACTION_ESP_KEYMAT_AES_GCM] = validate_flow_action_esp_keymat_aes_gcm,
|
||||
};
|
||||
|
||||
static int flow_action_esp_replay_none(struct ib_flow_action_attrs_esp_replays *replay,
|
||||
bool is_modify)
|
||||
{
|
||||
/* This is used in order to modify an esp flow action with an enabled
|
||||
* replay protection to a disabled one. This is only supported via
|
||||
* modify, as in create verb we can simply drop the REPLAY attribute and
|
||||
* achieve the same thing.
|
||||
*/
|
||||
return is_modify ? 0 : -EINVAL;
|
||||
}
|
||||
|
||||
static int flow_action_esp_replay_def_ok(struct ib_flow_action_attrs_esp_replays *replay,
|
||||
bool is_modify)
|
||||
{
|
||||
/* Some replay protections could always be enabled without validating
|
||||
* anything.
|
||||
*/
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int (* const flow_action_esp_replay_validate[])(struct ib_flow_action_attrs_esp_replays *replay,
|
||||
bool is_modify) = {
|
||||
[IB_UVERBS_FLOW_ACTION_ESP_REPLAY_NONE] = flow_action_esp_replay_none,
|
||||
[IB_UVERBS_FLOW_ACTION_ESP_REPLAY_BMP] = flow_action_esp_replay_def_ok,
|
||||
};
|
||||
|
||||
static int parse_esp_ip(enum ib_flow_spec_type proto,
|
||||
const void __user *val_ptr,
|
||||
size_t len, union ib_flow_spec *out)
|
||||
{
|
||||
int ret;
|
||||
const struct ib_uverbs_flow_ipv4_filter ipv4 = {
|
||||
.src_ip = cpu_to_be32(0xffffffffUL),
|
||||
.dst_ip = cpu_to_be32(0xffffffffUL),
|
||||
.proto = 0xff,
|
||||
.tos = 0xff,
|
||||
.ttl = 0xff,
|
||||
.flags = 0xff,
|
||||
};
|
||||
const struct ib_uverbs_flow_ipv6_filter ipv6 = {
|
||||
.src_ip = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff},
|
||||
.dst_ip = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff},
|
||||
.flow_label = cpu_to_be32(0xffffffffUL),
|
||||
.next_hdr = 0xff,
|
||||
.traffic_class = 0xff,
|
||||
.hop_limit = 0xff,
|
||||
};
|
||||
union {
|
||||
struct ib_uverbs_flow_ipv4_filter ipv4;
|
||||
struct ib_uverbs_flow_ipv6_filter ipv6;
|
||||
} user_val = {};
|
||||
const void *user_pmask;
|
||||
size_t val_len;
|
||||
|
||||
/* If the flow IPv4/IPv6 flow specifications are extended, the mask
|
||||
* should be changed as well.
|
||||
*/
|
||||
BUILD_BUG_ON(offsetof(struct ib_uverbs_flow_ipv4_filter, flags) +
|
||||
sizeof(ipv4.flags) != sizeof(ipv4));
|
||||
BUILD_BUG_ON(offsetof(struct ib_uverbs_flow_ipv6_filter, reserved) +
|
||||
sizeof(ipv6.reserved) != sizeof(ipv6));
|
||||
|
||||
switch (proto) {
|
||||
case IB_FLOW_SPEC_IPV4:
|
||||
if (len > sizeof(user_val.ipv4) &&
|
||||
!ib_is_buffer_cleared(val_ptr + sizeof(user_val.ipv4),
|
||||
len - sizeof(user_val.ipv4)))
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
val_len = min_t(size_t, len, sizeof(user_val.ipv4));
|
||||
ret = copy_from_user(&user_val.ipv4, val_ptr,
|
||||
val_len);
|
||||
if (ret)
|
||||
return -EFAULT;
|
||||
|
||||
user_pmask = &ipv4;
|
||||
break;
|
||||
case IB_FLOW_SPEC_IPV6:
|
||||
if (len > sizeof(user_val.ipv6) &&
|
||||
!ib_is_buffer_cleared(val_ptr + sizeof(user_val.ipv6),
|
||||
len - sizeof(user_val.ipv6)))
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
val_len = min_t(size_t, len, sizeof(user_val.ipv6));
|
||||
ret = copy_from_user(&user_val.ipv6, val_ptr,
|
||||
val_len);
|
||||
if (ret)
|
||||
return -EFAULT;
|
||||
|
||||
user_pmask = &ipv6;
|
||||
break;
|
||||
default:
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
return ib_uverbs_kern_spec_to_ib_spec_filter(proto, user_pmask,
|
||||
&user_val,
|
||||
val_len, out);
|
||||
}
|
||||
|
||||
static int flow_action_esp_get_encap(struct ib_flow_spec_list *out,
|
||||
struct uverbs_attr_bundle *attrs)
|
||||
{
|
||||
struct ib_uverbs_flow_action_esp_encap uverbs_encap;
|
||||
int ret;
|
||||
|
||||
ret = uverbs_copy_from(&uverbs_encap, attrs,
|
||||
UVERBS_ATTR_FLOW_ACTION_ESP_ENCAP);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* We currently support only one encap */
|
||||
if (uverbs_encap.next_ptr)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
if (uverbs_encap.type != IB_FLOW_SPEC_IPV4 &&
|
||||
uverbs_encap.type != IB_FLOW_SPEC_IPV6)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
return parse_esp_ip(uverbs_encap.type,
|
||||
u64_to_user_ptr(uverbs_encap.val_ptr),
|
||||
uverbs_encap.len,
|
||||
&out->spec);
|
||||
}
|
||||
|
||||
struct ib_flow_action_esp_attr {
|
||||
struct ib_flow_action_attrs_esp hdr;
|
||||
struct ib_flow_action_attrs_esp_keymats keymat;
|
||||
struct ib_flow_action_attrs_esp_replays replay;
|
||||
/* We currently support only one spec */
|
||||
struct ib_flow_spec_list encap;
|
||||
};
|
||||
|
||||
#define ESP_LAST_SUPPORTED_FLAG IB_UVERBS_FLOW_ACTION_ESP_FLAGS_ESN_NEW_WINDOW
|
||||
static int parse_flow_action_esp(struct ib_device *ib_dev,
|
||||
struct uverbs_attr_bundle *attrs,
|
||||
struct ib_flow_action_esp_attr *esp_attr,
|
||||
bool is_modify)
|
||||
{
|
||||
struct ib_uverbs_flow_action_esp uverbs_esp = {};
|
||||
int ret;
|
||||
|
||||
/* Optional param, if it doesn't exist, we get -ENOENT and skip it */
|
||||
ret = uverbs_copy_from(&esp_attr->hdr.esn, attrs,
|
||||
UVERBS_ATTR_FLOW_ACTION_ESP_ESN);
|
||||
if (IS_UVERBS_COPY_ERR(ret))
|
||||
return ret;
|
||||
|
||||
/* This can be called from FLOW_ACTION_ESP_MODIFY where
|
||||
* UVERBS_ATTR_FLOW_ACTION_ESP_ATTRS is optional
|
||||
*/
|
||||
if (uverbs_attr_is_valid(attrs, UVERBS_ATTR_FLOW_ACTION_ESP_ATTRS)) {
|
||||
ret = uverbs_copy_from_or_zero(&uverbs_esp, attrs,
|
||||
UVERBS_ATTR_FLOW_ACTION_ESP_ATTRS);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (uverbs_esp.flags & ~((ESP_LAST_SUPPORTED_FLAG << 1) - 1))
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
esp_attr->hdr.spi = uverbs_esp.spi;
|
||||
esp_attr->hdr.seq = uverbs_esp.seq;
|
||||
esp_attr->hdr.tfc_pad = uverbs_esp.tfc_pad;
|
||||
esp_attr->hdr.hard_limit_pkts = uverbs_esp.hard_limit_pkts;
|
||||
}
|
||||
esp_attr->hdr.flags = esp_flags_uverbs_to_verbs(attrs, uverbs_esp.flags,
|
||||
is_modify);
|
||||
|
||||
if (uverbs_attr_is_valid(attrs, UVERBS_ATTR_FLOW_ACTION_ESP_KEYMAT)) {
|
||||
esp_attr->keymat.protocol =
|
||||
uverbs_attr_get_enum_id(attrs,
|
||||
UVERBS_ATTR_FLOW_ACTION_ESP_KEYMAT);
|
||||
ret = uverbs_copy_from_or_zero(&esp_attr->keymat.keymat,
|
||||
attrs,
|
||||
UVERBS_ATTR_FLOW_ACTION_ESP_KEYMAT);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = flow_action_esp_keymat_validate[esp_attr->keymat.protocol](&esp_attr->keymat);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
esp_attr->hdr.keymat = &esp_attr->keymat;
|
||||
}
|
||||
|
||||
if (uverbs_attr_is_valid(attrs, UVERBS_ATTR_FLOW_ACTION_ESP_REPLAY)) {
|
||||
esp_attr->replay.protocol =
|
||||
uverbs_attr_get_enum_id(attrs,
|
||||
UVERBS_ATTR_FLOW_ACTION_ESP_REPLAY);
|
||||
|
||||
ret = uverbs_copy_from_or_zero(&esp_attr->replay.replay,
|
||||
attrs,
|
||||
UVERBS_ATTR_FLOW_ACTION_ESP_REPLAY);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = flow_action_esp_replay_validate[esp_attr->replay.protocol](&esp_attr->replay,
|
||||
is_modify);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
esp_attr->hdr.replay = &esp_attr->replay;
|
||||
}
|
||||
|
||||
if (uverbs_attr_is_valid(attrs, UVERBS_ATTR_FLOW_ACTION_ESP_ENCAP)) {
|
||||
ret = flow_action_esp_get_encap(&esp_attr->encap, attrs);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
esp_attr->hdr.encap = &esp_attr->encap;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int UVERBS_HANDLER(UVERBS_METHOD_FLOW_ACTION_ESP_CREATE)(
|
||||
struct uverbs_attr_bundle *attrs)
|
||||
{
|
||||
struct ib_uobject *uobj = uverbs_attr_get_uobject(
|
||||
attrs, UVERBS_ATTR_CREATE_FLOW_ACTION_ESP_HANDLE);
|
||||
struct ib_device *ib_dev = attrs->context->device;
|
||||
int ret;
|
||||
struct ib_flow_action *action;
|
||||
struct ib_flow_action_esp_attr esp_attr = {};
|
||||
|
||||
if (!ib_dev->ops.create_flow_action_esp)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
ret = parse_flow_action_esp(ib_dev, attrs, &esp_attr, false);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* No need to check as this attribute is marked as MANDATORY */
|
||||
action = ib_dev->ops.create_flow_action_esp(ib_dev, &esp_attr.hdr,
|
||||
attrs);
|
||||
if (IS_ERR(action))
|
||||
return PTR_ERR(action);
|
||||
|
||||
uverbs_flow_action_fill_action(action, uobj, ib_dev,
|
||||
IB_FLOW_ACTION_ESP);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int UVERBS_HANDLER(UVERBS_METHOD_FLOW_ACTION_ESP_MODIFY)(
|
||||
struct uverbs_attr_bundle *attrs)
|
||||
{
|
||||
struct ib_uobject *uobj = uverbs_attr_get_uobject(
|
||||
attrs, UVERBS_ATTR_MODIFY_FLOW_ACTION_ESP_HANDLE);
|
||||
struct ib_flow_action *action = uobj->object;
|
||||
int ret;
|
||||
struct ib_flow_action_esp_attr esp_attr = {};
|
||||
|
||||
if (!action->device->ops.modify_flow_action_esp)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
ret = parse_flow_action_esp(action->device, attrs, &esp_attr, true);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (action->type != IB_FLOW_ACTION_ESP)
|
||||
return -EINVAL;
|
||||
|
||||
return action->device->ops.modify_flow_action_esp(action,
|
||||
&esp_attr.hdr,
|
||||
attrs);
|
||||
}
|
||||
|
||||
static const struct uverbs_attr_spec uverbs_flow_action_esp_keymat[] = {
|
||||
[IB_UVERBS_FLOW_ACTION_ESP_KEYMAT_AES_GCM] = {
|
||||
.type = UVERBS_ATTR_TYPE_PTR_IN,
|
||||
UVERBS_ATTR_STRUCT(
|
||||
struct ib_uverbs_flow_action_esp_keymat_aes_gcm,
|
||||
aes_key),
|
||||
},
|
||||
};
|
||||
|
||||
static const struct uverbs_attr_spec uverbs_flow_action_esp_replay[] = {
|
||||
[IB_UVERBS_FLOW_ACTION_ESP_REPLAY_NONE] = {
|
||||
.type = UVERBS_ATTR_TYPE_PTR_IN,
|
||||
UVERBS_ATTR_NO_DATA(),
|
||||
},
|
||||
[IB_UVERBS_FLOW_ACTION_ESP_REPLAY_BMP] = {
|
||||
.type = UVERBS_ATTR_TYPE_PTR_IN,
|
||||
UVERBS_ATTR_STRUCT(struct ib_uverbs_flow_action_esp_replay_bmp,
|
||||
size),
|
||||
},
|
||||
};
|
||||
|
||||
DECLARE_UVERBS_NAMED_METHOD(
|
||||
UVERBS_METHOD_FLOW_ACTION_ESP_CREATE,
|
||||
UVERBS_ATTR_IDR(UVERBS_ATTR_CREATE_FLOW_ACTION_ESP_HANDLE,
|
||||
UVERBS_OBJECT_FLOW_ACTION,
|
||||
UVERBS_ACCESS_NEW,
|
||||
UA_MANDATORY),
|
||||
UVERBS_ATTR_PTR_IN(UVERBS_ATTR_FLOW_ACTION_ESP_ATTRS,
|
||||
UVERBS_ATTR_STRUCT(struct ib_uverbs_flow_action_esp,
|
||||
hard_limit_pkts),
|
||||
UA_MANDATORY),
|
||||
UVERBS_ATTR_PTR_IN(UVERBS_ATTR_FLOW_ACTION_ESP_ESN,
|
||||
UVERBS_ATTR_TYPE(__u32),
|
||||
UA_OPTIONAL),
|
||||
UVERBS_ATTR_ENUM_IN(UVERBS_ATTR_FLOW_ACTION_ESP_KEYMAT,
|
||||
uverbs_flow_action_esp_keymat,
|
||||
UA_MANDATORY),
|
||||
UVERBS_ATTR_ENUM_IN(UVERBS_ATTR_FLOW_ACTION_ESP_REPLAY,
|
||||
uverbs_flow_action_esp_replay,
|
||||
UA_OPTIONAL),
|
||||
UVERBS_ATTR_PTR_IN(
|
||||
UVERBS_ATTR_FLOW_ACTION_ESP_ENCAP,
|
||||
UVERBS_ATTR_TYPE(struct ib_uverbs_flow_action_esp_encap),
|
||||
UA_OPTIONAL));
|
||||
|
||||
DECLARE_UVERBS_NAMED_METHOD(
|
||||
UVERBS_METHOD_FLOW_ACTION_ESP_MODIFY,
|
||||
UVERBS_ATTR_IDR(UVERBS_ATTR_MODIFY_FLOW_ACTION_ESP_HANDLE,
|
||||
UVERBS_OBJECT_FLOW_ACTION,
|
||||
UVERBS_ACCESS_WRITE,
|
||||
UA_MANDATORY),
|
||||
UVERBS_ATTR_PTR_IN(UVERBS_ATTR_FLOW_ACTION_ESP_ATTRS,
|
||||
UVERBS_ATTR_STRUCT(struct ib_uverbs_flow_action_esp,
|
||||
hard_limit_pkts),
|
||||
UA_OPTIONAL),
|
||||
UVERBS_ATTR_PTR_IN(UVERBS_ATTR_FLOW_ACTION_ESP_ESN,
|
||||
UVERBS_ATTR_TYPE(__u32),
|
||||
UA_OPTIONAL),
|
||||
UVERBS_ATTR_ENUM_IN(UVERBS_ATTR_FLOW_ACTION_ESP_KEYMAT,
|
||||
uverbs_flow_action_esp_keymat,
|
||||
UA_OPTIONAL),
|
||||
UVERBS_ATTR_ENUM_IN(UVERBS_ATTR_FLOW_ACTION_ESP_REPLAY,
|
||||
uverbs_flow_action_esp_replay,
|
||||
UA_OPTIONAL),
|
||||
UVERBS_ATTR_PTR_IN(
|
||||
UVERBS_ATTR_FLOW_ACTION_ESP_ENCAP,
|
||||
UVERBS_ATTR_TYPE(struct ib_uverbs_flow_action_esp_encap),
|
||||
UA_OPTIONAL));
|
||||
|
||||
DECLARE_UVERBS_NAMED_METHOD_DESTROY(
|
||||
UVERBS_METHOD_FLOW_ACTION_DESTROY,
|
||||
UVERBS_ATTR_IDR(UVERBS_ATTR_DESTROY_FLOW_ACTION_HANDLE,
|
||||
|
@ -435,9 +56,7 @@ DECLARE_UVERBS_NAMED_METHOD_DESTROY(
|
|||
DECLARE_UVERBS_NAMED_OBJECT(
|
||||
UVERBS_OBJECT_FLOW_ACTION,
|
||||
UVERBS_TYPE_ALLOC_IDR(uverbs_free_flow_action),
|
||||
&UVERBS_METHOD(UVERBS_METHOD_FLOW_ACTION_ESP_CREATE),
|
||||
&UVERBS_METHOD(UVERBS_METHOD_FLOW_ACTION_DESTROY),
|
||||
&UVERBS_METHOD(UVERBS_METHOD_FLOW_ACTION_ESP_MODIFY));
|
||||
&UVERBS_METHOD(UVERBS_METHOD_FLOW_ACTION_DESTROY));
|
||||
|
||||
const struct uapi_definition uverbs_def_obj_flow_action[] = {
|
||||
UAPI_DEF_CHAIN_OBJ_TREE_NAMED(
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue