Networking changes for 5.14.
Core: - BPF: - add syscall program type and libbpf support for generating instructions and bindings for in-kernel BPF loaders (BPF loaders for BPF), this is a stepping stone for signed BPF programs - infrastructure to migrate TCP child sockets from one listener to another in the same reuseport group/map to improve flexibility of service hand-off/restart - add broadcast support to XDP redirect - allow bypass of the lockless qdisc to improving performance (for pktgen: +23% with one thread, +44% with 2 threads) - add a simpler version of "DO_ONCE()" which does not require jump labels, intended for slow-path usage - virtio/vsock: introduce SOCK_SEQPACKET support - add getsocketopt to retrieve netns cookie - ip: treat lowest address of a IPv4 subnet as ordinary unicast address allowing reclaiming of precious IPv4 addresses - ipv6: use prandom_u32() for ID generation - ip: add support for more flexible field selection for hashing across multi-path routes (w/ offload to mlxsw) - icmp: add support for extended RFC 8335 PROBE (ping) - seg6: add support for SRv6 End.DT46 behavior - mptcp: - DSS checksum support (RFC 8684) to detect middlebox meddling - support Connection-time 'C' flag - time stamping support - sctp: packetization Layer Path MTU Discovery (RFC 8899) - xfrm: speed up state addition with seq set - WiFi: - hidden AP discovery on 6 GHz and other HE 6 GHz improvements - aggregation handling improvements for some drivers - minstrel improvements for no-ack frames - deferred rate control for TXQs to improve reaction times - switch from round robin to virtual time-based airtime scheduler - add trace points: - tcp checksum errors - openvswitch - action execution, upcalls - socket errors via sk_error_report Device APIs: - devlink: add rate API for hierarchical control of max egress rate of virtual devices (VFs, SFs etc.) - don't require RCU read lock to be held around BPF hooks in NAPI context - page_pool: generic buffer recycling New hardware/drivers: - mobile: - iosm: PCIe Driver for Intel M.2 Modem - support for Qualcomm MSM8998 (ipa) - WiFi: Qualcomm QCN9074 and WCN6855 PCI devices - sparx5: Microchip SparX-5 family of Enterprise Ethernet switches - Mellanox BlueField Gigabit Ethernet (control NIC of the DPU) - NXP SJA1110 Automotive Ethernet 10-port switch - Qualcomm QCA8327 switch support (qca8k) - Mikrotik 10/25G NIC (atl1c) Driver changes: - ACPI support for some MDIO, MAC and PHY devices from Marvell and NXP (our first foray into MAC/PHY description via ACPI) - HW timestamping (PTP) support: bnxt_en, ice, sja1105, hns3, tja11xx - Mellanox/Nvidia NIC (mlx5) - NIC VF offload of L2 bridging - support IRQ distribution to Sub-functions - Marvell (prestera): - add flower and match all - devlink trap - link aggregation - Netronome (nfp): connection tracking offload - Intel 1GE (igc): add AF_XDP support - Marvell DPU (octeontx2): ingress ratelimit offload - Google vNIC (gve): new ring/descriptor format support - Qualcomm mobile (rmnet & ipa): inline checksum offload support - MediaTek WiFi (mt76) - mt7915 MSI support - mt7915 Tx status reporting - mt7915 thermal sensors support - mt7921 decapsulation offload - mt7921 enable runtime pm and deep sleep - Realtek WiFi (rtw88) - beacon filter support - Tx antenna path diversity support - firmware crash information via devcoredump - Qualcomm 60GHz WiFi (wcn36xx) - Wake-on-WLAN support with magic packets and GTK rekeying - Micrel PHY (ksz886x/ksz8081): add cable test support Signed-off-by: Jakub Kicinski <kuba@kernel.org> -----BEGIN PGP SIGNATURE----- iQIzBAABCAAdFiEE6jPA+I1ugmIBA4hXMUZtbf5SIrsFAmDb+fUACgkQMUZtbf5S Irs2Jg//aqN0Q8CgIvYCVhPxQw1tY7pTAbgyqgBZ01vwjyvtIOgJiWzSfFEU84mX M8fcpFX5eTKrOyJ9S6UFfQ/JG114n3hjAxFFT4Hxk2gC1Tg0vHuFQTDHcUl28bUE mTm61e1YpdorILnv2k5JVQ/wu0vs5QKDrjcYcrcPnh+j93wvnPOgAfDBV95nZzjS OTt4q2fR8GzLcSYWWsclMbDNkzyTG50RW/0Yd6aGjr5QGvXfrMeXfUJNz533PMf/ w5lNyjRKv+x9mdTZJzU0+msNUrZgUdRz7W8Ey8lD3hJZRE+D6/uU7FtsE8Mi3+uc HWxeZUyzA3YF1MfVl/eesbxyPT7S/OkLzk4O5B35FbqP0YltaP+bOjq1/nM3ce1/ io9Dx9pIl/2JANUgRCAtLi8Z2dkvRoqTaBxZ/nPudCCljFwDwl6joTMJ7Ow22i5Y 5aIkcXFmZq4LbJDiHvbTlqT7yiuaEvu2UK/23bSIg/K3nF4eAmkY9Y1EgiMf60OF 78Ttw0wk2tUegwaS5MZnCniKBKDyl9gM2F6rbZ/IxQRR2LTXFc1B6gC+ynUxgXfh Ub8O++6qGYGYZ0XvQH4pzco79p3qQWBTK5beIp2eu6BOAjBVIXq4AibUfoQLACsu hX7jMPYd0kc3WFgUnKgQP8EnjFSwbf4XiaE7fIXvWBY8hzCw2h4= =LvtX -----END PGP SIGNATURE----- Merge tag 'net-next-5.14' of git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net-next Pull networking updates from Jakub Kicinski: "Core: - BPF: - add syscall program type and libbpf support for generating instructions and bindings for in-kernel BPF loaders (BPF loaders for BPF), this is a stepping stone for signed BPF programs - infrastructure to migrate TCP child sockets from one listener to another in the same reuseport group/map to improve flexibility of service hand-off/restart - add broadcast support to XDP redirect - allow bypass of the lockless qdisc to improving performance (for pktgen: +23% with one thread, +44% with 2 threads) - add a simpler version of "DO_ONCE()" which does not require jump labels, intended for slow-path usage - virtio/vsock: introduce SOCK_SEQPACKET support - add getsocketopt to retrieve netns cookie - ip: treat lowest address of a IPv4 subnet as ordinary unicast address allowing reclaiming of precious IPv4 addresses - ipv6: use prandom_u32() for ID generation - ip: add support for more flexible field selection for hashing across multi-path routes (w/ offload to mlxsw) - icmp: add support for extended RFC 8335 PROBE (ping) - seg6: add support for SRv6 End.DT46 behavior - mptcp: - DSS checksum support (RFC 8684) to detect middlebox meddling - support Connection-time 'C' flag - time stamping support - sctp: packetization Layer Path MTU Discovery (RFC 8899) - xfrm: speed up state addition with seq set - WiFi: - hidden AP discovery on 6 GHz and other HE 6 GHz improvements - aggregation handling improvements for some drivers - minstrel improvements for no-ack frames - deferred rate control for TXQs to improve reaction times - switch from round robin to virtual time-based airtime scheduler - add trace points: - tcp checksum errors - openvswitch - action execution, upcalls - socket errors via sk_error_report Device APIs: - devlink: add rate API for hierarchical control of max egress rate of virtual devices (VFs, SFs etc.) - don't require RCU read lock to be held around BPF hooks in NAPI context - page_pool: generic buffer recycling New hardware/drivers: - mobile: - iosm: PCIe Driver for Intel M.2 Modem - support for Qualcomm MSM8998 (ipa) - WiFi: Qualcomm QCN9074 and WCN6855 PCI devices - sparx5: Microchip SparX-5 family of Enterprise Ethernet switches - Mellanox BlueField Gigabit Ethernet (control NIC of the DPU) - NXP SJA1110 Automotive Ethernet 10-port switch - Qualcomm QCA8327 switch support (qca8k) - Mikrotik 10/25G NIC (atl1c) Driver changes: - ACPI support for some MDIO, MAC and PHY devices from Marvell and NXP (our first foray into MAC/PHY description via ACPI) - HW timestamping (PTP) support: bnxt_en, ice, sja1105, hns3, tja11xx - Mellanox/Nvidia NIC (mlx5) - NIC VF offload of L2 bridging - support IRQ distribution to Sub-functions - Marvell (prestera): - add flower and match all - devlink trap - link aggregation - Netronome (nfp): connection tracking offload - Intel 1GE (igc): add AF_XDP support - Marvell DPU (octeontx2): ingress ratelimit offload - Google vNIC (gve): new ring/descriptor format support - Qualcomm mobile (rmnet & ipa): inline checksum offload support - MediaTek WiFi (mt76) - mt7915 MSI support - mt7915 Tx status reporting - mt7915 thermal sensors support - mt7921 decapsulation offload - mt7921 enable runtime pm and deep sleep - Realtek WiFi (rtw88) - beacon filter support - Tx antenna path diversity support - firmware crash information via devcoredump - Qualcomm WiFi (wcn36xx) - Wake-on-WLAN support with magic packets and GTK rekeying - Micrel PHY (ksz886x/ksz8081): add cable test support" * tag 'net-next-5.14' of git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net-next: (2168 commits) tcp: change ICSK_CA_PRIV_SIZE definition tcp_yeah: check struct yeah size at compile time gve: DQO: Fix off by one in gve_rx_dqo() stmmac: intel: set PCI_D3hot in suspend stmmac: intel: Enable PHY WOL option in EHL net: stmmac: option to enable PHY WOL with PMT enabled net: say "local" instead of "static" addresses in ndo_dflt_fdb_{add,del} net: use netdev_info in ndo_dflt_fdb_{add,del} ptp: Set lookup cookie when creating a PTP PPS source. net: sock: add trace for socket errors net: sock: introduce sk_error_report net: dsa: replay the local bridge FDB entries pointing to the bridge dev too net: dsa: ensure during dsa_fdb_offload_notify that dev_hold and dev_put are on the same dev net: dsa: include fdb entries pointing to bridge in the host fdb list net: dsa: include bridge addresses which are local in the host fdb list net: dsa: sync static FDB entries on foreign interfaces to hardware net: dsa: install the host MDB and FDB entries in the master's RX filter net: dsa: reference count the FDB addresses at the cross-chip notifier level net: dsa: introduce a separate cross-chip notifier type for host FDBs net: dsa: reference count the MDB entries at the cross-chip notifier level ...
This commit is contained in:
commit
dbe69e4337
|
@ -0,0 +1,78 @@
|
|||
What: /sys/devices/platform/soc@X/XXXXXXX.ipa/
|
||||
Date: June 2021
|
||||
KernelVersion: v5.14
|
||||
Contact: Alex Elder <elder@kernel.org>
|
||||
Description:
|
||||
The /sys/devices/platform/soc@X/XXXXXXX.ipa/ directory
|
||||
contains read-only attributes exposing information about
|
||||
an IPA device. The X values could vary, but are typically
|
||||
"soc@0/1e40000.ipa".
|
||||
|
||||
What: .../XXXXXXX.ipa/version
|
||||
Date: June 2021
|
||||
KernelVersion: v5.14
|
||||
Contact: Alex Elder <elder@kernel.org>
|
||||
Description:
|
||||
The .../XXXXXXX.ipa/version file contains the IPA hardware
|
||||
version, as a period-separated set of two or three integers
|
||||
(e.g., "3.5.1" or "4.2").
|
||||
|
||||
What: .../XXXXXXX.ipa/feature/
|
||||
Date: June 2021
|
||||
KernelVersion: v5.14
|
||||
Contact: Alex Elder <elder@kernel.org>
|
||||
Description:
|
||||
The .../XXXXXXX.ipa/feature/ directory contains a set of
|
||||
attributes describing features implemented by the IPA
|
||||
hardware.
|
||||
|
||||
What: .../XXXXXXX.ipa/feature/rx_offload
|
||||
Date: June 2021
|
||||
KernelVersion: v5.14
|
||||
Contact: Alex Elder <elder@kernel.org>
|
||||
Description:
|
||||
The .../XXXXXXX.ipa/feature/rx_offload file contains a
|
||||
string indicating the type of receive checksum offload
|
||||
that is supported by the hardware. The possible values
|
||||
are "MAPv4" or "MAPv5".
|
||||
|
||||
What: .../XXXXXXX.ipa/feature/tx_offload
|
||||
Date: June 2021
|
||||
KernelVersion: v5.14
|
||||
Contact: Alex Elder <elder@kernel.org>
|
||||
Description:
|
||||
The .../XXXXXXX.ipa/feature/tx_offload file contains a
|
||||
string indicating the type of transmit checksum offload
|
||||
that is supported by the hardware. The possible values
|
||||
are "MAPv4" or "MAPv5".
|
||||
|
||||
What: .../XXXXXXX.ipa/modem/
|
||||
Date: June 2021
|
||||
KernelVersion: v5.14
|
||||
Contact: Alex Elder <elder@kernel.org>
|
||||
Description:
|
||||
The .../XXXXXXX.ipa/modem/ directory contains a set of
|
||||
attributes describing properties of the modem execution
|
||||
environment reachable by the IPA hardware.
|
||||
|
||||
What: .../XXXXXXX.ipa/modem/rx_endpoint_id
|
||||
Date: June 2021
|
||||
KernelVersion: v5.14
|
||||
Contact: Alex Elder <elder@kernel.org>
|
||||
Description:
|
||||
The .../XXXXXXX.ipa/feature/rx_endpoint_id file contains
|
||||
the AP endpoint ID that receives packets originating from
|
||||
the modem execution environment. The "rx" is from the
|
||||
perspective of the AP; this endpoint is considered an "IPA
|
||||
producer". An endpoint ID is a small unsigned integer.
|
||||
|
||||
What: .../XXXXXXX.ipa/modem/tx_endpoint_id
|
||||
Date: June 2021
|
||||
KernelVersion: v5.14
|
||||
Contact: Alex Elder <elder@kernel.org>
|
||||
Description:
|
||||
The .../XXXXXXX.ipa/feature/tx_endpoint_id file contains
|
||||
the AP endpoint ID used to transmit packets destined for
|
||||
the modem execution environment. The "tx" is from the
|
||||
perspective of the AP; this endpoint is considered an "IPA
|
||||
consumer". An endpoint ID is a small unsigned integer.
|
|
@ -211,27 +211,40 @@ over a rather long period of time, but improvements are always welcome!
|
|||
of the system, especially to real-time workloads running on
|
||||
the rest of the system.
|
||||
|
||||
7. As of v4.20, a given kernel implements only one RCU flavor,
|
||||
which is RCU-sched for PREEMPTION=n and RCU-preempt for PREEMPTION=y.
|
||||
If the updater uses call_rcu() or synchronize_rcu(),
|
||||
then the corresponding readers may use rcu_read_lock() and
|
||||
rcu_read_unlock(), rcu_read_lock_bh() and rcu_read_unlock_bh(),
|
||||
or any pair of primitives that disables and re-enables preemption,
|
||||
for example, rcu_read_lock_sched() and rcu_read_unlock_sched().
|
||||
If the updater uses synchronize_srcu() or call_srcu(),
|
||||
then the corresponding readers must use srcu_read_lock() and
|
||||
srcu_read_unlock(), and with the same srcu_struct. The rules for
|
||||
the expedited primitives are the same as for their non-expedited
|
||||
counterparts. Mixing things up will result in confusion and
|
||||
broken kernels, and has even resulted in an exploitable security
|
||||
issue.
|
||||
7. As of v4.20, a given kernel implements only one RCU flavor, which
|
||||
is RCU-sched for PREEMPTION=n and RCU-preempt for PREEMPTION=y.
|
||||
If the updater uses call_rcu() or synchronize_rcu(), then
|
||||
the corresponding readers may use: (1) rcu_read_lock() and
|
||||
rcu_read_unlock(), (2) any pair of primitives that disables
|
||||
and re-enables softirq, for example, rcu_read_lock_bh() and
|
||||
rcu_read_unlock_bh(), or (3) any pair of primitives that disables
|
||||
and re-enables preemption, for example, rcu_read_lock_sched() and
|
||||
rcu_read_unlock_sched(). If the updater uses synchronize_srcu()
|
||||
or call_srcu(), then the corresponding readers must use
|
||||
srcu_read_lock() and srcu_read_unlock(), and with the same
|
||||
srcu_struct. The rules for the expedited RCU grace-period-wait
|
||||
primitives are the same as for their non-expedited counterparts.
|
||||
|
||||
One exception to this rule: rcu_read_lock() and rcu_read_unlock()
|
||||
may be substituted for rcu_read_lock_bh() and rcu_read_unlock_bh()
|
||||
in cases where local bottom halves are already known to be
|
||||
disabled, for example, in irq or softirq context. Commenting
|
||||
such cases is a must, of course! And the jury is still out on
|
||||
whether the increased speed is worth it.
|
||||
If the updater uses call_rcu_tasks() or synchronize_rcu_tasks(),
|
||||
then the readers must refrain from executing voluntary
|
||||
context switches, that is, from blocking. If the updater uses
|
||||
call_rcu_tasks_trace() or synchronize_rcu_tasks_trace(), then
|
||||
the corresponding readers must use rcu_read_lock_trace() and
|
||||
rcu_read_unlock_trace(). If an updater uses call_rcu_tasks_rude()
|
||||
or synchronize_rcu_tasks_rude(), then the corresponding readers
|
||||
must use anything that disables interrupts.
|
||||
|
||||
Mixing things up will result in confusion and broken kernels, and
|
||||
has even resulted in an exploitable security issue. Therefore,
|
||||
when using non-obvious pairs of primitives, commenting is
|
||||
of course a must. One example of non-obvious pairing is
|
||||
the XDP feature in networking, which calls BPF programs from
|
||||
network-driver NAPI (softirq) context. BPF relies heavily on RCU
|
||||
protection for its data structures, but because the BPF program
|
||||
invocation happens entirely within a single local_bh_disable()
|
||||
section in a NAPI poll cycle, this usage is safe. The reason
|
||||
that this usage is safe is that readers can use anything that
|
||||
disables BH when updaters use call_rcu() or synchronize_rcu().
|
||||
|
||||
8. Although synchronize_rcu() is slower than is call_rcu(), it
|
||||
usually results in simpler code. So, unless update performance is
|
||||
|
|
|
@ -12,6 +12,19 @@ BPF instruction-set.
|
|||
The Cilium project also maintains a `BPF and XDP Reference Guide`_
|
||||
that goes into great technical depth about the BPF Architecture.
|
||||
|
||||
libbpf
|
||||
======
|
||||
|
||||
Libbpf is a userspace library for loading and interacting with bpf programs.
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 1
|
||||
|
||||
libbpf/libbpf
|
||||
libbpf/libbpf_api
|
||||
libbpf/libbpf_build
|
||||
libbpf/libbpf_naming_convention
|
||||
|
||||
BPF Type Format (BTF)
|
||||
=====================
|
||||
|
||||
|
@ -84,6 +97,7 @@ Other
|
|||
:maxdepth: 1
|
||||
|
||||
ringbuf
|
||||
llvm_reloc
|
||||
|
||||
.. Links:
|
||||
.. _networking-filter: ../networking/filter.rst
|
||||
|
|
|
@ -0,0 +1,14 @@
|
|||
.. SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause)
|
||||
|
||||
libbpf
|
||||
======
|
||||
|
||||
This is documentation for libbpf, a userspace library for loading and
|
||||
interacting with bpf programs.
|
||||
|
||||
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
|
||||
mailing list search its `archive <https://lore.kernel.org/bpf/>`_.
|
||||
Please search the archive before asking new questions. It very well might
|
||||
be that this was already addressed or answered before.
|
|
@ -0,0 +1,27 @@
|
|||
.. SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause)
|
||||
|
||||
API
|
||||
===
|
||||
|
||||
This documentation is autogenerated from header files in libbpf, tools/lib/bpf
|
||||
|
||||
.. kernel-doc:: tools/lib/bpf/libbpf.h
|
||||
:internal:
|
||||
|
||||
.. kernel-doc:: tools/lib/bpf/bpf.h
|
||||
:internal:
|
||||
|
||||
.. kernel-doc:: tools/lib/bpf/btf.h
|
||||
:internal:
|
||||
|
||||
.. kernel-doc:: tools/lib/bpf/xsk.h
|
||||
:internal:
|
||||
|
||||
.. kernel-doc:: tools/lib/bpf/bpf_tracing.h
|
||||
:internal:
|
||||
|
||||
.. kernel-doc:: tools/lib/bpf/bpf_core_read.h
|
||||
:internal:
|
||||
|
||||
.. kernel-doc:: tools/lib/bpf/bpf_endian.h
|
||||
:internal:
|
|
@ -0,0 +1,37 @@
|
|||
.. SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause)
|
||||
|
||||
Building libbpf
|
||||
===============
|
||||
|
||||
libelf and zlib are internal dependencies of libbpf and thus are required to link
|
||||
against and must be installed on the system for applications to work.
|
||||
pkg-config is used by default to find libelf, and the program called
|
||||
can be overridden with PKG_CONFIG.
|
||||
|
||||
If using pkg-config at build time is not desired, it can be disabled by
|
||||
setting NO_PKG_CONFIG=1 when calling make.
|
||||
|
||||
To build both static libbpf.a and shared libbpf.so:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
$ cd src
|
||||
$ make
|
||||
|
||||
To build only static libbpf.a library in directory build/ and install them
|
||||
together with libbpf headers in a staging directory root/:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
$ cd src
|
||||
$ mkdir build root
|
||||
$ BUILD_STATIC_ONLY=y OBJDIR=build DESTDIR=root make install
|
||||
|
||||
To build both static libbpf.a and shared libbpf.so against a custom libelf
|
||||
dependency installed in /build/root/ and install them together with libbpf
|
||||
headers in a build directory /build/root/:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
$ cd src
|
||||
$ PKG_CONFIG_PATH=/build/root/lib64/pkgconfig DESTDIR=/build/root make
|
|
@ -1,7 +1,7 @@
|
|||
.. SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause)
|
||||
|
||||
libbpf API naming convention
|
||||
============================
|
||||
API naming convention
|
||||
=====================
|
||||
|
||||
libbpf API provides access to a few logically separated groups of
|
||||
functions and types. Every group has its own naming convention
|
||||
|
@ -10,14 +10,14 @@ new function or type is added to keep libbpf API clean and consistent.
|
|||
|
||||
All types and functions provided by libbpf API should have one of the
|
||||
following prefixes: ``bpf_``, ``btf_``, ``libbpf_``, ``xsk_``,
|
||||
``perf_buffer_``.
|
||||
``btf_dump_``, ``ring_buffer_``, ``perf_buffer_``.
|
||||
|
||||
System call wrappers
|
||||
--------------------
|
||||
|
||||
System call wrappers are simple wrappers for commands supported by
|
||||
sys_bpf system call. These wrappers should go to ``bpf.h`` header file
|
||||
and map one-on-one to corresponding commands.
|
||||
and map one to one to corresponding commands.
|
||||
|
||||
For example ``bpf_map_lookup_elem`` wraps ``BPF_MAP_LOOKUP_ELEM``
|
||||
command of sys_bpf, ``bpf_prog_attach`` wraps ``BPF_PROG_ATTACH``, etc.
|
||||
|
@ -49,10 +49,6 @@ object, ``bpf_object``, double underscore and ``open`` that defines the
|
|||
purpose of the function to open ELF file and create ``bpf_object`` from
|
||||
it.
|
||||
|
||||
Another example: ``bpf_program__load`` is named for corresponding
|
||||
object, ``bpf_program``, that is separated from other part of the name
|
||||
by double underscore.
|
||||
|
||||
All objects and corresponding functions other than BTF related should go
|
||||
to ``libbpf.h``. BTF types and functions should go to ``btf.h``.
|
||||
|
||||
|
@ -72,11 +68,7 @@ of both low-level ring access functions and high-level configuration
|
|||
functions. These can be mixed and matched. Note that these functions
|
||||
are not reentrant for performance reasons.
|
||||
|
||||
Please take a look at Documentation/networking/af_xdp.rst in the Linux
|
||||
kernel source tree on how to use XDP sockets and for some common
|
||||
mistakes in case you do not get any traffic up to user space.
|
||||
|
||||
libbpf ABI
|
||||
ABI
|
||||
==========
|
||||
|
||||
libbpf can be both linked statically or used as DSO. To avoid possible
|
||||
|
@ -116,7 +108,8 @@ This bump in ABI version is at most once per kernel development cycle.
|
|||
|
||||
For example, if current state of ``libbpf.map`` is:
|
||||
|
||||
.. code-block::
|
||||
.. code-block:: c
|
||||
|
||||
LIBBPF_0.0.1 {
|
||||
global:
|
||||
bpf_func_a;
|
||||
|
@ -128,7 +121,8 @@ For example, if current state of ``libbpf.map`` is:
|
|||
, and a new symbol ``bpf_func_c`` is being introduced, then
|
||||
``libbpf.map`` should be changed like this:
|
||||
|
||||
.. code-block::
|
||||
.. code-block:: c
|
||||
|
||||
LIBBPF_0.0.1 {
|
||||
global:
|
||||
bpf_func_a;
|
||||
|
@ -148,7 +142,7 @@ Format of version script and ways to handle ABI changes, including
|
|||
incompatible ones, described in details in [1].
|
||||
|
||||
Stand-alone build
|
||||
=================
|
||||
-------------------
|
||||
|
||||
Under https://github.com/libbpf/libbpf there is a (semi-)automated
|
||||
mirror of the mainline's version of libbpf for a stand-alone build.
|
||||
|
@ -157,12 +151,12 @@ However, all changes to libbpf's code base must be upstreamed through
|
|||
the mainline kernel tree.
|
||||
|
||||
License
|
||||
=======
|
||||
-------------------
|
||||
|
||||
libbpf is dual-licensed under LGPL 2.1 and BSD 2-Clause.
|
||||
|
||||
Links
|
||||
=====
|
||||
-------------------
|
||||
|
||||
[1] https://www.akkadia.org/drepper/dsohowto.pdf
|
||||
(Chapter 3. Maintaining APIs and ABIs).
|
|
@ -0,0 +1,240 @@
|
|||
.. SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause)
|
||||
|
||||
====================
|
||||
BPF LLVM Relocations
|
||||
====================
|
||||
|
||||
This document describes LLVM BPF backend relocation types.
|
||||
|
||||
Relocation Record
|
||||
=================
|
||||
|
||||
LLVM BPF backend records each relocation with the following 16-byte
|
||||
ELF structure::
|
||||
|
||||
typedef struct
|
||||
{
|
||||
Elf64_Addr r_offset; // Offset from the beginning of section.
|
||||
Elf64_Xword r_info; // Relocation type and symbol index.
|
||||
} Elf64_Rel;
|
||||
|
||||
For example, for the following code::
|
||||
|
||||
int g1 __attribute__((section("sec")));
|
||||
int g2 __attribute__((section("sec")));
|
||||
static volatile int l1 __attribute__((section("sec")));
|
||||
static volatile int l2 __attribute__((section("sec")));
|
||||
int test() {
|
||||
return g1 + g2 + l1 + l2;
|
||||
}
|
||||
|
||||
Compiled with ``clang -target bpf -O2 -c test.c``, the following is
|
||||
the code with ``llvm-objdump -dr test.o``::
|
||||
|
||||
0: 18 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 r1 = 0 ll
|
||||
0000000000000000: R_BPF_64_64 g1
|
||||
2: 61 11 00 00 00 00 00 00 r1 = *(u32 *)(r1 + 0)
|
||||
3: 18 02 00 00 00 00 00 00 00 00 00 00 00 00 00 00 r2 = 0 ll
|
||||
0000000000000018: R_BPF_64_64 g2
|
||||
5: 61 20 00 00 00 00 00 00 r0 = *(u32 *)(r2 + 0)
|
||||
6: 0f 10 00 00 00 00 00 00 r0 += r1
|
||||
7: 18 01 00 00 08 00 00 00 00 00 00 00 00 00 00 00 r1 = 8 ll
|
||||
0000000000000038: R_BPF_64_64 sec
|
||||
9: 61 11 00 00 00 00 00 00 r1 = *(u32 *)(r1 + 0)
|
||||
10: 0f 10 00 00 00 00 00 00 r0 += r1
|
||||
11: 18 01 00 00 0c 00 00 00 00 00 00 00 00 00 00 00 r1 = 12 ll
|
||||
0000000000000058: R_BPF_64_64 sec
|
||||
13: 61 11 00 00 00 00 00 00 r1 = *(u32 *)(r1 + 0)
|
||||
14: 0f 10 00 00 00 00 00 00 r0 += r1
|
||||
15: 95 00 00 00 00 00 00 00 exit
|
||||
|
||||
There are four relations in the above for four ``LD_imm64`` instructions.
|
||||
The following ``llvm-readelf -r test.o`` shows the binary values of the four
|
||||
relocations::
|
||||
|
||||
Relocation section '.rel.text' at offset 0x190 contains 4 entries:
|
||||
Offset Info Type Symbol's Value Symbol's Name
|
||||
0000000000000000 0000000600000001 R_BPF_64_64 0000000000000000 g1
|
||||
0000000000000018 0000000700000001 R_BPF_64_64 0000000000000004 g2
|
||||
0000000000000038 0000000400000001 R_BPF_64_64 0000000000000000 sec
|
||||
0000000000000058 0000000400000001 R_BPF_64_64 0000000000000000 sec
|
||||
|
||||
Each relocation is represented by ``Offset`` (8 bytes) and ``Info`` (8 bytes).
|
||||
For example, the first relocation corresponds to the first instruction
|
||||
(Offset 0x0) and the corresponding ``Info`` indicates the relocation type
|
||||
of ``R_BPF_64_64`` (type 1) and the entry in the symbol table (entry 6).
|
||||
The following is the symbol table with ``llvm-readelf -s test.o``::
|
||||
|
||||
Symbol table '.symtab' contains 8 entries:
|
||||
Num: Value Size Type Bind Vis Ndx Name
|
||||
0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND
|
||||
1: 0000000000000000 0 FILE LOCAL DEFAULT ABS test.c
|
||||
2: 0000000000000008 4 OBJECT LOCAL DEFAULT 4 l1
|
||||
3: 000000000000000c 4 OBJECT LOCAL DEFAULT 4 l2
|
||||
4: 0000000000000000 0 SECTION LOCAL DEFAULT 4 sec
|
||||
5: 0000000000000000 128 FUNC GLOBAL DEFAULT 2 test
|
||||
6: 0000000000000000 4 OBJECT GLOBAL DEFAULT 4 g1
|
||||
7: 0000000000000004 4 OBJECT GLOBAL DEFAULT 4 g2
|
||||
|
||||
The 6th entry is global variable ``g1`` with value 0.
|
||||
|
||||
Similarly, the second relocation is at ``.text`` offset ``0x18``, instruction 3,
|
||||
for global variable ``g2`` which has a symbol value 4, the offset
|
||||
from the start of ``.data`` section.
|
||||
|
||||
The third and fourth relocations refers to static variables ``l1``
|
||||
and ``l2``. From ``.rel.text`` section above, it is not clear
|
||||
which symbols they really refers to as they both refers to
|
||||
symbol table entry 4, symbol ``sec``, which has ``STT_SECTION`` type
|
||||
and represents a section. So for static variable or function,
|
||||
the section offset is written to the original insn
|
||||
buffer, which is called ``A`` (addend). Looking at
|
||||
above insn ``7`` and ``11``, they have section offset ``8`` and ``12``.
|
||||
From symbol table, we can find that they correspond to entries ``2``
|
||||
and ``3`` for ``l1`` and ``l2``.
|
||||
|
||||
In general, the ``A`` is 0 for global variables and functions,
|
||||
and is the section offset or some computation result based on
|
||||
section offset for static variables/functions. The non-section-offset
|
||||
case refers to function calls. See below for more details.
|
||||
|
||||
Different Relocation Types
|
||||
==========================
|
||||
|
||||
Six relocation types are supported. The following is an overview and
|
||||
``S`` represents the value of the symbol in the symbol table::
|
||||
|
||||
Enum ELF Reloc Type Description BitSize Offset Calculation
|
||||
0 R_BPF_NONE None
|
||||
1 R_BPF_64_64 ld_imm64 insn 32 r_offset + 4 S + A
|
||||
2 R_BPF_64_ABS64 normal data 64 r_offset S + A
|
||||
3 R_BPF_64_ABS32 normal data 32 r_offset S + A
|
||||
4 R_BPF_64_NODYLD32 .BTF[.ext] data 32 r_offset S + A
|
||||
10 R_BPF_64_32 call insn 32 r_offset + 4 (S + A) / 8 - 1
|
||||
|
||||
For example, ``R_BPF_64_64`` relocation type is used for ``ld_imm64`` instruction.
|
||||
The actual to-be-relocated data (0 or section offset)
|
||||
is stored at ``r_offset + 4`` and the read/write
|
||||
data bitsize is 32 (4 bytes). The relocation can be resolved with
|
||||
the symbol value plus implicit addend. Note that the ``BitSize`` is 32 which
|
||||
means the section offset must be less than or equal to ``UINT32_MAX`` and this
|
||||
is enforced by LLVM BPF backend.
|
||||
|
||||
In another case, ``R_BPF_64_ABS64`` relocation type is used for normal 64-bit data.
|
||||
The actual to-be-relocated data is stored at ``r_offset`` and the read/write data
|
||||
bitsize is 64 (8 bytes). The relocation can be resolved with
|
||||
the symbol value plus implicit addend.
|
||||
|
||||
Both ``R_BPF_64_ABS32`` and ``R_BPF_64_NODYLD32`` types are for 32-bit data.
|
||||
But ``R_BPF_64_NODYLD32`` specifically refers to relocations in ``.BTF`` and
|
||||
``.BTF.ext`` sections. For cases like bcc where llvm ``ExecutionEngine RuntimeDyld``
|
||||
is involved, ``R_BPF_64_NODYLD32`` types of relocations should not be resolved
|
||||
to actual function/variable address. Otherwise, ``.BTF`` and ``.BTF.ext``
|
||||
become unusable by bcc and kernel.
|
||||
|
||||
Type ``R_BPF_64_32`` is used for call instruction. The call target section
|
||||
offset is stored at ``r_offset + 4`` (32bit) and calculated as
|
||||
``(S + A) / 8 - 1``.
|
||||
|
||||
Examples
|
||||
========
|
||||
|
||||
Types ``R_BPF_64_64`` and ``R_BPF_64_32`` are used to resolve ``ld_imm64``
|
||||
and ``call`` instructions. For example::
|
||||
|
||||
__attribute__((noinline)) __attribute__((section("sec1")))
|
||||
int gfunc(int a, int b) {
|
||||
return a * b;
|
||||
}
|
||||
static __attribute__((noinline)) __attribute__((section("sec1")))
|
||||
int lfunc(int a, int b) {
|
||||
return a + b;
|
||||
}
|
||||
int global __attribute__((section("sec2")));
|
||||
int test(int a, int b) {
|
||||
return gfunc(a, b) + lfunc(a, b) + global;
|
||||
}
|
||||
|
||||
Compiled with ``clang -target bpf -O2 -c test.c``, we will have
|
||||
following code with `llvm-objdump -dr test.o``::
|
||||
|
||||
Disassembly of section .text:
|
||||
|
||||
0000000000000000 <test>:
|
||||
0: bf 26 00 00 00 00 00 00 r6 = r2
|
||||
1: bf 17 00 00 00 00 00 00 r7 = r1
|
||||
2: 85 10 00 00 ff ff ff ff call -1
|
||||
0000000000000010: R_BPF_64_32 gfunc
|
||||
3: bf 08 00 00 00 00 00 00 r8 = r0
|
||||
4: bf 71 00 00 00 00 00 00 r1 = r7
|
||||
5: bf 62 00 00 00 00 00 00 r2 = r6
|
||||
6: 85 10 00 00 02 00 00 00 call 2
|
||||
0000000000000030: R_BPF_64_32 sec1
|
||||
7: 0f 80 00 00 00 00 00 00 r0 += r8
|
||||
8: 18 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 r1 = 0 ll
|
||||
0000000000000040: R_BPF_64_64 global
|
||||
10: 61 11 00 00 00 00 00 00 r1 = *(u32 *)(r1 + 0)
|
||||
11: 0f 10 00 00 00 00 00 00 r0 += r1
|
||||
12: 95 00 00 00 00 00 00 00 exit
|
||||
|
||||
Disassembly of section sec1:
|
||||
|
||||
0000000000000000 <gfunc>:
|
||||
0: bf 20 00 00 00 00 00 00 r0 = r2
|
||||
1: 2f 10 00 00 00 00 00 00 r0 *= r1
|
||||
2: 95 00 00 00 00 00 00 00 exit
|
||||
|
||||
0000000000000018 <lfunc>:
|
||||
3: bf 20 00 00 00 00 00 00 r0 = r2
|
||||
4: 0f 10 00 00 00 00 00 00 r0 += r1
|
||||
5: 95 00 00 00 00 00 00 00 exit
|
||||
|
||||
The first relocation corresponds to ``gfunc(a, b)`` where ``gfunc`` has a value of 0,
|
||||
so the ``call`` instruction offset is ``(0 + 0)/8 - 1 = -1``.
|
||||
The second relocation corresponds to ``lfunc(a, b)`` where ``lfunc`` has a section
|
||||
offset ``0x18``, so the ``call`` instruction offset is ``(0 + 0x18)/8 - 1 = 2``.
|
||||
The third relocation corresponds to ld_imm64 of ``global``, which has a section
|
||||
offset ``0``.
|
||||
|
||||
The following is an example to show how R_BPF_64_ABS64 could be generated::
|
||||
|
||||
int global() { return 0; }
|
||||
struct t { void *g; } gbl = { global };
|
||||
|
||||
Compiled with ``clang -target bpf -O2 -g -c test.c``, we will see a
|
||||
relocation below in ``.data`` section with command
|
||||
``llvm-readelf -r test.o``::
|
||||
|
||||
Relocation section '.rel.data' at offset 0x458 contains 1 entries:
|
||||
Offset Info Type Symbol's Value Symbol's Name
|
||||
0000000000000000 0000000700000002 R_BPF_64_ABS64 0000000000000000 global
|
||||
|
||||
The relocation says the first 8-byte of ``.data`` section should be
|
||||
filled with address of ``global`` variable.
|
||||
|
||||
With ``llvm-readelf`` output, we can see that dwarf sections have a bunch of
|
||||
``R_BPF_64_ABS32`` and ``R_BPF_64_ABS64`` relocations::
|
||||
|
||||
Relocation section '.rel.debug_info' at offset 0x468 contains 13 entries:
|
||||
Offset Info Type Symbol's Value Symbol's Name
|
||||
0000000000000006 0000000300000003 R_BPF_64_ABS32 0000000000000000 .debug_abbrev
|
||||
000000000000000c 0000000400000003 R_BPF_64_ABS32 0000000000000000 .debug_str
|
||||
0000000000000012 0000000400000003 R_BPF_64_ABS32 0000000000000000 .debug_str
|
||||
0000000000000016 0000000600000003 R_BPF_64_ABS32 0000000000000000 .debug_line
|
||||
000000000000001a 0000000400000003 R_BPF_64_ABS32 0000000000000000 .debug_str
|
||||
000000000000001e 0000000200000002 R_BPF_64_ABS64 0000000000000000 .text
|
||||
000000000000002b 0000000400000003 R_BPF_64_ABS32 0000000000000000 .debug_str
|
||||
0000000000000037 0000000800000002 R_BPF_64_ABS64 0000000000000000 gbl
|
||||
0000000000000040 0000000400000003 R_BPF_64_ABS32 0000000000000000 .debug_str
|
||||
......
|
||||
|
||||
The .BTF/.BTF.ext sections has R_BPF_64_NODYLD32 relocations::
|
||||
|
||||
Relocation section '.rel.BTF' at offset 0x538 contains 1 entries:
|
||||
Offset Info Type Symbol's Value Symbol's Name
|
||||
0000000000000084 0000000800000004 R_BPF_64_NODYLD32 0000000000000000 gbl
|
||||
|
||||
Relocation section '.rel.BTF.ext' at offset 0x548 contains 2 entries:
|
||||
Offset Info Type Symbol's Value Symbol's Name
|
||||
000000000000002c 0000000200000004 R_BPF_64_NODYLD32 0000000000000000 .text
|
||||
0000000000000040 0000000200000004 R_BPF_64_NODYLD32 0000000000000000 .text
|
|
@ -1,23 +0,0 @@
|
|||
* Broadcom iProc MDIO bus controller
|
||||
|
||||
Required properties:
|
||||
- compatible: should be "brcm,iproc-mdio"
|
||||
- reg: address and length of the register set for the MDIO interface
|
||||
- #size-cells: must be 1
|
||||
- #address-cells: must be 0
|
||||
|
||||
Child nodes of this MDIO bus controller node are standard Ethernet PHY device
|
||||
nodes as described in Documentation/devicetree/bindings/net/phy.txt
|
||||
|
||||
Example:
|
||||
|
||||
mdio@18002000 {
|
||||
compatible = "brcm,iproc-mdio";
|
||||
reg = <0x18002000 0x8>;
|
||||
#size-cells = <1>;
|
||||
#address-cells = <0>;
|
||||
|
||||
enet-gphy@0 {
|
||||
reg = <0>;
|
||||
};
|
||||
};
|
|
@ -0,0 +1,38 @@
|
|||
# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/net/brcm,iproc-mdio.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Broadcom iProc MDIO bus controller
|
||||
|
||||
maintainers:
|
||||
- Rafał Miłecki <rafal@milecki.pl>
|
||||
|
||||
allOf:
|
||||
- $ref: mdio.yaml#
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
const: brcm,iproc-mdio
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
unevaluatedProperties: false
|
||||
|
||||
required:
|
||||
- reg
|
||||
|
||||
examples:
|
||||
- |
|
||||
mdio@18002000 {
|
||||
compatible = "brcm,iproc-mdio";
|
||||
reg = <0x18002000 0x8>;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
ethernet-phy@0 {
|
||||
reg = <0>;
|
||||
};
|
||||
};
|
|
@ -1,80 +0,0 @@
|
|||
Renesas R-Car CAN controller Device Tree Bindings
|
||||
-------------------------------------------------
|
||||
|
||||
Required properties:
|
||||
- compatible: "renesas,can-r8a7742" if CAN controller is a part of R8A7742 SoC.
|
||||
"renesas,can-r8a7743" if CAN controller is a part of R8A7743 SoC.
|
||||
"renesas,can-r8a7744" if CAN controller is a part of R8A7744 SoC.
|
||||
"renesas,can-r8a7745" if CAN controller is a part of R8A7745 SoC.
|
||||
"renesas,can-r8a77470" if CAN controller is a part of R8A77470 SoC.
|
||||
"renesas,can-r8a774a1" if CAN controller is a part of R8A774A1 SoC.
|
||||
"renesas,can-r8a774b1" if CAN controller is a part of R8A774B1 SoC.
|
||||
"renesas,can-r8a774c0" if CAN controller is a part of R8A774C0 SoC.
|
||||
"renesas,can-r8a774e1" if CAN controller is a part of R8A774E1 SoC.
|
||||
"renesas,can-r8a7778" if CAN controller is a part of R8A7778 SoC.
|
||||
"renesas,can-r8a7779" if CAN controller is a part of R8A7779 SoC.
|
||||
"renesas,can-r8a7790" if CAN controller is a part of R8A7790 SoC.
|
||||
"renesas,can-r8a7791" if CAN controller is a part of R8A7791 SoC.
|
||||
"renesas,can-r8a7792" if CAN controller is a part of R8A7792 SoC.
|
||||
"renesas,can-r8a7793" if CAN controller is a part of R8A7793 SoC.
|
||||
"renesas,can-r8a7794" if CAN controller is a part of R8A7794 SoC.
|
||||
"renesas,can-r8a7795" if CAN controller is a part of R8A7795 SoC.
|
||||
"renesas,can-r8a7796" if CAN controller is a part of R8A77960 SoC.
|
||||
"renesas,can-r8a77961" if CAN controller is a part of R8A77961 SoC.
|
||||
"renesas,can-r8a77965" if CAN controller is a part of R8A77965 SoC.
|
||||
"renesas,can-r8a77990" if CAN controller is a part of R8A77990 SoC.
|
||||
"renesas,can-r8a77995" if CAN controller is a part of R8A77995 SoC.
|
||||
"renesas,rcar-gen1-can" for a generic R-Car Gen1 compatible device.
|
||||
"renesas,rcar-gen2-can" for a generic R-Car Gen2 or RZ/G1
|
||||
compatible device.
|
||||
"renesas,rcar-gen3-can" for a generic R-Car Gen3 or RZ/G2
|
||||
compatible device.
|
||||
When compatible with the generic version, nodes must list the
|
||||
SoC-specific version corresponding to the platform first
|
||||
followed by the generic version.
|
||||
|
||||
- reg: physical base address and size of the R-Car CAN register map.
|
||||
- interrupts: interrupt specifier for the sole interrupt.
|
||||
- clocks: phandles and clock specifiers for 3 CAN clock inputs.
|
||||
- clock-names: 3 clock input name strings: "clkp1", "clkp2", and "can_clk".
|
||||
- pinctrl-0: pin control group to be used for this controller.
|
||||
- pinctrl-names: must be "default".
|
||||
|
||||
Required properties for R8A774A1, R8A774B1, R8A774C0, R8A774E1, R8A7795,
|
||||
R8A77960, R8A77961, R8A77965, R8A77990, and R8A77995:
|
||||
For the denoted SoCs, "clkp2" can be CANFD clock. This is a div6 clock and can
|
||||
be used by both CAN and CAN FD controller at the same time. It needs to be
|
||||
scaled to maximum frequency if any of these controllers use it. This is done
|
||||
using the below properties:
|
||||
|
||||
- assigned-clocks: phandle of clkp2(CANFD) clock.
|
||||
- assigned-clock-rates: maximum frequency of this clock.
|
||||
|
||||
Optional properties:
|
||||
- renesas,can-clock-select: R-Car CAN Clock Source Select. Valid values are:
|
||||
<0x0> (default) : Peripheral clock (clkp1)
|
||||
<0x1> : Peripheral clock (clkp2)
|
||||
<0x3> : External input clock
|
||||
|
||||
Example
|
||||
-------
|
||||
|
||||
SoC common .dtsi file:
|
||||
|
||||
can0: can@e6e80000 {
|
||||
compatible = "renesas,can-r8a7791", "renesas,rcar-gen2-can";
|
||||
reg = <0 0xe6e80000 0 0x1000>;
|
||||
interrupts = <0 186 IRQ_TYPE_LEVEL_HIGH>;
|
||||
clocks = <&mstp9_clks R8A7791_CLK_RCAN0>,
|
||||
<&cpg_clocks R8A7791_CLK_RCAN>, <&can_clk>;
|
||||
clock-names = "clkp1", "clkp2", "can_clk";
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
Board specific .dts file:
|
||||
|
||||
&can0 {
|
||||
pinctrl-0 = <&can0_pins>;
|
||||
pinctrl-names = "default";
|
||||
status = "okay";
|
||||
};
|
|
@ -1,107 +0,0 @@
|
|||
Renesas R-Car CAN FD controller Device Tree Bindings
|
||||
----------------------------------------------------
|
||||
|
||||
Required properties:
|
||||
- compatible: Must contain one or more of the following:
|
||||
- "renesas,rcar-gen3-canfd" for R-Car Gen3 and RZ/G2 compatible controllers.
|
||||
- "renesas,r8a774a1-canfd" for R8A774A1 (RZ/G2M) compatible controller.
|
||||
- "renesas,r8a774b1-canfd" for R8A774B1 (RZ/G2N) compatible controller.
|
||||
- "renesas,r8a774c0-canfd" for R8A774C0 (RZ/G2E) compatible controller.
|
||||
- "renesas,r8a774e1-canfd" for R8A774E1 (RZ/G2H) compatible controller.
|
||||
- "renesas,r8a7795-canfd" for R8A7795 (R-Car H3) compatible controller.
|
||||
- "renesas,r8a7796-canfd" for R8A7796 (R-Car M3-W) compatible controller.
|
||||
- "renesas,r8a77965-canfd" for R8A77965 (R-Car M3-N) compatible controller.
|
||||
- "renesas,r8a77970-canfd" for R8A77970 (R-Car V3M) compatible controller.
|
||||
- "renesas,r8a77980-canfd" for R8A77980 (R-Car V3H) compatible controller.
|
||||
- "renesas,r8a77990-canfd" for R8A77990 (R-Car E3) compatible controller.
|
||||
- "renesas,r8a77995-canfd" for R8A77995 (R-Car D3) compatible controller.
|
||||
|
||||
When compatible with the generic version, nodes must list the
|
||||
SoC-specific version corresponding to the platform first, followed by the
|
||||
family-specific and/or generic versions.
|
||||
|
||||
- reg: physical base address and size of the R-Car CAN FD register map.
|
||||
- interrupts: interrupt specifiers for the Channel & Global interrupts
|
||||
- clocks: phandles and clock specifiers for 3 clock inputs.
|
||||
- clock-names: 3 clock input name strings: "fck", "canfd", "can_clk".
|
||||
- pinctrl-0: pin control group to be used for this controller.
|
||||
- pinctrl-names: must be "default".
|
||||
|
||||
Required child nodes:
|
||||
The controller supports two channels and each is represented as a child node.
|
||||
The name of the child nodes are "channel0" and "channel1" respectively. Each
|
||||
child node supports the "status" property only, which is used to
|
||||
enable/disable the respective channel.
|
||||
|
||||
Required properties for R8A774A1, R8A774B1, R8A774C0, R8A774E1, R8A7795,
|
||||
R8A7796, R8A77965, R8A77990, and R8A77995:
|
||||
In the denoted SoCs, canfd clock is a div6 clock and can be used by both CAN
|
||||
and CAN FD controller at the same time. It needs to be scaled to maximum
|
||||
frequency if any of these controllers use it. This is done using the below
|
||||
properties:
|
||||
|
||||
- assigned-clocks: phandle of canfd clock.
|
||||
- assigned-clock-rates: maximum frequency of this clock.
|
||||
|
||||
Optional property:
|
||||
The controller can operate in either CAN FD only mode (default) or
|
||||
Classical CAN only mode. The mode is global to both the channels. In order to
|
||||
enable the later, define the following optional property.
|
||||
- renesas,no-can-fd: puts the controller in Classical CAN only mode.
|
||||
|
||||
Example
|
||||
-------
|
||||
|
||||
SoC common .dtsi file:
|
||||
|
||||
canfd: can@e66c0000 {
|
||||
compatible = "renesas,r8a7795-canfd",
|
||||
"renesas,rcar-gen3-canfd";
|
||||
reg = <0 0xe66c0000 0 0x8000>;
|
||||
interrupts = <GIC_SPI 29 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 30 IRQ_TYPE_LEVEL_HIGH>;
|
||||
clocks = <&cpg CPG_MOD 914>,
|
||||
<&cpg CPG_CORE R8A7795_CLK_CANFD>,
|
||||
<&can_clk>;
|
||||
clock-names = "fck", "canfd", "can_clk";
|
||||
assigned-clocks = <&cpg CPG_CORE R8A7795_CLK_CANFD>;
|
||||
assigned-clock-rates = <40000000>;
|
||||
power-domains = <&cpg>;
|
||||
status = "disabled";
|
||||
|
||||
channel0 {
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
channel1 {
|
||||
status = "disabled";
|
||||
};
|
||||
};
|
||||
|
||||
Board specific .dts file:
|
||||
|
||||
E.g. below enables Channel 1 alone in the board in Classical CAN only mode.
|
||||
|
||||
&canfd {
|
||||
pinctrl-0 = <&canfd1_pins>;
|
||||
pinctrl-names = "default";
|
||||
renesas,no-can-fd;
|
||||
status = "okay";
|
||||
|
||||
channel1 {
|
||||
status = "okay";
|
||||
};
|
||||
};
|
||||
|
||||
E.g. below enables Channel 0 alone in the board using External clock
|
||||
as fCAN clock.
|
||||
|
||||
&canfd {
|
||||
pinctrl-0 = <&canfd0_pins>, <&can_clk_pins>;
|
||||
pinctrl-names = "default";
|
||||
status = "okay";
|
||||
|
||||
channel0 {
|
||||
status = "okay";
|
||||
};
|
||||
};
|
|
@ -0,0 +1,139 @@
|
|||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/net/can/renesas,rcar-can.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Renesas R-Car CAN Controller
|
||||
|
||||
maintainers:
|
||||
- Sergei Shtylyov <sergei.shtylyov@gmail.com>
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
oneOf:
|
||||
- items:
|
||||
- enum:
|
||||
- renesas,can-r8a7778 # R-Car M1-A
|
||||
- renesas,can-r8a7779 # R-Car H1
|
||||
- const: renesas,rcar-gen1-can # R-Car Gen1
|
||||
|
||||
- items:
|
||||
- enum:
|
||||
- renesas,can-r8a7742 # RZ/G1H
|
||||
- renesas,can-r8a7743 # RZ/G1M
|
||||
- renesas,can-r8a7744 # RZ/G1N
|
||||
- renesas,can-r8a7745 # RZ/G1E
|
||||
- renesas,can-r8a77470 # RZ/G1C
|
||||
- renesas,can-r8a7790 # R-Car H2
|
||||
- renesas,can-r8a7791 # R-Car M2-W
|
||||
- renesas,can-r8a7792 # R-Car V2H
|
||||
- renesas,can-r8a7793 # R-Car M2-N
|
||||
- renesas,can-r8a7794 # R-Car E2
|
||||
- const: renesas,rcar-gen2-can # R-Car Gen2 and RZ/G1
|
||||
|
||||
- items:
|
||||
- enum:
|
||||
- renesas,can-r8a774a1 # RZ/G2M
|
||||
- renesas,can-r8a774b1 # RZ/G2N
|
||||
- renesas,can-r8a774c0 # RZ/G2E
|
||||
- renesas,can-r8a774e1 # RZ/G2H
|
||||
- renesas,can-r8a7795 # R-Car H3
|
||||
- renesas,can-r8a7796 # R-Car M3-W
|
||||
- renesas,can-r8a77961 # R-Car M3-W+
|
||||
- renesas,can-r8a77965 # R-Car M3-N
|
||||
- renesas,can-r8a77990 # R-Car E3
|
||||
- renesas,can-r8a77995 # R-Car D3
|
||||
- const: renesas,rcar-gen3-can # R-Car Gen3 and RZ/G2
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
interrupts:
|
||||
maxItems: 1
|
||||
|
||||
clocks:
|
||||
maxItems: 3
|
||||
|
||||
clock-names:
|
||||
items:
|
||||
- const: clkp1
|
||||
- const: clkp2
|
||||
- const: can_clk
|
||||
|
||||
power-domains:
|
||||
maxItems: 1
|
||||
|
||||
resets:
|
||||
maxItems: 1
|
||||
|
||||
renesas,can-clock-select:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
enum: [ 0, 1, 3 ]
|
||||
default: 0
|
||||
description: |
|
||||
R-Car CAN Clock Source Select. Valid values are:
|
||||
<0x0> (default) : Peripheral clock (clkp1)
|
||||
<0x1> : Peripheral clock (clkp2)
|
||||
<0x3> : External input clock
|
||||
|
||||
assigned-clocks:
|
||||
description:
|
||||
Reference to the clkp2 (CANFD) clock.
|
||||
On R-Car Gen3 and RZ/G2 SoCs, "clkp2" is the CANFD clock. This is a div6
|
||||
clock and can be used by both CAN and CAN FD controllers at the same
|
||||
time. It needs to be scaled to maximum frequency if any of these
|
||||
controllers use it.
|
||||
|
||||
assigned-clock-rates:
|
||||
description: Maximum frequency of the CANFD clock.
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- interrupts
|
||||
- clocks
|
||||
- clock-names
|
||||
- power-domains
|
||||
|
||||
allOf:
|
||||
- $ref: can-controller.yaml#
|
||||
|
||||
- if:
|
||||
not:
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
const: renesas,rcar-gen1-can
|
||||
then:
|
||||
required:
|
||||
- resets
|
||||
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
const: renesas,rcar-gen3-can
|
||||
then:
|
||||
required:
|
||||
- assigned-clocks
|
||||
- assigned-clock-rates
|
||||
|
||||
unevaluatedProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/clock/r8a7791-cpg-mssr.h>
|
||||
#include <dt-bindings/interrupt-controller/arm-gic.h>
|
||||
#include <dt-bindings/power/r8a7791-sysc.h>
|
||||
|
||||
can0: can@e6e80000 {
|
||||
compatible = "renesas,can-r8a7791", "renesas,rcar-gen2-can";
|
||||
reg = <0xe6e80000 0x1000>;
|
||||
interrupts = <GIC_SPI 186 IRQ_TYPE_LEVEL_HIGH>;
|
||||
clocks = <&cpg CPG_MOD 916>,
|
||||
<&cpg CPG_CORE R8A7791_CLK_RCAN>, <&can_clk>;
|
||||
clock-names = "clkp1", "clkp2", "can_clk";
|
||||
power-domains = <&sysc R8A7791_PD_ALWAYS_ON>;
|
||||
resets = <&cpg 916>;
|
||||
};
|
|
@ -0,0 +1,122 @@
|
|||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/net/can/renesas,rcar-canfd.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Renesas R-Car CAN FD Controller
|
||||
|
||||
maintainers:
|
||||
- Fabrizio Castro <fabrizio.castro.jz@renesas.com>
|
||||
|
||||
allOf:
|
||||
- $ref: can-controller.yaml#
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
oneOf:
|
||||
- items:
|
||||
- enum:
|
||||
- renesas,r8a774a1-canfd # RZ/G2M
|
||||
- renesas,r8a774b1-canfd # RZ/G2N
|
||||
- renesas,r8a774c0-canfd # RZ/G2E
|
||||
- renesas,r8a774e1-canfd # RZ/G2H
|
||||
- renesas,r8a7795-canfd # R-Car H3
|
||||
- renesas,r8a7796-canfd # R-Car M3-W
|
||||
- renesas,r8a77965-canfd # R-Car M3-N
|
||||
- renesas,r8a77970-canfd # R-Car V3M
|
||||
- renesas,r8a77980-canfd # R-Car V3H
|
||||
- renesas,r8a77990-canfd # R-Car E3
|
||||
- renesas,r8a77995-canfd # R-Car D3
|
||||
- const: renesas,rcar-gen3-canfd # R-Car Gen3 and RZ/G2
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
interrupts:
|
||||
items:
|
||||
- description: Channel interrupt
|
||||
- description: Global interrupt
|
||||
|
||||
clocks:
|
||||
maxItems: 3
|
||||
|
||||
clock-names:
|
||||
items:
|
||||
- const: fck
|
||||
- const: canfd
|
||||
- const: can_clk
|
||||
|
||||
power-domains:
|
||||
maxItems: 1
|
||||
|
||||
resets:
|
||||
maxItems: 1
|
||||
|
||||
renesas,no-can-fd:
|
||||
$ref: /schemas/types.yaml#/definitions/flag
|
||||
description:
|
||||
The controller can operate in either CAN FD only mode (default) or
|
||||
Classical CAN only mode. The mode is global to both the channels.
|
||||
Specify this property to put the controller in Classical CAN only mode.
|
||||
|
||||
assigned-clocks:
|
||||
description:
|
||||
Reference to the CANFD clock. The CANFD clock is a div6 clock and can be
|
||||
used by both CAN (if present) and CAN FD controllers at the same time.
|
||||
It needs to be scaled to maximum frequency if any of these controllers
|
||||
use it.
|
||||
|
||||
assigned-clock-rates:
|
||||
description: Maximum frequency of the CANFD clock.
|
||||
|
||||
patternProperties:
|
||||
"^channel[01]$":
|
||||
type: object
|
||||
description:
|
||||
The controller supports two channels and each is represented as a child
|
||||
node. Each child node supports the "status" property only, which
|
||||
is used to enable/disable the respective channel.
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- interrupts
|
||||
- clocks
|
||||
- clock-names
|
||||
- power-domains
|
||||
- resets
|
||||
- assigned-clocks
|
||||
- assigned-clock-rates
|
||||
- channel0
|
||||
- channel1
|
||||
|
||||
unevaluatedProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/clock/r8a7795-cpg-mssr.h>
|
||||
#include <dt-bindings/interrupt-controller/arm-gic.h>
|
||||
#include <dt-bindings/power/r8a7795-sysc.h>
|
||||
|
||||
canfd: can@e66c0000 {
|
||||
compatible = "renesas,r8a7795-canfd",
|
||||
"renesas,rcar-gen3-canfd";
|
||||
reg = <0xe66c0000 0x8000>;
|
||||
interrupts = <GIC_SPI 29 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 30 IRQ_TYPE_LEVEL_HIGH>;
|
||||
clocks = <&cpg CPG_MOD 914>,
|
||||
<&cpg CPG_CORE R8A7795_CLK_CANFD>,
|
||||
<&can_clk>;
|
||||
clock-names = "fck", "canfd", "can_clk";
|
||||
assigned-clocks = <&cpg CPG_CORE R8A7795_CLK_CANFD>;
|
||||
assigned-clock-rates = <40000000>;
|
||||
power-domains = <&sysc R8A7795_PD_ALWAYS_ON>;
|
||||
resets = <&cpg 914>;
|
||||
|
||||
channel0 {
|
||||
};
|
||||
|
||||
channel1 {
|
||||
};
|
||||
};
|
|
@ -81,6 +81,12 @@ Optional properties:
|
|||
- gpio-controller: Boolean; if defined, MT7530's LED controller will run on
|
||||
GPIO mode.
|
||||
- #gpio-cells: Must be 2 if gpio-controller is defined.
|
||||
- interrupt-controller: Boolean; Enables the internal interrupt controller.
|
||||
|
||||
If interrupt-controller is defined, the following properties are required.
|
||||
|
||||
- #interrupt-cells: Must be 1.
|
||||
- interrupts: Parent interrupt for the interrupt controller.
|
||||
|
||||
See Documentation/devicetree/bindings/net/dsa/dsa.txt for a list of additional
|
||||
required, optional properties and how the integrated switch subnodes must
|
||||
|
|
|
@ -0,0 +1,132 @@
|
|||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/net/dsa/nxp,sja1105.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: NXP SJA1105 Automotive Ethernet Switch Family Device Tree Bindings
|
||||
|
||||
description:
|
||||
The SJA1105 SPI interface requires a CS-to-CLK time (t2 in UM10944.pdf) of at
|
||||
least one half of t_CLK. At an SPI frequency of 1MHz, this means a minimum
|
||||
cs_sck_delay of 500ns. Ensuring that this SPI timing requirement is observed
|
||||
depends on the SPI bus master driver.
|
||||
|
||||
allOf:
|
||||
- $ref: "dsa.yaml#"
|
||||
|
||||
maintainers:
|
||||
- Vladimir Oltean <vladimir.oltean@nxp.com>
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
enum:
|
||||
- nxp,sja1105e
|
||||
- nxp,sja1105t
|
||||
- nxp,sja1105p
|
||||
- nxp,sja1105q
|
||||
- nxp,sja1105r
|
||||
- nxp,sja1105s
|
||||
- nxp,sja1110a
|
||||
- nxp,sja1110b
|
||||
- nxp,sja1110c
|
||||
- nxp,sja1110d
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
# Optional container node for the 2 internal MDIO buses of the SJA1110
|
||||
# (one for the internal 100base-T1 PHYs and the other for the single
|
||||
# 100base-TX PHY). The "reg" property does not have physical significance.
|
||||
# The PHY addresses to port correspondence is as follows: for 100base-T1,
|
||||
# port 5 has PHY 1, port 6 has PHY 2 etc, while for 100base-TX, port 1 has
|
||||
# PHY 1.
|
||||
mdios:
|
||||
type: object
|
||||
|
||||
properties:
|
||||
'#address-cells':
|
||||
const: 1
|
||||
'#size-cells':
|
||||
const: 0
|
||||
|
||||
patternProperties:
|
||||
"^mdio@[0-1]$":
|
||||
type: object
|
||||
|
||||
allOf:
|
||||
- $ref: "http://devicetree.org/schemas/net/mdio.yaml#"
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
oneOf:
|
||||
- enum:
|
||||
- nxp,sja1110-base-t1-mdio
|
||||
- nxp,sja1110-base-tx-mdio
|
||||
|
||||
reg:
|
||||
oneOf:
|
||||
- enum:
|
||||
- 0
|
||||
- 1
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
|
||||
unevaluatedProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
spi {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
ethernet-switch@1 {
|
||||
reg = <0x1>;
|
||||
compatible = "nxp,sja1105t";
|
||||
|
||||
ethernet-ports {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
port@0 {
|
||||
phy-handle = <&rgmii_phy6>;
|
||||
phy-mode = "rgmii-id";
|
||||
reg = <0>;
|
||||
};
|
||||
|
||||
port@1 {
|
||||
phy-handle = <&rgmii_phy3>;
|
||||
phy-mode = "rgmii-id";
|
||||
reg = <1>;
|
||||
};
|
||||
|
||||
port@2 {
|
||||
phy-handle = <&rgmii_phy4>;
|
||||
phy-mode = "rgmii-id";
|
||||
reg = <2>;
|
||||
};
|
||||
|
||||
port@3 {
|
||||
phy-mode = "rgmii-id";
|
||||
reg = <3>;
|
||||
};
|
||||
|
||||
port@4 {
|
||||
ethernet = <&enet2>;
|
||||
phy-mode = "rgmii";
|
||||
reg = <4>;
|
||||
|
||||
fixed-link {
|
||||
speed = <1000>;
|
||||
full-duplex;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
|
@ -3,6 +3,7 @@
|
|||
Required properties:
|
||||
|
||||
- compatible: should be one of:
|
||||
"qca,qca8327"
|
||||
"qca,qca8334"
|
||||
"qca,qca8337"
|
||||
|
||||
|
@ -20,6 +21,10 @@ described in dsa/dsa.txt. If the QCA8K switch is connect to a SoC's external
|
|||
mdio-bus each subnode describing a port needs to have a valid phandle
|
||||
referencing the internal PHY it is connected to. This is because there's no
|
||||
N:N mapping of port and PHY id.
|
||||
To declare the internal mdio-bus configuration, declare a mdio node in the
|
||||
switch node and declare the phandle for the port referencing the internal
|
||||
PHY is connected to. In this config a internal mdio-bus is registered and
|
||||
the mdio MASTER is used as communication.
|
||||
|
||||
Don't use mixed external and internal mdio-bus configurations, as this is
|
||||
not supported by the hardware.
|
||||
|
@ -149,26 +154,61 @@ for the internal master mdio-bus configuration:
|
|||
port@1 {
|
||||
reg = <1>;
|
||||
label = "lan1";
|
||||
phy-mode = "internal";
|
||||
phy-handle = <&phy_port1>;
|
||||
};
|
||||
|
||||
port@2 {
|
||||
reg = <2>;
|
||||
label = "lan2";
|
||||
phy-mode = "internal";
|
||||
phy-handle = <&phy_port2>;
|
||||
};
|
||||
|
||||
port@3 {
|
||||
reg = <3>;
|
||||
label = "lan3";
|
||||
phy-mode = "internal";
|
||||
phy-handle = <&phy_port3>;
|
||||
};
|
||||
|
||||
port@4 {
|
||||
reg = <4>;
|
||||
label = "lan4";
|
||||
phy-mode = "internal";
|
||||
phy-handle = <&phy_port4>;
|
||||
};
|
||||
|
||||
port@5 {
|
||||
reg = <5>;
|
||||
label = "wan";
|
||||
phy-mode = "internal";
|
||||
phy-handle = <&phy_port5>;
|
||||
};
|
||||
};
|
||||
|
||||
mdio {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
phy_port1: phy@0 {
|
||||
reg = <0>;
|
||||
};
|
||||
|
||||
phy_port2: phy@1 {
|
||||
reg = <1>;
|
||||
};
|
||||
|
||||
phy_port3: phy@2 {
|
||||
reg = <2>;
|
||||
};
|
||||
|
||||
phy_port4: phy@3 {
|
||||
reg = <3>;
|
||||
};
|
||||
|
||||
phy_port5: phy@4 {
|
||||
reg = <4>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
|
|
@ -1,156 +0,0 @@
|
|||
NXP SJA1105 switch driver
|
||||
=========================
|
||||
|
||||
Required properties:
|
||||
|
||||
- compatible:
|
||||
Must be one of:
|
||||
- "nxp,sja1105e"
|
||||
- "nxp,sja1105t"
|
||||
- "nxp,sja1105p"
|
||||
- "nxp,sja1105q"
|
||||
- "nxp,sja1105r"
|
||||
- "nxp,sja1105s"
|
||||
|
||||
Although the device ID could be detected at runtime, explicit bindings
|
||||
are required in order to be able to statically check their validity.
|
||||
For example, SGMII can only be specified on port 4 of R and S devices,
|
||||
and the non-SGMII devices, while pin-compatible, are not equal in terms
|
||||
of support for RGMII internal delays (supported on P/Q/R/S, but not on
|
||||
E/T).
|
||||
|
||||
Optional properties:
|
||||
|
||||
- sja1105,role-mac:
|
||||
- sja1105,role-phy:
|
||||
Boolean properties that can be assigned under each port node. By
|
||||
default (unless otherwise specified) a port is configured as MAC if it
|
||||
is driving a PHY (phy-handle is present) or as PHY if it is PHY-less
|
||||
(fixed-link specified, presumably because it is connected to a MAC).
|
||||
The effect of this property (in either its implicit or explicit form)
|
||||
is:
|
||||
- In the case of MII or RMII it specifies whether the SJA1105 port is a
|
||||
clock source or sink for this interface (not applicable for RGMII
|
||||
where there is a Tx and an Rx clock).
|
||||
- In the case of RGMII it affects the behavior regarding internal
|
||||
delays:
|
||||
1. If sja1105,role-mac is specified, and the phy-mode property is one
|
||||
of "rgmii-id", "rgmii-txid" or "rgmii-rxid", then the entity
|
||||
designated to apply the delay/clock skew necessary for RGMII
|
||||
is the PHY. The SJA1105 MAC does not apply any internal delays.
|
||||
2. If sja1105,role-phy is specified, and the phy-mode property is one
|
||||
of the above, the designated entity to apply the internal delays
|
||||
is the SJA1105 MAC (if hardware-supported). This is only supported
|
||||
by the second-generation (P/Q/R/S) hardware. On a first-generation
|
||||
E or T device, it is an error to specify an RGMII phy-mode other
|
||||
than "rgmii" for a port that is in fixed-link mode. In that case,
|
||||
the clock skew must either be added by the MAC at the other end of
|
||||
the fixed-link, or by PCB serpentine traces on the board.
|
||||
These properties are required, for example, in the case where SJA1105
|
||||
ports are at both ends of a MII/RMII PHY-less setup. One end would need
|
||||
to have sja1105,role-mac, while the other sja1105,role-phy.
|
||||
|
||||
See Documentation/devicetree/bindings/net/dsa/dsa.txt for the list of standard
|
||||
DSA required and optional properties.
|
||||
|
||||
Other observations
|
||||
------------------
|
||||
|
||||
The SJA1105 SPI interface requires a CS-to-CLK time (t2 in UM10944) of at least
|
||||
one half of t_CLK. At an SPI frequency of 1MHz, this means a minimum
|
||||
cs_sck_delay of 500ns. Ensuring that this SPI timing requirement is observed
|
||||
depends on the SPI bus master driver.
|
||||
|
||||
Example
|
||||
-------
|
||||
|
||||
Ethernet switch connected via SPI to the host, CPU port wired to enet2:
|
||||
|
||||
arch/arm/boot/dts/ls1021a-tsn.dts:
|
||||
|
||||
/* SPI controller of the LS1021 */
|
||||
&dspi0 {
|
||||
sja1105@1 {
|
||||
reg = <0x1>;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
compatible = "nxp,sja1105t";
|
||||
spi-max-frequency = <4000000>;
|
||||
fsl,spi-cs-sck-delay = <1000>;
|
||||
fsl,spi-sck-cs-delay = <1000>;
|
||||
ports {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
port@0 {
|
||||
/* ETH5 written on chassis */
|
||||
label = "swp5";
|
||||
phy-handle = <&rgmii_phy6>;
|
||||
phy-mode = "rgmii-id";
|
||||
reg = <0>;
|
||||
/* Implicit "sja1105,role-mac;" */
|
||||
};
|
||||
port@1 {
|
||||
/* ETH2 written on chassis */
|
||||
label = "swp2";
|
||||
phy-handle = <&rgmii_phy3>;
|
||||
phy-mode = "rgmii-id";
|
||||
reg = <1>;
|
||||
/* Implicit "sja1105,role-mac;" */
|
||||
};
|
||||
port@2 {
|
||||
/* ETH3 written on chassis */
|
||||
label = "swp3";
|
||||
phy-handle = <&rgmii_phy4>;
|
||||
phy-mode = "rgmii-id";
|
||||
reg = <2>;
|
||||
/* Implicit "sja1105,role-mac;" */
|
||||
};
|
||||
port@3 {
|
||||
/* ETH4 written on chassis */
|
||||
phy-handle = <&rgmii_phy5>;
|
||||
label = "swp4";
|
||||
phy-mode = "rgmii-id";
|
||||
reg = <3>;
|
||||
/* Implicit "sja1105,role-mac;" */
|
||||
};
|
||||
port@4 {
|
||||
/* Internal port connected to eth2 */
|
||||
ethernet = <&enet2>;
|
||||
phy-mode = "rgmii";
|
||||
reg = <4>;
|
||||
/* Implicit "sja1105,role-phy;" */
|
||||
fixed-link {
|
||||
speed = <1000>;
|
||||
full-duplex;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
/* MDIO controller of the LS1021 */
|
||||
&mdio0 {
|
||||
/* BCM5464 */
|
||||
rgmii_phy3: ethernet-phy@3 {
|
||||
reg = <0x3>;
|
||||
};
|
||||
rgmii_phy4: ethernet-phy@4 {
|
||||
reg = <0x4>;
|
||||
};
|
||||
rgmii_phy5: ethernet-phy@5 {
|
||||
reg = <0x5>;
|
||||
};
|
||||
rgmii_phy6: ethernet-phy@6 {
|
||||
reg = <0x6>;
|
||||
};
|
||||
};
|
||||
|
||||
/* Ethernet master port of the LS1021 */
|
||||
&enet2 {
|
||||
phy-connection-type = "rgmii";
|
||||
status = "ok";
|
||||
fixed-link {
|
||||
speed = <1000>;
|
||||
full-duplex;
|
||||
};
|
||||
};
|
|
@ -68,6 +68,7 @@ properties:
|
|||
- tbi
|
||||
- rev-mii
|
||||
- rmii
|
||||
- rev-rmii
|
||||
|
||||
# RX and TX delays are added by the MAC when required
|
||||
- rgmii
|
||||
|
@ -97,6 +98,7 @@ properties:
|
|||
- 10gbase-kr
|
||||
- usxgmii
|
||||
- 10gbase-r
|
||||
- 25gbase-r
|
||||
|
||||
phy-mode:
|
||||
$ref: "#/properties/phy-connection-type"
|
||||
|
|
|
@ -0,0 +1,76 @@
|
|||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/net/ingenic,mac.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Bindings for MAC in Ingenic SoCs
|
||||
|
||||
maintainers:
|
||||
- 周琰杰 (Zhou Yanjie) <zhouyanjie@wanyeetech.com>
|
||||
|
||||
description:
|
||||
The Ethernet Media Access Controller in Ingenic SoCs.
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
enum:
|
||||
- ingenic,jz4775-mac
|
||||
- ingenic,x1000-mac
|
||||
- ingenic,x1600-mac
|
||||
- ingenic,x1830-mac
|
||||
- ingenic,x2000-mac
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
interrupts:
|
||||
maxItems: 1
|
||||
|
||||
interrupt-names:
|
||||
const: macirq
|
||||
|
||||
clocks:
|
||||
maxItems: 1
|
||||
|
||||
clock-names:
|
||||
const: stmmaceth
|
||||
|
||||
mode-reg:
|
||||
description: An extra syscon register that control ethernet interface and timing delay
|
||||
|
||||
rx-clk-delay-ps:
|
||||
description: RGMII receive clock delay defined in pico seconds
|
||||
|
||||
tx-clk-delay-ps:
|
||||
description: RGMII transmit clock delay defined in pico seconds
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- interrupts
|
||||
- interrupt-names
|
||||
- clocks
|
||||
- clock-names
|
||||
- mode-reg
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/clock/x1000-cgu.h>
|
||||
|
||||
mac: ethernet@134b0000 {
|
||||
compatible = "ingenic,x1000-mac";
|
||||
reg = <0x134b0000 0x2000>;
|
||||
|
||||
interrupt-parent = <&intc>;
|
||||
interrupts = <55>;
|
||||
interrupt-names = "macirq";
|
||||
|
||||
clocks = <&cgu X1000_CLK_MAC>;
|
||||
clock-names = "stmmaceth";
|
||||
|
||||
mode-reg = <&mac_phy_ctrl>;
|
||||
};
|
||||
...
|
|
@ -0,0 +1,226 @@
|
|||
# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/net/microchip,sparx5-switch.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Microchip Sparx5 Ethernet switch controller
|
||||
|
||||
maintainers:
|
||||
- Steen Hegelund <steen.hegelund@microchip.com>
|
||||
- Lars Povlsen <lars.povlsen@microchip.com>
|
||||
|
||||
description: |
|
||||
The SparX-5 Enterprise Ethernet switch family provides a rich set of
|
||||
Enterprise switching features such as advanced TCAM-based VLAN and
|
||||
QoS processing enabling delivery of differentiated services, and
|
||||
security through TCAM-based frame processing using versatile content
|
||||
aware processor (VCAP).
|
||||
|
||||
IPv4/IPv6 Layer 3 (L3) unicast and multicast routing is supported
|
||||
with up to 18K IPv4/9K IPv6 unicast LPM entries and up to 9K IPv4/3K
|
||||
IPv6 (S,G) multicast groups.
|
||||
|
||||
L3 security features include source guard and reverse path
|
||||
forwarding (uRPF) tasks. Additional L3 features include VRF-Lite and
|
||||
IP tunnels (IP over GRE/IP).
|
||||
|
||||
The SparX-5 switch family targets managed Layer 2 and Layer 3
|
||||
equipment in SMB, SME, and Enterprise where high port count
|
||||
1G/2.5G/5G/10G switching with 10G/25G aggregation links is required.
|
||||
|
||||
properties:
|
||||
$nodename:
|
||||
pattern: "^switch@[0-9a-f]+$"
|
||||
|
||||
compatible:
|
||||
const: microchip,sparx5-switch
|
||||
|
||||
reg:
|
||||
items:
|
||||
- description: cpu target
|
||||
- description: devices target
|
||||
- description: general control block target
|
||||
|
||||
reg-names:
|
||||
items:
|
||||
- const: cpu
|
||||
- const: devices
|
||||
- const: gcb
|
||||
|
||||
interrupts:
|
||||
minItems: 1
|
||||
items:
|
||||
- description: register based extraction
|
||||
- description: frame dma based extraction
|
||||
|
||||
interrupt-names:
|
||||
minItems: 1
|
||||
items:
|
||||
- const: xtr
|
||||
- const: fdma
|
||||
|
||||
resets:
|
||||
items:
|
||||
- description: Reset controller used for switch core reset (soft reset)
|
||||
|
||||
reset-names:
|
||||
items:
|
||||
- const: switch
|
||||
|
||||
mac-address: true
|
||||
|
||||
ethernet-ports:
|
||||
type: object
|
||||
patternProperties:
|
||||
"^port@[0-9a-f]+$":
|
||||
type: object
|
||||
|
||||
properties:
|
||||
'#address-cells':
|
||||
const: 1
|
||||
'#size-cells':
|
||||
const: 0
|
||||
|
||||
reg:
|
||||
description: Switch port number
|
||||
|
||||
phys:
|
||||
maxItems: 1
|
||||
description:
|
||||
phandle of a Ethernet SerDes PHY. This defines which SerDes
|
||||
instance will handle the Ethernet traffic.
|
||||
|
||||
phy-mode:
|
||||
description:
|
||||
This specifies the interface used by the Ethernet SerDes towards
|
||||
the PHY or SFP.
|
||||
|
||||
microchip,bandwidth:
|
||||
description: Specifies bandwidth in Mbit/s allocated to the port.
|
||||
$ref: "/schemas/types.yaml#/definitions/uint32"
|
||||
maximum: 25000
|
||||
|
||||
phy-handle:
|
||||
description:
|
||||
phandle of a Ethernet PHY. This is optional and if provided it
|
||||
points to the cuPHY used by the Ethernet SerDes.
|
||||
|
||||
sfp:
|
||||
description:
|
||||
phandle of an SFP. This is optional and used when not specifying
|
||||
a cuPHY. It points to the SFP node that describes the SFP used by
|
||||
the Ethernet SerDes.
|
||||
|
||||
managed: true
|
||||
|
||||
microchip,sd-sgpio:
|
||||
description:
|
||||
Index of the ports Signal Detect SGPIO in the set of 384 SGPIOs
|
||||
This is optional, and only needed if the default used index is
|
||||
is not correct.
|
||||
$ref: "/schemas/types.yaml#/definitions/uint32"
|
||||
minimum: 0
|
||||
maximum: 383
|
||||
|
||||
required:
|
||||
- reg
|
||||
- phys
|
||||
- phy-mode
|
||||
- microchip,bandwidth
|
||||
|
||||
oneOf:
|
||||
- required:
|
||||
- phy-handle
|
||||
- required:
|
||||
- sfp
|
||||
- managed
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- reg-names
|
||||
- interrupts
|
||||
- interrupt-names
|
||||
- resets
|
||||
- reset-names
|
||||
- ethernet-ports
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/interrupt-controller/arm-gic.h>
|
||||
switch: switch@600000000 {
|
||||
compatible = "microchip,sparx5-switch";
|
||||
reg = <0 0x401000>,
|
||||
<0x10004000 0x7fc000>,
|
||||
<0x11010000 0xaf0000>;
|
||||
reg-names = "cpu", "devices", "gcb";
|
||||
interrupts = <GIC_SPI 30 IRQ_TYPE_LEVEL_HIGH>;
|
||||
interrupt-names = "xtr";
|
||||
resets = <&reset 0>;
|
||||
reset-names = "switch";
|
||||
ethernet-ports {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
port0: port@0 {
|
||||
reg = <0>;
|
||||
microchip,bandwidth = <1000>;
|
||||
phys = <&serdes 13>;
|
||||
phy-handle = <&phy0>;
|
||||
phy-mode = "qsgmii";
|
||||
};
|
||||
/* ... */
|
||||
/* Then the 25G interfaces */
|
||||
port60: port@60 {
|
||||
reg = <60>;
|
||||
microchip,bandwidth = <25000>;
|
||||
phys = <&serdes 29>;
|
||||
phy-mode = "10gbase-r";
|
||||
sfp = <&sfp_eth60>;
|
||||
managed = "in-band-status";
|
||||
microchip,sd-sgpio = <365>;
|
||||
};
|
||||
port61: port@61 {
|
||||
reg = <61>;
|
||||
microchip,bandwidth = <25000>;
|
||||
phys = <&serdes 30>;
|
||||
phy-mode = "10gbase-r";
|
||||
sfp = <&sfp_eth61>;
|
||||
managed = "in-band-status";
|
||||
microchip,sd-sgpio = <369>;
|
||||
};
|
||||
port62: port@62 {
|
||||
reg = <62>;
|
||||
microchip,bandwidth = <25000>;
|
||||
phys = <&serdes 31>;
|
||||
phy-mode = "10gbase-r";
|
||||
sfp = <&sfp_eth62>;
|
||||
managed = "in-band-status";
|
||||
microchip,sd-sgpio = <373>;
|
||||
};
|
||||
port63: port@63 {
|
||||
reg = <63>;
|
||||
microchip,bandwidth = <25000>;
|
||||
phys = <&serdes 32>;
|
||||
phy-mode = "10gbase-r";
|
||||
sfp = <&sfp_eth63>;
|
||||
managed = "in-band-status";
|
||||
microchip,sd-sgpio = <377>;
|
||||
};
|
||||
/* Finally the Management interface */
|
||||
port64: port@64 {
|
||||
reg = <64>;
|
||||
microchip,bandwidth = <1000>;
|
||||
phys = <&serdes 0>;
|
||||
phy-handle = <&phy64>;
|
||||
phy-mode = "sgmii";
|
||||
mac-address = [ 00 00 00 01 02 03 ];
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
...
|
||||
# vim: set ts=2 sw=2 sts=2 tw=80 et cc=80 ft=yaml :
|
|
@ -27,6 +27,9 @@ properties:
|
|||
reg:
|
||||
maxItems: 1
|
||||
|
||||
clocks:
|
||||
maxItems: 1
|
||||
|
||||
wake-gpios:
|
||||
maxItems: 1
|
||||
description:
|
||||
|
@ -80,6 +83,8 @@ examples:
|
|||
|
||||
en-gpios = <&gpf1 4 GPIO_ACTIVE_HIGH>;
|
||||
wake-gpios = <&gpj0 2 GPIO_ACTIVE_HIGH>;
|
||||
|
||||
clocks = <&rpmcc 20>;
|
||||
};
|
||||
};
|
||||
# UART example on Raspberry Pi
|
||||
|
|
|
@ -44,6 +44,7 @@ description:
|
|||
properties:
|
||||
compatible:
|
||||
enum:
|
||||
- qcom,msm8998-ipa
|
||||
- qcom,sc7180-ipa
|
||||
- qcom,sc7280-ipa
|
||||
- qcom,sdm845-ipa
|
||||
|
|
|
@ -1,69 +0,0 @@
|
|||
Qualcomm Bluetooth Chips
|
||||
---------------------
|
||||
|
||||
This documents the binding structure and common properties for serial
|
||||
attached Qualcomm devices.
|
||||
|
||||
Serial attached Qualcomm devices shall be a child node of the host UART
|
||||
device the slave device is attached to.
|
||||
|
||||
Required properties:
|
||||
- compatible: should contain one of the following:
|
||||
* "qcom,qca6174-bt"
|
||||
* "qcom,qca9377-bt"
|
||||
* "qcom,wcn3990-bt"
|
||||
* "qcom,wcn3991-bt"
|
||||
* "qcom,wcn3998-bt"
|
||||
* "qcom,qca6390-bt"
|
||||
|
||||
Optional properties for compatible string qcom,qca6174-bt:
|
||||
|
||||
- enable-gpios: gpio specifier used to enable chip
|
||||
- clocks: clock provided to the controller (SUSCLK_32KHZ)
|
||||
- firmware-name: specify the name of nvm firmware to load
|
||||
|
||||
Optional properties for compatible string qcom,qca9377-bt:
|
||||
|
||||
- max-speed: see Documentation/devicetree/bindings/serial/serial.yaml
|
||||
|
||||
Required properties for compatible string qcom,wcn399x-bt:
|
||||
|
||||
- vddio-supply: VDD_IO supply regulator handle.
|
||||
- vddxo-supply: VDD_XO supply regulator handle.
|
||||
- vddrf-supply: VDD_RF supply regulator handle.
|
||||
- vddch0-supply: VDD_CH0 supply regulator handle.
|
||||
|
||||
Optional properties for compatible string qcom,wcn399x-bt:
|
||||
|
||||
- max-speed: see Documentation/devicetree/bindings/serial/serial.yaml
|
||||
- firmware-name: specify the name of nvm firmware to load
|
||||
- clocks: clock provided to the controller
|
||||
|
||||
Examples:
|
||||
|
||||
serial@7570000 {
|
||||
label = "BT-UART";
|
||||
status = "okay";
|
||||
|
||||
bluetooth {
|
||||
compatible = "qcom,qca6174-bt";
|
||||
|
||||
enable-gpios = <&pm8994_gpios 19 GPIO_ACTIVE_HIGH>;
|
||||
clocks = <&divclk4>;
|
||||
firmware-name = "nvm_00440302.bin";
|
||||
};
|
||||
};
|
||||
|
||||
serial@898000 {
|
||||
bluetooth {
|
||||
compatible = "qcom,wcn3990-bt";
|
||||
|
||||
vddio-supply = <&vreg_s4a_1p8>;
|
||||
vddxo-supply = <&vreg_l7a_1p8>;
|
||||
vddrf-supply = <&vreg_l17a_1p3>;
|
||||
vddch0-supply = <&vreg_l25a_3p3>;
|
||||
max-speed = <3200000>;
|
||||
firmware-name = "crnv21.bin";
|
||||
clocks = <&rpmhcc RPMH_RF_CLK2>;
|
||||
};
|
||||
};
|
|
@ -0,0 +1,183 @@
|
|||
# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/net/qualcomm-bluetooth.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Qualcomm Bluetooth Chips
|
||||
|
||||
maintainers:
|
||||
- Balakrishna Godavarthi <bgodavar@codeaurora.org>
|
||||
- Rocky Liao <rjliao@codeaurora.org>
|
||||
|
||||
description:
|
||||
This binding describes Qualcomm UART-attached bluetooth chips.
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
enum:
|
||||
- qcom,qca6174-bt
|
||||
- qcom,qca9377-bt
|
||||
- qcom,wcn3990-bt
|
||||
- qcom,wcn3991-bt
|
||||
- qcom,wcn3998-bt
|
||||
- qcom,qca6390-bt
|
||||
- qcom,wcn6750-bt
|
||||
|
||||
enable-gpios:
|
||||
maxItems: 1
|
||||
description: gpio specifier used to enable chip
|
||||
|
||||
swctrl-gpios:
|
||||
maxItems: 1
|
||||
description: gpio specifier is used to find status
|
||||
of clock supply to SoC
|
||||
|
||||
clocks:
|
||||
maxItems: 1
|
||||
description: clock provided to the controller (SUSCLK_32KHZ)
|
||||
|
||||
vddio-supply:
|
||||
description: VDD_IO supply regulator handle
|
||||
|
||||
vddxo-supply:
|
||||
description: VDD_XO supply regulator handle
|
||||
|
||||
vddrf-supply:
|
||||
description: VDD_RF supply regulator handle
|
||||
|
||||
vddch0-supply:
|
||||
description: VDD_CH0 supply regulator handle
|
||||
|
||||
vddaon-supply:
|
||||
description: VDD_AON supply regulator handle
|
||||
|
||||
vddbtcxmx-supply:
|
||||
description: VDD_BT_CXMX supply regulator handle
|
||||
|
||||
vddrfacmn-supply:
|
||||
description: VDD_RFA_CMN supply regulator handle
|
||||
|
||||
vddrfa0p8-supply:
|
||||
description: VDD_RFA_0P8 suppply regulator handle
|
||||
|
||||
vddrfa1p7-supply:
|
||||
description: VDD_RFA_1P7 supply regulator handle
|
||||
|
||||
vddrfa1p2-supply:
|
||||
description: VDD_RFA_1P2 supply regulator handle
|
||||
|
||||
vddrfa2p2-supply:
|
||||
description: VDD_RFA_2P2 supply regulator handle
|
||||
|
||||
vddasd-supply:
|
||||
description: VDD_ASD supply regulator handle
|
||||
|
||||
max-speed:
|
||||
description: see Documentation/devicetree/bindings/serial/serial.yaml
|
||||
|
||||
firmware-name:
|
||||
description: specify the name of nvm firmware to load
|
||||
|
||||
local-bd-address:
|
||||
description: see Documentation/devicetree/bindings/net/bluetooth.txt
|
||||
|
||||
|
||||
required:
|
||||
- compatible
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
allOf:
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
enum:
|
||||
- qcom,qca6174-bt
|
||||
then:
|
||||
required:
|
||||
- enable-gpios
|
||||
- clocks
|
||||
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
enum:
|
||||
- qcom,wcn3990-bt
|
||||
- qcom,wcn3991-bt
|
||||
- qcom,wcn3998-bt
|
||||
then:
|
||||
required:
|
||||
- vddio-supply
|
||||
- vddxo-supply
|
||||
- vddrf-supply
|
||||
- vddch0-supply
|
||||
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
enum:
|
||||
- qcom,wcn6750-bt
|
||||
then:
|
||||
required:
|
||||
- enable-gpios
|
||||
- swctrl-gpios
|
||||
- vddio-supply
|
||||
- vddaon-supply
|
||||
- vddbtcxmx-supply
|
||||
- vddrfacmn-supply
|
||||
- vddrfa0p8-supply
|
||||
- vddrfa1p7-supply
|
||||
- vddrfa1p2-supply
|
||||
- vddasd-supply
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/gpio/gpio.h>
|
||||
serial {
|
||||
|
||||
bluetooth {
|
||||
compatible = "qcom,qca6174-bt";
|
||||
enable-gpios = <&pm8994_gpios 19 GPIO_ACTIVE_HIGH>;
|
||||
clocks = <&divclk4>;
|
||||
firmware-name = "nvm_00440302.bin";
|
||||
};
|
||||
};
|
||||
- |
|
||||
serial {
|
||||
|
||||
bluetooth {
|
||||
compatible = "qcom,wcn3990-bt";
|
||||
vddio-supply = <&vreg_s4a_1p8>;
|
||||
vddxo-supply = <&vreg_l7a_1p8>;
|
||||
vddrf-supply = <&vreg_l17a_1p3>;
|
||||
vddch0-supply = <&vreg_l25a_3p3>;
|
||||
max-speed = <3200000>;
|
||||
firmware-name = "crnv21.bin";
|
||||
};
|
||||
};
|
||||
- |
|
||||
serial {
|
||||
|
||||
bluetooth {
|
||||
compatible = "qcom,wcn6750-bt";
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&bt_en_default>;
|
||||
enable-gpios = <&tlmm 85 GPIO_ACTIVE_HIGH>;
|
||||
swctrl-gpios = <&tlmm 86 GPIO_ACTIVE_HIGH>;
|
||||
vddio-supply = <&vreg_l19b_1p8>;
|
||||
vddaon-supply = <&vreg_s7b_0p9>;
|
||||
vddbtcxmx-supply = <&vreg_s7b_0p9>;
|
||||
vddrfacmn-supply = <&vreg_s7b_0p9>;
|
||||
vddrfa0p8-supply = <&vreg_s7b_0p9>;
|
||||
vddrfa1p7-supply = <&vreg_s1b_1p8>;
|
||||
vddrfa1p2-supply = <&vreg_s8b_1p2>;
|
||||
vddrfa2p2-supply = <&vreg_s1c_2p2>;
|
||||
vddasd-supply = <&vreg_l11c_2p8>;
|
||||
max-speed = <3200000>;
|
||||
firmware-name = "msnv11.bin";
|
||||
};
|
||||
};
|
|
@ -0,0 +1,45 @@
|
|||
# SPDX-License-Identifier: GPL-2.0+
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/net/realtek,rtl82xx.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Realtek RTL82xx PHY
|
||||
|
||||
maintainers:
|
||||
- Andrew Lunn <andrew@lunn.ch>
|
||||
- Florian Fainelli <f.fainelli@gmail.com>
|
||||
- Heiner Kallweit <hkallweit1@gmail.com>
|
||||
|
||||
description:
|
||||
Bindings for Realtek RTL82xx PHYs
|
||||
|
||||
allOf:
|
||||
- $ref: ethernet-phy.yaml#
|
||||
|
||||
properties:
|
||||
realtek,clkout-disable:
|
||||
type: boolean
|
||||
description:
|
||||
Disable CLKOUT clock, CLKOUT clock default is enabled after hardware reset.
|
||||
|
||||
|
||||
realtek,aldps-enable:
|
||||
type: boolean
|
||||
description:
|
||||
Enable ALDPS mode, ALDPS mode default is disabled after hardware reset.
|
||||
|
||||
unevaluatedProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
mdio {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
ethphy1: ethernet-phy@1 {
|
||||
reg = <1>;
|
||||
realtek,clkout-disable;
|
||||
realtek,aldps-enable;
|
||||
};
|
||||
};
|
|
@ -19,10 +19,12 @@ select:
|
|||
- rockchip,rk3128-gmac
|
||||
- rockchip,rk3228-gmac
|
||||
- rockchip,rk3288-gmac
|
||||
- rockchip,rk3308-gmac
|
||||
- rockchip,rk3328-gmac
|
||||
- rockchip,rk3366-gmac
|
||||
- rockchip,rk3368-gmac
|
||||
- rockchip,rk3399-gmac
|
||||
- rockchip,rk3568-gmac
|
||||
- rockchip,rv1108-gmac
|
||||
required:
|
||||
- compatible
|
||||
|
@ -32,17 +34,23 @@ allOf:
|
|||
|
||||
properties:
|
||||
compatible:
|
||||
items:
|
||||
- enum:
|
||||
- rockchip,px30-gmac
|
||||
- rockchip,rk3128-gmac
|
||||
- rockchip,rk3228-gmac
|
||||
- rockchip,rk3288-gmac
|
||||
- rockchip,rk3328-gmac
|
||||
- rockchip,rk3366-gmac
|
||||
- rockchip,rk3368-gmac
|
||||
- rockchip,rk3399-gmac
|
||||
- rockchip,rv1108-gmac
|
||||
oneOf:
|
||||
- items:
|
||||
- enum:
|
||||
- rockchip,px30-gmac
|
||||
- rockchip,rk3128-gmac
|
||||
- rockchip,rk3228-gmac
|
||||
- rockchip,rk3288-gmac
|
||||
- rockchip,rk3308-gmac
|
||||
- rockchip,rk3328-gmac
|
||||
- rockchip,rk3366-gmac
|
||||
- rockchip,rk3368-gmac
|
||||
- rockchip,rk3399-gmac
|
||||
- rockchip,rv1108-gmac
|
||||
- items:
|
||||
- enum:
|
||||
- rockchip,rk3568-gmac
|
||||
- const: snps,dwmac-4.20a
|
||||
|
||||
clocks:
|
||||
minItems: 5
|
||||
|
|
|
@ -51,11 +51,20 @@ properties:
|
|||
- allwinner,sun8i-r40-emac
|
||||
- allwinner,sun8i-v3s-emac
|
||||
- allwinner,sun50i-a64-emac
|
||||
- loongson,ls2k-dwmac
|
||||
- loongson,ls7a-dwmac
|
||||
- amlogic,meson6-dwmac
|
||||
- amlogic,meson8b-dwmac
|
||||
- amlogic,meson8m2-dwmac
|
||||
- amlogic,meson-gxbb-dwmac
|
||||
- amlogic,meson-axg-dwmac
|
||||
- loongson,ls2k-dwmac
|
||||
- loongson,ls7a-dwmac
|
||||
- ingenic,jz4775-mac
|
||||
- ingenic,x1000-mac
|
||||
- ingenic,x1600-mac
|
||||
- ingenic,x1830-mac
|
||||
- ingenic,x2000-mac
|
||||
- rockchip,px30-gmac
|
||||
- rockchip,rk3128-gmac
|
||||
- rockchip,rk3228-gmac
|
||||
|
@ -310,6 +319,11 @@ allOf:
|
|||
- allwinner,sun8i-r40-emac
|
||||
- allwinner,sun8i-v3s-emac
|
||||
- allwinner,sun50i-a64-emac
|
||||
- ingenic,jz4775-mac
|
||||
- ingenic,x1000-mac
|
||||
- ingenic,x1600-mac
|
||||
- ingenic,x1830-mac
|
||||
- ingenic,x2000-mac
|
||||
- snps,dwxgmac
|
||||
- snps,dwxgmac-2.10
|
||||
- st,spear600-gmac
|
||||
|
@ -353,6 +367,13 @@ allOf:
|
|||
- allwinner,sun8i-r40-emac
|
||||
- allwinner,sun8i-v3s-emac
|
||||
- allwinner,sun50i-a64-emac
|
||||
- loongson,ls2k-dwmac
|
||||
- loongson,ls7a-dwmac
|
||||
- ingenic,jz4775-mac
|
||||
- ingenic,x1000-mac
|
||||
- ingenic,x1600-mac
|
||||
- ingenic,x1830-mac
|
||||
- ingenic,x2000-mac
|
||||
- snps,dwmac-4.00
|
||||
- snps,dwmac-4.10a
|
||||
- snps,dwmac-4.20a
|
||||
|
|
|
@ -0,0 +1,199 @@
|
|||
.. SPDX-License-Identifier: GPL-2.0
|
||||
|
||||
=========================
|
||||
MDIO bus and PHYs in ACPI
|
||||
=========================
|
||||
|
||||
The PHYs on an MDIO bus [1] are probed and registered using
|
||||
fwnode_mdiobus_register_phy().
|
||||
|
||||
Later, for connecting these PHYs to their respective MACs, the PHYs registered
|
||||
on the MDIO bus have to be referenced.
|
||||
|
||||
This document introduces two _DSD properties that are to be used
|
||||
for connecting PHYs on the MDIO bus [3] to the MAC layer.
|
||||
|
||||
These properties are defined in accordance with the "Device
|
||||
Properties UUID For _DSD" [2] document and the
|
||||
daffd814-6eba-4d8c-8a91-bc9bbf4aa301 UUID must be used in the Device
|
||||
Data Descriptors containing them.
|
||||
|
||||
phy-handle
|
||||
----------
|
||||
For each MAC node, a device property "phy-handle" is used to reference
|
||||
the PHY that is registered on an MDIO bus. This is mandatory for
|
||||
network interfaces that have PHYs connected to MAC via MDIO bus.
|
||||
|
||||
During the MDIO bus driver initialization, PHYs on this bus are probed
|
||||
using the _ADR object as shown below and are registered on the MDIO bus.
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
Scope(\_SB.MDI0)
|
||||
{
|
||||
Device(PHY1) {
|
||||
Name (_ADR, 0x1)
|
||||
} // end of PHY1
|
||||
|
||||
Device(PHY2) {
|
||||
Name (_ADR, 0x2)
|
||||
} // end of PHY2
|
||||
}
|
||||
|
||||
Later, during the MAC driver initialization, the registered PHY devices
|
||||
have to be retrieved from the MDIO bus. For this, the MAC driver needs
|
||||
references to the previously registered PHYs which are provided
|
||||
as device object references (e.g. \_SB.MDI0.PHY1).
|
||||
|
||||
phy-mode
|
||||
--------
|
||||
The "phy-mode" _DSD property is used to describe the connection to
|
||||
the PHY. The valid values for "phy-mode" are defined in [4].
|
||||
|
||||
managed
|
||||
-------
|
||||
Optional property, which specifies the PHY management type.
|
||||
The valid values for "managed" are defined in [4].
|
||||
|
||||
fixed-link
|
||||
----------
|
||||
The "fixed-link" is described by a data-only subnode of the
|
||||
MAC port, which is linked in the _DSD package via
|
||||
hierarchical data extension (UUID dbb8e3e6-5886-4ba6-8795-1319f52a966b
|
||||
in accordance with [5] "_DSD Implementation Guide" document).
|
||||
The subnode should comprise a required property ("speed") and
|
||||
possibly the optional ones - complete list of parameters and
|
||||
their values are specified in [4].
|
||||
|
||||
The following ASL example illustrates the usage of these properties.
|
||||
|
||||
DSDT entry for MDIO node
|
||||
------------------------
|
||||
|
||||
The MDIO bus has an SoC component (MDIO controller) and a platform
|
||||
component (PHYs on the MDIO bus).
|
||||
|
||||
a) Silicon Component
|
||||
This node describes the MDIO controller, MDI0
|
||||
---------------------------------------------
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
Scope(_SB)
|
||||
{
|
||||
Device(MDI0) {
|
||||
Name(_HID, "NXP0006")
|
||||
Name(_CCA, 1)
|
||||
Name(_UID, 0)
|
||||
Name(_CRS, ResourceTemplate() {
|
||||
Memory32Fixed(ReadWrite, MDI0_BASE, MDI_LEN)
|
||||
Interrupt(ResourceConsumer, Level, ActiveHigh, Shared)
|
||||
{
|
||||
MDI0_IT
|
||||
}
|
||||
}) // end of _CRS for MDI0
|
||||
} // end of MDI0
|
||||
}
|
||||
|
||||
b) Platform Component
|
||||
The PHY1 and PHY2 nodes represent the PHYs connected to MDIO bus MDI0
|
||||
---------------------------------------------------------------------
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
Scope(\_SB.MDI0)
|
||||
{
|
||||
Device(PHY1) {
|
||||
Name (_ADR, 0x1)
|
||||
} // end of PHY1
|
||||
|
||||
Device(PHY2) {
|
||||
Name (_ADR, 0x2)
|
||||
} // end of PHY2
|
||||
}
|
||||
|
||||
DSDT entries representing MAC nodes
|
||||
-----------------------------------
|
||||
|
||||
Below are the MAC nodes where PHY nodes are referenced.
|
||||
phy-mode and phy-handle are used as explained earlier.
|
||||
------------------------------------------------------
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
Scope(\_SB.MCE0.PR17)
|
||||
{
|
||||
Name (_DSD, Package () {
|
||||
ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
|
||||
Package () {
|
||||
Package (2) {"phy-mode", "rgmii-id"},
|
||||
Package (2) {"phy-handle", \_SB.MDI0.PHY1}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
Scope(\_SB.MCE0.PR18)
|
||||
{
|
||||
Name (_DSD, Package () {
|
||||
ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
|
||||
Package () {
|
||||
Package (2) {"phy-mode", "rgmii-id"},
|
||||
Package (2) {"phy-handle", \_SB.MDI0.PHY2}}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
MAC node example where "managed" property is specified.
|
||||
-------------------------------------------------------
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
Scope(\_SB.PP21.ETH0)
|
||||
{
|
||||
Name (_DSD, Package () {
|
||||
ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
|
||||
Package () {
|
||||
Package () {"phy-mode", "sgmii"},
|
||||
Package () {"managed", "in-band-status"}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
MAC node example with a "fixed-link" subnode.
|
||||
---------------------------------------------
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
Scope(\_SB.PP21.ETH1)
|
||||
{
|
||||
Name (_DSD, Package () {
|
||||
ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
|
||||
Package () {
|
||||
Package () {"phy-mode", "sgmii"},
|
||||
},
|
||||
ToUUID("dbb8e3e6-5886-4ba6-8795-1319f52a966b"),
|
||||
Package () {
|
||||
Package () {"fixed-link", "LNK0"}
|
||||
}
|
||||
})
|
||||
Name (LNK0, Package(){ // Data-only subnode of port
|
||||
ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
|
||||
Package () {
|
||||
Package () {"speed", 1000},
|
||||
Package () {"full-duplex", 1}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
References
|
||||
==========
|
||||
|
||||
[1] Documentation/networking/phy.rst
|
||||
|
||||
[2] https://www.uefi.org/sites/default/files/resources/_DSD-device-properties-UUID.pdf
|
||||
|
||||
[3] Documentation/firmware-guide/acpi/DSD-properties-rules.rst
|
||||
|
||||
[4] Documentation/devicetree/bindings/net/ethernet-controller.yaml
|
||||
|
||||
[5] https://github.com/UEFI/DSD-Guide/blob/main/dsd-guide.pdf
|
|
@ -11,6 +11,7 @@ ACPI Support
|
|||
dsd/graph
|
||||
dsd/data-node-references
|
||||
dsd/leds
|
||||
dsd/phy
|
||||
enumeration
|
||||
osi
|
||||
method-customizing
|
||||
|
|
|
@ -290,19 +290,19 @@ round-robin example of distributing packets is shown below:
|
|||
#define MAX_SOCKS 16
|
||||
|
||||
struct {
|
||||
__uint(type, BPF_MAP_TYPE_XSKMAP);
|
||||
__uint(max_entries, MAX_SOCKS);
|
||||
__uint(key_size, sizeof(int));
|
||||
__uint(value_size, sizeof(int));
|
||||
__uint(type, BPF_MAP_TYPE_XSKMAP);
|
||||
__uint(max_entries, MAX_SOCKS);
|
||||
__uint(key_size, sizeof(int));
|
||||
__uint(value_size, sizeof(int));
|
||||
} xsks_map SEC(".maps");
|
||||
|
||||
static unsigned int rr;
|
||||
|
||||
SEC("xdp_sock") int xdp_sock_prog(struct xdp_md *ctx)
|
||||
{
|
||||
rr = (rr + 1) & (MAX_SOCKS - 1);
|
||||
rr = (rr + 1) & (MAX_SOCKS - 1);
|
||||
|
||||
return bpf_redirect_map(&xsks_map, rr, XDP_DROP);
|
||||
return bpf_redirect_map(&xsks_map, rr, XDP_DROP);
|
||||
}
|
||||
|
||||
Note, that since there is only a single set of FILL and COMPLETION
|
||||
|
@ -379,7 +379,7 @@ would look like this for the TX path:
|
|||
.. code-block:: c
|
||||
|
||||
if (xsk_ring_prod__needs_wakeup(&my_tx_ring))
|
||||
sendto(xsk_socket__fd(xsk_handle), NULL, 0, MSG_DONTWAIT, NULL, 0);
|
||||
sendto(xsk_socket__fd(xsk_handle), NULL, 0, MSG_DONTWAIT, NULL, 0);
|
||||
|
||||
I.e., only use the syscall if the flag is set.
|
||||
|
||||
|
@ -442,9 +442,9 @@ purposes. The supported statistics are shown below:
|
|||
.. code-block:: c
|
||||
|
||||
struct xdp_statistics {
|
||||
__u64 rx_dropped; /* Dropped for reasons other than invalid desc */
|
||||
__u64 rx_invalid_descs; /* Dropped due to invalid descriptor */
|
||||
__u64 tx_invalid_descs; /* Dropped due to invalid descriptor */
|
||||
__u64 rx_dropped; /* Dropped for reasons other than invalid desc */
|
||||
__u64 rx_invalid_descs; /* Dropped due to invalid descriptor */
|
||||
__u64 tx_invalid_descs; /* Dropped due to invalid descriptor */
|
||||
};
|
||||
|
||||
XDP_OPTIONS getsockopt
|
||||
|
@ -483,15 +483,15 @@ like this:
|
|||
.. code-block:: c
|
||||
|
||||
// struct xdp_rxtx_ring {
|
||||
// __u32 *producer;
|
||||
// __u32 *consumer;
|
||||
// struct xdp_desc *desc;
|
||||
// __u32 *producer;
|
||||
// __u32 *consumer;
|
||||
// struct xdp_desc *desc;
|
||||
// };
|
||||
|
||||
// struct xdp_umem_ring {
|
||||
// __u32 *producer;
|
||||
// __u32 *consumer;
|
||||
// __u64 *desc;
|
||||
// __u32 *producer;
|
||||
// __u32 *consumer;
|
||||
// __u64 *desc;
|
||||
// };
|
||||
|
||||
// typedef struct xdp_rxtx_ring RING;
|
||||
|
|
|
@ -27,34 +27,136 @@ these MAP frames and send them to appropriate PDN's.
|
|||
2. Packet format
|
||||
================
|
||||
|
||||
a. MAP packet (data / control)
|
||||
a. MAP packet v1 (data / control)
|
||||
|
||||
MAP header has the same endianness of the IP packet.
|
||||
MAP header fields are in big endian format.
|
||||
|
||||
Packet format::
|
||||
|
||||
Bit 0 1 2-7 8 - 15 16 - 31
|
||||
Bit 0 1 2-7 8-15 16-31
|
||||
Function Command / Data Reserved Pad Multiplexer ID Payload length
|
||||
Bit 32 - x
|
||||
Function Raw Bytes
|
||||
|
||||
Bit 32-x
|
||||
Function Raw bytes
|
||||
|
||||
Command (1)/ Data (0) bit value is to indicate if the packet is a MAP command
|
||||
or data packet. Control packet is used for transport level flow control. Data
|
||||
or data packet. Command packet is used for transport level flow control. Data
|
||||
packets are standard IP packets.
|
||||
|
||||
Reserved bits are usually zeroed out and to be ignored by receiver.
|
||||
Reserved bits must be zero when sent and ignored when received.
|
||||
|
||||
Padding is number of bytes to be added for 4 byte alignment if required by
|
||||
hardware.
|
||||
Padding is the number of bytes to be appended to the payload to
|
||||
ensure 4 byte alignment.
|
||||
|
||||
Multiplexer ID is to indicate the PDN on which data has to be sent.
|
||||
|
||||
Payload length includes the padding length but does not include MAP header
|
||||
length.
|
||||
|
||||
b. MAP packet (command specific)::
|
||||
b. Map packet v4 (data / control)
|
||||
|
||||
Bit 0 1 2-7 8 - 15 16 - 31
|
||||
MAP header fields are in big endian format.
|
||||
|
||||
Packet format::
|
||||
|
||||
Bit 0 1 2-7 8-15 16-31
|
||||
Function Command / Data Reserved Pad Multiplexer ID Payload length
|
||||
|
||||
Bit 32-(x-33) (x-32)-x
|
||||
Function Raw bytes Checksum offload header
|
||||
|
||||
Command (1)/ Data (0) bit value is to indicate if the packet is a MAP command
|
||||
or data packet. Command packet is used for transport level flow control. Data
|
||||
packets are standard IP packets.
|
||||
|
||||
Reserved bits must be zero when sent and ignored when received.
|
||||
|
||||
Padding is the number of bytes to be appended to the payload to
|
||||
ensure 4 byte alignment.
|
||||
|
||||
Multiplexer ID is to indicate the PDN on which data has to be sent.
|
||||
|
||||
Payload length includes the padding length but does not include MAP header
|
||||
length.
|
||||
|
||||
Checksum offload header, has the information about the checksum processing done
|
||||
by the hardware.Checksum offload header fields are in big endian format.
|
||||
|
||||
Packet format::
|
||||
|
||||
Bit 0-14 15 16-31
|
||||
Function Reserved Valid Checksum start offset
|
||||
|
||||
Bit 31-47 48-64
|
||||
Function Checksum length Checksum value
|
||||
|
||||
Reserved bits must be zero when sent and ignored when received.
|
||||
|
||||
Valid bit indicates whether the partial checksum is calculated and is valid.
|
||||
Set to 1, if its is valid. Set to 0 otherwise.
|
||||
|
||||
Padding is the number of bytes to be appended to the payload to
|
||||
ensure 4 byte alignment.
|
||||
|
||||
Checksum start offset, Indicates the offset in bytes from the beginning of the
|
||||
IP header, from which modem computed checksum.
|
||||
|
||||
Checksum length is the Length in bytes starting from CKSUM_START_OFFSET,
|
||||
over which checksum is computed.
|
||||
|
||||
Checksum value, indicates the checksum computed.
|
||||
|
||||
c. MAP packet v5 (data / control)
|
||||
|
||||
MAP header fields are in big endian format.
|
||||
|
||||
Packet format::
|
||||
|
||||
Bit 0 1 2-7 8-15 16-31
|
||||
Function Command / Data Next header Pad Multiplexer ID Payload length
|
||||
|
||||
Bit 32-x
|
||||
Function Raw bytes
|
||||
|
||||
Command (1)/ Data (0) bit value is to indicate if the packet is a MAP command
|
||||
or data packet. Command packet is used for transport level flow control. Data
|
||||
packets are standard IP packets.
|
||||
|
||||
Next header is used to indicate the presence of another header, currently is
|
||||
limited to checksum header.
|
||||
|
||||
Padding is the number of bytes to be appended to the payload to
|
||||
ensure 4 byte alignment.
|
||||
|
||||
Multiplexer ID is to indicate the PDN on which data has to be sent.
|
||||
|
||||
Payload length includes the padding length but does not include MAP header
|
||||
length.
|
||||
|
||||
d. Checksum offload header v5
|
||||
|
||||
Checksum offload header fields are in big endian format.
|
||||
|
||||
Bit 0 - 6 7 8-15 16-31
|
||||
Function Header Type Next Header Checksum Valid Reserved
|
||||
|
||||
Header Type is to indicate the type of header, this usually is set to CHECKSUM
|
||||
|
||||
Header types
|
||||
= ==========================================
|
||||
0 Reserved
|
||||
1 Reserved
|
||||
2 checksum header
|
||||
|
||||
Checksum Valid is to indicate whether the header checksum is valid. Value of 1
|
||||
implies that checksum is calculated on this packet and is valid, value of 0
|
||||
indicates that the calculated packet checksum is invalid.
|
||||
|
||||
Reserved bits must be zero when sent and ignored when received.
|
||||
|
||||
e. MAP packet v1/v5 (command specific)::
|
||||
|
||||
Bit 0 1 2-7 8 - 15 16 - 31
|
||||
Function Command Reserved Pad Multiplexer ID Payload length
|
||||
Bit 32 - 39 40 - 45 46 - 47 48 - 63
|
||||
Function Command name Reserved Command Type Reserved
|
||||
|
@ -74,7 +176,7 @@ Command types
|
|||
3 is for error during processing of commands
|
||||
= ==========================================
|
||||
|
||||
c. Aggregation
|
||||
f. Aggregation
|
||||
|
||||
Aggregation is multiple MAP packets (can be data or command) delivered to
|
||||
rmnet in a single linear skb. rmnet will process the individual
|
||||
|
|
|
@ -11,12 +11,12 @@ ENA is a networking interface designed to make good use of modern CPU
|
|||
features and system architectures.
|
||||
|
||||
The ENA device exposes a lightweight management interface with a
|
||||
minimal set of memory mapped registers and extendable command set
|
||||
minimal set of memory mapped registers and extendible command set
|
||||
through an Admin Queue.
|
||||
|
||||
The driver supports a range of ENA devices, is link-speed independent
|
||||
(i.e., the same driver is used for 10GbE, 25GbE, 40GbE, etc.), and has
|
||||
a negotiated and extendable feature set.
|
||||
(i.e., the same driver is used for 10GbE, 25GbE, 40GbE, etc), and has
|
||||
a negotiated and extendible feature set.
|
||||
|
||||
Some ENA devices support SR-IOV. This driver is used for both the
|
||||
SR-IOV Physical Function (PF) and Virtual Function (VF) devices.
|
||||
|
@ -27,9 +27,9 @@ is advertised by the device via the Admin Queue), a dedicated MSI-X
|
|||
interrupt vector per Tx/Rx queue pair, adaptive interrupt moderation,
|
||||
and CPU cacheline optimized data placement.
|
||||
|
||||
The ENA driver supports industry standard TCP/IP offload features such
|
||||
as checksum offload and TCP transmit segmentation offload (TSO).
|
||||
Receive-side scaling (RSS) is supported for multi-core scaling.
|
||||
The ENA driver supports industry standard TCP/IP offload features such as
|
||||
checksum offload. Receive-side scaling (RSS) is supported for multi-core
|
||||
scaling.
|
||||
|
||||
The ENA driver and its corresponding devices implement health
|
||||
monitoring mechanisms such as watchdog, enabling the device and driver
|
||||
|
@ -38,22 +38,20 @@ debug logs.
|
|||
|
||||
Some of the ENA devices support a working mode called Low-latency
|
||||
Queue (LLQ), which saves several more microseconds.
|
||||
|
||||
ENA Source Code Directory Structure
|
||||
===================================
|
||||
|
||||
================= ======================================================
|
||||
ena_com.[ch] Management communication layer. This layer is
|
||||
responsible for the handling all the management
|
||||
(admin) communication between the device and the
|
||||
driver.
|
||||
responsible for the handling all the management
|
||||
(admin) communication between the device and the
|
||||
driver.
|
||||
ena_eth_com.[ch] Tx/Rx data path.
|
||||
ena_admin_defs.h Definition of ENA management interface.
|
||||
ena_eth_io_defs.h Definition of ENA data path interface.
|
||||
ena_common_defs.h Common definitions for ena_com layer.
|
||||
ena_regs_defs.h Definition of ENA PCI memory-mapped (MMIO) registers.
|
||||
ena_netdev.[ch] Main Linux kernel driver.
|
||||
ena_syfsfs.[ch] Sysfs files.
|
||||
ena_ethtool.c ethtool callbacks.
|
||||
ena_pci_id_tbl.h Supported device IDs.
|
||||
================= ======================================================
|
||||
|
@ -69,7 +67,7 @@ ENA management interface is exposed by means of:
|
|||
- Asynchronous Event Notification Queue (AENQ)
|
||||
|
||||
ENA device MMIO Registers are accessed only during driver
|
||||
initialization and are not involved in further normal device
|
||||
initialization and are not used during further normal device
|
||||
operation.
|
||||
|
||||
AQ is used for submitting management commands, and the
|
||||
|
@ -100,28 +98,27 @@ group may have multiple syndromes, as shown below
|
|||
|
||||
The events are:
|
||||
|
||||
==================== ===============
|
||||
Group Syndrome
|
||||
==================== ===============
|
||||
Link state change **X**
|
||||
Fatal error **X**
|
||||
Notification Suspend traffic
|
||||
Notification Resume traffic
|
||||
Keep-Alive **X**
|
||||
==================== ===============
|
||||
==================== ===============
|
||||
Group Syndrome
|
||||
==================== ===============
|
||||
Link state change **X**
|
||||
Fatal error **X**
|
||||
Notification Suspend traffic
|
||||
Notification Resume traffic
|
||||
Keep-Alive **X**
|
||||
==================== ===============
|
||||
|
||||
ACQ and AENQ share the same MSI-X vector.
|
||||
|
||||
Keep-Alive is a special mechanism that allows monitoring of the
|
||||
device's health. The driver maintains a watchdog (WD) handler which,
|
||||
if fired, logs the current state and statistics then resets and
|
||||
restarts the ENA device and driver. A Keep-Alive event is delivered by
|
||||
the device every second. The driver re-arms the WD upon reception of a
|
||||
Keep-Alive event. A missed Keep-Alive event causes the WD handler to
|
||||
fire.
|
||||
Keep-Alive is a special mechanism that allows monitoring the device's health.
|
||||
A Keep-Alive event is delivered by the device every second.
|
||||
The driver maintains a watchdog (WD) handler which logs the current state and
|
||||
statistics. If the keep-alive events aren't delivered as expected the WD resets
|
||||
the device and the driver.
|
||||
|
||||
Data Path Interface
|
||||
===================
|
||||
|
||||
I/O operations are based on Tx and Rx Submission Queues (Tx SQ and Rx
|
||||
SQ correspondingly). Each SQ has a completion queue (CQ) associated
|
||||
with it.
|
||||
|
@ -131,26 +128,24 @@ physical memory.
|
|||
|
||||
The ENA driver supports two Queue Operation modes for Tx SQs:
|
||||
|
||||
- Regular mode
|
||||
- **Regular mode:**
|
||||
In this mode the Tx SQs reside in the host's memory. The ENA
|
||||
device fetches the ENA Tx descriptors and packet data from host
|
||||
memory.
|
||||
|
||||
* In this mode the Tx SQs reside in the host's memory. The ENA
|
||||
device fetches the ENA Tx descriptors and packet data from host
|
||||
memory.
|
||||
- **Low Latency Queue (LLQ) mode or "push-mode":**
|
||||
In this mode the driver pushes the transmit descriptors and the
|
||||
first 128 bytes of the packet directly to the ENA device memory
|
||||
space. The rest of the packet payload is fetched by the
|
||||
device. For this operation mode, the driver uses a dedicated PCI
|
||||
device memory BAR, which is mapped with write-combine capability.
|
||||
|
||||
- Low Latency Queue (LLQ) mode or "push-mode".
|
||||
|
||||
* In this mode the driver pushes the transmit descriptors and the
|
||||
first 128 bytes of the packet directly to the ENA device memory
|
||||
space. The rest of the packet payload is fetched by the
|
||||
device. For this operation mode, the driver uses a dedicated PCI
|
||||
device memory BAR, which is mapped with write-combine capability.
|
||||
**Note that** not all ENA devices support LLQ, and this feature is negotiated
|
||||
with the device upon initialization. If the ENA device does not
|
||||
support LLQ mode, the driver falls back to the regular mode.
|
||||
|
||||
The Rx SQs support only the regular mode.
|
||||
|
||||
Note: Not all ENA devices support LLQ, and this feature is negotiated
|
||||
with the device upon initialization. If the ENA device does not
|
||||
support LLQ mode, the driver falls back to the regular mode.
|
||||
|
||||
The driver supports multi-queue for both Tx and Rx. This has various
|
||||
benefits:
|
||||
|
||||
|
@ -165,6 +160,7 @@ benefits:
|
|||
|
||||
Interrupt Modes
|
||||
===============
|
||||
|
||||
The driver assigns a single MSI-X vector per queue pair (for both Tx
|
||||
and Rx directions). The driver assigns an additional dedicated MSI-X vector
|
||||
for management (for ACQ and AENQ).
|
||||
|
@ -190,20 +186,21 @@ unmasked by the driver after NAPI processing is complete.
|
|||
|
||||
Interrupt Moderation
|
||||
====================
|
||||
|
||||
ENA driver and device can operate in conventional or adaptive interrupt
|
||||
moderation mode.
|
||||
|
||||
In conventional mode the driver instructs device to postpone interrupt
|
||||
**In conventional mode** the driver instructs device to postpone interrupt
|
||||
posting according to static interrupt delay value. The interrupt delay
|
||||
value can be configured through ethtool(8). The following ethtool
|
||||
parameters are supported by the driver: tx-usecs, rx-usecs
|
||||
value can be configured through `ethtool(8)`. The following `ethtool`
|
||||
parameters are supported by the driver: ``tx-usecs``, ``rx-usecs``
|
||||
|
||||
In adaptive interrupt moderation mode the interrupt delay value is
|
||||
**In adaptive interrupt** moderation mode the interrupt delay value is
|
||||
updated by the driver dynamically and adjusted every NAPI cycle
|
||||
according to the traffic nature.
|
||||
|
||||
Adaptive coalescing can be switched on/off through ethtool(8)
|
||||
adaptive_rx on|off parameter.
|
||||
Adaptive coalescing can be switched on/off through `ethtool(8)`'s
|
||||
:code:`adaptive_rx on|off` parameter.
|
||||
|
||||
More information about Adaptive Interrupt Moderation (DIM) can be found in
|
||||
Documentation/networking/net_dim.rst
|
||||
|
@ -214,17 +211,10 @@ The rx_copybreak is initialized by default to ENA_DEFAULT_RX_COPYBREAK
|
|||
and can be configured by the ETHTOOL_STUNABLE command of the
|
||||
SIOCETHTOOL ioctl.
|
||||
|
||||
SKB
|
||||
===
|
||||
The driver-allocated SKB for frames received from Rx handling using
|
||||
NAPI context. The allocation method depends on the size of the packet.
|
||||
If the frame length is larger than rx_copybreak, napi_get_frags()
|
||||
is used, otherwise netdev_alloc_skb_ip_align() is used, the buffer
|
||||
content is copied (by CPU) to the SKB, and the buffer is recycled.
|
||||
|
||||
Statistics
|
||||
==========
|
||||
The user can obtain ENA device and driver statistics using ethtool.
|
||||
|
||||
The user can obtain ENA device and driver statistics using `ethtool`.
|
||||
The driver can collect regular or extended statistics (including
|
||||
per-queue stats) from the device.
|
||||
|
||||
|
@ -232,22 +222,23 @@ In addition the driver logs the stats to syslog upon device reset.
|
|||
|
||||
MTU
|
||||
===
|
||||
|
||||
The driver supports an arbitrarily large MTU with a maximum that is
|
||||
negotiated with the device. The driver configures MTU using the
|
||||
SetFeature command (ENA_ADMIN_MTU property). The user can change MTU
|
||||
via ip(8) and similar legacy tools.
|
||||
via `ip(8)` and similar legacy tools.
|
||||
|
||||
Stateless Offloads
|
||||
==================
|
||||
|
||||
The ENA driver supports:
|
||||
|
||||
- TSO over IPv4/IPv6
|
||||
- TSO with ECN
|
||||
- IPv4 header checksum offload
|
||||
- TCP/UDP over IPv4/IPv6 checksum offloads
|
||||
|
||||
RSS
|
||||
===
|
||||
|
||||
- The ENA device supports RSS that allows flexible Rx traffic
|
||||
steering.
|
||||
- Toeplitz and CRC32 hash functions are supported.
|
||||
|
@ -260,41 +251,42 @@ RSS
|
|||
function delivered in the Rx CQ descriptor is set in the received
|
||||
SKB.
|
||||
- The user can provide a hash key, hash function, and configure the
|
||||
indirection table through ethtool(8).
|
||||
indirection table through `ethtool(8)`.
|
||||
|
||||
DATA PATH
|
||||
=========
|
||||
|
||||
Tx
|
||||
--
|
||||
|
||||
ena_start_xmit() is called by the stack. This function does the following:
|
||||
:code:`ena_start_xmit()` is called by the stack. This function does the following:
|
||||
|
||||
- Maps data buffers (skb->data and frags).
|
||||
- Populates ena_buf for the push buffer (if the driver and device are
|
||||
in push mode.)
|
||||
- Maps data buffers (``skb->data`` and frags).
|
||||
- Populates ``ena_buf`` for the push buffer (if the driver and device are
|
||||
in push mode).
|
||||
- Prepares ENA bufs for the remaining frags.
|
||||
- Allocates a new request ID from the empty req_id ring. The request
|
||||
- Allocates a new request ID from the empty ``req_id`` ring. The request
|
||||
ID is the index of the packet in the Tx info. This is used for
|
||||
out-of-order TX completions.
|
||||
out-of-order Tx completions.
|
||||
- Adds the packet to the proper place in the Tx ring.
|
||||
- Calls ena_com_prepare_tx(), an ENA communication layer that converts
|
||||
the ena_bufs to ENA descriptors (and adds meta ENA descriptors as
|
||||
needed.)
|
||||
- Calls :code:`ena_com_prepare_tx()`, an ENA communication layer that converts
|
||||
the ``ena_bufs`` to ENA descriptors (and adds meta ENA descriptors as
|
||||
needed).
|
||||
|
||||
* This function also copies the ENA descriptors and the push buffer
|
||||
to the Device memory space (if in push mode.)
|
||||
to the Device memory space (if in push mode).
|
||||
|
||||
- Writes doorbell to the ENA device.
|
||||
- Writes a doorbell to the ENA device.
|
||||
- When the ENA device finishes sending the packet, a completion
|
||||
interrupt is raised.
|
||||
- The interrupt handler schedules NAPI.
|
||||
- The ena_clean_tx_irq() function is called. This function handles the
|
||||
- The :code:`ena_clean_tx_irq()` function is called. This function handles the
|
||||
completion descriptors generated by the ENA, with a single
|
||||
completion descriptor per completed packet.
|
||||
|
||||
* req_id is retrieved from the completion descriptor. The tx_info of
|
||||
the packet is retrieved via the req_id. The data buffers are
|
||||
unmapped and req_id is returned to the empty req_id ring.
|
||||
* ``req_id`` is retrieved from the completion descriptor. The ``tx_info`` of
|
||||
the packet is retrieved via the ``req_id``. The data buffers are
|
||||
unmapped and ``req_id`` is returned to the empty ``req_id`` ring.
|
||||
* The function stops when the completion descriptors are completed or
|
||||
the budget is reached.
|
||||
|
||||
|
@ -303,12 +295,11 @@ Rx
|
|||
|
||||
- When a packet is received from the ENA device.
|
||||
- The interrupt handler schedules NAPI.
|
||||
- The ena_clean_rx_irq() function is called. This function calls
|
||||
ena_rx_pkt(), an ENA communication layer function, which returns the
|
||||
number of descriptors used for a new unhandled packet, and zero if
|
||||
- The :code:`ena_clean_rx_irq()` function is called. This function calls
|
||||
:code:`ena_com_rx_pkt()`, an ENA communication layer function, which returns the
|
||||
number of descriptors used for a new packet, and zero if
|
||||
no new packet is found.
|
||||
- Then it calls the ena_clean_rx_irq() function.
|
||||
- ena_eth_rx_skb() checks packet length:
|
||||
- :code:`ena_rx_skb()` checks packet length:
|
||||
|
||||
* If the packet is small (len < rx_copybreak), the driver allocates
|
||||
a SKB for the new packet, and copies the packet payload into the
|
||||
|
@ -317,9 +308,10 @@ Rx
|
|||
- In this way the original data buffer is not passed to the stack
|
||||
and is reused for future Rx packets.
|
||||
|
||||
* Otherwise the function unmaps the Rx buffer, then allocates the
|
||||
new SKB structure and hooks the Rx buffer to the SKB frags.
|
||||
* Otherwise the function unmaps the Rx buffer, sets the first
|
||||
descriptor as `skb`'s linear part and the other descriptors as the
|
||||
`skb`'s frags.
|
||||
|
||||
- The new SKB is updated with the necessary information (protocol,
|
||||
checksum hw verify result, etc.), and then passed to the network
|
||||
stack, using the NAPI interface function napi_gro_receive().
|
||||
checksum hw verify result, etc), and then passed to the network
|
||||
stack, using the NAPI interface function :code:`napi_gro_receive()`.
|
||||
|
|
|
@ -47,13 +47,24 @@ The driver interacts with the device in the following ways:
|
|||
- Transmit and Receive Queues
|
||||
- See description below
|
||||
|
||||
Descriptor Formats
|
||||
------------------
|
||||
GVE supports two descriptor formats: GQI and DQO. These two formats have
|
||||
entirely different descriptors, which will be described below.
|
||||
|
||||
Registers
|
||||
---------
|
||||
All registers are MMIO and big endian.
|
||||
All registers are MMIO.
|
||||
|
||||
The registers are used for initializing and configuring the device as well as
|
||||
querying device status in response to management interrupts.
|
||||
|
||||
Endianness
|
||||
----------
|
||||
- Admin Queue messages and registers are all Big Endian.
|
||||
- GQI descriptors and datapath registers are Big Endian.
|
||||
- DQO descriptors and datapath registers are Little Endian.
|
||||
|
||||
Admin Queue (AQ)
|
||||
----------------
|
||||
The Admin Queue is a PAGE_SIZE memory block, treated as an array of AQ
|
||||
|
@ -97,10 +108,10 @@ the queues associated with that interrupt.
|
|||
The handler for these irqs schedule the napi for that block to run
|
||||
and poll the queues.
|
||||
|
||||
Traffic Queues
|
||||
--------------
|
||||
gVNIC's queues are composed of a descriptor ring and a buffer and are
|
||||
assigned to a notification block.
|
||||
GQI Traffic Queues
|
||||
------------------
|
||||
GQI queues are composed of a descriptor ring and a buffer and are assigned to a
|
||||
notification block.
|
||||
|
||||
The descriptor rings are power-of-two-sized ring buffers consisting of
|
||||
fixed-size descriptors. They advance their head pointer using a __be32
|
||||
|
@ -121,3 +132,35 @@ Receive
|
|||
The buffers for receive rings are put into a data ring that is the same
|
||||
length as the descriptor ring and the head and tail pointers advance over
|
||||
the rings together.
|
||||
|
||||
DQO Traffic Queues
|
||||
------------------
|
||||
- Every TX and RX queue is assigned a notification block.
|
||||
|
||||
- TX and RX buffers queues, which send descriptors to the device, use MMIO
|
||||
doorbells to notify the device of new descriptors.
|
||||
|
||||
- RX and TX completion queues, which receive descriptors from the device, use a
|
||||
"generation bit" to know when a descriptor was populated by the device. The
|
||||
driver initializes all bits with the "current generation". The device will
|
||||
populate received descriptors with the "next generation" which is inverted
|
||||
from the current generation. When the ring wraps, the current/next generation
|
||||
are swapped.
|
||||
|
||||
- It's the driver's responsibility to ensure that the RX and TX completion
|
||||
queues are not overrun. This can be accomplished by limiting the number of
|
||||
descriptors posted to HW.
|
||||
|
||||
- TX packets have a 16 bit completion_tag and RX buffers have a 16 bit
|
||||
buffer_id. These will be returned on the TX completion and RX queues
|
||||
respectively to let the driver know which packet/buffer was completed.
|
||||
|
||||
Transmit
|
||||
~~~~~~~~
|
||||
A packet's buffers are DMA mapped for the device to access before transmission.
|
||||
After the packet was successfully transmitted, the buffers are unmapped.
|
||||
|
||||
Receive
|
||||
~~~~~~~
|
||||
The driver posts fixed sized buffers to HW on the RX buffer queue. The packet
|
||||
received on the associated RX queue may span multiple descriptors.
|
||||
|
|
|
@ -12,6 +12,7 @@ Contents
|
|||
- `Enabling the driver and kconfig options`_
|
||||
- `Devlink info`_
|
||||
- `Devlink parameters`_
|
||||
- `Bridge offload`_
|
||||
- `mlx5 subfunction`_
|
||||
- `mlx5 function attributes`_
|
||||
- `Devlink health reporters`_
|
||||
|
@ -217,6 +218,37 @@ users try to enable them.
|
|||
|
||||
$ devlink dev eswitch set pci/0000:06:00.0 mode switchdev
|
||||
|
||||
Bridge offload
|
||||
==============
|
||||
The mlx5 driver implements support for offloading bridge rules when in switchdev
|
||||
mode. Linux bridge FDBs are automatically offloaded when mlx5 switchdev
|
||||
representor is attached to bridge.
|
||||
|
||||
- Change device to switchdev mode::
|
||||
|
||||
$ devlink dev eswitch set pci/0000:06:00.0 mode switchdev
|
||||
|
||||
- Attach mlx5 switchdev representor 'enp8s0f0' to bridge netdev 'bridge1'::
|
||||
|
||||
$ ip link set enp8s0f0 master bridge1
|
||||
|
||||
VLANs
|
||||
-----
|
||||
Following bridge VLAN functions are supported by mlx5:
|
||||
|
||||
- VLAN filtering (including multiple VLANs per port)::
|
||||
|
||||
$ ip link set bridge1 type bridge vlan_filtering 1
|
||||
$ bridge vlan add dev enp8s0f0 vid 2-3
|
||||
|
||||
- VLAN push on bridge ingress::
|
||||
|
||||
$ bridge vlan add dev enp8s0f0 vid 3 pvid
|
||||
|
||||
- VLAN pop on bridge egress::
|
||||
|
||||
$ bridge vlan add dev enp8s0f0 vid 3 untagged
|
||||
|
||||
mlx5 subfunction
|
||||
================
|
||||
mlx5 supports subfunction management using devlink port (see :ref:`Documentation/networking/devlink/devlink-port.rst <devlink_port>`) interface.
|
||||
|
@ -568,3 +600,59 @@ tc and eswitch offloads tracepoints:
|
|||
$ cat /sys/kernel/debug/tracing/trace
|
||||
...
|
||||
kworker/u48:7-2221 [009] ...1 1475.387435: mlx5e_rep_neigh_update: netdev: ens1f0 MAC: 24:8a:07:9a:17:9a IPv4: 1.1.1.10 IPv6: ::ffff:1.1.1.10 neigh_connected=1
|
||||
|
||||
Bridge offloads tracepoints:
|
||||
|
||||
- mlx5_esw_bridge_fdb_entry_init: trace bridge FDB entry offloaded to mlx5::
|
||||
|
||||
$ echo mlx5:mlx5_esw_bridge_fdb_entry_init >> set_event
|
||||
$ cat /sys/kernel/debug/tracing/trace
|
||||
...
|
||||
kworker/u20:9-2217 [003] ...1 318.582243: mlx5_esw_bridge_fdb_entry_init: net_device=enp8s0f0_0 addr=e4:fd:05:08:00:02 vid=0 flags=0 used=0
|
||||
|
||||
- mlx5_esw_bridge_fdb_entry_cleanup: trace bridge FDB entry deleted from mlx5::
|
||||
|
||||
$ echo mlx5:mlx5_esw_bridge_fdb_entry_cleanup >> set_event
|
||||
$ cat /sys/kernel/debug/tracing/trace
|
||||
...
|
||||
ip-2581 [005] ...1 318.629871: mlx5_esw_bridge_fdb_entry_cleanup: net_device=enp8s0f0_1 addr=e4:fd:05:08:00:03 vid=0 flags=0 used=16
|
||||
|
||||
- mlx5_esw_bridge_fdb_entry_refresh: trace bridge FDB entry offload refreshed in
|
||||
mlx5::
|
||||
|
||||
$ echo mlx5:mlx5_esw_bridge_fdb_entry_refresh >> set_event
|
||||
$ cat /sys/kernel/debug/tracing/trace
|
||||
...
|
||||
kworker/u20:8-3849 [003] ...1 466716: mlx5_esw_bridge_fdb_entry_refresh: net_device=enp8s0f0_0 addr=e4:fd:05:08:00:02 vid=3 flags=0 used=0
|
||||
|
||||
- mlx5_esw_bridge_vlan_create: trace bridge VLAN object add on mlx5
|
||||
representor::
|
||||
|
||||
$ echo mlx5:mlx5_esw_bridge_vlan_create >> set_event
|
||||
$ cat /sys/kernel/debug/tracing/trace
|
||||
...
|
||||
ip-2560 [007] ...1 318.460258: mlx5_esw_bridge_vlan_create: vid=1 flags=6
|
||||
|
||||
- mlx5_esw_bridge_vlan_cleanup: trace bridge VLAN object delete from mlx5
|
||||
representor::
|
||||
|
||||
$ echo mlx5:mlx5_esw_bridge_vlan_cleanup >> set_event
|
||||
$ cat /sys/kernel/debug/tracing/trace
|
||||
...
|
||||
bridge-2582 [007] ...1 318.653496: mlx5_esw_bridge_vlan_cleanup: vid=2 flags=8
|
||||
|
||||
- mlx5_esw_bridge_vport_init: trace mlx5 vport assigned with bridge upper
|
||||
device::
|
||||
|
||||
$ echo mlx5:mlx5_esw_bridge_vport_init >> set_event
|
||||
$ cat /sys/kernel/debug/tracing/trace
|
||||
...
|
||||
ip-2560 [007] ...1 318.458915: mlx5_esw_bridge_vport_init: vport_num=1
|
||||
|
||||
- mlx5_esw_bridge_vport_cleanup: trace mlx5 vport removed from bridge upper
|
||||
device::
|
||||
|
||||
$ echo mlx5:mlx5_esw_bridge_vport_cleanup >> set_event
|
||||
$ cat /sys/kernel/debug/tracing/trace
|
||||
...
|
||||
ip-5387 [000] ...1 573713: mlx5_esw_bridge_vport_cleanup: vport_num=1
|
||||
|
|
|
@ -18,6 +18,7 @@ Contents:
|
|||
qlogic/index
|
||||
wan/index
|
||||
wifi/index
|
||||
wwan/index
|
||||
|
||||
.. only:: subproject and html
|
||||
|
||||
|
|
|
@ -0,0 +1,18 @@
|
|||
.. SPDX-License-Identifier: GPL-2.0-only
|
||||
|
||||
WWAN Device Drivers
|
||||
===================
|
||||
|
||||
Contents:
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 2
|
||||
|
||||
iosm
|
||||
|
||||
.. only:: subproject and html
|
||||
|
||||
Indices
|
||||
=======
|
||||
|
||||
* :ref:`genindex`
|
|
@ -0,0 +1,96 @@
|
|||
.. SPDX-License-Identifier: GPL-2.0-only
|
||||
|
||||
.. Copyright (C) 2020-21 Intel Corporation
|
||||
|
||||
.. _iosm_driver_doc:
|
||||
|
||||
===========================================
|
||||
IOSM Driver for Intel M.2 PCIe based Modems
|
||||
===========================================
|
||||
The IOSM (IPC over Shared Memory) driver is a WWAN PCIe host driver developed
|
||||
for linux or chrome platform for data exchange over PCIe interface between
|
||||
Host platform & Intel M.2 Modem. The driver exposes interface conforming to the
|
||||
MBIM protocol [1]. Any front end application ( eg: Modem Manager) could easily
|
||||
manage the MBIM interface to enable data communication towards WWAN.
|
||||
|
||||
Basic usage
|
||||
===========
|
||||
MBIM functions are inactive when unmanaged. The IOSM driver only provides a
|
||||
userspace interface MBIM "WWAN PORT" representing MBIM control channel and does
|
||||
not play any role in managing the functionality. It is the job of a userspace
|
||||
application to detect port enumeration and enable MBIM functionality.
|
||||
|
||||
Examples of few such userspace application 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 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 IOSM 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 Driver supports
|
||||
upto 8 IP sessions for simultaneous IP communication.
|
||||
|
||||
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-name wwan0 type wwan linkid 1
|
||||
|
||||
The driver will automatically map the "wwan0-1" network device to MBIM IP
|
||||
session 1.
|
||||
|
||||
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) devices and connections"
|
||||
- http://www.freedesktop.org/wiki/Software/ModemManager/
|
|
@ -164,6 +164,41 @@ device to instantiate the subfunction device on particular PCI function.
|
|||
A subfunction device is created on the :ref:`Documentation/driver-api/auxiliary_bus.rst <auxiliary_bus>`.
|
||||
At this point a matching subfunction driver binds to the subfunction's auxiliary device.
|
||||
|
||||
Rate object management
|
||||
======================
|
||||
|
||||
Devlink provides API to manage tx rates of single devlink port or a group.
|
||||
This is done through rate objects, which can be one of the two types:
|
||||
|
||||
``leaf``
|
||||
Represents a single devlink port; created/destroyed by the driver. Since leaf
|
||||
have 1to1 mapping to its devlink port, in user space it is referred as
|
||||
``pci/<bus_addr>/<port_index>``;
|
||||
|
||||
``node``
|
||||
Represents a group of rate objects (leafs and/or nodes); created/deleted by
|
||||
request from the userspace; initially empty (no rate objects added). In
|
||||
userspace it is referred as ``pci/<bus_addr>/<node_name>``, where
|
||||
``node_name`` can be any identifier, except decimal number, to avoid
|
||||
collisions with leafs.
|
||||
|
||||
API allows to configure following rate object's parameters:
|
||||
|
||||
``tx_share``
|
||||
Minimum TX rate value shared among all other rate objects, or rate objects
|
||||
that parts of the parent group, if it is a part of the same group.
|
||||
|
||||
``tx_max``
|
||||
Maximum TX rate value.
|
||||
|
||||
``parent``
|
||||
Parent node name. Parent node rate limits are considered as additional limits
|
||||
to all node children limits. ``tx_max`` is an upper limit for children.
|
||||
``tx_share`` is a total bandwidth distributed among children.
|
||||
|
||||
Driver implementations are allowed to support both or either rate object types
|
||||
and setting methods of their parameters.
|
||||
|
||||
Terms and Definitions
|
||||
=====================
|
||||
|
||||
|
|
|
@ -497,6 +497,7 @@ drivers:
|
|||
|
||||
* Documentation/networking/devlink/netdevsim.rst
|
||||
* Documentation/networking/devlink/mlxsw.rst
|
||||
* Documentation/networking/devlink/prestera.rst
|
||||
|
||||
.. _Generic-Packet-Trap-Groups:
|
||||
|
||||
|
|
|
@ -46,3 +46,4 @@ parameters, info versions, and other features it supports.
|
|||
qed
|
||||
ti-cpsw-switch
|
||||
am65-nuss-cpsw-switch
|
||||
prestera
|
||||
|
|
|
@ -57,6 +57,32 @@ entries, FIB rule entries and nexthops that the driver will allow.
|
|||
$ devlink resource set netdevsim/netdevsim0 path /nexthops size 16
|
||||
$ devlink dev reload netdevsim/netdevsim0
|
||||
|
||||
Rate objects
|
||||
============
|
||||
|
||||
The ``netdevsim`` driver supports rate objects management, which includes:
|
||||
|
||||
- registerging/unregistering leaf rate objects per VF devlink port;
|
||||
- creation/deletion node rate objects;
|
||||
- setting tx_share and tx_max rate values for any rate object type;
|
||||
- setting parent node for any rate object type.
|
||||
|
||||
Rate nodes and it's parameters are exposed in ``netdevsim`` debugfs in RO mode.
|
||||
For example created rate node with name ``some_group``:
|
||||
|
||||
.. code:: shell
|
||||
|
||||
$ ls /sys/kernel/debug/netdevsim/netdevsim0/rate_groups/some_group
|
||||
rate_parent tx_max tx_share
|
||||
|
||||
Same parameters are exposed for leaf objects in corresponding ports directories.
|
||||
For ex.:
|
||||
|
||||
.. code:: shell
|
||||
|
||||
$ ls /sys/kernel/debug/netdevsim/netdevsim0/ports/1
|
||||
dev ethtool rate_parent tx_max tx_share
|
||||
|
||||
Driver-specific Traps
|
||||
=====================
|
||||
|
||||
|
|
|
@ -0,0 +1,141 @@
|
|||
.. SPDX-License-Identifier: GPL-2.0
|
||||
|
||||
========================
|
||||
prestera devlink support
|
||||
========================
|
||||
|
||||
This document describes the devlink features implemented by the ``prestera``
|
||||
device driver.
|
||||
|
||||
Driver-specific Traps
|
||||
=====================
|
||||
|
||||
.. list-table:: List of Driver-specific Traps Registered by ``prestera``
|
||||
:widths: 5 5 90
|
||||
|
||||
* - Name
|
||||
- Type
|
||||
- Description
|
||||
.. list-table:: List of Driver-specific Traps Registered by ``prestera``
|
||||
:widths: 5 5 90
|
||||
|
||||
* - Name
|
||||
- Type
|
||||
- Description
|
||||
* - ``arp_bc``
|
||||
- ``trap``
|
||||
- Traps ARP broadcast packets (both requests/responses)
|
||||
* - ``is_is``
|
||||
- ``trap``
|
||||
- Traps IS-IS packets
|
||||
* - ``ospf``
|
||||
- ``trap``
|
||||
- Traps OSPF packets
|
||||
* - ``ip_bc_mac``
|
||||
- ``trap``
|
||||
- Traps IPv4 packets with broadcast DA Mac address
|
||||
* - ``stp``
|
||||
- ``trap``
|
||||
- Traps STP BPDU
|
||||
* - ``lacp``
|
||||
- ``trap``
|
||||
- Traps LACP packets
|
||||
* - ``lldp``
|
||||
- ``trap``
|
||||
- Traps LLDP packets
|
||||
* - ``router_mc``
|
||||
- ``trap``
|
||||
- Traps multicast packets
|
||||
* - ``vrrp``
|
||||
- ``trap``
|
||||
- Traps VRRP packets
|
||||
* - ``dhcp``
|
||||
- ``trap``
|
||||
- Traps DHCP packets
|
||||
* - ``mtu_error``
|
||||
- ``trap``
|
||||
- Traps (exception) packets that exceeded port's MTU
|
||||
* - ``mac_to_me``
|
||||
- ``trap``
|
||||
- Traps packets with switch-port's DA Mac address
|
||||
* - ``ttl_error``
|
||||
- ``trap``
|
||||
- Traps (exception) IPv4 packets whose TTL exceeded
|
||||
* - ``ipv4_options``
|
||||
- ``trap``
|
||||
- Traps (exception) packets due to the malformed IPV4 header options
|
||||
* - ``ip_default_route``
|
||||
- ``trap``
|
||||
- Traps packets that have no specific IP interface (IP to me) and no forwarding prefix
|
||||
* - ``local_route``
|
||||
- ``trap``
|
||||
- Traps packets that have been send to one of switch IP interfaces addresses
|
||||
* - ``ipv4_icmp_redirect``
|
||||
- ``trap``
|
||||
- Traps (exception) IPV4 ICMP redirect packets
|
||||
* - ``arp_response``
|
||||
- ``trap``
|
||||
- Traps ARP replies packets that have switch-port's DA Mac address
|
||||
* - ``acl_code_0``
|
||||
- ``trap``
|
||||
- Traps packets that have ACL priority set to 0 (tc pref 0)
|
||||
* - ``acl_code_1``
|
||||
- ``trap``
|
||||
- Traps packets that have ACL priority set to 1 (tc pref 1)
|
||||
* - ``acl_code_2``
|
||||
- ``trap``
|
||||
- Traps packets that have ACL priority set to 2 (tc pref 2)
|
||||
* - ``acl_code_3``
|
||||
- ``trap``
|
||||
- Traps packets that have ACL priority set to 3 (tc pref 3)
|
||||
* - ``acl_code_4``
|
||||
- ``trap``
|
||||
- Traps packets that have ACL priority set to 4 (tc pref 4)
|
||||
* - ``acl_code_5``
|
||||
- ``trap``
|
||||
- Traps packets that have ACL priority set to 5 (tc pref 5)
|
||||
* - ``acl_code_6``
|
||||
- ``trap``
|
||||
- Traps packets that have ACL priority set to 6 (tc pref 6)
|
||||
* - ``acl_code_7``
|
||||
- ``trap``
|
||||
- Traps packets that have ACL priority set to 7 (tc pref 7)
|
||||
* - ``ipv4_bgp``
|
||||
- ``trap``
|
||||
- Traps IPv4 BGP packets
|
||||
* - ``ssh``
|
||||
- ``trap``
|
||||
- Traps SSH packets
|
||||
* - ``telnet``
|
||||
- ``trap``
|
||||
- Traps Telnet packets
|
||||
* - ``icmp``
|
||||
- ``trap``
|
||||
- Traps ICMP packets
|
||||
* - ``rxdma_drop``
|
||||
- ``drop``
|
||||
- Drops packets (RxDMA) due to the lack of ingress buffers etc.
|
||||
* - ``port_no_vlan``
|
||||
- ``drop``
|
||||
- Drops packets due to faulty-configured network or due to internal bug (config issue).
|
||||
* - ``local_port``
|
||||
- ``drop``
|
||||
- Drops packets whose decision (FDB entry) is to bridge packet back to the incoming port/trunk.
|
||||
* - ``invalid_sa``
|
||||
- ``drop``
|
||||
- Drops packets with multicast source MAC address.
|
||||
* - ``illegal_ip_addr``
|
||||
- ``drop``
|
||||
- Drops packets with illegal SIP/DIP multicast/unicast addresses.
|
||||
* - ``illegal_ipv4_hdr``
|
||||
- ``drop``
|
||||
- Drops packets with illegal IPV4 header.
|
||||
* - ``ip_uc_dip_da_mismatch``
|
||||
- ``drop``
|
||||
- Drops packets with destination MAC being unicast, but destination IP address being multicast.
|
||||
* - ``ip_sip_is_zero``
|
||||
- ``drop``
|
||||
- Drops packets with zero (0) IPV4 source address.
|
||||
* - ``met_red``
|
||||
- ``drop``
|
||||
- Drops non-conforming packets (dropped by Ingress policer, metering drop), e.g. packet rate exceeded configured bandwith.
|
|
@ -292,3 +292,71 @@ configuration.
|
|||
|
||||
# bring up the bridge devices
|
||||
ip link set br0 up
|
||||
|
||||
Forwarding database (FDB) management
|
||||
------------------------------------
|
||||
|
||||
The existing DSA switches do not have the necessary hardware support to keep
|
||||
the software FDB of the bridge in sync with the hardware tables, so the two
|
||||
tables are managed separately (``bridge fdb show`` queries both, and depending
|
||||
on whether the ``self`` or ``master`` flags are being used, a ``bridge fdb
|
||||
add`` or ``bridge fdb del`` command acts upon entries from one or both tables).
|
||||
|
||||
Up until kernel v4.14, DSA only supported user space management of bridge FDB
|
||||
entries using the bridge bypass operations (which do not update the software
|
||||
FDB, just the hardware one) using the ``self`` flag (which is optional and can
|
||||
be omitted).
|
||||
|
||||
.. code-block:: sh
|
||||
|
||||
bridge fdb add dev swp0 00:01:02:03:04:05 self static
|
||||
# or shorthand
|
||||
bridge fdb add dev swp0 00:01:02:03:04:05 static
|
||||
|
||||
Due to a bug, the bridge bypass FDB implementation provided by DSA did not
|
||||
distinguish between ``static`` and ``local`` FDB entries (``static`` are meant
|
||||
to be forwarded, while ``local`` are meant to be locally terminated, i.e. sent
|
||||
to the host port). Instead, all FDB entries with the ``self`` flag (implicit or
|
||||
explicit) are treated by DSA as ``static`` even if they are ``local``.
|
||||
|
||||
.. code-block:: sh
|
||||
|
||||
# This command:
|
||||
bridge fdb add dev swp0 00:01:02:03:04:05 static
|
||||
# behaves the same for DSA as this command:
|
||||
bridge fdb add dev swp0 00:01:02:03:04:05 local
|
||||
# or shorthand, because the 'local' flag is implicit if 'static' is not
|
||||
# specified, it also behaves the same as:
|
||||
bridge fdb add dev swp0 00:01:02:03:04:05
|
||||
|
||||
The last command is an incorrect way of adding a static bridge FDB entry to a
|
||||
DSA switch using the bridge bypass operations, and works by mistake. Other
|
||||
drivers will treat an FDB entry added by the same command as ``local`` and as
|
||||
such, will not forward it, as opposed to DSA.
|
||||
|
||||
Between kernel v4.14 and v5.14, DSA has supported in parallel two modes of
|
||||
adding a bridge FDB entry to the switch: the bridge bypass discussed above, as
|
||||
well as a new mode using the ``master`` flag which installs FDB entries in the
|
||||
software bridge too.
|
||||
|
||||
.. code-block:: sh
|
||||
|
||||
bridge fdb add dev swp0 00:01:02:03:04:05 master static
|
||||
|
||||
Since kernel v5.14, DSA has gained stronger integration with the bridge's
|
||||
software FDB, and the support for its bridge bypass FDB implementation (using
|
||||
the ``self`` flag) has been removed. This results in the following changes:
|
||||
|
||||
.. code-block:: sh
|
||||
|
||||
# This is the only valid way of adding an FDB entry that is supported,
|
||||
# compatible with v4.14 kernels and later:
|
||||
bridge fdb add dev swp0 00:01:02:03:04:05 master static
|
||||
# This command is no longer buggy and the entry is properly treated as
|
||||
# 'local' instead of being forwarded:
|
||||
bridge fdb add dev swp0 00:01:02:03:04:05
|
||||
# This command no longer installs a static FDB entry to hardware:
|
||||
bridge fdb add dev swp0 00:01:02:03:04:05 static
|
||||
|
||||
Script writers are therefore encouraged to use the ``master static`` set of
|
||||
flags when working with bridge FDB entries on DSA switch interfaces.
|
||||
|
|
|
@ -93,14 +93,15 @@ A tagging protocol may tag all packets with switch tags of the same length, or
|
|||
the tag length might vary (for example packets with PTP timestamps might
|
||||
require an extended switch tag, or there might be one tag length on TX and a
|
||||
different one on RX). Either way, the tagging protocol driver must populate the
|
||||
``struct dsa_device_ops::overhead`` with the length in octets of the longest
|
||||
switch frame header. The DSA framework will automatically adjust the MTU of the
|
||||
master interface to accomodate for this extra size in order for DSA user ports
|
||||
to support the standard MTU (L2 payload length) of 1500 octets. The ``overhead``
|
||||
is also used to request from the network stack, on a best-effort basis, the
|
||||
allocation of packets with a ``needed_headroom`` or ``needed_tailroom``
|
||||
sufficient such that the act of pushing the switch tag on transmission of a
|
||||
packet does not cause it to reallocate due to lack of memory.
|
||||
``struct dsa_device_ops::needed_headroom`` and/or ``struct dsa_device_ops::needed_tailroom``
|
||||
with the length in octets of the longest switch frame header/trailer. The DSA
|
||||
framework will automatically adjust the MTU of the master interface to
|
||||
accommodate for this extra size in order for DSA user ports to support the
|
||||
standard MTU (L2 payload length) of 1500 octets. The ``needed_headroom`` and
|
||||
``needed_tailroom`` properties are also used to request from the network stack,
|
||||
on a best-effort basis, the allocation of packets with enough extra space such
|
||||
that the act of pushing the switch tag on transmission of a packet does not
|
||||
cause it to reallocate due to lack of memory.
|
||||
|
||||
Even though applications are not expected to parse DSA-specific frame headers,
|
||||
the format on the wire of the tagging protocol represents an Application Binary
|
||||
|
@ -169,8 +170,8 @@ The job of this method is to prepare the skb in a way that the switch will
|
|||
understand what egress port the packet is for (and not deliver it towards other
|
||||
ports). Typically this is fulfilled by pushing a frame header. Checking for
|
||||
insufficient size in the skb headroom or tailroom is unnecessary provided that
|
||||
the ``overhead`` and ``tail_tag`` properties were filled out properly, because
|
||||
DSA ensures there is enough space before calling this method.
|
||||
the ``needed_headroom`` and ``needed_tailroom`` properties were filled out
|
||||
properly, because DSA ensures there is enough space before calling this method.
|
||||
|
||||
The reception of a packet goes through the tagger's ``rcv`` function. The
|
||||
passed ``struct sk_buff *skb`` has ``skb->data`` pointing at
|
||||
|
|
|
@ -5,7 +5,7 @@ NXP SJA1105 switch driver
|
|||
Overview
|
||||
========
|
||||
|
||||
The NXP SJA1105 is a family of 6 devices:
|
||||
The NXP SJA1105 is a family of 10 SPI-managed automotive switches:
|
||||
|
||||
- SJA1105E: First generation, no TTEthernet
|
||||
- SJA1105T: First generation, TTEthernet
|
||||
|
@ -13,9 +13,11 @@ The NXP SJA1105 is a family of 6 devices:
|
|||
- SJA1105Q: Second generation, TTEthernet, no SGMII
|
||||
- SJA1105R: Second generation, no TTEthernet, SGMII
|
||||
- SJA1105S: Second generation, TTEthernet, SGMII
|
||||
|
||||
These are SPI-managed automotive switches, with all ports being gigabit
|
||||
capable, and supporting MII/RMII/RGMII and optionally SGMII on one port.
|
||||
- SJA1110A: Third generation, TTEthernet, SGMII, integrated 100base-T1 and
|
||||
100base-TX PHYs
|
||||
- SJA1110B: Third generation, TTEthernet, SGMII, 100base-T1, 100base-TX
|
||||
- SJA1110C: Third generation, TTEthernet, SGMII, 100base-T1, 100base-TX
|
||||
- SJA1110D: Third generation, TTEthernet, SGMII, 100base-T1
|
||||
|
||||
Being automotive parts, their configuration interface is geared towards
|
||||
set-and-forget use, with minimal dynamic interaction at runtime. They
|
||||
|
@ -579,3 +581,54 @@ A board would need to hook up the PHYs connected to the switch to any other
|
|||
MDIO bus available to Linux within the system (e.g. to the DSA master's MDIO
|
||||
bus). Link state management then works by the driver manually keeping in sync
|
||||
(over SPI commands) the MAC link speed with the settings negotiated by the PHY.
|
||||
|
||||
By comparison, the SJA1110 supports an MDIO slave access point over which its
|
||||
internal 100base-T1 PHYs can be accessed from the host. This is, however, not
|
||||
used by the driver, instead the internal 100base-T1 and 100base-TX PHYs are
|
||||
accessed through SPI commands, modeled in Linux as virtual MDIO buses.
|
||||
|
||||
The microcontroller attached to the SJA1110 port 0 also has an MDIO controller
|
||||
operating in master mode, however the driver does not support this either,
|
||||
since the microcontroller gets disabled when the Linux driver operates.
|
||||
Discrete PHYs connected to the switch ports should have their MDIO interface
|
||||
attached to an MDIO controller from the host system and not to the switch,
|
||||
similar to SJA1105.
|
||||
|
||||
Port compatibility matrix
|
||||
-------------------------
|
||||
|
||||
The SJA1105 port compatibility matrix is:
|
||||
|
||||
===== ============== ============== ==============
|
||||
Port SJA1105E/T SJA1105P/Q SJA1105R/S
|
||||
===== ============== ============== ==============
|
||||
0 xMII xMII xMII
|
||||
1 xMII xMII xMII
|
||||
2 xMII xMII xMII
|
||||
3 xMII xMII xMII
|
||||
4 xMII xMII SGMII
|
||||
===== ============== ============== ==============
|
||||
|
||||
|
||||
The SJA1110 port compatibility matrix is:
|
||||
|
||||
===== ============== ============== ============== ==============
|
||||
Port SJA1110A SJA1110B SJA1110C SJA1110D
|
||||
===== ============== ============== ============== ==============
|
||||
0 RevMII (uC) RevMII (uC) RevMII (uC) RevMII (uC)
|
||||
1 100base-TX 100base-TX 100base-TX
|
||||
or SGMII SGMII
|
||||
2 xMII xMII xMII xMII
|
||||
or SGMII or SGMII
|
||||
3 xMII xMII xMII
|
||||
or SGMII or SGMII SGMII
|
||||
or 2500base-X or 2500base-X or 2500base-X
|
||||
4 SGMII SGMII SGMII SGMII
|
||||
or 2500base-X or 2500base-X or 2500base-X or 2500base-X
|
||||
5 100base-T1 100base-T1 100base-T1 100base-T1
|
||||
6 100base-T1 100base-T1 100base-T1 100base-T1
|
||||
7 100base-T1 100base-T1 100base-T1 100base-T1
|
||||
8 100base-T1 100base-T1 n/a n/a
|
||||
9 100base-T1 100base-T1 n/a n/a
|
||||
10 100base-T1 n/a n/a n/a
|
||||
===== ============== ============== ============== ==============
|
||||
|
|
|
@ -1363,8 +1363,8 @@ in an implementation specific way.
|
|||
``ETHTOOL_A_FEC_AUTO`` requests the driver to choose FEC mode based on SFP
|
||||
module parameters. This does not mean autonegotiation.
|
||||
|
||||
MODULE_EEPROM
|
||||
=============
|
||||
MODULE_EEPROM_GET
|
||||
=================
|
||||
|
||||
Fetch module EEPROM data dump.
|
||||
This interface is designed to allow dumps of at most 1/2 page at once. This
|
||||
|
@ -1383,12 +1383,14 @@ Request contents:
|
|||
``ETHTOOL_A_MODULE_EEPROM_I2C_ADDRESS`` u8 page I2C address
|
||||
======================================= ====== ==========================
|
||||
|
||||
If ``ETHTOOL_A_MODULE_EEPROM_BANK`` is not specified, bank 0 is assumed.
|
||||
|
||||
Kernel response contents:
|
||||
|
||||
+---------------------------------------------+--------+---------------------+
|
||||
| ``ETHTOOL_A_MODULE_EEPROM_HEADER`` | nested | reply header |
|
||||
+---------------------------------------------+--------+---------------------+
|
||||
| ``ETHTOOL_A_MODULE_EEPROM_DATA`` | nested | array of bytes from |
|
||||
| ``ETHTOOL_A_MODULE_EEPROM_DATA`` | binary | array of bytes from |
|
||||
| | | module EEPROM |
|
||||
+---------------------------------------------+--------+---------------------+
|
||||
|
||||
|
|
|
@ -99,6 +99,35 @@ fib_multipath_hash_policy - INTEGER
|
|||
- 0 - Layer 3
|
||||
- 1 - Layer 4
|
||||
- 2 - Layer 3 or inner Layer 3 if present
|
||||
- 3 - Custom multipath hash. Fields used for multipath hash calculation
|
||||
are determined by fib_multipath_hash_fields sysctl
|
||||
|
||||
fib_multipath_hash_fields - UNSIGNED INTEGER
|
||||
When fib_multipath_hash_policy is set to 3 (custom multipath hash), the
|
||||
fields used for multipath hash calculation are determined by this
|
||||
sysctl.
|
||||
|
||||
This value is a bitmask which enables various fields for multipath hash
|
||||
calculation.
|
||||
|
||||
Possible fields are:
|
||||
|
||||
====== ============================
|
||||
0x0001 Source IP address
|
||||
0x0002 Destination IP address
|
||||
0x0004 IP protocol
|
||||
0x0008 Unused (Flow Label)
|
||||
0x0010 Source port
|
||||
0x0020 Destination port
|
||||
0x0040 Inner source IP address
|
||||
0x0080 Inner destination IP address
|
||||
0x0100 Inner IP protocol
|
||||
0x0200 Inner Flow Label
|
||||
0x0400 Inner source port
|
||||
0x0800 Inner destination port
|
||||
====== ============================
|
||||
|
||||
Default: 0x0007 (source IP, destination IP and IP protocol)
|
||||
|
||||
fib_sync_mem - UNSIGNED INTEGER
|
||||
Amount of dirty memory from fib entries that can be backlogged before
|
||||
|
@ -732,6 +761,31 @@ tcp_syncookies - INTEGER
|
|||
network connections you can set this knob to 2 to enable
|
||||
unconditionally generation of syncookies.
|
||||
|
||||
tcp_migrate_req - BOOLEAN
|
||||
The incoming connection is tied to a specific listening socket when
|
||||
the initial SYN packet is received during the three-way handshake.
|
||||
When a listener is closed, in-flight request sockets during the
|
||||
handshake and established sockets in the accept queue are aborted.
|
||||
|
||||
If the listener has SO_REUSEPORT enabled, other listeners on the
|
||||
same port should have been able to accept such connections. This
|
||||
option makes it possible to migrate such child sockets to another
|
||||
listener after close() or shutdown().
|
||||
|
||||
The BPF_SK_REUSEPORT_SELECT_OR_MIGRATE type of eBPF program should
|
||||
usually be used to define the policy to pick an alive listener.
|
||||
Otherwise, the kernel will randomly pick an alive listener only if
|
||||
this option is enabled.
|
||||
|
||||
Note that migration between listeners with different settings may
|
||||
crash applications. Let's say migration happens from listener A to
|
||||
B, and only B has TCP_SAVE_SYN enabled. B cannot read SYN data from
|
||||
the requests migrated from A. To avoid such a situation, cancel
|
||||
migration by returning SK_DROP in the type of eBPF program, or
|
||||
disable this option.
|
||||
|
||||
Default: 0
|
||||
|
||||
tcp_fastopen - INTEGER
|
||||
Enable TCP Fast Open (RFC7413) to send and accept data in the opening
|
||||
SYN packet.
|
||||
|
@ -1743,6 +1797,35 @@ fib_multipath_hash_policy - INTEGER
|
|||
- 0 - Layer 3 (source and destination addresses plus flow label)
|
||||
- 1 - Layer 4 (standard 5-tuple)
|
||||
- 2 - Layer 3 or inner Layer 3 if present
|
||||
- 3 - Custom multipath hash. Fields used for multipath hash calculation
|
||||
are determined by fib_multipath_hash_fields sysctl
|
||||
|
||||
fib_multipath_hash_fields - UNSIGNED INTEGER
|
||||
When fib_multipath_hash_policy is set to 3 (custom multipath hash), the
|
||||
fields used for multipath hash calculation are determined by this
|
||||
sysctl.
|
||||
|
||||
This value is a bitmask which enables various fields for multipath hash
|
||||
calculation.
|
||||
|
||||
Possible fields are:
|
||||
|
||||
====== ============================
|
||||
0x0001 Source IP address
|
||||
0x0002 Destination IP address
|
||||
0x0004 IP protocol
|
||||
0x0008 Flow Label
|
||||
0x0010 Source port
|
||||
0x0020 Destination port
|
||||
0x0040 Inner source IP address
|
||||
0x0080 Inner destination IP address
|
||||
0x0100 Inner IP protocol
|
||||
0x0200 Inner Flow Label
|
||||
0x0400 Inner source port
|
||||
0x0800 Inner destination port
|
||||
====== ============================
|
||||
|
||||
Default: 0x0007 (source IP, destination IP and IP protocol)
|
||||
|
||||
anycast_src_echo_reply - BOOLEAN
|
||||
Controls the use of anycast addresses as source addresses for ICMPv6
|
||||
|
@ -2751,6 +2834,18 @@ encap_port - INTEGER
|
|||
|
||||
Default: 0
|
||||
|
||||
plpmtud_probe_interval - INTEGER
|
||||
The time interval (in milliseconds) for the PLPMTUD probe timer,
|
||||
which is configured to expire after this period to receive an
|
||||
acknowledgment to a probe packet. This is also the time interval
|
||||
between the probes for the current pmtu when the probe search
|
||||
is done.
|
||||
|
||||
PLPMTUD will be disabled when 0 is set, and other values for it
|
||||
must be >= 5000.
|
||||
|
||||
Default: 0
|
||||
|
||||
|
||||
``/proc/sys/net/core/*``
|
||||
========================
|
||||
|
|
|
@ -7,13 +7,13 @@ MPTCP Sysfs variables
|
|||
/proc/sys/net/mptcp/* Variables
|
||||
===============================
|
||||
|
||||
enabled - INTEGER
|
||||
enabled - BOOLEAN
|
||||
Control whether MPTCP sockets can be created.
|
||||
|
||||
MPTCP sockets can be created if the value is nonzero. This is
|
||||
a per-namespace sysctl.
|
||||
MPTCP sockets can be created if the value is 1. This is a
|
||||
per-namespace sysctl.
|
||||
|
||||
Default: 1
|
||||
Default: 1 (enabled)
|
||||
|
||||
add_addr_timeout - INTEGER (seconds)
|
||||
Set the timeout after which an ADD_ADDR control message will be
|
||||
|
@ -24,3 +24,24 @@ add_addr_timeout - INTEGER (seconds)
|
|||
sysctl.
|
||||
|
||||
Default: 120
|
||||
|
||||
checksum_enabled - BOOLEAN
|
||||
Control whether DSS checksum can be enabled.
|
||||
|
||||
DSS checksum can be enabled if the value is nonzero. This is a
|
||||
per-namespace sysctl.
|
||||
|
||||
Default: 0
|
||||
|
||||
allow_join_initial_addr_port - BOOLEAN
|
||||
Allow peers to send join requests to the IP address and port number used
|
||||
by the initial subflow if the value is 1. This controls a flag that is
|
||||
sent to the peer at connection time, and whether such join requests are
|
||||
accepted or denied.
|
||||
|
||||
Joins to addresses advertised with ADD_ADDR are not affected by this
|
||||
value.
|
||||
|
||||
This is a per-namespace sysctl.
|
||||
|
||||
Default: 1
|
||||
|
|
|
@ -177,3 +177,27 @@ nf_conntrack_gre_timeout_stream - INTEGER (seconds)
|
|||
|
||||
This extended timeout will be used in case there is an GRE stream
|
||||
detected.
|
||||
|
||||
nf_flowtable_tcp_timeout - INTEGER (seconds)
|
||||
default 30
|
||||
|
||||
Control offload timeout for tcp connections.
|
||||
TCP connections may be offloaded from nf conntrack to nf flow table.
|
||||
Once aged, the connection is returned to nf conntrack with tcp pickup timeout.
|
||||
|
||||
nf_flowtable_tcp_pickup - INTEGER (seconds)
|
||||
default 120
|
||||
|
||||
TCP connection timeout after being aged from nf flow table offload.
|
||||
|
||||
nf_flowtable_udp_timeout - INTEGER (seconds)
|
||||
default 30
|
||||
|
||||
Control offload timeout for udp connections.
|
||||
UDP connections may be offloaded from nf conntrack to nf flow table.
|
||||
Once aged, the connection is returned to nf conntrack with udp pickup timeout.
|
||||
|
||||
nf_flowtable_udp_pickup - INTEGER (seconds)
|
||||
default 30
|
||||
|
||||
UDP connection timeout after being aged from nf flow table offload.
|
||||
|
|
|
@ -292,6 +292,12 @@ Some of the interface modes are described below:
|
|||
Note: due to legacy usage, some 10GBASE-R usage incorrectly makes
|
||||
use of this definition.
|
||||
|
||||
``PHY_INTERFACE_MODE_25GBASER``
|
||||
This is the IEEE 802.3 PCS Clause 107 defined 25GBASE-R protocol.
|
||||
The PCS is identical to 10GBASE-R, i.e. 64B/66B encoded
|
||||
running 2.5 as fast, giving a fixed bit rate of 25.78125 Gbaud.
|
||||
Please refer to the IEEE standard for further information.
|
||||
|
||||
``PHY_INTERFACE_MODE_100BASEX``
|
||||
This defines IEEE 802.3 Clause 24. The link operates at a fixed data
|
||||
rate of 125Mpbs using a 4B/5B encoding scheme, resulting in an underlying
|
||||
|
|
36
MAINTAINERS
36
MAINTAINERS
|
@ -6847,6 +6847,8 @@ F: Documentation/devicetree/bindings/net/mdio*
|
|||
F: Documentation/devicetree/bindings/net/qca,ar803x.yaml
|
||||
F: Documentation/networking/phy.rst
|
||||
F: drivers/net/mdio/
|
||||
F: drivers/net/mdio/acpi_mdio.c
|
||||
F: drivers/net/mdio/fwnode_mdio.c
|
||||
F: drivers/net/mdio/of_mdio.c
|
||||
F: drivers/net/pcs/
|
||||
F: drivers/net/phy/
|
||||
|
@ -9163,6 +9165,7 @@ F: Documentation/networking/device_drivers/ethernet/intel/
|
|||
F: drivers/net/ethernet/intel/
|
||||
F: drivers/net/ethernet/intel/*/
|
||||
F: include/linux/avf/virtchnl.h
|
||||
F: include/linux/net/intel/iidc.h
|
||||
|
||||
INTEL FRAMEBUFFER DRIVER (excluding 810 and 815)
|
||||
M: Maik Broemme <mbroemme@libmpq.org>
|
||||
|
@ -9487,6 +9490,13 @@ L: Dell.Client.Kernel@dell.com
|
|||
S: Maintained
|
||||
F: drivers/platform/x86/intel-wmi-thunderbolt.c
|
||||
|
||||
INTEL WWAN IOSM DRIVER
|
||||
M: M Chetan Kumar <m.chetan.kumar@intel.com>
|
||||
M: Intel Corporation <linuxwwan@intel.com>
|
||||
L: netdev@vger.kernel.org
|
||||
S: Maintained
|
||||
F: drivers/net/wwan/iosm/
|
||||
|
||||
INTEL(R) TRACE HUB
|
||||
M: Alexander Shishkin <alexander.shishkin@linux.intel.com>
|
||||
S: Supported
|
||||
|
@ -12430,6 +12440,12 @@ F: Documentation/userspace-api/media/drivers/meye*
|
|||
F: drivers/media/pci/meye/
|
||||
F: include/uapi/linux/meye.h
|
||||
|
||||
MOTORCOMM PHY DRIVER
|
||||
M: Peter Geis <pgwipeout@gmail.com>
|
||||
L: netdev@vger.kernel.org
|
||||
S: Maintained
|
||||
F: drivers/net/phy/motorcomm.c
|
||||
|
||||
MOXA SMARTIO/INDUSTIO/INTELLIO SERIAL CARD
|
||||
S: Orphan
|
||||
F: Documentation/driver-api/serial/moxa-smartio.rst
|
||||
|
@ -12701,6 +12717,7 @@ W: http://www.netfilter.org/
|
|||
W: http://www.iptables.org/
|
||||
W: http://www.nftables.org/
|
||||
Q: http://patchwork.ozlabs.org/project/netfilter-devel/list/
|
||||
C: irc://irc.libera.chat/netfilter
|
||||
T: git git://git.kernel.org/pub/scm/linux/kernel/git/pablo/nf.git
|
||||
T: git git://git.kernel.org/pub/scm/linux/kernel/git/pablo/nf-next.git
|
||||
F: include/linux/netfilter*
|
||||
|
@ -13238,6 +13255,7 @@ M: Vladimir Oltean <olteanv@gmail.com>
|
|||
L: linux-kernel@vger.kernel.org
|
||||
S: Maintained
|
||||
F: drivers/net/dsa/sja1105
|
||||
F: drivers/net/pcs/pcs-xpcs-nxp.c
|
||||
|
||||
NXP TDA998X DRM DRIVER
|
||||
M: Russell King <linux@armlinux.org.uk>
|
||||
|
@ -15625,6 +15643,13 @@ F: include/linux/rpmsg/
|
|||
F: include/uapi/linux/rpmsg.h
|
||||
F: samples/rpmsg/
|
||||
|
||||
REMOTE PROCESSOR MESSAGING (RPMSG) WWAN CONTROL DRIVER
|
||||
M: Stephan Gerhold <stephan@gerhold.net>
|
||||
L: netdev@vger.kernel.org
|
||||
L: linux-remoteproc@vger.kernel.org
|
||||
S: Maintained
|
||||
F: drivers/net/wwan/rpmsg_wwan_ctrl.c
|
||||
|
||||
RENESAS CLOCK DRIVERS
|
||||
M: Geert Uytterhoeven <geert+renesas@glider.be>
|
||||
L: linux-renesas-soc@vger.kernel.org
|
||||
|
@ -17738,6 +17763,7 @@ M: Jose Abreu <Jose.Abreu@synopsys.com>
|
|||
L: netdev@vger.kernel.org
|
||||
S: Supported
|
||||
F: drivers/net/pcs/pcs-xpcs.c
|
||||
F: drivers/net/pcs/pcs-xpcs.h
|
||||
F: include/linux/pcs/pcs-xpcs.h
|
||||
|
||||
SYNOPSYS DESIGNWARE I2C DRIVER
|
||||
|
@ -19854,6 +19880,16 @@ F: Documentation/core-api/workqueue.rst
|
|||
F: include/linux/workqueue.h
|
||||
F: kernel/workqueue.c
|
||||
|
||||
WWAN DRIVERS
|
||||
M: Loic Poulain <loic.poulain@linaro.org>
|
||||
M: Sergey Ryazanov <ryazanov.s.a@gmail.com>
|
||||
R: Johannes Berg <johannes@sipsolutions.net>
|
||||
L: netdev@vger.kernel.org
|
||||
S: Maintained
|
||||
F: drivers/net/wwan/
|
||||
F: include/linux/wwan.h
|
||||
F: include/uapi/linux/wwan.h
|
||||
|
||||
X-POWERS AXP288 PMIC DRIVERS
|
||||
M: Hans de Goede <hdegoede@redhat.com>
|
||||
S: Maintained
|
||||
|
|
|
@ -127,6 +127,8 @@
|
|||
#define SO_PREFER_BUSY_POLL 69
|
||||
#define SO_BUSY_POLL_BUDGET 70
|
||||
|
||||
#define SO_NETNS_COOKIE 71
|
||||
|
||||
#if !defined(__KERNEL__)
|
||||
|
||||
#if __BITS_PER_LONG == 64
|
||||
|
|
|
@ -135,9 +135,12 @@
|
|||
};
|
||||
};
|
||||
|
||||
reset@611010008 {
|
||||
compatible = "microchip,sparx5-chip-reset";
|
||||
reset: reset-controller@611010008 {
|
||||
compatible = "microchip,sparx5-switch-reset";
|
||||
reg = <0x6 0x11010008 0x4>;
|
||||
reg-names = "gcb";
|
||||
#reset-cells = <1>;
|
||||
cpu-syscon = <&cpu_ctrl>;
|
||||
};
|
||||
|
||||
uart0: serial@600100000 {
|
||||
|
@ -275,6 +278,21 @@
|
|||
"GPIO_46", "GPIO_47";
|
||||
function = "emmc";
|
||||
};
|
||||
|
||||
miim1_pins: miim1-pins {
|
||||
pins = "GPIO_56", "GPIO_57";
|
||||
function = "miim";
|
||||
};
|
||||
|
||||
miim2_pins: miim2-pins {
|
||||
pins = "GPIO_58", "GPIO_59";
|
||||
function = "miim";
|
||||
};
|
||||
|
||||
miim3_pins: miim3-pins {
|
||||
pins = "GPIO_52", "GPIO_53";
|
||||
function = "miim";
|
||||
};
|
||||
};
|
||||
|
||||
sgpio0: gpio@61101036c {
|
||||
|
@ -285,6 +303,8 @@
|
|||
clocks = <&sys_clk>;
|
||||
pinctrl-0 = <&sgpio0_pins>;
|
||||
pinctrl-names = "default";
|
||||
resets = <&reset 0>;
|
||||
reset-names = "switch";
|
||||
reg = <0x6 0x1101036c 0x100>;
|
||||
sgpio_in0: gpio@0 {
|
||||
compatible = "microchip,sparx5-sgpio-bank";
|
||||
|
@ -292,6 +312,9 @@
|
|||
gpio-controller;
|
||||
#gpio-cells = <3>;
|
||||
ngpios = <96>;
|
||||
interrupts = <GIC_SPI 17 IRQ_TYPE_LEVEL_HIGH>;
|
||||
interrupt-controller;
|
||||
#interrupt-cells = <3>;
|
||||
};
|
||||
sgpio_out0: gpio@1 {
|
||||
compatible = "microchip,sparx5-sgpio-bank";
|
||||
|
@ -310,6 +333,8 @@
|
|||
clocks = <&sys_clk>;
|
||||
pinctrl-0 = <&sgpio1_pins>;
|
||||
pinctrl-names = "default";
|
||||
resets = <&reset 0>;
|
||||
reset-names = "switch";
|
||||
reg = <0x6 0x11010484 0x100>;
|
||||
sgpio_in1: gpio@0 {
|
||||
compatible = "microchip,sparx5-sgpio-bank";
|
||||
|
@ -317,6 +342,9 @@
|
|||
gpio-controller;
|
||||
#gpio-cells = <3>;
|
||||
ngpios = <96>;
|
||||
interrupts = <GIC_SPI 18 IRQ_TYPE_LEVEL_HIGH>;
|
||||
interrupt-controller;
|
||||
#interrupt-cells = <3>;
|
||||
};
|
||||
sgpio_out1: gpio@1 {
|
||||
compatible = "microchip,sparx5-sgpio-bank";
|
||||
|
@ -335,6 +363,8 @@
|
|||
clocks = <&sys_clk>;
|
||||
pinctrl-0 = <&sgpio2_pins>;
|
||||
pinctrl-names = "default";
|
||||
resets = <&reset 0>;
|
||||
reset-names = "switch";
|
||||
reg = <0x6 0x1101059c 0x100>;
|
||||
sgpio_in2: gpio@0 {
|
||||
reg = <0>;
|
||||
|
@ -342,6 +372,9 @@
|
|||
gpio-controller;
|
||||
#gpio-cells = <3>;
|
||||
ngpios = <96>;
|
||||
interrupts = <GIC_SPI 19 IRQ_TYPE_LEVEL_HIGH>;
|
||||
interrupt-controller;
|
||||
#interrupt-cells = <3>;
|
||||
};
|
||||
sgpio_out2: gpio@1 {
|
||||
compatible = "microchip,sparx5-sgpio-bank";
|
||||
|
@ -386,5 +419,62 @@
|
|||
#thermal-sensor-cells = <0>;
|
||||
clocks = <&ahb_clk>;
|
||||
};
|
||||
|
||||
mdio0: mdio@6110102b0 {
|
||||
compatible = "mscc,ocelot-miim";
|
||||
status = "disabled";
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
reg = <0x6 0x110102b0 0x24>;
|
||||
};
|
||||
|
||||
mdio1: mdio@6110102d4 {
|
||||
compatible = "mscc,ocelot-miim";
|
||||
status = "disabled";
|
||||
pinctrl-0 = <&miim1_pins>;
|
||||
pinctrl-names = "default";
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
reg = <0x6 0x110102d4 0x24>;
|
||||
};
|
||||
|
||||
mdio2: mdio@6110102f8 {
|
||||
compatible = "mscc,ocelot-miim";
|
||||
status = "disabled";
|
||||
pinctrl-0 = <&miim2_pins>;
|
||||
pinctrl-names = "default";
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
reg = <0x6 0x110102d4 0x24>;
|
||||
};
|
||||
|
||||
mdio3: mdio@61101031c {
|
||||
compatible = "mscc,ocelot-miim";
|
||||
status = "disabled";
|
||||
pinctrl-0 = <&miim3_pins>;
|
||||
pinctrl-names = "default";
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
reg = <0x6 0x1101031c 0x24>;
|
||||
};
|
||||
|
||||
serdes: serdes@10808000 {
|
||||
compatible = "microchip,sparx5-serdes";
|
||||
#phy-cells = <1>;
|
||||
clocks = <&sys_clk>;
|
||||
reg = <0x6 0x10808000 0x5d0000>;
|
||||
};
|
||||
|
||||
switch: switch@0x600000000 {
|
||||
compatible = "microchip,sparx5-switch";
|
||||
reg = <0x6 0 0x401000>,
|
||||
<0x6 0x10004000 0x7fc000>,
|
||||
<0x6 0x11010000 0xaf0000>;
|
||||
reg-names = "cpu", "dev", "gcb";
|
||||
interrupt-names = "xtr";
|
||||
interrupts = <GIC_SPI 30 IRQ_TYPE_LEVEL_HIGH>;
|
||||
resets = <&reset 0>;
|
||||
reset-names = "switch";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
|
|
@ -7,30 +7,6 @@
|
|||
#include "sparx5_pcb_common.dtsi"
|
||||
|
||||
/{
|
||||
aliases {
|
||||
i2c0 = &i2c0;
|
||||
i2c100 = &i2c100;
|
||||
i2c101 = &i2c101;
|
||||
i2c102 = &i2c102;
|
||||
i2c103 = &i2c103;
|
||||
i2c104 = &i2c104;
|
||||
i2c105 = &i2c105;
|
||||
i2c106 = &i2c106;
|
||||
i2c107 = &i2c107;
|
||||
i2c108 = &i2c108;
|
||||
i2c109 = &i2c109;
|
||||
i2c110 = &i2c110;
|
||||
i2c111 = &i2c111;
|
||||
i2c112 = &i2c112;
|
||||
i2c113 = &i2c113;
|
||||
i2c114 = &i2c114;
|
||||
i2c115 = &i2c115;
|
||||
i2c116 = &i2c116;
|
||||
i2c117 = &i2c117;
|
||||
i2c118 = &i2c118;
|
||||
i2c119 = &i2c119;
|
||||
};
|
||||
|
||||
gpio-restart {
|
||||
compatible = "gpio-restart";
|
||||
gpios = <&gpio 37 GPIO_ACTIVE_LOW>;
|
||||
|
@ -298,17 +274,10 @@
|
|||
|
||||
&spi0 {
|
||||
status = "okay";
|
||||
spi@0 {
|
||||
compatible = "spi-mux";
|
||||
mux-controls = <&mux>;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
reg = <0>; /* CS0 */
|
||||
spi-flash@9 {
|
||||
compatible = "jedec,spi-nor";
|
||||
spi-max-frequency = <8000000>;
|
||||
reg = <0x9>; /* SPI */
|
||||
};
|
||||
spi-flash@0 {
|
||||
compatible = "jedec,spi-nor";
|
||||
spi-max-frequency = <8000000>;
|
||||
reg = <0>;
|
||||
};
|
||||
};
|
||||
|
||||
|
@ -328,6 +297,33 @@
|
|||
};
|
||||
};
|
||||
|
||||
&sgpio0 {
|
||||
status = "okay";
|
||||
microchip,sgpio-port-ranges = <8 15>;
|
||||
gpio@0 {
|
||||
ngpios = <64>;
|
||||
};
|
||||
gpio@1 {
|
||||
ngpios = <64>;
|
||||
};
|
||||
};
|
||||
|
||||
&sgpio1 {
|
||||
status = "okay";
|
||||
microchip,sgpio-port-ranges = <24 31>;
|
||||
gpio@0 {
|
||||
ngpios = <64>;
|
||||
};
|
||||
gpio@1 {
|
||||
ngpios = <64>;
|
||||
};
|
||||
};
|
||||
|
||||
&sgpio2 {
|
||||
status = "okay";
|
||||
microchip,sgpio-port-ranges = <0 0>, <11 31>;
|
||||
};
|
||||
|
||||
&gpio {
|
||||
i2cmux_pins_i: i2cmux-pins-i {
|
||||
pins = "GPIO_16", "GPIO_17", "GPIO_18", "GPIO_19",
|
||||
|
@ -415,9 +411,9 @@
|
|||
|
||||
&i2c0_imux {
|
||||
pinctrl-names =
|
||||
"i2c100", "i2c101", "i2c102", "i2c103",
|
||||
"i2c104", "i2c105", "i2c106", "i2c107",
|
||||
"i2c108", "i2c109", "i2c110", "i2c111", "idle";
|
||||
"i2c_sfp1", "i2c_sfp2", "i2c_sfp3", "i2c_sfp4",
|
||||
"i2c_sfp5", "i2c_sfp6", "i2c_sfp7", "i2c_sfp8",
|
||||
"i2c_sfp9", "i2c_sfp10", "i2c_sfp11", "i2c_sfp12", "idle";
|
||||
pinctrl-0 = <&i2cmux_0>;
|
||||
pinctrl-1 = <&i2cmux_1>;
|
||||
pinctrl-2 = <&i2cmux_2>;
|
||||
|
@ -431,62 +427,62 @@
|
|||
pinctrl-10 = <&i2cmux_10>;
|
||||
pinctrl-11 = <&i2cmux_11>;
|
||||
pinctrl-12 = <&i2cmux_pins_i>;
|
||||
i2c100: i2c_sfp1 {
|
||||
i2c_sfp1: i2c_sfp1 {
|
||||
reg = <0x0>;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
};
|
||||
i2c101: i2c_sfp2 {
|
||||
i2c_sfp2: i2c_sfp2 {
|
||||
reg = <0x1>;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
};
|
||||
i2c102: i2c_sfp3 {
|
||||
i2c_sfp3: i2c_sfp3 {
|
||||
reg = <0x2>;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
};
|
||||
i2c103: i2c_sfp4 {
|
||||
i2c_sfp4: i2c_sfp4 {
|
||||
reg = <0x3>;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
};
|
||||
i2c104: i2c_sfp5 {
|
||||
i2c_sfp5: i2c_sfp5 {
|
||||
reg = <0x4>;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
};
|
||||
i2c105: i2c_sfp6 {
|
||||
i2c_sfp6: i2c_sfp6 {
|
||||
reg = <0x5>;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
};
|
||||
i2c106: i2c_sfp7 {
|
||||
i2c_sfp7: i2c_sfp7 {
|
||||
reg = <0x6>;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
};
|
||||
i2c107: i2c_sfp8 {
|
||||
i2c_sfp8: i2c_sfp8 {
|
||||
reg = <0x7>;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
};
|
||||
i2c108: i2c_sfp9 {
|
||||
i2c_sfp9: i2c_sfp9 {
|
||||
reg = <0x8>;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
};
|
||||
i2c109: i2c_sfp10 {
|
||||
i2c_sfp10: i2c_sfp10 {
|
||||
reg = <0x9>;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
};
|
||||
i2c110: i2c_sfp11 {
|
||||
i2c_sfp11: i2c_sfp11 {
|
||||
reg = <0xa>;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
};
|
||||
i2c111: i2c_sfp12 {
|
||||
i2c_sfp12: i2c_sfp12 {
|
||||
reg = <0xb>;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
@ -499,44 +495,413 @@
|
|||
&gpio 61 GPIO_ACTIVE_HIGH
|
||||
&gpio 54 GPIO_ACTIVE_HIGH>;
|
||||
idle-state = <0x8>;
|
||||
i2c112: i2c_sfp13 {
|
||||
i2c_sfp13: i2c_sfp13 {
|
||||
reg = <0x0>;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
};
|
||||
i2c113: i2c_sfp14 {
|
||||
i2c_sfp14: i2c_sfp14 {
|
||||
reg = <0x1>;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
};
|
||||
i2c114: i2c_sfp15 {
|
||||
i2c_sfp15: i2c_sfp15 {
|
||||
reg = <0x2>;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
};
|
||||
i2c115: i2c_sfp16 {
|
||||
i2c_sfp16: i2c_sfp16 {
|
||||
reg = <0x3>;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
};
|
||||
i2c116: i2c_sfp17 {
|
||||
i2c_sfp17: i2c_sfp17 {
|
||||
reg = <0x4>;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
};
|
||||
i2c117: i2c_sfp18 {
|
||||
i2c_sfp18: i2c_sfp18 {
|
||||
reg = <0x5>;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
};
|
||||
i2c118: i2c_sfp19 {
|
||||
i2c_sfp19: i2c_sfp19 {
|
||||
reg = <0x6>;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
};
|
||||
i2c119: i2c_sfp20 {
|
||||
i2c_sfp20: i2c_sfp20 {
|
||||
reg = <0x7>;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
};
|
||||
};
|
||||
|
||||
&mdio3 {
|
||||
status = "ok";
|
||||
phy64: ethernet-phy@64 {
|
||||
reg = <28>;
|
||||
};
|
||||
};
|
||||
|
||||
&axi {
|
||||
sfp_eth12: sfp-eth12 {
|
||||
compatible = "sff,sfp";
|
||||
i2c-bus = <&i2c_sfp1>;
|
||||
tx-disable-gpios = <&sgpio_out2 11 1 GPIO_ACTIVE_LOW>;
|
||||
los-gpios = <&sgpio_in2 11 1 GPIO_ACTIVE_HIGH>;
|
||||
mod-def0-gpios = <&sgpio_in2 11 2 GPIO_ACTIVE_LOW>;
|
||||
tx-fault-gpios = <&sgpio_in2 12 0 GPIO_ACTIVE_HIGH>;
|
||||
};
|
||||
sfp_eth13: sfp-eth13 {
|
||||
compatible = "sff,sfp";
|
||||
i2c-bus = <&i2c_sfp2>;
|
||||
tx-disable-gpios = <&sgpio_out2 12 1 GPIO_ACTIVE_LOW>;
|
||||
los-gpios = <&sgpio_in2 12 1 GPIO_ACTIVE_HIGH>;
|
||||
mod-def0-gpios = <&sgpio_in2 12 2 GPIO_ACTIVE_LOW>;
|
||||
tx-fault-gpios = <&sgpio_in2 13 0 GPIO_ACTIVE_HIGH>;
|
||||
};
|
||||
sfp_eth14: sfp-eth14 {
|
||||
compatible = "sff,sfp";
|
||||
i2c-bus = <&i2c_sfp3>;
|
||||
tx-disable-gpios = <&sgpio_out2 13 1 GPIO_ACTIVE_LOW>;
|
||||
los-gpios = <&sgpio_in2 13 1 GPIO_ACTIVE_HIGH>;
|
||||
mod-def0-gpios = <&sgpio_in2 13 2 GPIO_ACTIVE_LOW>;
|
||||
tx-fault-gpios = <&sgpio_in2 14 0 GPIO_ACTIVE_HIGH>;
|
||||
};
|
||||
sfp_eth15: sfp-eth15 {
|
||||
compatible = "sff,sfp";
|
||||
i2c-bus = <&i2c_sfp4>;
|
||||
tx-disable-gpios = <&sgpio_out2 14 1 GPIO_ACTIVE_LOW>;
|
||||
los-gpios = <&sgpio_in2 14 1 GPIO_ACTIVE_HIGH>;
|
||||
mod-def0-gpios = <&sgpio_in2 14 2 GPIO_ACTIVE_LOW>;
|
||||
tx-fault-gpios = <&sgpio_in2 15 0 GPIO_ACTIVE_HIGH>;
|
||||
};
|
||||
sfp_eth48: sfp-eth48 {
|
||||
compatible = "sff,sfp";
|
||||
i2c-bus = <&i2c_sfp5>;
|
||||
tx-disable-gpios = <&sgpio_out2 15 1 GPIO_ACTIVE_LOW>;
|
||||
los-gpios = <&sgpio_in2 15 1 GPIO_ACTIVE_HIGH>;
|
||||
mod-def0-gpios = <&sgpio_in2 15 2 GPIO_ACTIVE_LOW>;
|
||||
tx-fault-gpios = <&sgpio_in2 16 0 GPIO_ACTIVE_HIGH>;
|
||||
};
|
||||
sfp_eth49: sfp-eth49 {
|
||||
compatible = "sff,sfp";
|
||||
i2c-bus = <&i2c_sfp6>;
|
||||
tx-disable-gpios = <&sgpio_out2 16 1 GPIO_ACTIVE_LOW>;
|
||||
los-gpios = <&sgpio_in2 16 1 GPIO_ACTIVE_HIGH>;
|
||||
mod-def0-gpios = <&sgpio_in2 16 2 GPIO_ACTIVE_LOW>;
|
||||
tx-fault-gpios = <&sgpio_in2 17 0 GPIO_ACTIVE_HIGH>;
|
||||
};
|
||||
sfp_eth50: sfp-eth50 {
|
||||
compatible = "sff,sfp";
|
||||
i2c-bus = <&i2c_sfp7>;
|
||||
tx-disable-gpios = <&sgpio_out2 17 1 GPIO_ACTIVE_LOW>;
|
||||
los-gpios = <&sgpio_in2 17 1 GPIO_ACTIVE_HIGH>;
|
||||
mod-def0-gpios = <&sgpio_in2 17 2 GPIO_ACTIVE_LOW>;
|
||||
tx-fault-gpios = <&sgpio_in2 18 0 GPIO_ACTIVE_HIGH>;
|
||||
};
|
||||
sfp_eth51: sfp-eth51 {
|
||||
compatible = "sff,sfp";
|
||||
i2c-bus = <&i2c_sfp8>;
|
||||
tx-disable-gpios = <&sgpio_out2 18 1 GPIO_ACTIVE_LOW>;
|
||||
los-gpios = <&sgpio_in2 18 1 GPIO_ACTIVE_HIGH>;
|
||||
mod-def0-gpios = <&sgpio_in2 18 2 GPIO_ACTIVE_LOW>;
|
||||
tx-fault-gpios = <&sgpio_in2 19 0 GPIO_ACTIVE_HIGH>;
|
||||
};
|
||||
sfp_eth52: sfp-eth52 {
|
||||
compatible = "sff,sfp";
|
||||
i2c-bus = <&i2c_sfp9>;
|
||||
tx-disable-gpios = <&sgpio_out2 19 1 GPIO_ACTIVE_LOW>;
|
||||
los-gpios = <&sgpio_in2 19 1 GPIO_ACTIVE_HIGH>;
|
||||
mod-def0-gpios = <&sgpio_in2 19 2 GPIO_ACTIVE_LOW>;
|
||||
tx-fault-gpios = <&sgpio_in2 20 0 GPIO_ACTIVE_HIGH>;
|
||||
};
|
||||
sfp_eth53: sfp-eth53 {
|
||||
compatible = "sff,sfp";
|
||||
i2c-bus = <&i2c_sfp10>;
|
||||
tx-disable-gpios = <&sgpio_out2 20 1 GPIO_ACTIVE_LOW>;
|
||||
los-gpios = <&sgpio_in2 20 1 GPIO_ACTIVE_HIGH>;
|
||||
mod-def0-gpios = <&sgpio_in2 20 2 GPIO_ACTIVE_LOW>;
|
||||
tx-fault-gpios = <&sgpio_in2 21 0 GPIO_ACTIVE_HIGH>;
|
||||
};
|
||||
sfp_eth54: sfp-eth54 {
|
||||
compatible = "sff,sfp";
|
||||
i2c-bus = <&i2c_sfp11>;
|
||||
tx-disable-gpios = <&sgpio_out2 21 1 GPIO_ACTIVE_LOW>;
|
||||
los-gpios = <&sgpio_in2 21 1 GPIO_ACTIVE_HIGH>;
|
||||
mod-def0-gpios = <&sgpio_in2 21 2 GPIO_ACTIVE_LOW>;
|
||||
tx-fault-gpios = <&sgpio_in2 22 0 GPIO_ACTIVE_HIGH>;
|
||||
};
|
||||
sfp_eth55: sfp-eth55 {
|
||||
compatible = "sff,sfp";
|
||||
i2c-bus = <&i2c_sfp12>;
|
||||
tx-disable-gpios = <&sgpio_out2 22 1 GPIO_ACTIVE_LOW>;
|
||||
los-gpios = <&sgpio_in2 22 1 GPIO_ACTIVE_HIGH>;
|
||||
mod-def0-gpios = <&sgpio_in2 22 2 GPIO_ACTIVE_LOW>;
|
||||
tx-fault-gpios = <&sgpio_in2 23 0 GPIO_ACTIVE_HIGH>;
|
||||
};
|
||||
sfp_eth56: sfp-eth56 {
|
||||
compatible = "sff,sfp";
|
||||
i2c-bus = <&i2c_sfp13>;
|
||||
tx-disable-gpios = <&sgpio_out2 23 1 GPIO_ACTIVE_LOW>;
|
||||
los-gpios = <&sgpio_in2 23 1 GPIO_ACTIVE_HIGH>;
|
||||
mod-def0-gpios = <&sgpio_in2 23 2 GPIO_ACTIVE_LOW>;
|
||||
tx-fault-gpios = <&sgpio_in2 24 0 GPIO_ACTIVE_HIGH>;
|
||||
};
|
||||
sfp_eth57: sfp-eth57 {
|
||||
compatible = "sff,sfp";
|
||||
i2c-bus = <&i2c_sfp14>;
|
||||
tx-disable-gpios = <&sgpio_out2 24 1 GPIO_ACTIVE_LOW>;
|
||||
los-gpios = <&sgpio_in2 24 1 GPIO_ACTIVE_HIGH>;
|
||||
mod-def0-gpios = <&sgpio_in2 24 2 GPIO_ACTIVE_LOW>;
|
||||
tx-fault-gpios = <&sgpio_in2 25 0 GPIO_ACTIVE_HIGH>;
|
||||
};
|
||||
sfp_eth58: sfp-eth58 {
|
||||
compatible = "sff,sfp";
|
||||
i2c-bus = <&i2c_sfp15>;
|
||||
tx-disable-gpios = <&sgpio_out2 25 1 GPIO_ACTIVE_LOW>;
|
||||
los-gpios = <&sgpio_in2 25 1 GPIO_ACTIVE_HIGH>;
|
||||
mod-def0-gpios = <&sgpio_in2 25 2 GPIO_ACTIVE_LOW>;
|
||||
tx-fault-gpios = <&sgpio_in2 26 0 GPIO_ACTIVE_HIGH>;
|
||||
};
|
||||
sfp_eth59: sfp-eth59 {
|
||||
compatible = "sff,sfp";
|
||||
i2c-bus = <&i2c_sfp16>;
|
||||
tx-disable-gpios = <&sgpio_out2 26 1 GPIO_ACTIVE_LOW>;
|
||||
los-gpios = <&sgpio_in2 26 1 GPIO_ACTIVE_HIGH>;
|
||||
mod-def0-gpios = <&sgpio_in2 26 2 GPIO_ACTIVE_LOW>;
|
||||
tx-fault-gpios = <&sgpio_in2 27 0 GPIO_ACTIVE_HIGH>;
|
||||
};
|
||||
sfp_eth60: sfp-eth60 {
|
||||
compatible = "sff,sfp";
|
||||
i2c-bus = <&i2c_sfp17>;
|
||||
tx-disable-gpios = <&sgpio_out2 27 1 GPIO_ACTIVE_LOW>;
|
||||
los-gpios = <&sgpio_in2 27 1 GPIO_ACTIVE_HIGH>;
|
||||
mod-def0-gpios = <&sgpio_in2 27 2 GPIO_ACTIVE_LOW>;
|
||||
tx-fault-gpios = <&sgpio_in2 28 0 GPIO_ACTIVE_HIGH>;
|
||||
};
|
||||
sfp_eth61: sfp-eth61 {
|
||||
compatible = "sff,sfp";
|
||||
i2c-bus = <&i2c_sfp18>;
|
||||
tx-disable-gpios = <&sgpio_out2 28 1 GPIO_ACTIVE_LOW>;
|
||||
los-gpios = <&sgpio_in2 28 1 GPIO_ACTIVE_HIGH>;
|
||||
mod-def0-gpios = <&sgpio_in2 28 2 GPIO_ACTIVE_LOW>;
|
||||
tx-fault-gpios = <&sgpio_in2 29 0 GPIO_ACTIVE_HIGH>;
|
||||
};
|
||||
sfp_eth62: sfp-eth62 {
|
||||
compatible = "sff,sfp";
|
||||
i2c-bus = <&i2c_sfp19>;
|
||||
tx-disable-gpios = <&sgpio_out2 29 1 GPIO_ACTIVE_LOW>;
|
||||
los-gpios = <&sgpio_in2 29 1 GPIO_ACTIVE_HIGH>;
|
||||
mod-def0-gpios = <&sgpio_in2 29 2 GPIO_ACTIVE_LOW>;
|
||||
tx-fault-gpios = <&sgpio_in2 30 0 GPIO_ACTIVE_HIGH>;
|
||||
};
|
||||
sfp_eth63: sfp-eth63 {
|
||||
compatible = "sff,sfp";
|
||||
i2c-bus = <&i2c_sfp20>;
|
||||
tx-disable-gpios = <&sgpio_out2 30 1 GPIO_ACTIVE_LOW>;
|
||||
los-gpios = <&sgpio_in2 30 1 GPIO_ACTIVE_HIGH>;
|
||||
mod-def0-gpios = <&sgpio_in2 30 2 GPIO_ACTIVE_LOW>;
|
||||
tx-fault-gpios = <&sgpio_in2 31 0 GPIO_ACTIVE_HIGH>;
|
||||
};
|
||||
};
|
||||
|
||||
&switch {
|
||||
ethernet-ports {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
/* 10G SFPs */
|
||||
port12: port@12 {
|
||||
reg = <12>;
|
||||
microchip,bandwidth = <10000>;
|
||||
phys = <&serdes 13>;
|
||||
phy-mode = "10gbase-r";
|
||||
sfp = <&sfp_eth12>;
|
||||
microchip,sd-sgpio = <301>;
|
||||
managed = "in-band-status";
|
||||
};
|
||||
port13: port@13 {
|
||||
reg = <13>;
|
||||
/* Example: CU SFP, 1G speed */
|
||||
microchip,bandwidth = <10000>;
|
||||
phys = <&serdes 14>;
|
||||
phy-mode = "10gbase-r";
|
||||
sfp = <&sfp_eth13>;
|
||||
microchip,sd-sgpio = <305>;
|
||||
managed = "in-band-status";
|
||||
};
|
||||
port14: port@14 {
|
||||
reg = <14>;
|
||||
microchip,bandwidth = <10000>;
|
||||
phys = <&serdes 15>;
|
||||
phy-mode = "10gbase-r";
|
||||
sfp = <&sfp_eth14>;
|
||||
microchip,sd-sgpio = <309>;
|
||||
managed = "in-band-status";
|
||||
};
|
||||
port15: port@15 {
|
||||
reg = <15>;
|
||||
microchip,bandwidth = <10000>;
|
||||
phys = <&serdes 16>;
|
||||
phy-mode = "10gbase-r";
|
||||
sfp = <&sfp_eth15>;
|
||||
microchip,sd-sgpio = <313>;
|
||||
managed = "in-band-status";
|
||||
};
|
||||
port48: port@48 {
|
||||
reg = <48>;
|
||||
microchip,bandwidth = <10000>;
|
||||
phys = <&serdes 17>;
|
||||
phy-mode = "10gbase-r";
|
||||
sfp = <&sfp_eth48>;
|
||||
microchip,sd-sgpio = <317>;
|
||||
managed = "in-band-status";
|
||||
};
|
||||
port49: port@49 {
|
||||
reg = <49>;
|
||||
microchip,bandwidth = <10000>;
|
||||
phys = <&serdes 18>;
|
||||
phy-mode = "10gbase-r";
|
||||
sfp = <&sfp_eth49>;
|
||||
microchip,sd-sgpio = <321>;
|
||||
managed = "in-band-status";
|
||||
};
|
||||
port50: port@50 {
|
||||
reg = <50>;
|
||||
microchip,bandwidth = <10000>;
|
||||
phys = <&serdes 19>;
|
||||
phy-mode = "10gbase-r";
|
||||
sfp = <&sfp_eth50>;
|
||||
microchip,sd-sgpio = <325>;
|
||||
managed = "in-band-status";
|
||||
};
|
||||
port51: port@51 {
|
||||
reg = <51>;
|
||||
microchip,bandwidth = <10000>;
|
||||
phys = <&serdes 20>;
|
||||
phy-mode = "10gbase-r";
|
||||
sfp = <&sfp_eth51>;
|
||||
microchip,sd-sgpio = <329>;
|
||||
managed = "in-band-status";
|
||||
};
|
||||
port52: port@52 {
|
||||
reg = <52>;
|
||||
microchip,bandwidth = <10000>;
|
||||
phys = <&serdes 21>;
|
||||
phy-mode = "10gbase-r";
|
||||
sfp = <&sfp_eth52>;
|
||||
microchip,sd-sgpio = <333>;
|
||||
managed = "in-band-status";
|
||||
};
|
||||
port53: port@53 {
|
||||
reg = <53>;
|
||||
microchip,bandwidth = <10000>;
|
||||
phys = <&serdes 22>;
|
||||
phy-mode = "10gbase-r";
|
||||
sfp = <&sfp_eth53>;
|
||||
microchip,sd-sgpio = <337>;
|
||||
managed = "in-band-status";
|
||||
};
|
||||
port54: port@54 {
|
||||
reg = <54>;
|
||||
microchip,bandwidth = <10000>;
|
||||
phys = <&serdes 23>;
|
||||
phy-mode = "10gbase-r";
|
||||
sfp = <&sfp_eth54>;
|
||||
microchip,sd-sgpio = <341>;
|
||||
managed = "in-band-status";
|
||||
};
|
||||
port55: port@55 {
|
||||
reg = <55>;
|
||||
microchip,bandwidth = <10000>;
|
||||
phys = <&serdes 24>;
|
||||
phy-mode = "10gbase-r";
|
||||
sfp = <&sfp_eth55>;
|
||||
microchip,sd-sgpio = <345>;
|
||||
managed = "in-band-status";
|
||||
};
|
||||
/* 25G SFPs */
|
||||
port56: port@56 {
|
||||
reg = <56>;
|
||||
microchip,bandwidth = <10000>;
|
||||
phys = <&serdes 25>;
|
||||
phy-mode = "10gbase-r";
|
||||
sfp = <&sfp_eth56>;
|
||||
microchip,sd-sgpio = <349>;
|
||||
managed = "in-band-status";
|
||||
};
|
||||
port57: port@57 {
|
||||
reg = <57>;
|
||||
microchip,bandwidth = <10000>;
|
||||
phys = <&serdes 26>;
|
||||
phy-mode = "10gbase-r";
|
||||
sfp = <&sfp_eth57>;
|
||||
microchip,sd-sgpio = <353>;
|
||||
managed = "in-band-status";
|
||||
};
|
||||
port58: port@58 {
|
||||
reg = <58>;
|
||||
microchip,bandwidth = <10000>;
|
||||
phys = <&serdes 27>;
|
||||
phy-mode = "10gbase-r";
|
||||
sfp = <&sfp_eth58>;
|
||||
microchip,sd-sgpio = <357>;
|
||||
managed = "in-band-status";
|
||||
};
|
||||
port59: port@59 {
|
||||
reg = <59>;
|
||||
microchip,bandwidth = <10000>;
|
||||
phys = <&serdes 28>;
|
||||
phy-mode = "10gbase-r";
|
||||
sfp = <&sfp_eth59>;
|
||||
microchip,sd-sgpio = <361>;
|
||||
managed = "in-band-status";
|
||||
};
|
||||
port60: port@60 {
|
||||
reg = <60>;
|
||||
microchip,bandwidth = <10000>;
|
||||
phys = <&serdes 29>;
|
||||
phy-mode = "10gbase-r";
|
||||
sfp = <&sfp_eth60>;
|
||||
microchip,sd-sgpio = <365>;
|
||||
managed = "in-band-status";
|
||||
};
|
||||
port61: port@61 {
|
||||
reg = <61>;
|
||||
microchip,bandwidth = <10000>;
|
||||
phys = <&serdes 30>;
|
||||
phy-mode = "10gbase-r";
|
||||
sfp = <&sfp_eth61>;
|
||||
microchip,sd-sgpio = <369>;
|
||||
managed = "in-band-status";
|
||||
};
|
||||
port62: port@62 {
|
||||
reg = <62>;
|
||||
microchip,bandwidth = <10000>;
|
||||
phys = <&serdes 31>;
|
||||
phy-mode = "10gbase-r";
|
||||
sfp = <&sfp_eth62>;
|
||||
microchip,sd-sgpio = <373>;
|
||||
managed = "in-band-status";
|
||||
};
|
||||
port63: port@63 {
|
||||
reg = <63>;
|
||||
microchip,bandwidth = <10000>;
|
||||
phys = <&serdes 32>;
|
||||
phy-mode = "10gbase-r";
|
||||
sfp = <&sfp_eth63>;
|
||||
microchip,sd-sgpio = <377>;
|
||||
managed = "in-band-status";
|
||||
};
|
||||
/* Finally the Management interface */
|
||||
port64: port@64 {
|
||||
reg = <64>;
|
||||
microchip,bandwidth = <1000>;
|
||||
phys = <&serdes 0>;
|
||||
phy-handle = <&phy64>;
|
||||
phy-mode = "sgmii";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
|
|
@ -7,14 +7,6 @@
|
|||
#include "sparx5_pcb_common.dtsi"
|
||||
|
||||
/{
|
||||
aliases {
|
||||
i2c0 = &i2c0;
|
||||
i2c152 = &i2c152;
|
||||
i2c153 = &i2c153;
|
||||
i2c154 = &i2c154;
|
||||
i2c155 = &i2c155;
|
||||
};
|
||||
|
||||
gpio-restart {
|
||||
compatible = "gpio-restart";
|
||||
gpios = <&gpio 37 GPIO_ACTIVE_LOW>;
|
||||
|
@ -97,17 +89,10 @@
|
|||
|
||||
&spi0 {
|
||||
status = "okay";
|
||||
spi@0 {
|
||||
compatible = "spi-mux";
|
||||
mux-controls = <&mux>;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
reg = <0>; /* CS0 */
|
||||
spi-flash@9 {
|
||||
compatible = "jedec,spi-nor";
|
||||
spi-max-frequency = <8000000>;
|
||||
reg = <0x9>; /* SPI */
|
||||
};
|
||||
spi-flash@0 {
|
||||
compatible = "jedec,spi-nor";
|
||||
spi-max-frequency = <8000000>;
|
||||
reg = <0>;
|
||||
};
|
||||
};
|
||||
|
||||
|
@ -138,6 +123,11 @@
|
|||
};
|
||||
};
|
||||
|
||||
&sgpio2 {
|
||||
status = "okay";
|
||||
microchip,sgpio-port-ranges = <0 0>, <16 18>, <28 31>;
|
||||
};
|
||||
|
||||
&axi {
|
||||
i2c0_imux: i2c0-imux@0 {
|
||||
compatible = "i2c-mux-pinctrl";
|
||||
|
@ -149,31 +139,614 @@
|
|||
|
||||
&i2c0_imux {
|
||||
pinctrl-names =
|
||||
"i2c152", "i2c153", "i2c154", "i2c155",
|
||||
"i2c_sfp1", "i2c_sfp2", "i2c_sfp3", "i2c_sfp4",
|
||||
"idle";
|
||||
pinctrl-0 = <&i2cmux_s29>;
|
||||
pinctrl-1 = <&i2cmux_s30>;
|
||||
pinctrl-2 = <&i2cmux_s31>;
|
||||
pinctrl-3 = <&i2cmux_s32>;
|
||||
pinctrl-4 = <&i2cmux_pins_i>;
|
||||
i2c152: i2c_sfp1 {
|
||||
i2c_sfp1: i2c_sfp1 {
|
||||
reg = <0x0>;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
};
|
||||
i2c153: i2c_sfp2 {
|
||||
i2c_sfp2: i2c_sfp2 {
|
||||
reg = <0x1>;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
};
|
||||
i2c154: i2c_sfp3 {
|
||||
i2c_sfp3: i2c_sfp3 {
|
||||
reg = <0x2>;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
};
|
||||
i2c155: i2c_sfp4 {
|
||||
i2c_sfp4: i2c_sfp4 {
|
||||
reg = <0x3>;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
};
|
||||
};
|
||||
|
||||
&axi {
|
||||
sfp_eth60: sfp-eth60 {
|
||||
compatible = "sff,sfp";
|
||||
i2c-bus = <&i2c_sfp1>;
|
||||
tx-disable-gpios = <&sgpio_out2 28 0 GPIO_ACTIVE_LOW>;
|
||||
rate-select0-gpios = <&sgpio_out2 28 1 GPIO_ACTIVE_HIGH>;
|
||||
los-gpios = <&sgpio_in2 28 0 GPIO_ACTIVE_HIGH>;
|
||||
mod-def0-gpios = <&sgpio_in2 28 1 GPIO_ACTIVE_LOW>;
|
||||
tx-fault-gpios = <&sgpio_in2 28 2 GPIO_ACTIVE_HIGH>;
|
||||
};
|
||||
sfp_eth61: sfp-eth61 {
|
||||
compatible = "sff,sfp";
|
||||
i2c-bus = <&i2c_sfp2>;
|
||||
tx-disable-gpios = <&sgpio_out2 29 0 GPIO_ACTIVE_LOW>;
|
||||
rate-select0-gpios = <&sgpio_out2 29 1 GPIO_ACTIVE_HIGH>;
|
||||
los-gpios = <&sgpio_in2 29 0 GPIO_ACTIVE_HIGH>;
|
||||
mod-def0-gpios = <&sgpio_in2 29 1 GPIO_ACTIVE_LOW>;
|
||||
tx-fault-gpios = <&sgpio_in2 29 2 GPIO_ACTIVE_HIGH>;
|
||||
};
|
||||
sfp_eth62: sfp-eth62 {
|
||||
compatible = "sff,sfp";
|
||||
i2c-bus = <&i2c_sfp3>;
|
||||
tx-disable-gpios = <&sgpio_out2 30 0 GPIO_ACTIVE_LOW>;
|
||||
rate-select0-gpios = <&sgpio_out2 30 1 GPIO_ACTIVE_HIGH>;
|
||||
los-gpios = <&sgpio_in2 30 0 GPIO_ACTIVE_HIGH>;
|
||||
mod-def0-gpios = <&sgpio_in2 30 1 GPIO_ACTIVE_LOW>;
|
||||
tx-fault-gpios = <&sgpio_in2 30 2 GPIO_ACTIVE_HIGH>;
|
||||
};
|
||||
sfp_eth63: sfp-eth63 {
|
||||
compatible = "sff,sfp";
|
||||
i2c-bus = <&i2c_sfp4>;
|
||||
tx-disable-gpios = <&sgpio_out2 31 0 GPIO_ACTIVE_LOW>;
|
||||
rate-select0-gpios = <&sgpio_out2 31 1 GPIO_ACTIVE_HIGH>;
|
||||
los-gpios = <&sgpio_in2 31 0 GPIO_ACTIVE_HIGH>;
|
||||
mod-def0-gpios = <&sgpio_in2 31 1 GPIO_ACTIVE_LOW>;
|
||||
tx-fault-gpios = <&sgpio_in2 31 2 GPIO_ACTIVE_HIGH>;
|
||||
};
|
||||
};
|
||||
|
||||
&mdio0 {
|
||||
status = "ok";
|
||||
phy0: ethernet-phy@0 {
|
||||
reg = <0>;
|
||||
};
|
||||
phy1: ethernet-phy@1 {
|
||||
reg = <1>;
|
||||
};
|
||||
phy2: ethernet-phy@2 {
|
||||
reg = <2>;
|
||||
};
|
||||
phy3: ethernet-phy@3 {
|
||||
reg = <3>;
|
||||
};
|
||||
phy4: ethernet-phy@4 {
|
||||
reg = <4>;
|
||||
};
|
||||
phy5: ethernet-phy@5 {
|
||||
reg = <5>;
|
||||
};
|
||||
phy6: ethernet-phy@6 {
|
||||
reg = <6>;
|
||||
};
|
||||
phy7: ethernet-phy@7 {
|
||||
reg = <7>;
|
||||
};
|
||||
phy8: ethernet-phy@8 {
|
||||
reg = <8>;
|
||||
};
|
||||
phy9: ethernet-phy@9 {
|
||||
reg = <9>;
|
||||
};
|
||||
phy10: ethernet-phy@10 {
|
||||
reg = <10>;
|
||||
};
|
||||
phy11: ethernet-phy@11 {
|
||||
reg = <11>;
|
||||
};
|
||||
phy12: ethernet-phy@12 {
|
||||
reg = <12>;
|
||||
};
|
||||
phy13: ethernet-phy@13 {
|
||||
reg = <13>;
|
||||
};
|
||||
phy14: ethernet-phy@14 {
|
||||
reg = <14>;
|
||||
};
|
||||
phy15: ethernet-phy@15 {
|
||||
reg = <15>;
|
||||
};
|
||||
phy16: ethernet-phy@16 {
|
||||
reg = <16>;
|
||||
};
|
||||
phy17: ethernet-phy@17 {
|
||||
reg = <17>;
|
||||
};
|
||||
phy18: ethernet-phy@18 {
|
||||
reg = <18>;
|
||||
};
|
||||
phy19: ethernet-phy@19 {
|
||||
reg = <19>;
|
||||
};
|
||||
phy20: ethernet-phy@20 {
|
||||
reg = <20>;
|
||||
};
|
||||
phy21: ethernet-phy@21 {
|
||||
reg = <21>;
|
||||
};
|
||||
phy22: ethernet-phy@22 {
|
||||
reg = <22>;
|
||||
};
|
||||
phy23: ethernet-phy@23 {
|
||||
reg = <23>;
|
||||
};
|
||||
};
|
||||
|
||||
&mdio1 {
|
||||
status = "ok";
|
||||
phy24: ethernet-phy@24 {
|
||||
reg = <0>;
|
||||
};
|
||||
phy25: ethernet-phy@25 {
|
||||
reg = <1>;
|
||||
};
|
||||
phy26: ethernet-phy@26 {
|
||||
reg = <2>;
|
||||
};
|
||||
phy27: ethernet-phy@27 {
|
||||
reg = <3>;
|
||||
};
|
||||
phy28: ethernet-phy@28 {
|
||||
reg = <4>;
|
||||
};
|
||||
phy29: ethernet-phy@29 {
|
||||
reg = <5>;
|
||||
};
|
||||
phy30: ethernet-phy@30 {
|
||||
reg = <6>;
|
||||
};
|
||||
phy31: ethernet-phy@31 {
|
||||
reg = <7>;
|
||||
};
|
||||
phy32: ethernet-phy@32 {
|
||||
reg = <8>;
|
||||
};
|
||||
phy33: ethernet-phy@33 {
|
||||
reg = <9>;
|
||||
};
|
||||
phy34: ethernet-phy@34 {
|
||||
reg = <10>;
|
||||
};
|
||||
phy35: ethernet-phy@35 {
|
||||
reg = <11>;
|
||||
};
|
||||
phy36: ethernet-phy@36 {
|
||||
reg = <12>;
|
||||
};
|
||||
phy37: ethernet-phy@37 {
|
||||
reg = <13>;
|
||||
};
|
||||
phy38: ethernet-phy@38 {
|
||||
reg = <14>;
|
||||
};
|
||||
phy39: ethernet-phy@39 {
|
||||
reg = <15>;
|
||||
};
|
||||
phy40: ethernet-phy@40 {
|
||||
reg = <16>;
|
||||
};
|
||||
phy41: ethernet-phy@41 {
|
||||
reg = <17>;
|
||||
};
|
||||
phy42: ethernet-phy@42 {
|
||||
reg = <18>;
|
||||
};
|
||||
phy43: ethernet-phy@43 {
|
||||
reg = <19>;
|
||||
};
|
||||
phy44: ethernet-phy@44 {
|
||||
reg = <20>;
|
||||
};
|
||||
phy45: ethernet-phy@45 {
|
||||
reg = <21>;
|
||||
};
|
||||
phy46: ethernet-phy@46 {
|
||||
reg = <22>;
|
||||
};
|
||||
phy47: ethernet-phy@47 {
|
||||
reg = <23>;
|
||||
};
|
||||
};
|
||||
|
||||
&mdio3 {
|
||||
status = "ok";
|
||||
phy64: ethernet-phy@64 {
|
||||
reg = <28>;
|
||||
};
|
||||
};
|
||||
|
||||
&switch {
|
||||
ethernet-ports {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
port0: port@0 {
|
||||
reg = <0>;
|
||||
microchip,bandwidth = <1000>;
|
||||
phys = <&serdes 13>;
|
||||
phy-handle = <&phy0>;
|
||||
phy-mode = "qsgmii";
|
||||
};
|
||||
port1: port@1 {
|
||||
reg = <1>;
|
||||
microchip,bandwidth = <1000>;
|
||||
phys = <&serdes 13>;
|
||||
phy-handle = <&phy1>;
|
||||
phy-mode = "qsgmii";
|
||||
};
|
||||
port2: port@2 {
|
||||
reg = <2>;
|
||||
microchip,bandwidth = <1000>;
|
||||
phys = <&serdes 13>;
|
||||
phy-handle = <&phy2>;
|
||||
phy-mode = "qsgmii";
|
||||
};
|
||||
port3: port@3 {
|
||||
reg = <3>;
|
||||
microchip,bandwidth = <1000>;
|
||||
phys = <&serdes 13>;
|
||||
phy-handle = <&phy3>;
|
||||
phy-mode = "qsgmii";
|
||||
};
|
||||
port4: port@4 {
|
||||
reg = <4>;
|
||||
microchip,bandwidth = <1000>;
|
||||
phys = <&serdes 14>;
|
||||
phy-handle = <&phy4>;
|
||||
phy-mode = "qsgmii";
|
||||
};
|
||||
port5: port@5 {
|
||||
reg = <5>;
|
||||
microchip,bandwidth = <1000>;
|
||||
phys = <&serdes 14>;
|
||||
phy-handle = <&phy5>;
|
||||
phy-mode = "qsgmii";
|
||||
};
|
||||
port6: port@6 {
|
||||
reg = <6>;
|
||||
microchip,bandwidth = <1000>;
|
||||
phys = <&serdes 14>;
|
||||
phy-handle = <&phy6>;
|
||||
phy-mode = "qsgmii";
|
||||
};
|
||||
port7: port@7 {
|
||||
reg = <7>;
|
||||
microchip,bandwidth = <1000>;
|
||||
phys = <&serdes 14>;
|
||||
phy-handle = <&phy7>;
|
||||
phy-mode = "qsgmii";
|
||||
};
|
||||
port8: port@8 {
|
||||
reg = <8>;
|
||||
microchip,bandwidth = <1000>;
|
||||
phys = <&serdes 15>;
|
||||
phy-handle = <&phy8>;
|
||||
phy-mode = "qsgmii";
|
||||
};
|
||||
port9: port@9 {
|
||||
reg = <9>;
|
||||
microchip,bandwidth = <1000>;
|
||||
phys = <&serdes 15>;
|
||||
phy-handle = <&phy9>;
|
||||
phy-mode = "qsgmii";
|
||||
};
|
||||
port10: port@10 {
|
||||
reg = <10>;
|
||||
microchip,bandwidth = <1000>;
|
||||
phys = <&serdes 15>;
|
||||
phy-handle = <&phy10>;
|
||||
phy-mode = "qsgmii";
|
||||
};
|
||||
port11: port@11 {
|
||||
reg = <11>;
|
||||
microchip,bandwidth = <1000>;
|
||||
phys = <&serdes 15>;
|
||||
phy-handle = <&phy11>;
|
||||
phy-mode = "qsgmii";
|
||||
};
|
||||
port12: port@12 {
|
||||
reg = <12>;
|
||||
microchip,bandwidth = <1000>;
|
||||
phys = <&serdes 16>;
|
||||
phy-handle = <&phy12>;
|
||||
phy-mode = "qsgmii";
|
||||
};
|
||||
port13: port@13 {
|
||||
reg = <13>;
|
||||
microchip,bandwidth = <1000>;
|
||||
phys = <&serdes 16>;
|
||||
phy-handle = <&phy13>;
|
||||
phy-mode = "qsgmii";
|
||||
};
|
||||
port14: port@14 {
|
||||
reg = <14>;
|
||||
microchip,bandwidth = <1000>;
|
||||
phys = <&serdes 16>;
|
||||
phy-handle = <&phy14>;
|
||||
phy-mode = "qsgmii";
|
||||
};
|
||||
port15: port@15 {
|
||||
reg = <15>;
|
||||
microchip,bandwidth = <1000>;
|
||||
phys = <&serdes 16>;
|
||||
phy-handle = <&phy15>;
|
||||
phy-mode = "qsgmii";
|
||||
};
|
||||
port16: port@16 {
|
||||
reg = <16>;
|
||||
microchip,bandwidth = <1000>;
|
||||
phys = <&serdes 17>;
|
||||
phy-handle = <&phy16>;
|
||||
phy-mode = "qsgmii";
|
||||
};
|
||||
port17: port@17 {
|
||||
reg = <17>;
|
||||
microchip,bandwidth = <1000>;
|
||||
phys = <&serdes 17>;
|
||||
phy-handle = <&phy17>;
|
||||
phy-mode = "qsgmii";
|
||||
};
|
||||
port18: port@18 {
|
||||
reg = <18>;
|
||||
microchip,bandwidth = <1000>;
|
||||
phys = <&serdes 17>;
|
||||
phy-handle = <&phy18>;
|
||||
phy-mode = "qsgmii";
|
||||
};
|
||||
port19: port@19 {
|
||||
reg = <19>;
|
||||
microchip,bandwidth = <1000>;
|
||||
phys = <&serdes 17>;
|
||||
phy-handle = <&phy19>;
|
||||
phy-mode = "qsgmii";
|
||||
};
|
||||
port20: port@20 {
|
||||
reg = <20>;
|
||||
microchip,bandwidth = <1000>;
|
||||
phys = <&serdes 18>;
|
||||
phy-handle = <&phy20>;
|
||||
phy-mode = "qsgmii";
|
||||
};
|
||||
port21: port@21 {
|
||||
reg = <21>;
|
||||
microchip,bandwidth = <1000>;
|
||||
phys = <&serdes 18>;
|
||||
phy-handle = <&phy21>;
|
||||
phy-mode = "qsgmii";
|
||||
};
|
||||
port22: port@22 {
|
||||
reg = <22>;
|
||||
microchip,bandwidth = <1000>;
|
||||
phys = <&serdes 18>;
|
||||
phy-handle = <&phy22>;
|
||||
phy-mode = "qsgmii";
|
||||
};
|
||||
port23: port@23 {
|
||||
reg = <23>;
|
||||
microchip,bandwidth = <1000>;
|
||||
phys = <&serdes 18>;
|
||||
phy-handle = <&phy23>;
|
||||
phy-mode = "qsgmii";
|
||||
};
|
||||
port24: port@24 {
|
||||
reg = <24>;
|
||||
microchip,bandwidth = <1000>;
|
||||
phys = <&serdes 19>;
|
||||
phy-handle = <&phy24>;
|
||||
phy-mode = "qsgmii";
|
||||
};
|
||||
port25: port@25 {
|
||||
reg = <25>;
|
||||
microchip,bandwidth = <1000>;
|
||||
phys = <&serdes 19>;
|
||||
phy-handle = <&phy25>;
|
||||
phy-mode = "qsgmii";
|
||||
};
|
||||
port26: port@26 {
|
||||
reg = <26>;
|
||||
microchip,bandwidth = <1000>;
|
||||
phys = <&serdes 19>;
|
||||
phy-handle = <&phy26>;
|
||||
phy-mode = "qsgmii";
|
||||
};
|
||||
port27: port@27 {
|
||||
reg = <27>;
|
||||
microchip,bandwidth = <1000>;
|
||||
phys = <&serdes 19>;
|
||||
phy-handle = <&phy27>;
|
||||
phy-mode = "qsgmii";
|
||||
};
|
||||
port28: port@28 {
|
||||
reg = <28>;
|
||||
microchip,bandwidth = <1000>;
|
||||
phys = <&serdes 20>;
|
||||
phy-handle = <&phy28>;
|
||||
phy-mode = "qsgmii";
|
||||
};
|
||||
port29: port@29 {
|
||||
reg = <29>;
|
||||
microchip,bandwidth = <1000>;
|
||||
phys = <&serdes 20>;
|
||||
phy-handle = <&phy29>;
|
||||
phy-mode = "qsgmii";
|
||||
};
|
||||
port30: port@30 {
|
||||
reg = <30>;
|
||||
microchip,bandwidth = <1000>;
|
||||
phys = <&serdes 20>;
|
||||
phy-handle = <&phy30>;
|
||||
phy-mode = "qsgmii";
|
||||
};
|
||||
port31: port@31 {
|
||||
reg = <31>;
|
||||
microchip,bandwidth = <1000>;
|
||||
phys = <&serdes 20>;
|
||||
phy-handle = <&phy31>;
|
||||
phy-mode = "qsgmii";
|
||||
};
|
||||
port32: port@32 {
|
||||
reg = <32>;
|
||||
microchip,bandwidth = <1000>;
|
||||
phys = <&serdes 21>;
|
||||
phy-handle = <&phy32>;
|
||||
phy-mode = "qsgmii";
|
||||
};
|
||||
port33: port@33 {
|
||||
reg = <33>;
|
||||
microchip,bandwidth = <1000>;
|
||||
phys = <&serdes 21>;
|
||||
phy-handle = <&phy33>;
|
||||
phy-mode = "qsgmii";
|
||||
};
|
||||
port34: port@34 {
|
||||
reg = <34>;
|
||||
microchip,bandwidth = <1000>;
|
||||
phys = <&serdes 21>;
|
||||
phy-handle = <&phy34>;
|
||||
phy-mode = "qsgmii";
|
||||
};
|
||||
port35: port@35 {
|
||||
reg = <35>;
|
||||
microchip,bandwidth = <1000>;
|
||||
phys = <&serdes 21>;
|
||||
phy-handle = <&phy35>;
|
||||
phy-mode = "qsgmii";
|
||||
};
|
||||
port36: port@36 {
|
||||
reg = <36>;
|
||||
microchip,bandwidth = <1000>;
|
||||
phys = <&serdes 22>;
|
||||
phy-handle = <&phy36>;
|
||||
phy-mode = "qsgmii";
|
||||
};
|
||||
port37: port@37 {
|
||||
reg = <37>;
|
||||
microchip,bandwidth = <1000>;
|
||||
phys = <&serdes 22>;
|
||||
phy-handle = <&phy37>;
|
||||
phy-mode = "qsgmii";
|
||||
};
|
||||
port38: port@38 {
|
||||
reg = <38>;
|
||||
microchip,bandwidth = <1000>;
|
||||
phys = <&serdes 22>;
|
||||
phy-handle = <&phy38>;
|
||||
phy-mode = "qsgmii";
|
||||
};
|
||||
port39: port@39 {
|
||||
reg = <39>;
|
||||
microchip,bandwidth = <1000>;
|
||||
phys = <&serdes 22>;
|
||||
phy-handle = <&phy39>;
|
||||
phy-mode = "qsgmii";
|
||||
};
|
||||
port40: port@40 {
|
||||
reg = <40>;
|
||||
microchip,bandwidth = <1000>;
|
||||
phys = <&serdes 23>;
|
||||
phy-handle = <&phy40>;
|
||||
phy-mode = "qsgmii";
|
||||
};
|
||||
port41: port@41 {
|
||||
reg = <41>;
|
||||
microchip,bandwidth = <1000>;
|
||||
phys = <&serdes 23>;
|
||||
phy-handle = <&phy41>;
|
||||
phy-mode = "qsgmii";
|
||||
};
|
||||
port42: port@42 {
|
||||
reg = <42>;
|
||||
microchip,bandwidth = <1000>;
|
||||
phys = <&serdes 23>;
|
||||
phy-handle = <&phy42>;
|
||||
phy-mode = "qsgmii";
|
||||
};
|
||||
port43: port@43 {
|
||||
reg = <43>;
|
||||
microchip,bandwidth = <1000>;
|
||||
phys = <&serdes 23>;
|
||||
phy-handle = <&phy43>;
|
||||
phy-mode = "qsgmii";
|
||||
};
|
||||
port44: port@44 {
|
||||
reg = <44>;
|
||||
microchip,bandwidth = <1000>;
|
||||
phys = <&serdes 24>;
|
||||
phy-handle = <&phy44>;
|
||||
phy-mode = "qsgmii";
|
||||
};
|
||||
port45: port@45 {
|
||||
reg = <45>;
|
||||
microchip,bandwidth = <1000>;
|
||||
phys = <&serdes 24>;
|
||||
phy-handle = <&phy45>;
|
||||
phy-mode = "qsgmii";
|
||||
};
|
||||
port46: port@46 {
|
||||
reg = <46>;
|
||||
microchip,bandwidth = <1000>;
|
||||
phys = <&serdes 24>;
|
||||
phy-handle = <&phy46>;
|
||||
phy-mode = "qsgmii";
|
||||
};
|
||||
port47: port@47 {
|
||||
reg = <47>;
|
||||
microchip,bandwidth = <1000>;
|
||||
phys = <&serdes 24>;
|
||||
phy-handle = <&phy47>;
|
||||
phy-mode = "qsgmii";
|
||||
};
|
||||
/* Then the 25G interfaces */
|
||||
port60: port@60 {
|
||||
reg = <60>;
|
||||
microchip,bandwidth = <25000>;
|
||||
phys = <&serdes 29>;
|
||||
phy-mode = "10gbase-r";
|
||||
sfp = <&sfp_eth60>;
|
||||
managed = "in-band-status";
|
||||
};
|
||||
port61: port@61 {
|
||||
reg = <61>;
|
||||
microchip,bandwidth = <25000>;
|
||||
phys = <&serdes 30>;
|
||||
phy-mode = "10gbase-r";
|
||||
sfp = <&sfp_eth61>;
|
||||
managed = "in-band-status";
|
||||
};
|
||||
port62: port@62 {
|
||||
reg = <62>;
|
||||
microchip,bandwidth = <25000>;
|
||||
phys = <&serdes 31>;
|
||||
phy-mode = "10gbase-r";
|
||||
sfp = <&sfp_eth62>;
|
||||
managed = "in-band-status";
|
||||
};
|
||||
port63: port@63 {
|
||||
reg = <63>;
|
||||
microchip,bandwidth = <25000>;
|
||||
phys = <&serdes 32>;
|
||||
phy-mode = "10gbase-r";
|
||||
sfp = <&sfp_eth63>;
|
||||
managed = "in-band-status";
|
||||
};
|
||||
/* Finally the Management interface */
|
||||
port64: port@64 {
|
||||
reg = <64>;
|
||||
microchip,bandwidth = <1000>;
|
||||
phys = <&serdes 0>;
|
||||
phy-handle = <&phy64>;
|
||||
phy-mode = "sgmii";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
|
|
@ -637,6 +637,28 @@
|
|||
status = "disabled";
|
||||
};
|
||||
|
||||
gmac: ethernet@ff4e0000 {
|
||||
compatible = "rockchip,rk3308-gmac";
|
||||
reg = <0x0 0xff4e0000 0x0 0x10000>;
|
||||
interrupts = <GIC_SPI 64 IRQ_TYPE_LEVEL_HIGH>;
|
||||
interrupt-names = "macirq";
|
||||
clocks = <&cru SCLK_MAC>, <&cru SCLK_MAC_RX_TX>,
|
||||
<&cru SCLK_MAC_RX_TX>, <&cru SCLK_MAC_REF>,
|
||||
<&cru SCLK_MAC>, <&cru ACLK_MAC>,
|
||||
<&cru PCLK_MAC>, <&cru SCLK_MAC_RMII>;
|
||||
clock-names = "stmmaceth", "mac_clk_rx",
|
||||
"mac_clk_tx", "clk_mac_ref",
|
||||
"clk_mac_refout", "aclk_mac",
|
||||
"pclk_mac", "clk_mac_speed";
|
||||
phy-mode = "rmii";
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&rmii_pins &mac_refclk_12ma>;
|
||||
resets = <&cru SRST_MAC_A>;
|
||||
reset-names = "stmmaceth";
|
||||
rockchip,grf = <&grf>;
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
cru: clock-controller@ff500000 {
|
||||
compatible = "rockchip,rk3308-cru";
|
||||
reg = <0x0 0xff500000 0x0 0x1000>;
|
||||
|
|
|
@ -179,9 +179,6 @@ static bool is_addsub_imm(u32 imm)
|
|||
return !(imm & ~0xfff) || !(imm & ~0xfff000);
|
||||
}
|
||||
|
||||
/* Stack must be multiples of 16B */
|
||||
#define STACK_ALIGN(sz) (((sz) + 15) & ~15)
|
||||
|
||||
/* Tail call offset to jump into */
|
||||
#if IS_ENABLED(CONFIG_ARM64_BTI_KERNEL)
|
||||
#define PROLOGUE_OFFSET 8
|
||||
|
@ -256,7 +253,8 @@ static int build_prologue(struct jit_ctx *ctx, bool ebpf_from_cbpf)
|
|||
emit(A64_BTI_J, ctx);
|
||||
}
|
||||
|
||||
ctx->stack_size = STACK_ALIGN(prog->aux->stack_depth);
|
||||
/* Stack must be multiples of 16B */
|
||||
ctx->stack_size = round_up(prog->aux->stack_depth, 16);
|
||||
|
||||
/* Set up function call stack */
|
||||
emit(A64_SUB_I(1, A64_SP, A64_SP, ctx->stack_size), ctx);
|
||||
|
@ -488,17 +486,12 @@ static int build_insn(const struct bpf_insn *insn, struct jit_ctx *ctx,
|
|||
break;
|
||||
case BPF_ALU | BPF_DIV | BPF_X:
|
||||
case BPF_ALU64 | BPF_DIV | BPF_X:
|
||||
emit(A64_UDIV(is64, dst, dst, src), ctx);
|
||||
break;
|
||||
case BPF_ALU | BPF_MOD | BPF_X:
|
||||
case BPF_ALU64 | BPF_MOD | BPF_X:
|
||||
switch (BPF_OP(code)) {
|
||||
case BPF_DIV:
|
||||
emit(A64_UDIV(is64, dst, dst, src), ctx);
|
||||
break;
|
||||
case BPF_MOD:
|
||||
emit(A64_UDIV(is64, tmp, dst, src), ctx);
|
||||
emit(A64_MSUB(is64, dst, dst, tmp, src), ctx);
|
||||
break;
|
||||
}
|
||||
emit(A64_UDIV(is64, tmp, dst, src), ctx);
|
||||
emit(A64_MSUB(is64, dst, dst, tmp, src), ctx);
|
||||
break;
|
||||
case BPF_ALU | BPF_LSH | BPF_X:
|
||||
case BPF_ALU64 | BPF_LSH | BPF_X:
|
||||
|
|
|
@ -114,6 +114,52 @@
|
|||
ranges = <0x01000000 0x0 0x00000000 0x0 0x18000000 0x0 0x00010000>,
|
||||
<0x02000000 0x0 0x40000000 0x0 0x40000000 0x0 0x40000000>;
|
||||
|
||||
gmac@3,0 {
|
||||
compatible = "pci0014,7a03.0",
|
||||
"pci0014,7a03",
|
||||
"pciclass0c0320",
|
||||
"pciclass0c03",
|
||||
"loongson, pci-gmac";
|
||||
|
||||
reg = <0x1800 0x0 0x0 0x0 0x0>;
|
||||
interrupts = <12 IRQ_TYPE_LEVEL_LOW>,
|
||||
<13 IRQ_TYPE_LEVEL_LOW>;
|
||||
interrupt-names = "macirq", "eth_lpi";
|
||||
interrupt-parent = <&liointc0>;
|
||||
phy-mode = "rgmii";
|
||||
mdio {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
compatible = "snps,dwmac-mdio";
|
||||
phy0: ethernet-phy@0 {
|
||||
reg = <0>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
gmac@3,1 {
|
||||
compatible = "pci0014,7a03.0",
|
||||
"pci0014,7a03",
|
||||
"pciclass0c0320",
|
||||
"pciclass0c03",
|
||||
"loongson, pci-gmac";
|
||||
|
||||
reg = <0x1900 0x0 0x0 0x0 0x0>;
|
||||
interrupts = <14 IRQ_TYPE_LEVEL_LOW>,
|
||||
<15 IRQ_TYPE_LEVEL_LOW>;
|
||||
interrupt-names = "macirq", "eth_lpi";
|
||||
interrupt-parent = <&liointc0>;
|
||||
phy-mode = "rgmii";
|
||||
mdio {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
compatible = "snps,dwmac-mdio";
|
||||
phy1: ethernet-phy@1 {
|
||||
reg = <0>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
ehci@4,1 {
|
||||
compatible = "pci0014,7a14.0",
|
||||
"pci0014,7a14",
|
||||
|
|
|
@ -186,7 +186,8 @@
|
|||
compatible = "pci0014,7a03.0",
|
||||
"pci0014,7a03",
|
||||
"pciclass020000",
|
||||
"pciclass0200";
|
||||
"pciclass0200",
|
||||
"loongson, pci-gmac";
|
||||
|
||||
reg = <0x1800 0x0 0x0 0x0 0x0>;
|
||||
interrupts = <12 IRQ_TYPE_LEVEL_HIGH>,
|
||||
|
@ -208,7 +209,8 @@
|
|||
compatible = "pci0014,7a03.0",
|
||||
"pci0014,7a03",
|
||||
"pciclass020000",
|
||||
"pciclass0200";
|
||||
"pciclass0200",
|
||||
"loongson, pci-gmac";
|
||||
|
||||
reg = <0x1900 0x0 0x0 0x0 0x0>;
|
||||
interrupts = <14 IRQ_TYPE_LEVEL_HIGH>,
|
||||
|
|
|
@ -138,6 +138,8 @@
|
|||
#define SO_PREFER_BUSY_POLL 69
|
||||
#define SO_BUSY_POLL_BUDGET 70
|
||||
|
||||
#define SO_NETNS_COOKIE 71
|
||||
|
||||
#if !defined(__KERNEL__)
|
||||
|
||||
#if __BITS_PER_LONG == 64
|
||||
|
|
|
@ -119,6 +119,8 @@
|
|||
#define SO_PREFER_BUSY_POLL 0x4043
|
||||
#define SO_BUSY_POLL_BUDGET 0x4044
|
||||
|
||||
#define SO_NETNS_COOKIE 0x4045
|
||||
|
||||
#if !defined(__KERNEL__)
|
||||
|
||||
#if __BITS_PER_LONG == 64
|
||||
|
|
|
@ -137,7 +137,6 @@ struct slibe {
|
|||
* @user0: user defineable value
|
||||
* @res4: reserved paramater
|
||||
* @user1: user defineable value
|
||||
* @user2: user defineable value
|
||||
*/
|
||||
struct qaob {
|
||||
u64 res0[6];
|
||||
|
@ -152,8 +151,7 @@ struct qaob {
|
|||
u16 dcount[QDIO_MAX_ELEMENTS_PER_BUFFER];
|
||||
u64 user0;
|
||||
u64 res4[2];
|
||||
u64 user1;
|
||||
u64 user2;
|
||||
u8 user1[16];
|
||||
} __attribute__ ((packed, aligned(256)));
|
||||
|
||||
/**
|
||||
|
|
|
@ -120,6 +120,8 @@
|
|||
#define SO_PREFER_BUSY_POLL 0x0048
|
||||
#define SO_BUSY_POLL_BUDGET 0x0049
|
||||
|
||||
#define SO_NETNS_COOKIE 0x0050
|
||||
|
||||
#if !defined(__KERNEL__)
|
||||
|
||||
|
||||
|
|
|
@ -31,7 +31,7 @@ static u8 *emit_code(u8 *ptr, u32 bytes, unsigned int len)
|
|||
}
|
||||
|
||||
#define EMIT(bytes, len) \
|
||||
do { prog = emit_code(prog, bytes, len); cnt += len; } while (0)
|
||||
do { prog = emit_code(prog, bytes, len); } while (0)
|
||||
|
||||
#define EMIT1(b1) EMIT(b1, 1)
|
||||
#define EMIT2(b1, b2) EMIT((b1) + ((b2) << 8), 2)
|
||||
|
@ -239,7 +239,6 @@ struct jit_context {
|
|||
static void push_callee_regs(u8 **pprog, bool *callee_regs_used)
|
||||
{
|
||||
u8 *prog = *pprog;
|
||||
int cnt = 0;
|
||||
|
||||
if (callee_regs_used[0])
|
||||
EMIT1(0x53); /* push rbx */
|
||||
|
@ -255,7 +254,6 @@ static void push_callee_regs(u8 **pprog, bool *callee_regs_used)
|
|||
static void pop_callee_regs(u8 **pprog, bool *callee_regs_used)
|
||||
{
|
||||
u8 *prog = *pprog;
|
||||
int cnt = 0;
|
||||
|
||||
if (callee_regs_used[3])
|
||||
EMIT2(0x41, 0x5F); /* pop r15 */
|
||||
|
@ -277,13 +275,12 @@ static void emit_prologue(u8 **pprog, u32 stack_depth, bool ebpf_from_cbpf,
|
|||
bool tail_call_reachable, bool is_subprog)
|
||||
{
|
||||
u8 *prog = *pprog;
|
||||
int cnt = X86_PATCH_SIZE;
|
||||
|
||||
/* BPF trampoline can be made to work without these nops,
|
||||
* but let's waste 5 bytes for now and optimize later
|
||||
*/
|
||||
memcpy(prog, x86_nops[5], cnt);
|
||||
prog += cnt;
|
||||
memcpy(prog, x86_nops[5], X86_PATCH_SIZE);
|
||||
prog += X86_PATCH_SIZE;
|
||||
if (!ebpf_from_cbpf) {
|
||||
if (tail_call_reachable && !is_subprog)
|
||||
EMIT2(0x31, 0xC0); /* xor eax, eax */
|
||||
|
@ -303,7 +300,6 @@ static void emit_prologue(u8 **pprog, u32 stack_depth, bool ebpf_from_cbpf,
|
|||
static int emit_patch(u8 **pprog, void *func, void *ip, u8 opcode)
|
||||
{
|
||||
u8 *prog = *pprog;
|
||||
int cnt = 0;
|
||||
s64 offset;
|
||||
|
||||
offset = func - (ip + X86_PATCH_SIZE);
|
||||
|
@ -423,7 +419,6 @@ static void emit_bpf_tail_call_indirect(u8 **pprog, bool *callee_regs_used,
|
|||
int off1 = 42;
|
||||
int off2 = 31;
|
||||
int off3 = 9;
|
||||
int cnt = 0;
|
||||
|
||||
/* count the additional bytes used for popping callee regs from stack
|
||||
* that need to be taken into account for each of the offsets that
|
||||
|
@ -513,7 +508,6 @@ static void emit_bpf_tail_call_direct(struct bpf_jit_poke_descriptor *poke,
|
|||
int pop_bytes = 0;
|
||||
int off1 = 20;
|
||||
int poke_off;
|
||||
int cnt = 0;
|
||||
|
||||
/* count the additional bytes used for popping callee regs to stack
|
||||
* that need to be taken into account for jump offset that is used for
|
||||
|
@ -615,7 +609,6 @@ static void emit_mov_imm32(u8 **pprog, bool sign_propagate,
|
|||
{
|
||||
u8 *prog = *pprog;
|
||||
u8 b1, b2, b3;
|
||||
int cnt = 0;
|
||||
|
||||
/*
|
||||
* Optimization: if imm32 is positive, use 'mov %eax, imm32'
|
||||
|
@ -655,7 +648,6 @@ static void emit_mov_imm64(u8 **pprog, u32 dst_reg,
|
|||
const u32 imm32_hi, const u32 imm32_lo)
|
||||
{
|
||||
u8 *prog = *pprog;
|
||||
int cnt = 0;
|
||||
|
||||
if (is_uimm32(((u64)imm32_hi << 32) | (u32)imm32_lo)) {
|
||||
/*
|
||||
|
@ -678,7 +670,6 @@ static void emit_mov_imm64(u8 **pprog, u32 dst_reg,
|
|||
static void emit_mov_reg(u8 **pprog, bool is64, u32 dst_reg, u32 src_reg)
|
||||
{
|
||||
u8 *prog = *pprog;
|
||||
int cnt = 0;
|
||||
|
||||
if (is64) {
|
||||
/* mov dst, src */
|
||||
|
@ -697,7 +688,6 @@ static void emit_mov_reg(u8 **pprog, bool is64, u32 dst_reg, u32 src_reg)
|
|||
static void emit_insn_suffix(u8 **pprog, u32 ptr_reg, u32 val_reg, int off)
|
||||
{
|
||||
u8 *prog = *pprog;
|
||||
int cnt = 0;
|
||||
|
||||
if (is_imm8(off)) {
|
||||
/* 1-byte signed displacement.
|
||||
|
@ -720,7 +710,6 @@ static void emit_insn_suffix(u8 **pprog, u32 ptr_reg, u32 val_reg, int off)
|
|||
static void maybe_emit_mod(u8 **pprog, u32 dst_reg, u32 src_reg, bool is64)
|
||||
{
|
||||
u8 *prog = *pprog;
|
||||
int cnt = 0;
|
||||
|
||||
if (is64)
|
||||
EMIT1(add_2mod(0x48, dst_reg, src_reg));
|
||||
|
@ -733,7 +722,6 @@ static void maybe_emit_mod(u8 **pprog, u32 dst_reg, u32 src_reg, bool is64)
|
|||
static void emit_ldx(u8 **pprog, u32 size, u32 dst_reg, u32 src_reg, int off)
|
||||
{
|
||||
u8 *prog = *pprog;
|
||||
int cnt = 0;
|
||||
|
||||
switch (size) {
|
||||
case BPF_B:
|
||||
|
@ -764,7 +752,6 @@ static void emit_ldx(u8 **pprog, u32 size, u32 dst_reg, u32 src_reg, int off)
|
|||
static void emit_stx(u8 **pprog, u32 size, u32 dst_reg, u32 src_reg, int off)
|
||||
{
|
||||
u8 *prog = *pprog;
|
||||
int cnt = 0;
|
||||
|
||||
switch (size) {
|
||||
case BPF_B:
|
||||
|
@ -799,7 +786,6 @@ static int emit_atomic(u8 **pprog, u8 atomic_op,
|
|||
u32 dst_reg, u32 src_reg, s16 off, u8 bpf_size)
|
||||
{
|
||||
u8 *prog = *pprog;
|
||||
int cnt = 0;
|
||||
|
||||
EMIT1(0xF0); /* lock prefix */
|
||||
|
||||
|
@ -869,10 +855,10 @@ static void detect_reg_usage(struct bpf_insn *insn, int insn_cnt,
|
|||
}
|
||||
}
|
||||
|
||||
static int emit_nops(u8 **pprog, int len)
|
||||
static void emit_nops(u8 **pprog, int len)
|
||||
{
|
||||
u8 *prog = *pprog;
|
||||
int i, noplen, cnt = 0;
|
||||
int i, noplen;
|
||||
|
||||
while (len > 0) {
|
||||
noplen = len;
|
||||
|
@ -886,8 +872,6 @@ static int emit_nops(u8 **pprog, int len)
|
|||
}
|
||||
|
||||
*pprog = prog;
|
||||
|
||||
return cnt;
|
||||
}
|
||||
|
||||
#define INSN_SZ_DIFF (((addrs[i] - addrs[i - 1]) - (prog - temp)))
|
||||
|
@ -902,7 +886,7 @@ static int do_jit(struct bpf_prog *bpf_prog, int *addrs, u8 *image,
|
|||
bool tail_call_seen = false;
|
||||
bool seen_exit = false;
|
||||
u8 temp[BPF_MAX_INSN_SIZE + BPF_INSN_SAFETY];
|
||||
int i, cnt = 0, excnt = 0;
|
||||
int i, excnt = 0;
|
||||
int ilen, proglen = 0;
|
||||
u8 *prog = temp;
|
||||
int err;
|
||||
|
@ -1297,7 +1281,7 @@ st: if (is_imm8(insn->off))
|
|||
emit_ldx(&prog, BPF_SIZE(insn->code), dst_reg, src_reg, insn->off);
|
||||
if (BPF_MODE(insn->code) == BPF_PROBE_MEM) {
|
||||
struct exception_table_entry *ex;
|
||||
u8 *_insn = image + proglen;
|
||||
u8 *_insn = image + proglen + (start_of_ldx - temp);
|
||||
s64 delta;
|
||||
|
||||
/* populate jmp_offset for JMP above */
|
||||
|
@ -1576,7 +1560,7 @@ emit_cond_jmp: /* Convert BPF opcode to x86 */
|
|||
nops);
|
||||
return -EFAULT;
|
||||
}
|
||||
cnt += emit_nops(&prog, nops);
|
||||
emit_nops(&prog, nops);
|
||||
}
|
||||
EMIT2(jmp_cond, jmp_offset);
|
||||
} else if (is_simm32(jmp_offset)) {
|
||||
|
@ -1622,7 +1606,7 @@ emit_cond_jmp: /* Convert BPF opcode to x86 */
|
|||
nops);
|
||||
return -EFAULT;
|
||||
}
|
||||
cnt += emit_nops(&prog, nops);
|
||||
emit_nops(&prog, nops);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -1647,7 +1631,7 @@ emit_jmp:
|
|||
nops);
|
||||
return -EFAULT;
|
||||
}
|
||||
cnt += emit_nops(&prog, INSN_SZ_DIFF - 2);
|
||||
emit_nops(&prog, INSN_SZ_DIFF - 2);
|
||||
}
|
||||
EMIT2(0xEB, jmp_offset);
|
||||
} else if (is_simm32(jmp_offset)) {
|
||||
|
@ -1754,7 +1738,6 @@ static int invoke_bpf_prog(const struct btf_func_model *m, u8 **pprog,
|
|||
{
|
||||
u8 *prog = *pprog;
|
||||
u8 *jmp_insn;
|
||||
int cnt = 0;
|
||||
|
||||
/* arg1: mov rdi, progs[i] */
|
||||
emit_mov_imm64(&prog, BPF_REG_1, (long) p >> 32, (u32) (long) p);
|
||||
|
@ -1822,7 +1805,6 @@ static void emit_align(u8 **pprog, u32 align)
|
|||
static int emit_cond_near_jump(u8 **pprog, void *func, void *ip, u8 jmp_cond)
|
||||
{
|
||||
u8 *prog = *pprog;
|
||||
int cnt = 0;
|
||||
s64 offset;
|
||||
|
||||
offset = func - (ip + 2 + 4);
|
||||
|
@ -1854,7 +1836,7 @@ static int invoke_bpf_mod_ret(const struct btf_func_model *m, u8 **pprog,
|
|||
u8 **branches)
|
||||
{
|
||||
u8 *prog = *pprog;
|
||||
int i, cnt = 0;
|
||||
int i;
|
||||
|
||||
/* The first fmod_ret program will receive a garbage return value.
|
||||
* Set this to 0 to avoid confusing the program.
|
||||
|
@ -1950,7 +1932,7 @@ int arch_prepare_bpf_trampoline(struct bpf_tramp_image *im, void *image, void *i
|
|||
struct bpf_tramp_progs *tprogs,
|
||||
void *orig_call)
|
||||
{
|
||||
int ret, i, cnt = 0, nr_args = m->nr_args;
|
||||
int ret, i, nr_args = m->nr_args;
|
||||
int stack_size = nr_args * 8;
|
||||
struct bpf_tramp_progs *fentry = &tprogs[BPF_TRAMP_FENTRY];
|
||||
struct bpf_tramp_progs *fexit = &tprogs[BPF_TRAMP_FEXIT];
|
||||
|
@ -2095,8 +2077,6 @@ static int emit_fallback_jump(u8 **pprog)
|
|||
*/
|
||||
err = emit_jump(&prog, __x86_indirect_thunk_rdx, prog);
|
||||
#else
|
||||
int cnt = 0;
|
||||
|
||||
EMIT2(0xFF, 0xE2); /* jmp rdx */
|
||||
#endif
|
||||
*pprog = prog;
|
||||
|
@ -2106,7 +2086,7 @@ static int emit_fallback_jump(u8 **pprog)
|
|||
static int emit_bpf_dispatcher(u8 **pprog, int a, int b, s64 *progs)
|
||||
{
|
||||
u8 *jg_reloc, *prog = *pprog;
|
||||
int pivot, err, jg_bytes = 1, cnt = 0;
|
||||
int pivot, err, jg_bytes = 1;
|
||||
s64 jg_offset;
|
||||
|
||||
if (a == b) {
|
||||
|
|
|
@ -277,6 +277,20 @@ acpi_evaluate_integer(acpi_handle handle,
|
|||
|
||||
EXPORT_SYMBOL(acpi_evaluate_integer);
|
||||
|
||||
int acpi_get_local_address(acpi_handle handle, u32 *addr)
|
||||
{
|
||||
unsigned long long adr;
|
||||
acpi_status status;
|
||||
|
||||
status = acpi_evaluate_integer(handle, METHOD_NAME__ADR, NULL, &adr);
|
||||
if (ACPI_FAILURE(status))
|
||||
return -ENODATA;
|
||||
|
||||
*addr = (u32)adr;
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(acpi_get_local_address);
|
||||
|
||||
acpi_status
|
||||
acpi_evaluate_reference(acpi_handle handle,
|
||||
acpi_string pathname,
|
||||
|
|
|
@ -47,6 +47,7 @@
|
|||
#include <linux/errno.h>
|
||||
#include <linux/atm.h>
|
||||
#include <linux/atmdev.h>
|
||||
#include <linux/ctype.h>
|
||||
#include <linux/sonet.h>
|
||||
#include <linux/skbuff.h>
|
||||
#include <linux/time.h>
|
||||
|
@ -996,10 +997,12 @@ static void xdump( u_char* cp, int length, char* prefix )
|
|||
}
|
||||
pBuf += sprintf( pBuf, " " );
|
||||
for(col = 0;count + col < length && col < 16; col++){
|
||||
if (isprint((int)cp[count + col]))
|
||||
pBuf += sprintf( pBuf, "%c", cp[count + col] );
|
||||
else
|
||||
pBuf += sprintf( pBuf, "." );
|
||||
u_char c = cp[count + col];
|
||||
|
||||
if (isascii(c) && isprint(c))
|
||||
pBuf += sprintf(pBuf, "%c", c);
|
||||
else
|
||||
pBuf += sprintf(pBuf, ".");
|
||||
}
|
||||
printk("%s\n", prntBuf);
|
||||
count += col;
|
||||
|
@ -3279,7 +3282,7 @@ static void __exit ia_module_exit(void)
|
|||
{
|
||||
pci_unregister_driver(&ia_driver);
|
||||
|
||||
del_timer(&ia_timer);
|
||||
del_timer_sync(&ia_timer);
|
||||
}
|
||||
|
||||
module_init(ia_module_init);
|
||||
|
|
|
@ -124,7 +124,6 @@
|
|||
#define IF_RXPKT(A)
|
||||
#endif /* CONFIG_ATM_IA_DEBUG */
|
||||
|
||||
#define isprint(a) ((a >=' ')&&(a <= '~'))
|
||||
#define ATM_DESC(skb) (skb->protocol)
|
||||
#define IA_SKB_STATE(skb) (skb->protocol)
|
||||
#define IA_DLED 1
|
||||
|
|
|
@ -299,7 +299,7 @@ static void __exit nicstar_cleanup(void)
|
|||
{
|
||||
XPRINTK("nicstar: nicstar_cleanup() called.\n");
|
||||
|
||||
del_timer(&ns_timer);
|
||||
del_timer_sync(&ns_timer);
|
||||
|
||||
pci_unregister_driver(&nicstar_driver);
|
||||
|
||||
|
@ -527,6 +527,15 @@ static int ns_init_card(int i, struct pci_dev *pcidev)
|
|||
/* Set the VPI/VCI MSb mask to zero so we can receive OAM cells */
|
||||
writel(0x00000000, card->membase + VPM);
|
||||
|
||||
card->intcnt = 0;
|
||||
if (request_irq
|
||||
(pcidev->irq, &ns_irq_handler, IRQF_SHARED, "nicstar", card) != 0) {
|
||||
pr_err("nicstar%d: can't allocate IRQ %d.\n", i, pcidev->irq);
|
||||
error = 9;
|
||||
ns_init_card_error(card, error);
|
||||
return error;
|
||||
}
|
||||
|
||||
/* Initialize TSQ */
|
||||
card->tsq.org = dma_alloc_coherent(&card->pcidev->dev,
|
||||
NS_TSQSIZE + NS_TSQ_ALIGNMENT,
|
||||
|
@ -753,15 +762,6 @@ static int ns_init_card(int i, struct pci_dev *pcidev)
|
|||
|
||||
card->efbie = 1;
|
||||
|
||||
card->intcnt = 0;
|
||||
if (request_irq
|
||||
(pcidev->irq, &ns_irq_handler, IRQF_SHARED, "nicstar", card) != 0) {
|
||||
printk("nicstar%d: can't allocate IRQ %d.\n", i, pcidev->irq);
|
||||
error = 9;
|
||||
ns_init_card_error(card, error);
|
||||
return error;
|
||||
}
|
||||
|
||||
/* Register device */
|
||||
card->atmdev = atm_dev_register("nicstar", &card->pcidev->dev, &atm_ops,
|
||||
-1, NULL);
|
||||
|
@ -839,10 +839,12 @@ static void ns_init_card_error(ns_dev *card, int error)
|
|||
dev_kfree_skb_any(hb);
|
||||
}
|
||||
if (error >= 12) {
|
||||
kfree(card->rsq.org);
|
||||
dma_free_coherent(&card->pcidev->dev, NS_RSQSIZE + NS_RSQ_ALIGNMENT,
|
||||
card->rsq.org, card->rsq.dma);
|
||||
}
|
||||
if (error >= 11) {
|
||||
kfree(card->tsq.org);
|
||||
dma_free_coherent(&card->pcidev->dev, NS_TSQSIZE + NS_TSQ_ALIGNMENT,
|
||||
card->tsq.org, card->tsq.dma);
|
||||
}
|
||||
if (error >= 10) {
|
||||
free_irq(card->pcidev->irq, card);
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
#define ZEPROM_V1_REG PCI_VENDOR_ID /* PCI register */
|
||||
#define ZEPROM_V2_REG 0x40
|
||||
|
||||
/* Bits in contol register */
|
||||
/* Bits in control register */
|
||||
|
||||
#define ZEPROM_SK 0x80000000 /* strobe (probably on raising edge) */
|
||||
#define ZEPROM_CS 0x40000000 /* Chip Select */
|
||||
|
|
|
@ -4727,6 +4727,13 @@ void device_set_of_node_from_dev(struct device *dev, const struct device *dev2)
|
|||
}
|
||||
EXPORT_SYMBOL_GPL(device_set_of_node_from_dev);
|
||||
|
||||
void device_set_node(struct device *dev, struct fwnode_handle *fwnode)
|
||||
{
|
||||
dev->fwnode = fwnode;
|
||||
dev->of_node = to_of_node(fwnode);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(device_set_node);
|
||||
|
||||
int device_match_name(struct device *dev, const void *name)
|
||||
{
|
||||
return sysfs_streq(dev_name(dev), name);
|
||||
|
|
|
@ -404,6 +404,7 @@ static const struct bcm_subver_table bcm_uart_subver_table[] = {
|
|||
{ 0x4217, "BCM4329B1" }, /* 002.002.023 */
|
||||
{ 0x6106, "BCM4359C0" }, /* 003.001.006 */
|
||||
{ 0x4106, "BCM4335A0" }, /* 002.001.006 */
|
||||
{ 0x410c, "BCM43430B0" }, /* 002.001.012 */
|
||||
{ }
|
||||
};
|
||||
|
||||
|
|
|
@ -1461,9 +1461,7 @@ static void btmrvl_sdio_coredump(struct device *dev)
|
|||
BT_ERR("Allocated buffer not enough");
|
||||
}
|
||||
|
||||
if (stat != RDWR_STATUS_DONE) {
|
||||
continue;
|
||||
} else {
|
||||
if (stat == RDWR_STATUS_DONE) {
|
||||
BT_INFO("%s done: size=0x%tx",
|
||||
entry->mem_name,
|
||||
dbg_ptr - entry->mem_ptr);
|
||||
|
|
|
@ -581,11 +581,9 @@ static int btmtkuart_open(struct hci_dev *hdev)
|
|||
|
||||
/* Enable the power domain and clock the device requires */
|
||||
pm_runtime_enable(dev);
|
||||
err = pm_runtime_get_sync(dev);
|
||||
if (err < 0) {
|
||||
pm_runtime_put_noidle(dev);
|
||||
err = pm_runtime_resume_and_get(dev);
|
||||
if (err < 0)
|
||||
goto err_disable_rpm;
|
||||
}
|
||||
|
||||
err = clk_prepare_enable(bdev->clk);
|
||||
if (err < 0)
|
||||
|
|
|
@ -182,8 +182,9 @@ int qca_send_pre_shutdown_cmd(struct hci_dev *hdev)
|
|||
}
|
||||
EXPORT_SYMBOL_GPL(qca_send_pre_shutdown_cmd);
|
||||
|
||||
static void qca_tlv_check_data(struct qca_fw_config *config,
|
||||
const struct firmware *fw, enum qca_btsoc_type soc_type)
|
||||
static void qca_tlv_check_data(struct hci_dev *hdev,
|
||||
struct qca_fw_config *config,
|
||||
u8 *fw_data, enum qca_btsoc_type soc_type)
|
||||
{
|
||||
const u8 *data;
|
||||
u32 type_len;
|
||||
|
@ -194,19 +195,21 @@ static void qca_tlv_check_data(struct qca_fw_config *config,
|
|||
struct tlv_type_nvm *tlv_nvm;
|
||||
uint8_t nvm_baud_rate = config->user_baud_rate;
|
||||
|
||||
tlv = (struct tlv_type_hdr *)fw->data;
|
||||
|
||||
type_len = le32_to_cpu(tlv->type_len);
|
||||
length = (type_len >> 8) & 0x00ffffff;
|
||||
|
||||
BT_DBG("TLV Type\t\t : 0x%x", type_len & 0x000000ff);
|
||||
BT_DBG("Length\t\t : %d bytes", length);
|
||||
|
||||
config->dnld_mode = QCA_SKIP_EVT_NONE;
|
||||
config->dnld_type = QCA_SKIP_EVT_NONE;
|
||||
|
||||
switch (config->type) {
|
||||
case ELF_TYPE_PATCH:
|
||||
config->dnld_mode = QCA_SKIP_EVT_VSE_CC;
|
||||
config->dnld_type = QCA_SKIP_EVT_VSE_CC;
|
||||
|
||||
bt_dev_dbg(hdev, "File Class : 0x%x", fw_data[4]);
|
||||
bt_dev_dbg(hdev, "Data Encoding : 0x%x", fw_data[5]);
|
||||
bt_dev_dbg(hdev, "File version : 0x%x", fw_data[6]);
|
||||
break;
|
||||
case TLV_TYPE_PATCH:
|
||||
tlv = (struct tlv_type_hdr *)fw_data;
|
||||
type_len = le32_to_cpu(tlv->type_len);
|
||||
tlv_patch = (struct tlv_type_patch *)tlv->data;
|
||||
|
||||
/* For Rome version 1.1 to 3.1, all segment commands
|
||||
|
@ -218,6 +221,7 @@ static void qca_tlv_check_data(struct qca_fw_config *config,
|
|||
config->dnld_mode = tlv_patch->download_mode;
|
||||
config->dnld_type = config->dnld_mode;
|
||||
|
||||
BT_DBG("TLV Type\t\t : 0x%x", type_len & 0x000000ff);
|
||||
BT_DBG("Total Length : %d bytes",
|
||||
le32_to_cpu(tlv_patch->total_size));
|
||||
BT_DBG("Patch Data Length : %d bytes",
|
||||
|
@ -243,6 +247,14 @@ static void qca_tlv_check_data(struct qca_fw_config *config,
|
|||
break;
|
||||
|
||||
case TLV_TYPE_NVM:
|
||||
tlv = (struct tlv_type_hdr *)fw_data;
|
||||
|
||||
type_len = le32_to_cpu(tlv->type_len);
|
||||
length = (type_len >> 8) & 0x00ffffff;
|
||||
|
||||
BT_DBG("TLV Type\t\t : 0x%x", type_len & 0x000000ff);
|
||||
BT_DBG("Length\t\t : %d bytes", length);
|
||||
|
||||
idx = 0;
|
||||
data = tlv->data;
|
||||
while (idx < length) {
|
||||
|
@ -387,25 +399,57 @@ static int qca_inject_cmd_complete_event(struct hci_dev *hdev)
|
|||
|
||||
static int qca_download_firmware(struct hci_dev *hdev,
|
||||
struct qca_fw_config *config,
|
||||
enum qca_btsoc_type soc_type)
|
||||
enum qca_btsoc_type soc_type,
|
||||
u8 rom_ver)
|
||||
{
|
||||
const struct firmware *fw;
|
||||
u8 *data;
|
||||
const u8 *segment;
|
||||
int ret, remain, i = 0;
|
||||
int ret, size, remain, i = 0;
|
||||
|
||||
bt_dev_info(hdev, "QCA Downloading %s", config->fwname);
|
||||
|
||||
ret = request_firmware(&fw, config->fwname, &hdev->dev);
|
||||
if (ret) {
|
||||
bt_dev_err(hdev, "QCA Failed to request file: %s (%d)",
|
||||
config->fwname, ret);
|
||||
return ret;
|
||||
/* For WCN6750, if mbn file is not present then check for
|
||||
* tlv file.
|
||||
*/
|
||||
if (soc_type == QCA_WCN6750 && config->type == ELF_TYPE_PATCH) {
|
||||
bt_dev_dbg(hdev, "QCA Failed to request file: %s (%d)",
|
||||
config->fwname, ret);
|
||||
config->type = TLV_TYPE_PATCH;
|
||||
snprintf(config->fwname, sizeof(config->fwname),
|
||||
"qca/msbtfw%02x.tlv", rom_ver);
|
||||
bt_dev_info(hdev, "QCA Downloading %s", config->fwname);
|
||||
ret = request_firmware(&fw, config->fwname, &hdev->dev);
|
||||
if (ret) {
|
||||
bt_dev_err(hdev, "QCA Failed to request file: %s (%d)",
|
||||
config->fwname, ret);
|
||||
return ret;
|
||||
}
|
||||
} else {
|
||||
bt_dev_err(hdev, "QCA Failed to request file: %s (%d)",
|
||||
config->fwname, ret);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
qca_tlv_check_data(config, fw, soc_type);
|
||||
size = fw->size;
|
||||
data = vmalloc(fw->size);
|
||||
if (!data) {
|
||||
bt_dev_err(hdev, "QCA Failed to allocate memory for file: %s",
|
||||
config->fwname);
|
||||
release_firmware(fw);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
segment = fw->data;
|
||||
remain = fw->size;
|
||||
memcpy(data, fw->data, size);
|
||||
release_firmware(fw);
|
||||
|
||||
qca_tlv_check_data(hdev, config, data, soc_type);
|
||||
|
||||
segment = data;
|
||||
remain = size;
|
||||
while (remain > 0) {
|
||||
int segsize = min(MAX_SIZE_PER_TLV_SEGMENT, remain);
|
||||
|
||||
|
@ -435,7 +479,7 @@ static int qca_download_firmware(struct hci_dev *hdev,
|
|||
ret = qca_inject_cmd_complete_event(hdev);
|
||||
|
||||
out:
|
||||
release_firmware(fw);
|
||||
vfree(data);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@ -502,27 +546,32 @@ int qca_uart_setup(struct hci_dev *hdev, uint8_t baudrate,
|
|||
|
||||
config.user_baud_rate = baudrate;
|
||||
|
||||
/* Firmware files to download are based on ROM version.
|
||||
* ROM version is derived from last two bytes of soc_ver.
|
||||
*/
|
||||
rom_ver = ((soc_ver & 0x00000f00) >> 0x04) | (soc_ver & 0x0000000f);
|
||||
|
||||
/* Download rampatch file */
|
||||
config.type = TLV_TYPE_PATCH;
|
||||
if (qca_is_wcn399x(soc_type)) {
|
||||
/* Firmware files to download are based on ROM version.
|
||||
* ROM version is derived from last two bytes of soc_ver.
|
||||
*/
|
||||
rom_ver = ((soc_ver & 0x00000f00) >> 0x04) |
|
||||
(soc_ver & 0x0000000f);
|
||||
snprintf(config.fwname, sizeof(config.fwname),
|
||||
"qca/crbtfw%02x.tlv", rom_ver);
|
||||
} else if (soc_type == QCA_QCA6390) {
|
||||
rom_ver = ((soc_ver & 0x00000f00) >> 0x04) |
|
||||
(soc_ver & 0x0000000f);
|
||||
snprintf(config.fwname, sizeof(config.fwname),
|
||||
"qca/htbtfw%02x.tlv", rom_ver);
|
||||
} else if (soc_type == QCA_WCN6750) {
|
||||
/* Choose mbn file by default.If mbn file is not found
|
||||
* then choose tlv file
|
||||
*/
|
||||
config.type = ELF_TYPE_PATCH;
|
||||
snprintf(config.fwname, sizeof(config.fwname),
|
||||
"qca/msbtfw%02x.mbn", rom_ver);
|
||||
} else {
|
||||
snprintf(config.fwname, sizeof(config.fwname),
|
||||
"qca/rampatch_%08x.bin", soc_ver);
|
||||
}
|
||||
|
||||
err = qca_download_firmware(hdev, &config, soc_type);
|
||||
err = qca_download_firmware(hdev, &config, soc_type, rom_ver);
|
||||
if (err < 0) {
|
||||
bt_dev_err(hdev, "QCA Failed to download patch (%d)", err);
|
||||
return err;
|
||||
|
@ -548,11 +597,14 @@ int qca_uart_setup(struct hci_dev *hdev, uint8_t baudrate,
|
|||
else if (soc_type == QCA_QCA6390)
|
||||
snprintf(config.fwname, sizeof(config.fwname),
|
||||
"qca/htnv%02x.bin", rom_ver);
|
||||
else if (soc_type == QCA_WCN6750)
|
||||
snprintf(config.fwname, sizeof(config.fwname),
|
||||
"qca/msnv%02x.bin", rom_ver);
|
||||
else
|
||||
snprintf(config.fwname, sizeof(config.fwname),
|
||||
"qca/nvm_%08x.bin", soc_ver);
|
||||
|
||||
err = qca_download_firmware(hdev, &config, soc_type);
|
||||
err = qca_download_firmware(hdev, &config, soc_type, rom_ver);
|
||||
if (err < 0) {
|
||||
bt_dev_err(hdev, "QCA Failed to download NVM (%d)", err);
|
||||
return err;
|
||||
|
@ -564,13 +616,14 @@ int qca_uart_setup(struct hci_dev *hdev, uint8_t baudrate,
|
|||
return err;
|
||||
}
|
||||
|
||||
/* WCN399x supports the Microsoft vendor extension with 0xFD70 as the
|
||||
/* WCN399x and WCN6750 supports the Microsoft vendor extension with 0xFD70 as the
|
||||
* VsMsftOpCode.
|
||||
*/
|
||||
switch (soc_type) {
|
||||
case QCA_WCN3990:
|
||||
case QCA_WCN3991:
|
||||
case QCA_WCN3998:
|
||||
case QCA_WCN6750:
|
||||
hci_set_msft_opcode(hdev, 0xFD70);
|
||||
break;
|
||||
default:
|
||||
|
@ -584,7 +637,7 @@ int qca_uart_setup(struct hci_dev *hdev, uint8_t baudrate,
|
|||
return err;
|
||||
}
|
||||
|
||||
if (soc_type == QCA_WCN3991) {
|
||||
if (soc_type == QCA_WCN3991 || soc_type == QCA_WCN6750) {
|
||||
/* get fw build info */
|
||||
err = qca_read_fw_build_info(hdev);
|
||||
if (err < 0)
|
||||
|
|
|
@ -80,7 +80,8 @@ enum qca_tlv_dnld_mode {
|
|||
|
||||
enum qca_tlv_type {
|
||||
TLV_TYPE_PATCH = 1,
|
||||
TLV_TYPE_NVM
|
||||
TLV_TYPE_NVM,
|
||||
ELF_TYPE_PATCH,
|
||||
};
|
||||
|
||||
struct qca_fw_config {
|
||||
|
@ -143,6 +144,7 @@ enum qca_btsoc_type {
|
|||
QCA_WCN3998,
|
||||
QCA_WCN3991,
|
||||
QCA_QCA6390,
|
||||
QCA_WCN6750,
|
||||
};
|
||||
|
||||
#if IS_ENABLED(CONFIG_BT_QCA)
|
||||
|
@ -160,6 +162,11 @@ static inline bool qca_is_wcn399x(enum qca_btsoc_type soc_type)
|
|||
return soc_type == QCA_WCN3990 || soc_type == QCA_WCN3991 ||
|
||||
soc_type == QCA_WCN3998;
|
||||
}
|
||||
static inline bool qca_is_wcn6750(enum qca_btsoc_type soc_type)
|
||||
{
|
||||
return soc_type == QCA_WCN6750;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
static inline int qca_set_bdaddr_rome(struct hci_dev *hdev, const bdaddr_t *bdaddr)
|
||||
|
@ -192,6 +199,11 @@ static inline bool qca_is_wcn399x(enum qca_btsoc_type soc_type)
|
|||
return false;
|
||||
}
|
||||
|
||||
static inline bool qca_is_wcn6750(enum qca_btsoc_type soc_type)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
static inline int qca_send_pre_shutdown_cmd(struct hci_dev *hdev)
|
||||
{
|
||||
return -EOPNOTSUPP;
|
||||
|
|
|
@ -132,12 +132,19 @@ static const struct id_table ic_id_table[] = {
|
|||
.cfg_name = "rtl_bt/rtl8761a_config" },
|
||||
|
||||
/* 8761B */
|
||||
{ IC_INFO(RTL_ROM_LMP_8761A, 0xb, 0xa, HCI_USB),
|
||||
{ IC_INFO(RTL_ROM_LMP_8761A, 0xb, 0xa, HCI_UART),
|
||||
.config_needed = false,
|
||||
.has_rom_version = true,
|
||||
.fw_name = "rtl_bt/rtl8761b_fw.bin",
|
||||
.cfg_name = "rtl_bt/rtl8761b_config" },
|
||||
|
||||
/* 8761BU */
|
||||
{ IC_INFO(RTL_ROM_LMP_8761A, 0xb, 0xa, HCI_USB),
|
||||
.config_needed = false,
|
||||
.has_rom_version = true,
|
||||
.fw_name = "rtl_bt/rtl8761bu_fw.bin",
|
||||
.cfg_name = "rtl_bt/rtl8761bu_config" },
|
||||
|
||||
/* 8822C with UART interface */
|
||||
{ IC_INFO(RTL_ROM_LMP_8822B, 0xc, 0xa, HCI_UART),
|
||||
.config_needed = true,
|
||||
|
@ -719,17 +726,8 @@ int btrtl_download_firmware(struct hci_dev *hdev,
|
|||
}
|
||||
EXPORT_SYMBOL_GPL(btrtl_download_firmware);
|
||||
|
||||
int btrtl_setup_realtek(struct hci_dev *hdev)
|
||||
void btrtl_set_quirks(struct hci_dev *hdev, struct btrtl_device_info *btrtl_dev)
|
||||
{
|
||||
struct btrtl_device_info *btrtl_dev;
|
||||
int ret;
|
||||
|
||||
btrtl_dev = btrtl_initialize(hdev, NULL);
|
||||
if (IS_ERR(btrtl_dev))
|
||||
return PTR_ERR(btrtl_dev);
|
||||
|
||||
ret = btrtl_download_firmware(hdev, btrtl_dev);
|
||||
|
||||
/* Enable controller to do both LE scan and BR/EDR inquiry
|
||||
* simultaneously.
|
||||
*/
|
||||
|
@ -750,6 +748,21 @@ int btrtl_setup_realtek(struct hci_dev *hdev)
|
|||
rtl_dev_dbg(hdev, "WBS supported not enabled.");
|
||||
break;
|
||||
}
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(btrtl_set_quirks);
|
||||
|
||||
int btrtl_setup_realtek(struct hci_dev *hdev)
|
||||
{
|
||||
struct btrtl_device_info *btrtl_dev;
|
||||
int ret;
|
||||
|
||||
btrtl_dev = btrtl_initialize(hdev, NULL);
|
||||
if (IS_ERR(btrtl_dev))
|
||||
return PTR_ERR(btrtl_dev);
|
||||
|
||||
ret = btrtl_download_firmware(hdev, btrtl_dev);
|
||||
|
||||
btrtl_set_quirks(hdev, btrtl_dev);
|
||||
|
||||
btrtl_free(btrtl_dev);
|
||||
return ret;
|
||||
|
|
|
@ -54,6 +54,8 @@ struct btrtl_device_info *btrtl_initialize(struct hci_dev *hdev,
|
|||
void btrtl_free(struct btrtl_device_info *btrtl_dev);
|
||||
int btrtl_download_firmware(struct hci_dev *hdev,
|
||||
struct btrtl_device_info *btrtl_dev);
|
||||
void btrtl_set_quirks(struct hci_dev *hdev,
|
||||
struct btrtl_device_info *btrtl_dev);
|
||||
int btrtl_setup_realtek(struct hci_dev *hdev);
|
||||
int btrtl_shutdown_realtek(struct hci_dev *hdev);
|
||||
int btrtl_get_uart_settings(struct hci_dev *hdev,
|
||||
|
@ -79,6 +81,11 @@ static inline int btrtl_download_firmware(struct hci_dev *hdev,
|
|||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
static inline void btrtl_set_quirks(struct hci_dev *hdev,
|
||||
struct btrtl_device_info *btrtl_dev)
|
||||
{
|
||||
}
|
||||
|
||||
static inline int btrtl_setup_realtek(struct hci_dev *hdev)
|
||||
{
|
||||
return -EOPNOTSUPP;
|
||||
|
|
|
@ -270,6 +270,8 @@ static const struct usb_device_id blacklist_table[] = {
|
|||
BTUSB_WIDEBAND_SPEECH },
|
||||
{ USB_DEVICE(0x0cf3, 0xe360), .driver_info = BTUSB_QCA_ROME |
|
||||
BTUSB_WIDEBAND_SPEECH },
|
||||
{ USB_DEVICE(0x0cf3, 0xe500), .driver_info = BTUSB_QCA_ROME |
|
||||
BTUSB_WIDEBAND_SPEECH },
|
||||
{ USB_DEVICE(0x0489, 0xe092), .driver_info = BTUSB_QCA_ROME |
|
||||
BTUSB_WIDEBAND_SPEECH },
|
||||
{ USB_DEVICE(0x0489, 0xe09f), .driver_info = BTUSB_QCA_ROME |
|
||||
|
@ -408,6 +410,11 @@ static const struct usb_device_id blacklist_table[] = {
|
|||
/* Additional MediaTek MT7615E Bluetooth devices */
|
||||
{ USB_DEVICE(0x13d3, 0x3560), .driver_info = BTUSB_MEDIATEK},
|
||||
|
||||
/* Additional MediaTek MT7921 Bluetooth devices */
|
||||
{ USB_DEVICE(0x04ca, 0x3802), .driver_info = BTUSB_MEDIATEK |
|
||||
BTUSB_WIDEBAND_SPEECH |
|
||||
BTUSB_VALID_LE_STATES },
|
||||
|
||||
/* Additional Realtek 8723AE Bluetooth devices */
|
||||
{ USB_DEVICE(0x0930, 0x021d), .driver_info = BTUSB_REALTEK },
|
||||
{ USB_DEVICE(0x13d3, 0x3394), .driver_info = BTUSB_REALTEK },
|
||||
|
@ -427,6 +434,10 @@ static const struct usb_device_id blacklist_table[] = {
|
|||
{ USB_DEVICE(0x0bda, 0xb009), .driver_info = BTUSB_REALTEK },
|
||||
{ USB_DEVICE(0x2ff8, 0xb011), .driver_info = BTUSB_REALTEK },
|
||||
|
||||
/* Additional Realtek 8761BU Bluetooth devices */
|
||||
{ USB_DEVICE(0x0b05, 0x190e), .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 },
|
||||
|
@ -1749,6 +1760,13 @@ static void btusb_work(struct work_struct *work)
|
|||
* which work with WBS at all.
|
||||
*/
|
||||
new_alts = btusb_find_altsetting(data, 6) ? 6 : 1;
|
||||
/* Because mSBC frames do not need to be aligned to the
|
||||
* SCO packet boundary. If support the Alt 3, use the
|
||||
* Alt 3 for HCI payload >= 60 Bytes let air packet
|
||||
* data satisfy 60 bytes.
|
||||
*/
|
||||
if (new_alts == 1 && btusb_find_altsetting(data, 3))
|
||||
new_alts = 3;
|
||||
}
|
||||
|
||||
if (btusb_switch_alt_setting(hdev, new_alts) < 0)
|
||||
|
@ -3312,11 +3330,6 @@ static int btusb_mtk_hci_wmt_sync(struct hci_dev *hdev,
|
|||
struct btmtk_wmt_hdr *hdr;
|
||||
int err;
|
||||
|
||||
/* Submit control IN URB on demand to process the WMT event */
|
||||
err = btusb_mtk_submit_wmt_recv_urb(hdev);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
/* Send the WMT command and wait until the WMT event returns */
|
||||
hlen = sizeof(*hdr) + wmt_params->dlen;
|
||||
if (hlen > 255)
|
||||
|
@ -3342,6 +3355,11 @@ static int btusb_mtk_hci_wmt_sync(struct hci_dev *hdev,
|
|||
goto err_free_wc;
|
||||
}
|
||||
|
||||
/* Submit control IN URB on demand to process the WMT event */
|
||||
err = btusb_mtk_submit_wmt_recv_urb(hdev);
|
||||
if (err < 0)
|
||||
goto err_free_wc;
|
||||
|
||||
/* The vendor specific WMT commands are all answered by a vendor
|
||||
* specific event and will have the Command Status or Command
|
||||
* Complete as with usual HCI command flow control.
|
||||
|
@ -4062,6 +4080,11 @@ static int btusb_setup_qca_download_fw(struct hci_dev *hdev,
|
|||
sent += size;
|
||||
count -= size;
|
||||
|
||||
/* ep2 need time to switch from function acl to function dfu,
|
||||
* so we add 20ms delay here.
|
||||
*/
|
||||
msleep(20);
|
||||
|
||||
while (count) {
|
||||
size = min_t(size_t, count, QCA_DFU_PACKET_LEN);
|
||||
|
||||
|
@ -4154,9 +4177,15 @@ static int btusb_setup_qca_load_nvm(struct hci_dev *hdev,
|
|||
int err;
|
||||
|
||||
if (((ver->flag >> 8) & 0xff) == QCA_FLAG_MULTI_NVM) {
|
||||
snprintf(fwname, sizeof(fwname), "qca/nvm_usb_%08x_%04x.bin",
|
||||
le32_to_cpu(ver->rom_version),
|
||||
le16_to_cpu(ver->board_id));
|
||||
/* if boardid equal 0, use default nvm without surfix */
|
||||
if (le16_to_cpu(ver->board_id) == 0x0) {
|
||||
snprintf(fwname, sizeof(fwname), "qca/nvm_usb_%08x.bin",
|
||||
le32_to_cpu(ver->rom_version));
|
||||
} else {
|
||||
snprintf(fwname, sizeof(fwname), "qca/nvm_usb_%08x_%04x.bin",
|
||||
le32_to_cpu(ver->rom_version),
|
||||
le16_to_cpu(ver->board_id));
|
||||
}
|
||||
} else {
|
||||
snprintf(fwname, sizeof(fwname), "qca/nvm_usb_%08x.bin",
|
||||
le32_to_cpu(ver->rom_version));
|
||||
|
|
|
@ -199,7 +199,6 @@ static int ag6xx_setup(struct hci_uart *hu)
|
|||
fwname, err);
|
||||
goto patch;
|
||||
}
|
||||
fw_ptr = fw->data;
|
||||
|
||||
bt_dev_info(hdev, "Applying bddata (%s)", fwname);
|
||||
|
||||
|
|
|
@ -906,10 +906,7 @@ static int h5_btrtl_setup(struct h5 *h5)
|
|||
/* Give the device some time before the hci-core sends it a reset */
|
||||
usleep_range(10000, 20000);
|
||||
|
||||
/* Enable controller to do both LE scan and BR/EDR inquiry
|
||||
* simultaneously.
|
||||
*/
|
||||
set_bit(HCI_QUIRK_SIMULTANEOUS_DISCOVERY, &h5->hu->hdev->quirks);
|
||||
btrtl_set_quirks(h5->hu->hdev, btrtl_dev);
|
||||
|
||||
out_free:
|
||||
btrtl_free(btrtl_dev);
|
||||
|
|
|
@ -218,6 +218,7 @@ struct qca_power {
|
|||
struct qca_serdev {
|
||||
struct hci_uart serdev_hu;
|
||||
struct gpio_desc *bt_en;
|
||||
struct gpio_desc *sw_ctrl;
|
||||
struct clk *susclk;
|
||||
enum qca_btsoc_type btsoc_type;
|
||||
struct qca_power *bt_power;
|
||||
|
@ -604,7 +605,8 @@ static int qca_open(struct hci_uart *hu)
|
|||
if (hu->serdev) {
|
||||
qcadev = serdev_device_get_drvdata(hu->serdev);
|
||||
|
||||
if (qca_is_wcn399x(qcadev->btsoc_type))
|
||||
if (qca_is_wcn399x(qcadev->btsoc_type) ||
|
||||
qca_is_wcn6750(qcadev->btsoc_type))
|
||||
hu->init_speed = qcadev->init_speed;
|
||||
|
||||
if (qcadev->oper_speed)
|
||||
|
@ -1308,7 +1310,8 @@ static int qca_set_baudrate(struct hci_dev *hdev, uint8_t baudrate)
|
|||
msecs_to_jiffies(CMD_TRANS_TIMEOUT_MS));
|
||||
|
||||
/* Give the controller time to process the request */
|
||||
if (qca_is_wcn399x(qca_soc_type(hu)))
|
||||
if (qca_is_wcn399x(qca_soc_type(hu)) ||
|
||||
qca_is_wcn6750(qca_soc_type(hu)))
|
||||
usleep_range(1000, 10000);
|
||||
else
|
||||
msleep(300);
|
||||
|
@ -1384,7 +1387,8 @@ static unsigned int qca_get_speed(struct hci_uart *hu,
|
|||
|
||||
static int qca_check_speeds(struct hci_uart *hu)
|
||||
{
|
||||
if (qca_is_wcn399x(qca_soc_type(hu))) {
|
||||
if (qca_is_wcn399x(qca_soc_type(hu)) ||
|
||||
qca_is_wcn6750(qca_soc_type(hu))) {
|
||||
if (!qca_get_speed(hu, QCA_INIT_SPEED) &&
|
||||
!qca_get_speed(hu, QCA_OPER_SPEED))
|
||||
return -EINVAL;
|
||||
|
@ -1417,7 +1421,8 @@ static int qca_set_speed(struct hci_uart *hu, enum qca_speed_type speed_type)
|
|||
/* Disable flow control for wcn3990 to deassert RTS while
|
||||
* changing the baudrate of chip and host.
|
||||
*/
|
||||
if (qca_is_wcn399x(soc_type))
|
||||
if (qca_is_wcn399x(soc_type) ||
|
||||
qca_is_wcn6750(soc_type))
|
||||
hci_uart_set_flow_control(hu, true);
|
||||
|
||||
if (soc_type == QCA_WCN3990) {
|
||||
|
@ -1434,7 +1439,8 @@ static int qca_set_speed(struct hci_uart *hu, enum qca_speed_type speed_type)
|
|||
host_set_baudrate(hu, speed);
|
||||
|
||||
error:
|
||||
if (qca_is_wcn399x(soc_type))
|
||||
if (qca_is_wcn399x(soc_type) ||
|
||||
qca_is_wcn6750(soc_type))
|
||||
hci_uart_set_flow_control(hu, false);
|
||||
|
||||
if (soc_type == QCA_WCN3990) {
|
||||
|
@ -1585,10 +1591,12 @@ static bool qca_prevent_wake(struct hci_dev *hdev)
|
|||
return !wakeup;
|
||||
}
|
||||
|
||||
static int qca_wcn3990_init(struct hci_uart *hu)
|
||||
static int qca_regulator_init(struct hci_uart *hu)
|
||||
{
|
||||
enum qca_btsoc_type soc_type = qca_soc_type(hu);
|
||||
struct qca_serdev *qcadev;
|
||||
int ret;
|
||||
bool sw_ctrl_state;
|
||||
|
||||
/* Check for vregs status, may be hci down has turned
|
||||
* off the voltage regulator.
|
||||
|
@ -1607,16 +1615,33 @@ static int qca_wcn3990_init(struct hci_uart *hu)
|
|||
}
|
||||
}
|
||||
|
||||
/* Forcefully enable wcn3990 to enter in to boot mode. */
|
||||
host_set_baudrate(hu, 2400);
|
||||
ret = qca_send_power_pulse(hu, false);
|
||||
if (ret)
|
||||
return ret;
|
||||
if (qca_is_wcn399x(soc_type)) {
|
||||
/* Forcefully enable wcn399x to enter in to boot mode. */
|
||||
host_set_baudrate(hu, 2400);
|
||||
ret = qca_send_power_pulse(hu, false);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* For wcn6750 need to enable gpio bt_en */
|
||||
if (qcadev->bt_en) {
|
||||
gpiod_set_value_cansleep(qcadev->bt_en, 0);
|
||||
msleep(50);
|
||||
gpiod_set_value_cansleep(qcadev->bt_en, 1);
|
||||
msleep(50);
|
||||
if (qcadev->sw_ctrl) {
|
||||
sw_ctrl_state = gpiod_get_value_cansleep(qcadev->sw_ctrl);
|
||||
bt_dev_dbg(hu->hdev, "SW_CTRL is %d", sw_ctrl_state);
|
||||
}
|
||||
}
|
||||
|
||||
qca_set_speed(hu, QCA_INIT_SPEED);
|
||||
ret = qca_send_power_pulse(hu, true);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (qca_is_wcn399x(soc_type)) {
|
||||
ret = qca_send_power_pulse(hu, true);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Now the device is in ready state to communicate with host.
|
||||
* To sync host with device we need to reopen port.
|
||||
|
@ -1649,8 +1674,9 @@ static int qca_power_on(struct hci_dev *hdev)
|
|||
if (!hu->serdev)
|
||||
return 0;
|
||||
|
||||
if (qca_is_wcn399x(soc_type)) {
|
||||
ret = qca_wcn3990_init(hu);
|
||||
if (qca_is_wcn399x(soc_type) ||
|
||||
qca_is_wcn6750(soc_type)) {
|
||||
ret = qca_regulator_init(hu);
|
||||
} else {
|
||||
qcadev = serdev_device_get_drvdata(hu->serdev);
|
||||
if (qcadev->bt_en) {
|
||||
|
@ -1689,7 +1715,8 @@ static int qca_setup(struct hci_uart *hu)
|
|||
set_bit(HCI_QUIRK_SIMULTANEOUS_DISCOVERY, &hdev->quirks);
|
||||
|
||||
bt_dev_info(hdev, "setting up %s",
|
||||
qca_is_wcn399x(soc_type) ? "wcn399x" : "ROME/QCA6390");
|
||||
qca_is_wcn399x(soc_type) ? "wcn399x" :
|
||||
(soc_type == QCA_WCN6750) ? "wcn6750" : "ROME/QCA6390");
|
||||
|
||||
qca->memdump_state = QCA_MEMDUMP_IDLE;
|
||||
|
||||
|
@ -1700,7 +1727,8 @@ retry:
|
|||
|
||||
clear_bit(QCA_SSR_TRIGGERED, &qca->flags);
|
||||
|
||||
if (qca_is_wcn399x(soc_type)) {
|
||||
if (qca_is_wcn399x(soc_type) ||
|
||||
qca_is_wcn6750(soc_type)) {
|
||||
set_bit(HCI_QUIRK_USE_BDADDR_PROPERTY, &hdev->quirks);
|
||||
|
||||
ret = qca_read_soc_version(hdev, &ver, soc_type);
|
||||
|
@ -1720,7 +1748,8 @@ retry:
|
|||
qca_baudrate = qca_get_baudrate_value(speed);
|
||||
}
|
||||
|
||||
if (!qca_is_wcn399x(soc_type)) {
|
||||
if (!(qca_is_wcn399x(soc_type) ||
|
||||
qca_is_wcn6750(soc_type))) {
|
||||
/* Get QCA version information */
|
||||
ret = qca_read_soc_version(hdev, &ver, soc_type);
|
||||
if (ret)
|
||||
|
@ -1828,14 +1857,30 @@ static const struct qca_device_data qca_soc_data_qca6390 = {
|
|||
.num_vregs = 0,
|
||||
};
|
||||
|
||||
static const struct qca_device_data qca_soc_data_wcn6750 = {
|
||||
.soc_type = QCA_WCN6750,
|
||||
.vregs = (struct qca_vreg []) {
|
||||
{ "vddio", 5000 },
|
||||
{ "vddaon", 26000 },
|
||||
{ "vddbtcxmx", 126000 },
|
||||
{ "vddrfacmn", 12500 },
|
||||
{ "vddrfa0p8", 102000 },
|
||||
{ "vddrfa1p7", 302000 },
|
||||
{ "vddrfa1p2", 257000 },
|
||||
{ "vddrfa2p2", 1700000 },
|
||||
{ "vddasd", 200 },
|
||||
},
|
||||
.num_vregs = 9,
|
||||
.capabilities = QCA_CAP_WIDEBAND_SPEECH | QCA_CAP_VALID_LE_STATES,
|
||||
};
|
||||
|
||||
static void qca_power_shutdown(struct hci_uart *hu)
|
||||
{
|
||||
struct qca_serdev *qcadev;
|
||||
struct qca_data *qca = hu->priv;
|
||||
unsigned long flags;
|
||||
enum qca_btsoc_type soc_type = qca_soc_type(hu);
|
||||
|
||||
qcadev = serdev_device_get_drvdata(hu->serdev);
|
||||
bool sw_ctrl_state;
|
||||
|
||||
/* From this point we go into power off state. But serial port is
|
||||
* still open, stop queueing the IBS data and flush all the buffered
|
||||
|
@ -1852,10 +1897,20 @@ static void qca_power_shutdown(struct hci_uart *hu)
|
|||
if (!hu->serdev)
|
||||
return;
|
||||
|
||||
qcadev = serdev_device_get_drvdata(hu->serdev);
|
||||
|
||||
if (qca_is_wcn399x(soc_type)) {
|
||||
host_set_baudrate(hu, 2400);
|
||||
qca_send_power_pulse(hu, false);
|
||||
qca_regulator_disable(qcadev);
|
||||
} else if (soc_type == QCA_WCN6750) {
|
||||
gpiod_set_value_cansleep(qcadev->bt_en, 0);
|
||||
msleep(100);
|
||||
qca_regulator_disable(qcadev);
|
||||
if (qcadev->sw_ctrl) {
|
||||
sw_ctrl_state = gpiod_get_value_cansleep(qcadev->sw_ctrl);
|
||||
bt_dev_dbg(hu->hdev, "SW_CTRL is %d", sw_ctrl_state);
|
||||
}
|
||||
} else if (qcadev->bt_en) {
|
||||
gpiod_set_value_cansleep(qcadev->bt_en, 0);
|
||||
}
|
||||
|
@ -1978,7 +2033,9 @@ static int qca_serdev_probe(struct serdev_device *serdev)
|
|||
if (!qcadev->oper_speed)
|
||||
BT_DBG("UART will pick default operating speed");
|
||||
|
||||
if (data && qca_is_wcn399x(data->soc_type)) {
|
||||
if (data &&
|
||||
(qca_is_wcn399x(data->soc_type) ||
|
||||
qca_is_wcn6750(data->soc_type))) {
|
||||
qcadev->btsoc_type = data->soc_type;
|
||||
qcadev->bt_power = devm_kzalloc(&serdev->dev,
|
||||
sizeof(struct qca_power),
|
||||
|
@ -1996,6 +2053,18 @@ static int qca_serdev_probe(struct serdev_device *serdev)
|
|||
|
||||
qcadev->bt_power->vregs_on = false;
|
||||
|
||||
qcadev->bt_en = devm_gpiod_get_optional(&serdev->dev, "enable",
|
||||
GPIOD_OUT_LOW);
|
||||
if (!qcadev->bt_en && data->soc_type == QCA_WCN6750) {
|
||||
dev_err(&serdev->dev, "failed to acquire BT_EN gpio\n");
|
||||
power_ctrl_enabled = false;
|
||||
}
|
||||
|
||||
qcadev->sw_ctrl = devm_gpiod_get_optional(&serdev->dev, "swctrl",
|
||||
GPIOD_IN);
|
||||
if (!qcadev->sw_ctrl && data->soc_type == QCA_WCN6750)
|
||||
dev_warn(&serdev->dev, "failed to acquire SW_CTRL gpio\n");
|
||||
|
||||
qcadev->susclk = devm_clk_get_optional(&serdev->dev, NULL);
|
||||
if (IS_ERR(qcadev->susclk)) {
|
||||
dev_err(&serdev->dev, "failed to acquire clk\n");
|
||||
|
@ -2068,7 +2137,9 @@ static void qca_serdev_remove(struct serdev_device *serdev)
|
|||
struct qca_serdev *qcadev = serdev_device_get_drvdata(serdev);
|
||||
struct qca_power *power = qcadev->bt_power;
|
||||
|
||||
if (qca_is_wcn399x(qcadev->btsoc_type) && power->vregs_on)
|
||||
if ((qca_is_wcn399x(qcadev->btsoc_type) ||
|
||||
qca_is_wcn6750(qcadev->btsoc_type)) &&
|
||||
power->vregs_on)
|
||||
qca_power_shutdown(&qcadev->serdev_hu);
|
||||
else if (qcadev->susclk)
|
||||
clk_disable_unprepare(qcadev->susclk);
|
||||
|
@ -2244,6 +2315,7 @@ static const struct of_device_id qca_bluetooth_of_match[] = {
|
|||
{ .compatible = "qcom,wcn3990-bt", .data = &qca_soc_data_wcn3990},
|
||||
{ .compatible = "qcom,wcn3991-bt", .data = &qca_soc_data_wcn3991},
|
||||
{ .compatible = "qcom,wcn3998-bt", .data = &qca_soc_data_wcn3998},
|
||||
{ .compatible = "qcom,wcn6750-bt", .data = &qca_soc_data_wcn6750},
|
||||
{ /* sentinel */ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, qca_bluetooth_of_match);
|
||||
|
|
|
@ -34,6 +34,9 @@ static int virtbt_add_inbuf(struct virtio_bluetooth *vbt)
|
|||
int err;
|
||||
|
||||
skb = alloc_skb(1000, GFP_KERNEL);
|
||||
if (!skb)
|
||||
return -ENOMEM;
|
||||
|
||||
sg_init_one(sg, skb->data, 1000);
|
||||
|
||||
err = virtqueue_add_inbuf(vq, sg, 1, skb, GFP_KERNEL);
|
||||
|
|
|
@ -1423,7 +1423,7 @@ static enum i40iw_status_code i40iw_save_msix_info(struct i40iw_device *iwdev,
|
|||
struct i40e_qv_info *iw_qvinfo;
|
||||
u32 ceq_idx;
|
||||
u32 i;
|
||||
u32 size;
|
||||
size_t size;
|
||||
|
||||
if (!ldev->msix_count) {
|
||||
i40iw_pr_err("No MSI-X vectors\n");
|
||||
|
@ -1433,8 +1433,7 @@ static enum i40iw_status_code i40iw_save_msix_info(struct i40iw_device *iwdev,
|
|||
iwdev->msix_count = ldev->msix_count;
|
||||
|
||||
size = sizeof(struct i40iw_msix_vector) * iwdev->msix_count;
|
||||
size += sizeof(struct i40e_qvlist_info);
|
||||
size += sizeof(struct i40e_qv_info) * iwdev->msix_count - 1;
|
||||
size += struct_size(iw_qvlist, qv_info, iwdev->msix_count);
|
||||
iwdev->iw_msixtbl = kzalloc(size, GFP_KERNEL);
|
||||
|
||||
if (!iwdev->iw_msixtbl)
|
||||
|
|
|
@ -2285,6 +2285,7 @@ static int mlx5_ib_flow_action_create_packet_reformat_ctx(
|
|||
u8 ft_type, u8 dv_prt,
|
||||
void *in, size_t len)
|
||||
{
|
||||
struct mlx5_pkt_reformat_params reformat_params;
|
||||
enum mlx5_flow_namespace_type namespace;
|
||||
u8 prm_prt;
|
||||
int ret;
|
||||
|
@ -2297,9 +2298,13 @@ static int mlx5_ib_flow_action_create_packet_reformat_ctx(
|
|||
if (ret)
|
||||
return ret;
|
||||
|
||||
memset(&reformat_params, 0, sizeof(reformat_params));
|
||||
reformat_params.type = prm_prt;
|
||||
reformat_params.size = len;
|
||||
reformat_params.data = in;
|
||||
maction->flow_action_raw.pkt_reformat =
|
||||
mlx5_packet_reformat_alloc(dev->mdev, prm_prt, len,
|
||||
in, namespace);
|
||||
mlx5_packet_reformat_alloc(dev->mdev, &reformat_params,
|
||||
namespace);
|
||||
if (IS_ERR(maction->flow_action_raw.pkt_reformat)) {
|
||||
ret = PTR_ERR(maction->flow_action_raw.pkt_reformat);
|
||||
return ret;
|
||||
|
|
|
@ -1559,12 +1559,16 @@ int mlx5r_odp_create_eq(struct mlx5_ib_dev *dev, struct mlx5_ib_pf_eq *eq)
|
|||
}
|
||||
|
||||
eq->irq_nb.notifier_call = mlx5_ib_eq_pf_int;
|
||||
param = (struct mlx5_eq_param){
|
||||
.irq_index = 0,
|
||||
param = (struct mlx5_eq_param) {
|
||||
.nent = MLX5_IB_NUM_PF_EQE,
|
||||
};
|
||||
param.mask[0] = 1ull << MLX5_EVENT_TYPE_PAGE_FAULT;
|
||||
if (!zalloc_cpumask_var(¶m.affinity, GFP_KERNEL)) {
|
||||
err = -ENOMEM;
|
||||
goto err_wq;
|
||||
}
|
||||
eq->core = mlx5_eq_create_generic(dev->mdev, ¶m);
|
||||
free_cpumask_var(param.affinity);
|
||||
if (IS_ERR(eq->core)) {
|
||||
err = PTR_ERR(eq->core);
|
||||
goto err_wq;
|
||||
|
|
|
@ -2342,7 +2342,7 @@ static void __exit
|
|||
HFC_cleanup(void)
|
||||
{
|
||||
if (timer_pending(&hfc_tl))
|
||||
del_timer(&hfc_tl);
|
||||
del_timer_sync(&hfc_tl);
|
||||
|
||||
pci_unregister_driver(&hfc_driver);
|
||||
}
|
||||
|
|
|
@ -17,9 +17,6 @@
|
|||
#include "dsp.h"
|
||||
#include "dsp_hwec.h"
|
||||
|
||||
/* uncomment for debugging */
|
||||
/*#define PIPELINE_DEBUG*/
|
||||
|
||||
struct dsp_pipeline_entry {
|
||||
struct mISDN_dsp_element *elem;
|
||||
void *p;
|
||||
|
@ -104,10 +101,6 @@ int mISDN_dsp_element_register(struct mISDN_dsp_element *elem)
|
|||
}
|
||||
}
|
||||
|
||||
#ifdef PIPELINE_DEBUG
|
||||
printk(KERN_DEBUG "%s: %s registered\n", __func__, elem->name);
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
|
||||
err2:
|
||||
|
@ -129,10 +122,6 @@ void mISDN_dsp_element_unregister(struct mISDN_dsp_element *elem)
|
|||
list_for_each_entry_safe(entry, n, &dsp_elements, list)
|
||||
if (entry->elem == elem) {
|
||||
device_unregister(&entry->dev);
|
||||
#ifdef PIPELINE_DEBUG
|
||||
printk(KERN_DEBUG "%s: %s unregistered\n",
|
||||
__func__, elem->name);
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
printk(KERN_ERR "%s: element %s not in list.\n", __func__, elem->name);
|
||||
|
@ -145,10 +134,6 @@ int dsp_pipeline_module_init(void)
|
|||
if (IS_ERR(elements_class))
|
||||
return PTR_ERR(elements_class);
|
||||
|
||||
#ifdef PIPELINE_DEBUG
|
||||
printk(KERN_DEBUG "%s: dsp pipeline module initialized\n", __func__);
|
||||
#endif
|
||||
|
||||
dsp_hwec_init();
|
||||
|
||||
return 0;
|
||||
|
@ -168,10 +153,6 @@ void dsp_pipeline_module_exit(void)
|
|||
__func__, entry->elem->name);
|
||||
kfree(entry);
|
||||
}
|
||||
|
||||
#ifdef PIPELINE_DEBUG
|
||||
printk(KERN_DEBUG "%s: dsp pipeline module exited\n", __func__);
|
||||
#endif
|
||||
}
|
||||
|
||||
int dsp_pipeline_init(struct dsp_pipeline *pipeline)
|
||||
|
@ -181,10 +162,6 @@ int dsp_pipeline_init(struct dsp_pipeline *pipeline)
|
|||
|
||||
INIT_LIST_HEAD(&pipeline->list);
|
||||
|
||||
#ifdef PIPELINE_DEBUG
|
||||
printk(KERN_DEBUG "%s: dsp pipeline ready\n", __func__);
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -210,15 +187,11 @@ void dsp_pipeline_destroy(struct dsp_pipeline *pipeline)
|
|||
return;
|
||||
|
||||
_dsp_pipeline_destroy(pipeline);
|
||||
|
||||
#ifdef PIPELINE_DEBUG
|
||||
printk(KERN_DEBUG "%s: dsp pipeline destroyed\n", __func__);
|
||||
#endif
|
||||
}
|
||||
|
||||
int dsp_pipeline_build(struct dsp_pipeline *pipeline, const char *cfg)
|
||||
{
|
||||
int incomplete = 0, found = 0;
|
||||
int found = 0;
|
||||
char *dup, *tok, *name, *args;
|
||||
struct dsp_element_entry *entry, *n;
|
||||
struct dsp_pipeline_entry *pipeline_entry;
|
||||
|
@ -251,7 +224,6 @@ int dsp_pipeline_build(struct dsp_pipeline *pipeline, const char *cfg)
|
|||
printk(KERN_ERR "%s: failed to add "
|
||||
"entry to pipeline: %s (out of "
|
||||
"memory)\n", __func__, elem->name);
|
||||
incomplete = 1;
|
||||
goto _out;
|
||||
}
|
||||
pipeline_entry->elem = elem;
|
||||
|
@ -268,20 +240,12 @@ int dsp_pipeline_build(struct dsp_pipeline *pipeline, const char *cfg)
|
|||
if (pipeline_entry->p) {
|
||||
list_add_tail(&pipeline_entry->
|
||||
list, &pipeline->list);
|
||||
#ifdef PIPELINE_DEBUG
|
||||
printk(KERN_DEBUG "%s: created "
|
||||
"instance of %s%s%s\n",
|
||||
__func__, name, args ?
|
||||
" with args " : "", args ?
|
||||
args : "");
|
||||
#endif
|
||||
} else {
|
||||
printk(KERN_ERR "%s: failed "
|
||||
"to add entry to pipeline: "
|
||||
"%s (new() returned NULL)\n",
|
||||
__func__, elem->name);
|
||||
kfree(pipeline_entry);
|
||||
incomplete = 1;
|
||||
}
|
||||
}
|
||||
found = 1;
|
||||
|
@ -290,11 +254,9 @@ int dsp_pipeline_build(struct dsp_pipeline *pipeline, const char *cfg)
|
|||
|
||||
if (found)
|
||||
found = 0;
|
||||
else {
|
||||
else
|
||||
printk(KERN_ERR "%s: element not found, skipping: "
|
||||
"%s\n", __func__, name);
|
||||
incomplete = 1;
|
||||
}
|
||||
}
|
||||
|
||||
_out:
|
||||
|
@ -303,10 +265,6 @@ _out:
|
|||
else
|
||||
pipeline->inuse = 0;
|
||||
|
||||
#ifdef PIPELINE_DEBUG
|
||||
printk(KERN_DEBUG "%s: dsp pipeline built%s: %s\n",
|
||||
__func__, incomplete ? " incomplete" : "", cfg);
|
||||
#endif
|
||||
kfree(dup);
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -326,7 +326,8 @@ int lirc_prog_query(const union bpf_attr *attr, union bpf_attr __user *uattr)
|
|||
}
|
||||
|
||||
if (attr->query.prog_cnt != 0 && prog_ids && cnt)
|
||||
ret = bpf_prog_array_copy_to_user(progs, prog_ids, cnt);
|
||||
ret = bpf_prog_array_copy_to_user(progs, prog_ids,
|
||||
attr->query.prog_cnt);
|
||||
|
||||
unlock:
|
||||
mutex_unlock(&ir_raw_handler_lock);
|
||||
|
|
|
@ -262,17 +262,17 @@ config GENEVE
|
|||
will be called geneve.
|
||||
|
||||
config BAREUDP
|
||||
tristate "Bare UDP Encapsulation"
|
||||
depends on INET
|
||||
depends on IPV6 || !IPV6
|
||||
select NET_UDP_TUNNEL
|
||||
select GRO_CELLS
|
||||
help
|
||||
This adds a bare UDP tunnel module for tunnelling different
|
||||
kinds of traffic like MPLS, IP, etc. inside a UDP tunnel.
|
||||
tristate "Bare UDP Encapsulation"
|
||||
depends on INET
|
||||
depends on IPV6 || !IPV6
|
||||
select NET_UDP_TUNNEL
|
||||
select GRO_CELLS
|
||||
help
|
||||
This adds a bare UDP tunnel module for tunnelling different
|
||||
kinds of traffic like MPLS, IP, etc. inside a UDP tunnel.
|
||||
|
||||
To compile this driver as a module, choose M here: the module
|
||||
will be called bareudp.
|
||||
To compile this driver as a module, choose M here: the module
|
||||
will be called bareudp.
|
||||
|
||||
config GTP
|
||||
tristate "GPRS Tunneling Protocol datapath (GTP-U)"
|
||||
|
@ -431,6 +431,7 @@ config VSOCKMON
|
|||
config MHI_NET
|
||||
tristate "MHI network driver"
|
||||
depends on MHI_BUS
|
||||
select WWAN
|
||||
help
|
||||
This is the network driver for MHI bus. It can be used with
|
||||
QCOM based WWAN modems (like SDX55). Say Y or M.
|
||||
|
|
|
@ -609,12 +609,12 @@ static int cops_nodeid (struct net_device *dev, int nodeid)
|
|||
|
||||
if(lp->board == DAYNA)
|
||||
{
|
||||
/* Empty any pending adapter responses. */
|
||||
/* Empty any pending adapter responses. */
|
||||
while((inb(ioaddr+DAYNA_CARD_STATUS)&DAYNA_TX_READY)==0)
|
||||
{
|
||||
outb(0, ioaddr+COPS_CLEAR_INT); /* Clear interrupts. */
|
||||
if((inb(ioaddr+DAYNA_CARD_STATUS)&0x03)==DAYNA_RX_REQUEST)
|
||||
cops_rx(dev); /* Kick any packets waiting. */
|
||||
if((inb(ioaddr+DAYNA_CARD_STATUS)&0x03)==DAYNA_RX_REQUEST)
|
||||
cops_rx(dev); /* Kick any packets waiting. */
|
||||
schedule();
|
||||
}
|
||||
|
||||
|
@ -630,13 +630,13 @@ static int cops_nodeid (struct net_device *dev, int nodeid)
|
|||
while(inb(ioaddr+TANG_CARD_STATUS)&TANG_RX_READY)
|
||||
{
|
||||
outb(0, ioaddr+COPS_CLEAR_INT); /* Clear interrupt. */
|
||||
cops_rx(dev); /* Kick out packets waiting. */
|
||||
cops_rx(dev); /* Kick out packets waiting. */
|
||||
schedule();
|
||||
}
|
||||
|
||||
/* Not sure what Tangent does if nodeid picked is used. */
|
||||
if(nodeid == 0) /* Seed. */
|
||||
nodeid = jiffies&0xFF; /* Get a random try */
|
||||
nodeid = jiffies&0xFF; /* Get a random try */
|
||||
outb(2, ioaddr); /* Command length LSB */
|
||||
outb(0, ioaddr); /* Command length MSB */
|
||||
outb(LAP_INIT, ioaddr); /* Send LAP_INIT byte */
|
||||
|
@ -651,13 +651,13 @@ static int cops_nodeid (struct net_device *dev, int nodeid)
|
|||
|
||||
if(lp->board == DAYNA)
|
||||
{
|
||||
if((inb(ioaddr+DAYNA_CARD_STATUS)&0x03)==DAYNA_RX_REQUEST)
|
||||
cops_rx(dev); /* Grab the nodeid put in lp->node_acquire. */
|
||||
if((inb(ioaddr+DAYNA_CARD_STATUS)&0x03)==DAYNA_RX_REQUEST)
|
||||
cops_rx(dev); /* Grab the nodeid put in lp->node_acquire. */
|
||||
}
|
||||
if(lp->board == TANGENT)
|
||||
{
|
||||
if(inb(ioaddr+TANG_CARD_STATUS)&TANG_RX_READY)
|
||||
cops_rx(dev); /* Grab the nodeid put in lp->node_acquire. */
|
||||
cops_rx(dev); /* Grab the nodeid put in lp->node_acquire. */
|
||||
}
|
||||
schedule();
|
||||
}
|
||||
|
@ -719,16 +719,16 @@ static irqreturn_t cops_interrupt(int irq, void *dev_id)
|
|||
{
|
||||
do {
|
||||
outb(0, ioaddr + COPS_CLEAR_INT);
|
||||
status=inb(ioaddr+DAYNA_CARD_STATUS);
|
||||
if((status&0x03)==DAYNA_RX_REQUEST)
|
||||
cops_rx(dev);
|
||||
netif_wake_queue(dev);
|
||||
status=inb(ioaddr+DAYNA_CARD_STATUS);
|
||||
if((status&0x03)==DAYNA_RX_REQUEST)
|
||||
cops_rx(dev);
|
||||
netif_wake_queue(dev);
|
||||
} while(++boguscount < 20);
|
||||
}
|
||||
else
|
||||
{
|
||||
do {
|
||||
status=inb(ioaddr+TANG_CARD_STATUS);
|
||||
status=inb(ioaddr+TANG_CARD_STATUS);
|
||||
if(status & TANG_RX_READY)
|
||||
cops_rx(dev);
|
||||
if(status & TANG_TX_READY)
|
||||
|
@ -855,7 +855,7 @@ static void cops_timeout(struct net_device *dev, unsigned int txqueue)
|
|||
if(lp->board==TANGENT)
|
||||
{
|
||||
if((inb(ioaddr+TANG_CARD_STATUS)&TANG_TX_READY)==0)
|
||||
printk(KERN_WARNING "%s: No TX complete interrupt.\n", dev->name);
|
||||
printk(KERN_WARNING "%s: No TX complete interrupt.\n", dev->name);
|
||||
}
|
||||
printk(KERN_WARNING "%s: Transmit timed out.\n", dev->name);
|
||||
cops_jumpstart(dev); /* Restart the card. */
|
||||
|
@ -897,7 +897,7 @@ static netdev_tx_t cops_send_packet(struct sk_buff *skb,
|
|||
outb(LAP_WRITE, ioaddr);
|
||||
|
||||
if(lp->board == DAYNA) /* Check the transmit buffer again. */
|
||||
while((inb(ioaddr+DAYNA_CARD_STATUS)&DAYNA_TX_READY)==0);
|
||||
while((inb(ioaddr+DAYNA_CARD_STATUS)&DAYNA_TX_READY)==0);
|
||||
|
||||
outsb(ioaddr, skb->data, skb->len); /* Send out the data. */
|
||||
|
||||
|
|
|
@ -584,11 +584,13 @@ loop:
|
|||
printk("%02x ",ltdmacbuf[i]);
|
||||
printk("\n");
|
||||
}
|
||||
|
||||
handlecommand(dev);
|
||||
if(0xfa==inb_p(base+6)) {
|
||||
/* we timed out, so return */
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (0xfa == inb_p(base + 6)) {
|
||||
/* we timed out, so return */
|
||||
goto done;
|
||||
}
|
||||
} else {
|
||||
/* we don't seem to have a command */
|
||||
if (!mboxinuse[0]) {
|
||||
|
@ -935,10 +937,10 @@ static netdev_tx_t ltpc_xmit(struct sk_buff *skb, struct net_device *dev)
|
|||
static int __init ltpc_probe_dma(int base, int dma)
|
||||
{
|
||||
int want = (dma == 3) ? 2 : (dma == 1) ? 1 : 3;
|
||||
unsigned long timeout;
|
||||
unsigned long f;
|
||||
unsigned long timeout;
|
||||
unsigned long f;
|
||||
|
||||
if (want & 1) {
|
||||
if (want & 1) {
|
||||
if (request_dma(1,"ltpc")) {
|
||||
want &= ~1;
|
||||
} else {
|
||||
|
|
|
@ -133,6 +133,7 @@ static int bareudp_udp_encap_recv(struct sock *sk, struct sk_buff *skb)
|
|||
skb->dev = bareudp->dev;
|
||||
oiph = skb_network_header(skb);
|
||||
skb_reset_network_header(skb);
|
||||
skb_reset_mac_header(skb);
|
||||
|
||||
if (!IS_ENABLED(CONFIG_IPV6) || family == AF_INET)
|
||||
err = IP_ECN_decapsulate(oiph, skb);
|
||||
|
|
|
@ -104,6 +104,7 @@ static void __tlb_clear_slave(struct bonding *bond, struct slave *slave,
|
|||
index = SLAVE_TLB_INFO(slave).head;
|
||||
while (index != TLB_NULL_INDEX) {
|
||||
u32 next_index = tx_hash_table[index].next;
|
||||
|
||||
tlb_init_table_entry(&tx_hash_table[index], save_load);
|
||||
index = next_index;
|
||||
}
|
||||
|
@ -228,7 +229,7 @@ static struct slave *tlb_choose_channel(struct bonding *bond, u32 hash_index,
|
|||
{
|
||||
struct slave *tx_slave;
|
||||
|
||||
/* We don't need to disable softirq here, becase
|
||||
/* We don't need to disable softirq here, because
|
||||
* tlb_choose_channel() is only called by bond_alb_xmit()
|
||||
* which already has softirq disabled.
|
||||
*/
|
||||
|
@ -608,7 +609,7 @@ static struct slave *rlb_choose_channel(struct sk_buff *skb,
|
|||
|
||||
client_info->ip_src = arp->ip_src;
|
||||
client_info->ip_dst = arp->ip_dst;
|
||||
/* arp->mac_dst is broadcast for arp reqeusts.
|
||||
/* arp->mac_dst is broadcast for arp requests.
|
||||
* will be updated with clients actual unicast mac address
|
||||
* upon receiving an arp reply.
|
||||
*/
|
||||
|
@ -628,6 +629,7 @@ static struct slave *rlb_choose_channel(struct sk_buff *skb,
|
|||
|
||||
if (!client_info->assigned) {
|
||||
u32 prev_tbl_head = bond_info->rx_hashtbl_used_head;
|
||||
|
||||
bond_info->rx_hashtbl_used_head = hash_index;
|
||||
client_info->used_next = prev_tbl_head;
|
||||
if (prev_tbl_head != RLB_NULL_INDEX) {
|
||||
|
@ -830,9 +832,10 @@ static void rlb_purge_src_ip(struct bonding *bond, struct arp_pkt *arp)
|
|||
while (index != RLB_NULL_INDEX) {
|
||||
struct rlb_client_info *entry = &(bond_info->rx_hashtbl[index]);
|
||||
u32 next_index = entry->src_next;
|
||||
|
||||
if (entry->ip_src == arp->ip_src &&
|
||||
!ether_addr_equal_64bits(arp->mac_src, entry->mac_src))
|
||||
rlb_delete_table_entry(bond, index);
|
||||
rlb_delete_table_entry(bond, index);
|
||||
index = next_index;
|
||||
}
|
||||
spin_unlock_bh(&bond->mode_lock);
|
||||
|
@ -1268,7 +1271,7 @@ unwind:
|
|||
return res;
|
||||
}
|
||||
|
||||
/************************ exported alb funcions ************************/
|
||||
/************************ exported alb functions ************************/
|
||||
|
||||
int bond_alb_initialize(struct bonding *bond, int rlb_enabled)
|
||||
{
|
||||
|
@ -1547,7 +1550,7 @@ void bond_alb_monitor(struct work_struct *work)
|
|||
|
||||
bond_for_each_slave_rcu(bond, slave, iter) {
|
||||
/* If updating current_active, use all currently
|
||||
* user mac addreses (!strict_match). Otherwise, only
|
||||
* user mac addresses (!strict_match). Otherwise, only
|
||||
* use mac of the slave device.
|
||||
* In RLB mode, we always use strict matches.
|
||||
*/
|
||||
|
|
|
@ -88,9 +88,8 @@ void bond_create_debugfs(void)
|
|||
{
|
||||
bonding_debug_root = debugfs_create_dir("bonding", NULL);
|
||||
|
||||
if (!bonding_debug_root) {
|
||||
if (!bonding_debug_root)
|
||||
pr_warn("Warning: Cannot create bonding directory in debugfs\n");
|
||||
}
|
||||
}
|
||||
|
||||
void bond_destroy_debugfs(void)
|
||||
|
|
|
@ -620,7 +620,7 @@ static int bond_check_dev_link(struct bonding *bond,
|
|||
*/
|
||||
|
||||
/* Yes, the mii is overlaid on the ifreq.ifr_ifru */
|
||||
strncpy(ifr.ifr_name, slave_dev->name, IFNAMSIZ);
|
||||
strscpy_pad(ifr.ifr_name, slave_dev->name, IFNAMSIZ);
|
||||
mii = if_mii(&ifr);
|
||||
if (ioctl(slave_dev, &ifr, SIOCGMIIPHY) == 0) {
|
||||
mii->reg_num = MII_BMSR;
|
||||
|
@ -1013,9 +1013,8 @@ void bond_change_active_slave(struct bonding *bond, struct slave *new_active)
|
|||
if (bond_is_lb(bond))
|
||||
bond_alb_handle_link_change(bond, new_active, BOND_LINK_UP);
|
||||
} else {
|
||||
if (bond_uses_primary(bond)) {
|
||||
if (bond_uses_primary(bond))
|
||||
slave_info(bond->dev, new_active->dev, "making interface the new active one\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1601,6 +1600,14 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev,
|
|||
int link_reporting;
|
||||
int res = 0, i;
|
||||
|
||||
if (slave_dev->flags & IFF_MASTER &&
|
||||
!netif_is_bond_master(slave_dev)) {
|
||||
NL_SET_ERR_MSG(extack, "Device with IFF_MASTER cannot be enslaved");
|
||||
netdev_err(bond_dev,
|
||||
"Error: Device with IFF_MASTER cannot be enslaved\n");
|
||||
return -EPERM;
|
||||
}
|
||||
|
||||
if (!bond->params.use_carrier &&
|
||||
slave_dev->ethtool_ops->get_link == NULL &&
|
||||
slave_ops->ndo_do_ioctl == NULL) {
|
||||
|
@ -2272,6 +2279,7 @@ static int bond_release_and_destroy(struct net_device *bond_dev,
|
|||
static void bond_info_query(struct net_device *bond_dev, struct ifbond *info)
|
||||
{
|
||||
struct bonding *bond = netdev_priv(bond_dev);
|
||||
|
||||
bond_fill_ifbond(bond, info);
|
||||
}
|
||||
|
||||
|
@ -4202,16 +4210,16 @@ static u32 bond_rr_gen_slave_id(struct bonding *bond)
|
|||
slave_id = prandom_u32();
|
||||
break;
|
||||
case 1:
|
||||
slave_id = bond->rr_tx_counter;
|
||||
slave_id = this_cpu_inc_return(*bond->rr_tx_counter);
|
||||
break;
|
||||
default:
|
||||
reciprocal_packets_per_slave =
|
||||
bond->params.reciprocal_packets_per_slave;
|
||||
slave_id = reciprocal_divide(bond->rr_tx_counter,
|
||||
slave_id = this_cpu_inc_return(*bond->rr_tx_counter);
|
||||
slave_id = reciprocal_divide(slave_id,
|
||||
reciprocal_packets_per_slave);
|
||||
break;
|
||||
}
|
||||
bond->rr_tx_counter++;
|
||||
|
||||
return slave_id;
|
||||
}
|
||||
|
@ -4849,8 +4857,12 @@ static const struct device_type bond_type = {
|
|||
static void bond_destructor(struct net_device *bond_dev)
|
||||
{
|
||||
struct bonding *bond = netdev_priv(bond_dev);
|
||||
|
||||
if (bond->wq)
|
||||
destroy_workqueue(bond->wq);
|
||||
|
||||
if (bond->rr_tx_counter)
|
||||
free_percpu(bond->rr_tx_counter);
|
||||
}
|
||||
|
||||
void bond_setup(struct net_device *bond_dev)
|
||||
|
@ -5329,10 +5341,8 @@ static int bond_check_params(struct bond_params *params)
|
|||
(struct reciprocal_value) { 0 };
|
||||
}
|
||||
|
||||
if (primary) {
|
||||
strncpy(params->primary, primary, IFNAMSIZ);
|
||||
params->primary[IFNAMSIZ - 1] = 0;
|
||||
}
|
||||
if (primary)
|
||||
strscpy_pad(params->primary, primary, sizeof(params->primary));
|
||||
|
||||
memcpy(params->arp_targets, arp_target, sizeof(arp_target));
|
||||
|
||||
|
@ -5351,6 +5361,15 @@ static int bond_init(struct net_device *bond_dev)
|
|||
if (!bond->wq)
|
||||
return -ENOMEM;
|
||||
|
||||
if (BOND_MODE(bond) == BOND_MODE_ROUNDROBIN) {
|
||||
bond->rr_tx_counter = alloc_percpu(u32);
|
||||
if (!bond->rr_tx_counter) {
|
||||
destroy_workqueue(bond->wq);
|
||||
bond->wq = NULL;
|
||||
return -ENOMEM;
|
||||
}
|
||||
}
|
||||
|
||||
spin_lock_init(&bond->stats_lock);
|
||||
netdev_lockdep_set_classes(bond_dev);
|
||||
|
||||
|
|
|
@ -598,7 +598,7 @@ static int bond_fill_info(struct sk_buff *skb,
|
|||
goto nla_put_failure;
|
||||
|
||||
if (nla_put_u32(skb, IFLA_BOND_RESEND_IGMP,
|
||||
bond->params.resend_igmp))
|
||||
bond->params.resend_igmp))
|
||||
goto nla_put_failure;
|
||||
|
||||
if (nla_put_u8(skb, IFLA_BOND_NUM_PEER_NOTIF,
|
||||
|
|
|
@ -705,7 +705,7 @@ out:
|
|||
int __bond_opt_set_notify(struct bonding *bond,
|
||||
unsigned int option, struct bond_opt_value *val)
|
||||
{
|
||||
int ret = -ENOENT;
|
||||
int ret;
|
||||
|
||||
ASSERT_RTNL();
|
||||
|
||||
|
@ -1206,8 +1206,7 @@ static int bond_option_primary_set(struct bonding *bond,
|
|||
RCU_INIT_POINTER(bond->primary_slave, NULL);
|
||||
bond_select_active_slave(bond);
|
||||
}
|
||||
strncpy(bond->params.primary, primary, IFNAMSIZ);
|
||||
bond->params.primary[IFNAMSIZ - 1] = 0;
|
||||
strscpy_pad(bond->params.primary, primary, IFNAMSIZ);
|
||||
|
||||
netdev_dbg(bond->dev, "Recording %s as primary, but it has not been enslaved yet\n",
|
||||
primary);
|
||||
|
|
|
@ -112,6 +112,7 @@ static void bond_info_show_master(struct seq_file *seq)
|
|||
/* ARP information */
|
||||
if (bond->params.arp_interval > 0) {
|
||||
int printed = 0;
|
||||
|
||||
seq_printf(seq, "ARP Polling Interval (ms): %d\n",
|
||||
bond->params.arp_interval);
|
||||
|
||||
|
|
|
@ -385,6 +385,7 @@ static ssize_t bonding_show_num_peer_notif(struct device *d,
|
|||
char *buf)
|
||||
{
|
||||
struct bonding *bond = to_bond(d);
|
||||
|
||||
return sprintf(buf, "%d\n", bond->params.num_peer_notif);
|
||||
}
|
||||
static DEVICE_ATTR(num_grat_arp, 0644,
|
||||
|
@ -496,6 +497,7 @@ static ssize_t bonding_show_ad_aggregator(struct device *d,
|
|||
|
||||
if (BOND_MODE(bond) == BOND_MODE_8023AD) {
|
||||
struct ad_info ad_info;
|
||||
|
||||
count = sprintf(buf, "%d\n",
|
||||
bond_3ad_get_active_agg_info(bond, &ad_info)
|
||||
? 0 : ad_info.aggregator_id);
|
||||
|
@ -516,6 +518,7 @@ static ssize_t bonding_show_ad_num_ports(struct device *d,
|
|||
|
||||
if (BOND_MODE(bond) == BOND_MODE_8023AD) {
|
||||
struct ad_info ad_info;
|
||||
|
||||
count = sprintf(buf, "%d\n",
|
||||
bond_3ad_get_active_agg_info(bond, &ad_info)
|
||||
? 0 : ad_info.ports);
|
||||
|
@ -536,6 +539,7 @@ static ssize_t bonding_show_ad_actor_key(struct device *d,
|
|||
|
||||
if (BOND_MODE(bond) == BOND_MODE_8023AD && capable(CAP_NET_ADMIN)) {
|
||||
struct ad_info ad_info;
|
||||
|
||||
count = sprintf(buf, "%d\n",
|
||||
bond_3ad_get_active_agg_info(bond, &ad_info)
|
||||
? 0 : ad_info.actor_key);
|
||||
|
@ -556,6 +560,7 @@ static ssize_t bonding_show_ad_partner_key(struct device *d,
|
|||
|
||||
if (BOND_MODE(bond) == BOND_MODE_8023AD && capable(CAP_NET_ADMIN)) {
|
||||
struct ad_info ad_info;
|
||||
|
||||
count = sprintf(buf, "%d\n",
|
||||
bond_3ad_get_active_agg_info(bond, &ad_info)
|
||||
? 0 : ad_info.partner_key);
|
||||
|
@ -576,6 +581,7 @@ static ssize_t bonding_show_ad_partner_mac(struct device *d,
|
|||
|
||||
if (BOND_MODE(bond) == BOND_MODE_8023AD && capable(CAP_NET_ADMIN)) {
|
||||
struct ad_info ad_info;
|
||||
|
||||
if (!bond_3ad_get_active_agg_info(bond, &ad_info))
|
||||
count = sprintf(buf, "%pM\n", ad_info.partner_system);
|
||||
}
|
||||
|
@ -660,6 +666,7 @@ static ssize_t bonding_show_tlb_dynamic_lb(struct device *d,
|
|||
char *buf)
|
||||
{
|
||||
struct bonding *bond = to_bond(d);
|
||||
|
||||
return sprintf(buf, "%d\n", bond->params.tlb_dynamic_lb);
|
||||
}
|
||||
static DEVICE_ATTR(tlb_dynamic_lb, 0644,
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue