mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2025-01-01 10:43:43 +00:00
Networking changes for 6.12.
The zero-copy changes are relatively significant, but regression risk should be contained. The feature needs to be used to cause trouble. The new code did trigger a PowerPC64 bug with GCC 14: https://lore.kernel.org/netdev/20240913125302.0a06b4c7@canb.auug.org.au/ a fix for which Michael will bring via his tree: https://lore.kernel.org/all/87jzffq9ge.fsf@mail.lhotse/ Unideal, not sure if you'll be willing to pull without that fix but since we caught this recently I figured we'll defer to you during the MW instead of trying to fix it cross-tree. Also it feels like we got an order of magnitude more semi-automated "refactoring" chaff than usual, I wonder if it's just us. Core & protocols ---------------- - Support Device Memory TCP, ability to zero-copy receive TCP payloads to a DMABUF region of memory while packet headers land separately in normal kernel buffers, and TCP processes then as usual. - The ability to read the PTP PHC (Physical Hardware Clock) alongside MONOTONIC_RAW timestamps with PTP_SYS_OFFSET_EXTENDED. Previously only CLOCK_REALTIME was supported. - Allow matching on all bits of IP DSCP for routing decisions. Previously we only supported on matching TOS bits in IPv4 which is a narrower interpretation of the same header field. - Increase the range of weights used for multi-path routing from 8 bits to 16 bits. - Add support for IPv6 PIO p flag in the Prefix Information Option per draft-ietf-6man-pio-pflag. - IPv6 IOAM6 support for new tunsrc encap mode for better performance. - Detect destinations which blackhole MPTCP traffic and avoid initiating MPTCP connections to them for a certain period of time, 1h by default. - Improve IPsec control path performance by removing the inexact policies list. - AF_VSOCK: add support for SIOCOUTQ ioctl. - Add enum for reasons TCP reset was sent for easier tracing. - Add SMC ringbufs usage statistics. Drivers ------- - Handle netconsole setup failures more gracefully, don't fail loading, retain the specified target as disabled. - Extend bonding's IPsec offload pass thru capabilities (ESN, stats). Filtering --------- - Add TCP_BPF_SOCK_OPS_CB_FLAGS to bpf_*sockopt() to address the case when long-lived sockets miss a chance to set additional callbacks if a sockops program was not attached early in their lifetime. - Support using BPF skb helpers in tracepoints. - Conntrack Netlink: support CTA_FILTER for flush. - Improve SCTP support in nfnetlink_queue. - Improve performance of large nftables flush transactions. Things we sprinkled into general kernel code -------------------------------------------- - selftests: support setting an "interpreter" for script files; make it easy to run as separate cases tests where one "interpreter" is fed various test descriptions (in our case packet sequences). Driver API ---------- - Extend core and ethtool APIs to support many PHYs connected to a single interface (PHY topologies). - Extend cable diagnostics to specify whether Time Domain Reflectometry (TDR) or Active Link Cable Diagnostic (ALCD) was used. - Add library for implementing MAC-PHY Ethernet drivers for SPI devices compatible with Open Alliance 10BASE-T1x MAC-PHY Serial Interface (TC6) standard. - Add helpers to the PHY framework, for PHYs following the Open Alliance standards: - 1000BaseT1 link settings - cable test and diagnostics - Support listing / dumping all allocated RSS contexts. - Add configuration for frequency Embedded SYNC in DPLL, which magically embeds sync pulses into Ethernet signaling. Device drivers -------------- - Ethernet high-speed NICs: - Broadcom (bnxt): - use better FW APIs for queue reset - support QOS and TPID settings for the SR-IOV VLAN - support dynamic MSI-X allocation - Intel (100G, ice, idpf): - ice: support PCIe subfunctions - iavf: add support for TC U32 filters on VFs - ice: support Embedded SYNC in DPLL - nVidia/Mellanox (mlx5): - support HW managed steering tables - support PCIe PTM cross timestamping - AMD/Pensando: - ionic: use page_pool to increase Rx performance - Cisco (enic): - report per-queue statistics - Ethernet virtual: - Microsoft vNIC: - mana: support configuring ring length - netvsc: enable more channels on systems with many CPUs - IBM veth: - optimize polling to improve TCP_RR performance - optimize performance of Tx handling - VirtIO net: - synchronize the operstate with the admin state to allow a lower virtio-net to propagate the link status to an upper device like macvlan - Ethernet NICs consumer, and embedded: - Add driver for Realtek automotive PCIe devices (RTL9054, RTL9068, RTL9072, RTL9075, RTL9068, RTL9071) - Add driver for Microchip LAN8650/1 10BASE-T1S MAC-PHY. - Microchip: - lan743x: use phylink - support WOL, EEE, pause, link settings - add Wake-on-LAN support for KSZ87xx family - add KSZ8895/KSZ8864 switch support - factor out FDMA code and use it in sparx5 and lan966x (including DCB support in both) - Synopsys (stmmac): - support frame preemption (configured using TC and ethtool) - support Loongson DWMAC (GMAC v3.73) - support RockChips RK3576 DWMAC - TI: - am65-cpsw: add multi queue RX support - icssg-prueth: HSR offload support - Cadence (macb): - enable software (hrtimer based) IRQ coalescing by default - Xilinx (axinet): - expose HW statistics - improve multicast filtering - relax Rx checksum offload constraints - MediaTek: - mt7530: add EN7581 support - Aspeed (ftgmac100): - report link speed and duplex - Intel: - igc: add mqprio offload - igc: report EEE configuration - RealTek (r8169): - add support for RTL8126A rev.b - Vitesse (vsc73xx): - implement FDB add/del/dump operations - Freescale (fs_enet): - use phylink - Ethernet PHYs: - vitesse: implement downshift and MDI-X in vsc73xx PHYs - microchip: support LAN887x, supporting IEEE 802.3bw (100BASE-T1) and IEEE 802.3bp (1000BASE-T1) specifications - add Applied Micro QT2025 PHY driver (in Rust) - add Motorcomm yt8821 2.5G Ethernet PHY driver - CAN: - add driver for Rockchip RK3568 CAN-FD controller - flexcan: add wakeup support for imx95 - kvaser_usb: set hardware timestamp on transmitted packets - WiFi: - mac80211/cfg80211: - EHT rate support in AQL airtime fairness - handle DFS (radar detection) per link in Multi-Link Operation - RealTek (rtw89): - support RTL8852BT and 8852BE-VT (WiFi 6) - support hardware rfkill - support HW encryption in unicast management frames - support Wake-on-WLAN with supported network detection - RealTek (rtw89): - improve Rx performance by using USB frame aggregation - support USB 3 with RTL8822CU/RTL8822BU - Intel (iwlwifi/mvm): - offload RLC/SMPS functionality to firmware - Marvell (mwifiex): - add host based MLME to enable WPA3 - Bluetooth: - add support for Amlogic HCI UART protocol - add support for ISO data/packets to Intel and NXP drivers Signed-off-by: Jakub Kicinski <kuba@kernel.org> -----BEGIN PGP SIGNATURE----- iQIyBAABCAAdFiEE6jPA+I1ugmIBA4hXMUZtbf5SIrsFAmbnFW0ACgkQMUZtbf5S IrvA8A/4yxw9SFLFZVFn2c1kRssssSUENAljnP29MaINjr74BT2B324e5V5xiCK/ yT+hr9M+mlFDZVlZYAxo7Z64X6EwmjXewaH+2/tIsZf9LFySnkNq3sCxCuZWQNtE WjVdT/t+7rS8sGQefSggchXrSqZg1Rw/oCI3cKjQl8jB/CvDs7n1ivjtNz409jHy MKvcvf4cfG/olN0SnXh8kHHmz4d1rnPOi2OmC/dNAU8ErcDgC1t7PmMAzTfJWzND Akyxe4BvMkoKjL+kzIdpaf6EoLjUENPqu9/KKseP37HtYZmE4M0ENJOJnr7FVWwP GHymKwyp+VyI3RLNPIWrMJyCOwyUg4n4N44tGDn5bC3fYi1qK7U14pTP1vSZfXsK K8D6kpkVNllTLvf2z+FbweHu6CSh87vgdt1p7aNKpkEO0jISJBDFxLAen1buayKt 9VYXclcM7ZdjDd6w/53woieYizNeV10L5917htJCh/BbQ+XM0IjDR9wiJuj3aZ1s BrmsTK/7VuKxJ4LQKFkWnqnB02/GUHDbGVQoQCUBF7uaSPcPv4FWW6ibqIUz8zq5 HyGFOIL1Lc/J4s7D3mvAEhs6AKcVd9eU29TIcgLAUFyAYvSq7Y50ZeFtZrCysv2y Uy43qagPl4jKcFlHCriD2b/vFHttppL1ijLs2bvydMQkhY9eoQ== =ZEaS -----END PGP SIGNATURE----- Merge tag 'net-next-6.12' of git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net-next Pull networking updates from Jakub Kicinski: "The zero-copy changes are relatively significant, but regression risk should be contained. The feature needs to be used to cause trouble. Also it feels like we got an order of magnitude more semi-automated "refactoring" chaff than usual, I wonder if it's just us. Core & protocols: - Support Device Memory TCP, ability to zero-copy receive TCP payloads to a DMABUF region of memory while packet headers land separately in normal kernel buffers, and TCP processes then as usual. - The ability to read the PTP PHC (Physical Hardware Clock) alongside MONOTONIC_RAW timestamps with PTP_SYS_OFFSET_EXTENDED. Previously only CLOCK_REALTIME was supported. - Allow matching on all bits of IP DSCP for routing decisions. Previously we only supported on matching TOS bits in IPv4 which is a narrower interpretation of the same header field. - Increase the range of weights used for multi-path routing from 8 bits to 16 bits. - Add support for IPv6 PIO p flag in the Prefix Information Option per draft-ietf-6man-pio-pflag. - IPv6 IOAM6 support for new tunsrc encap mode for better performance. - Detect destinations which blackhole MPTCP traffic and avoid initiating MPTCP connections to them for a certain period of time, 1h by default. - Improve IPsec control path performance by removing the inexact policies list. - AF_VSOCK: add support for SIOCOUTQ ioctl. - Add enum for reasons TCP reset was sent for easier tracing. - Add SMC ringbufs usage statistics. Drivers: - Handle netconsole setup failures more gracefully, don't fail loading, retain the specified target as disabled. - Extend bonding's IPsec offload pass thru capabilities (ESN, stats). Filtering: - Add TCP_BPF_SOCK_OPS_CB_FLAGS to bpf_*sockopt() to address the case when long-lived sockets miss a chance to set additional callbacks if a sockops program was not attached early in their lifetime. - Support using BPF skb helpers in tracepoints. - Conntrack Netlink: support CTA_FILTER for flush. - Improve SCTP support in nfnetlink_queue. - Improve performance of large nftables flush transactions. Things we sprinkled into general kernel code: - selftests: support setting an "interpreter" for script files; make it easy to run as separate cases tests where one "interpreter" is fed various test descriptions (in our case packet sequences). Driver API: - Extend core and ethtool APIs to support many PHYs connected to a single interface (PHY topologies). - Extend cable diagnostics to specify whether Time Domain Reflectometry (TDR) or Active Link Cable Diagnostic (ALCD) was used. - Add library for implementing MAC-PHY Ethernet drivers for SPI devices compatible with Open Alliance 10BASE-T1x MAC-PHY Serial Interface (TC6) standard. - Add helpers to the PHY framework, for PHYs following the Open Alliance standards: - 1000BaseT1 link settings - cable test and diagnostics - Support listing / dumping all allocated RSS contexts. - Add configuration for frequency Embedded SYNC in DPLL, which magically embeds sync pulses into Ethernet signaling. Device drivers: - Ethernet high-speed NICs: - Broadcom (bnxt): - use better FW APIs for queue reset - support QOS and TPID settings for the SR-IOV VLAN - support dynamic MSI-X allocation - Intel (100G, ice, idpf): - ice: support PCIe subfunctions - iavf: add support for TC U32 filters on VFs - ice: support Embedded SYNC in DPLL - nVidia/Mellanox (mlx5): - support HW managed steering tables - support PCIe PTM cross timestamping - AMD/Pensando: - ionic: use page_pool to increase Rx performance - Cisco (enic): - report per-queue statistics - Ethernet virtual: - Microsoft vNIC: - mana: support configuring ring length - netvsc: enable more channels on systems with many CPUs - IBM veth: - optimize polling to improve TCP_RR performance - optimize performance of Tx handling - VirtIO net: - synchronize the operstate with the admin state to allow a lower virtio-net to propagate the link status to an upper device like macvlan - Ethernet NICs consumer, and embedded: - Add driver for Realtek automotive PCIe devices (RTL9054, RTL9068, RTL9072, RTL9075, RTL9068, RTL9071) - Add driver for Microchip LAN8650/1 10BASE-T1S MAC-PHY. - Microchip: - lan743x: use phylink - support WOL, EEE, pause, link settings - add Wake-on-LAN support for KSZ87xx family - add KSZ8895/KSZ8864 switch support - factor out FDMA code and use it in sparx5 and lan966x (including DCB support in both) - Synopsys (stmmac): - support frame preemption (configured using TC and ethtool) - support Loongson DWMAC (GMAC v3.73) - support RockChips RK3576 DWMAC - TI: - am65-cpsw: add multi queue RX support - icssg-prueth: HSR offload support - Cadence (macb): - enable software (hrtimer based) IRQ coalescing by default - Xilinx (axinet): - expose HW statistics - improve multicast filtering - relax Rx checksum offload constraints - MediaTek: - mt7530: add EN7581 support - Aspeed (ftgmac100): - report link speed and duplex - Intel: - igc: add mqprio offload - igc: report EEE configuration - RealTek (r8169): - add support for RTL8126A rev.b - Vitesse (vsc73xx): - implement FDB add/del/dump operations - Freescale (fs_enet): - use phylink - Ethernet PHYs: - vitesse: implement downshift and MDI-X in vsc73xx PHYs - microchip: support LAN887x, supporting IEEE 802.3bw (100BASE-T1) and IEEE 802.3bp (1000BASE-T1) specifications - add Applied Micro QT2025 PHY driver (in Rust) - add Motorcomm yt8821 2.5G Ethernet PHY driver - CAN: - add driver for Rockchip RK3568 CAN-FD controller - flexcan: add wakeup support for imx95 - kvaser_usb: set hardware timestamp on transmitted packets - WiFi: - mac80211/cfg80211: - EHT rate support in AQL airtime fairness - handle DFS (radar detection) per link in Multi-Link Operation - RealTek (rtw89): - support RTL8852BT and 8852BE-VT (WiFi 6) - support hardware rfkill - support HW encryption in unicast management frames - support Wake-on-WLAN with supported network detection - RealTek (rtw89): - improve Rx performance by using USB frame aggregation - support USB 3 with RTL8822CU/RTL8822BU - Intel (iwlwifi/mvm): - offload RLC/SMPS functionality to firmware - Marvell (mwifiex): - add host based MLME to enable WPA3 - Bluetooth: - add support for Amlogic HCI UART protocol - add support for ISO data/packets to Intel and NXP drivers" * tag 'net-next-6.12' of git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net-next: (1303 commits) net/mlx5: HWS, check the correct variable in hws_send_ring_alloc_sq() netfilter: nft_socket: Fix a NULL vs IS_ERR() bug in nft_socket_cgroup_subtree_level() ice: Fix a NULL vs IS_ERR() check in probe() ice: Fix a couple NULL vs IS_ERR() bugs net: ethernet: fs_enet: Make the per clock optional net: ti: icssg-prueth: Add multicast filtering support in HSR mode net: ti: icssg-prueth: Enable HSR Tx duplication, Tx Tag and Rx Tag offload net: ti: icssg-prueth: Add support for HSR frame forward offload net: ti: icssg-prueth: Stop hardcoding def_inc net: ti: icss-iep: Move icss_iep structure net: ibm: emac: get rid of wol_irq net: ibm: emac: remove all waiting code net: ibm: emac: replace of_get_property net: ibm: emac: use netdev's phydev directly net: ibm: emac: use devm for register_netdev net: ibm: emac: remove mii_bus with devm net: ibm: emac: use devm for of_iomap net: ibm: emac: manage emac_irq with devm net: ibm: emac: use devm for alloc_etherdev octeontx2-af: debugfs: Add Channel info to RPM map ...
This commit is contained in:
commit
9410645520
1
.gitignore
vendored
1
.gitignore
vendored
@ -24,6 +24,7 @@
|
||||
*.dwo
|
||||
*.elf
|
||||
*.gcno
|
||||
*.gcda
|
||||
*.gz
|
||||
*.i
|
||||
*.ko
|
||||
|
@ -75,6 +75,17 @@ Only files which are linked to the main kernel image or are compiled as
|
||||
kernel modules are supported by this mechanism.
|
||||
|
||||
|
||||
Module specific configs
|
||||
-----------------------
|
||||
|
||||
Gcov kernel configs for specific modules are described below:
|
||||
|
||||
CONFIG_GCOV_PROFILE_RDS:
|
||||
Enables GCOV profiling on RDS for checking which functions or
|
||||
lines are executed. This config is used by the rds selftest to
|
||||
generate coverage reports. If left unset the report is omitted.
|
||||
|
||||
|
||||
Files
|
||||
-----
|
||||
|
||||
|
@ -58,18 +58,18 @@ allOf:
|
||||
- const: timing-adjustment
|
||||
|
||||
amlogic,tx-delay-ns:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
enum: [0, 2, 4, 6]
|
||||
default: 2
|
||||
description:
|
||||
The internal RGMII TX clock delay (provided by this driver) in
|
||||
nanoseconds. Allowed values are 0ns, 2ns, 4ns, 6ns.
|
||||
When phy-mode is set to "rgmii" then the TX delay should be
|
||||
explicitly configured. When not configured a fallback of 2ns is
|
||||
used. When the phy-mode is set to either "rgmii-id" or "rgmii-txid"
|
||||
the TX clock delay is already provided by the PHY. In that case
|
||||
this property should be set to 0ns (which disables the TX clock
|
||||
delay in the MAC to prevent the clock from going off because both
|
||||
PHY and MAC are adding a delay).
|
||||
Any configuration is ignored when the phy-mode is set to "rmii".
|
||||
The internal RGMII TX clock delay (provided by this driver)
|
||||
in nanoseconds. When phy-mode is set to "rgmii" then the TX
|
||||
delay should be explicitly configured. When the phy-mode is
|
||||
set to either "rgmii-id" or "rgmii-txid" the TX clock delay
|
||||
is already provided by the PHY. In that case this property
|
||||
should be set to 0ns (which disables the TX clock delay in
|
||||
the MAC to prevent the clock from going off because both
|
||||
PHY and MAC are adding a delay). Any configuration is
|
||||
ignored when the phy-mode is set to "rmii".
|
||||
|
||||
amlogic,rx-delay-ns:
|
||||
deprecated: true
|
||||
|
@ -0,0 +1,63 @@
|
||||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
# Copyright (C) 2024 Amlogic, Inc. All rights reserved
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/net/bluetooth/amlogic,w155s2-bt.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Amlogic Bluetooth chips
|
||||
|
||||
description:
|
||||
The W155S2 is an Amlogic Bluetooth and Wi-Fi combo chip. It works on
|
||||
the standard H4 protocol via a 4-wire UART interface, with baud rates
|
||||
up to 4 Mbps.
|
||||
|
||||
maintainers:
|
||||
- Yang Li <yang.li@amlogic.com>
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
oneOf:
|
||||
- items:
|
||||
- enum:
|
||||
- amlogic,w265s1-bt
|
||||
- amlogic,w265p1-bt
|
||||
- const: amlogic,w155s2-bt
|
||||
- enum:
|
||||
- amlogic,w155s2-bt
|
||||
- amlogic,w265s2-bt
|
||||
|
||||
clocks:
|
||||
maxItems: 1
|
||||
description: clock provided to the controller (32.768KHz)
|
||||
|
||||
enable-gpios:
|
||||
maxItems: 1
|
||||
|
||||
vddio-supply:
|
||||
description: VDD_IO supply regulator handle
|
||||
|
||||
firmware-name:
|
||||
maxItems: 1
|
||||
description: specify the path of firmware bin to load
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- clocks
|
||||
- enable-gpios
|
||||
- vddio-supply
|
||||
- firmware-name
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/gpio/gpio.h>
|
||||
bluetooth {
|
||||
compatible = "amlogic,w155s2-bt";
|
||||
clocks = <&extclk>;
|
||||
enable-gpios = <&gpio 17 GPIO_ACTIVE_HIGH>;
|
||||
vddio-supply = <&wcn_3v3>;
|
||||
firmware-name = "amlogic/aml_w155s2_bt_uart.bin";
|
||||
};
|
||||
|
@ -172,14 +172,14 @@ allOf:
|
||||
- qcom,wcn6855-bt
|
||||
then:
|
||||
required:
|
||||
- enable-gpios
|
||||
- swctrl-gpios
|
||||
- vddio-supply
|
||||
- vddbtcxmx-supply
|
||||
- vddrfacmn-supply
|
||||
- vddaon-supply
|
||||
- vddwlcx-supply
|
||||
- vddwlmx-supply
|
||||
- vddbtcmx-supply
|
||||
- vddrfa0p8-supply
|
||||
- vddrfa1p2-supply
|
||||
- vddrfa1p7-supply
|
||||
- vddrfa1p8-supply
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
|
@ -17,6 +17,7 @@ properties:
|
||||
compatible:
|
||||
oneOf:
|
||||
- enum:
|
||||
- fsl,imx95-flexcan
|
||||
- fsl,imx93-flexcan
|
||||
- fsl,imx8qm-flexcan
|
||||
- fsl,imx8mp-flexcan
|
||||
@ -38,9 +39,6 @@ properties:
|
||||
- fsl,imx6ul-flexcan
|
||||
- fsl,imx6sx-flexcan
|
||||
- const: fsl,imx6q-flexcan
|
||||
- items:
|
||||
- const: fsl,imx95-flexcan
|
||||
- const: fsl,imx93-flexcan
|
||||
- items:
|
||||
- enum:
|
||||
- fsl,ls1028ar1-flexcan
|
||||
@ -80,6 +78,10 @@ properties:
|
||||
node then controller is assumed to be little endian. If this property is
|
||||
present then controller is assumed to be big endian.
|
||||
|
||||
can-transceiver:
|
||||
$ref: can-transceiver.yaml#
|
||||
unevaluatedProperties: false
|
||||
|
||||
fsl,stop-mode:
|
||||
description: |
|
||||
Register bits of stop mode control.
|
||||
|
@ -0,0 +1,70 @@
|
||||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/can/microchip,mcp2510.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Microchip MCP251X stand-alone CAN controller
|
||||
|
||||
maintainers:
|
||||
- Marc Kleine-Budde <mkl@pengutronix.de>
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
enum:
|
||||
- microchip,mcp2510
|
||||
- microchip,mcp2515
|
||||
- microchip,mcp25625
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
clocks:
|
||||
maxItems: 1
|
||||
|
||||
interrupts:
|
||||
maxItems: 1
|
||||
|
||||
vdd-supply:
|
||||
description: Regulator that powers the CAN controller.
|
||||
|
||||
xceiver-supply:
|
||||
description: Regulator that powers the CAN transceiver.
|
||||
|
||||
gpio-controller: true
|
||||
|
||||
"#gpio-cells":
|
||||
const: 2
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- clocks
|
||||
- interrupts
|
||||
|
||||
allOf:
|
||||
- $ref: /schemas/spi/spi-peripheral-props.yaml#
|
||||
|
||||
unevaluatedProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/interrupt-controller/irq.h>
|
||||
|
||||
spi {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
can@1 {
|
||||
compatible = "microchip,mcp2515";
|
||||
reg = <1>;
|
||||
clocks = <&clk24m>;
|
||||
interrupt-parent = <&gpio4>;
|
||||
interrupts = <13 IRQ_TYPE_LEVEL_LOW>;
|
||||
vdd-supply = <®5v0>;
|
||||
xceiver-supply = <®5v0>;
|
||||
gpio-controller;
|
||||
#gpio-cells = <2>;
|
||||
};
|
||||
};
|
||||
|
@ -1,30 +0,0 @@
|
||||
* Microchip MCP251X stand-alone CAN controller device tree bindings
|
||||
|
||||
Required properties:
|
||||
- compatible: Should be one of the following:
|
||||
- "microchip,mcp2510" for MCP2510.
|
||||
- "microchip,mcp2515" for MCP2515.
|
||||
- "microchip,mcp25625" for MCP25625.
|
||||
- reg: SPI chip select.
|
||||
- clocks: The clock feeding the CAN controller.
|
||||
- interrupts: Should contain IRQ line for the CAN controller.
|
||||
|
||||
Optional properties:
|
||||
- vdd-supply: Regulator that powers the CAN controller.
|
||||
- xceiver-supply: Regulator that powers the CAN transceiver.
|
||||
- gpio-controller: Indicates this device is a GPIO controller.
|
||||
- #gpio-cells: Should be two. The first cell is the pin number and
|
||||
the second cell is used to specify the gpio polarity.
|
||||
|
||||
Example:
|
||||
can0: can@1 {
|
||||
compatible = "microchip,mcp2515";
|
||||
reg = <1>;
|
||||
clocks = <&clk24m>;
|
||||
interrupt-parent = <&gpio4>;
|
||||
interrupts = <13 IRQ_TYPE_LEVEL_LOW>;
|
||||
vdd-supply = <®5v0>;
|
||||
xceiver-supply = <®5v0>;
|
||||
gpio-controller;
|
||||
#gpio-cells = <2>;
|
||||
};
|
@ -32,6 +32,7 @@ properties:
|
||||
- enum:
|
||||
- renesas,r8a779a0-canfd # R-Car V3U
|
||||
- renesas,r8a779g0-canfd # R-Car V4H
|
||||
- renesas,r8a779h0-canfd # R-Car V4M
|
||||
- const: renesas,rcar-gen4-canfd # R-Car Gen4
|
||||
|
||||
- items:
|
||||
@ -163,14 +164,23 @@ allOf:
|
||||
maxItems: 1
|
||||
|
||||
- if:
|
||||
not:
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
const: renesas,rcar-gen4-canfd
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
const: renesas,r8a779h0-canfd
|
||||
then:
|
||||
patternProperties:
|
||||
"^channel[2-7]$": false
|
||||
"^channel[5-7]$": false
|
||||
else:
|
||||
if:
|
||||
not:
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
const: renesas,rcar-gen4-canfd
|
||||
then:
|
||||
patternProperties:
|
||||
"^channel[2-7]$": false
|
||||
|
||||
unevaluatedProperties: false
|
||||
|
||||
|
@ -0,0 +1,74 @@
|
||||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/net/can/rockchip,rk3568v2-canfd.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title:
|
||||
Rockchip CAN-FD controller
|
||||
|
||||
maintainers:
|
||||
- Marc Kleine-Budde <mkl@pengutronix.de>
|
||||
|
||||
allOf:
|
||||
- $ref: can-controller.yaml#
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
oneOf:
|
||||
- const: rockchip,rk3568v2-canfd
|
||||
- items:
|
||||
- const: rockchip,rk3568v3-canfd
|
||||
- const: rockchip,rk3568v2-canfd
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
interrupts:
|
||||
maxItems: 1
|
||||
|
||||
clocks:
|
||||
maxItems: 2
|
||||
|
||||
clock-names:
|
||||
items:
|
||||
- const: baud
|
||||
- const: pclk
|
||||
|
||||
resets:
|
||||
maxItems: 2
|
||||
|
||||
reset-names:
|
||||
items:
|
||||
- const: core
|
||||
- const: apb
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- interrupts
|
||||
- clocks
|
||||
- resets
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/clock/rk3568-cru.h>
|
||||
#include <dt-bindings/interrupt-controller/arm-gic.h>
|
||||
#include <dt-bindings/interrupt-controller/irq.h>
|
||||
|
||||
soc {
|
||||
#address-cells = <2>;
|
||||
#size-cells = <2>;
|
||||
|
||||
can@fe570000 {
|
||||
compatible = "rockchip,rk3568v2-canfd";
|
||||
reg = <0x0 0xfe570000 0x0 0x1000>;
|
||||
interrupts = <GIC_SPI 1 IRQ_TYPE_LEVEL_HIGH>;
|
||||
clocks = <&cru CLK_CAN0>, <&cru PCLK_CAN0>;
|
||||
clock-names = "baud", "pclk";
|
||||
resets = <&cru SRST_CAN0>, <&cru SRST_P_CAN0>;
|
||||
reset-names = "core", "apb";
|
||||
};
|
||||
};
|
@ -92,6 +92,10 @@ properties:
|
||||
Built-in switch of the MT7988 SoC
|
||||
const: mediatek,mt7988-switch
|
||||
|
||||
- description:
|
||||
Built-in switch of the Airoha EN7581 SoC
|
||||
const: airoha,en7581-switch
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
@ -284,7 +288,9 @@ allOf:
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
const: mediatek,mt7988-switch
|
||||
enum:
|
||||
- mediatek,mt7988-switch
|
||||
- airoha,en7581-switch
|
||||
then:
|
||||
$ref: "#/$defs/mt7530-dsa-port"
|
||||
properties:
|
||||
|
@ -22,7 +22,9 @@ properties:
|
||||
- microchip,ksz8794
|
||||
- microchip,ksz8795
|
||||
- microchip,ksz8863
|
||||
- microchip,ksz8864 # 4-port version of KSZ8895 family switch
|
||||
- microchip,ksz8873
|
||||
- microchip,ksz8895 # 5-port version of KSZ8895 family switch
|
||||
- microchip,ksz9477
|
||||
- microchip,ksz9897
|
||||
- microchip,ksz9896
|
||||
@ -51,6 +53,11 @@ properties:
|
||||
Set if the output SYNCLKO clock should be disabled. Do not mix with
|
||||
microchip,synclko-125.
|
||||
|
||||
microchip,pme-active-high:
|
||||
$ref: /schemas/types.yaml#/definitions/flag
|
||||
description:
|
||||
Indicates if the PME pin polarity is active-high.
|
||||
|
||||
microchip,io-drive-strength-microamp:
|
||||
description:
|
||||
IO Pad Drive Strength
|
||||
|
@ -52,6 +52,25 @@ properties:
|
||||
allOf:
|
||||
- $ref: dsa.yaml#/$defs/ethernet-ports
|
||||
|
||||
patternProperties:
|
||||
"^(ethernet-)?ports$":
|
||||
additionalProperties: true
|
||||
patternProperties:
|
||||
"^(ethernet-)?port@6$":
|
||||
allOf:
|
||||
- if:
|
||||
properties:
|
||||
phy-mode:
|
||||
contains:
|
||||
enum:
|
||||
- rgmii
|
||||
then:
|
||||
properties:
|
||||
rx-internal-delay-ps:
|
||||
$ref: "#/$defs/internal-delay-ps"
|
||||
tx-internal-delay-ps:
|
||||
$ref: "#/$defs/internal-delay-ps"
|
||||
|
||||
# This checks if reg is a chipselect so the device is on an SPI
|
||||
# bus, the if-clause will fail if reg is a tuple such as for a
|
||||
# platform device.
|
||||
@ -67,6 +86,15 @@ required:
|
||||
- compatible
|
||||
- reg
|
||||
|
||||
$defs:
|
||||
internal-delay-ps:
|
||||
description:
|
||||
Disable tunable delay lines using 0 ps, or enable them and select
|
||||
the phase between 1400 ps and 2000 ps in increments of 300 ps.
|
||||
default: 2000
|
||||
enum:
|
||||
[0, 1400, 1700, 2000]
|
||||
|
||||
unevaluatedProperties: false
|
||||
|
||||
examples:
|
||||
@ -108,6 +136,8 @@ examples:
|
||||
reg = <6>;
|
||||
ethernet = <&gmac1>;
|
||||
phy-mode = "rgmii";
|
||||
rx-internal-delay-ps = <0>;
|
||||
tx-internal-delay-ps = <0>;
|
||||
fixed-link {
|
||||
speed = <1000>;
|
||||
full-duplex;
|
||||
@ -150,6 +180,8 @@ examples:
|
||||
ethernet-port@6 {
|
||||
reg = <6>;
|
||||
ethernet = <&enet0>;
|
||||
rx-internal-delay-ps = <0>;
|
||||
tx-internal-delay-ps = <0>;
|
||||
phy-mode = "rgmii";
|
||||
fixed-link {
|
||||
speed = <1000>;
|
||||
|
@ -24,20 +24,12 @@ properties:
|
||||
maxItems: 1
|
||||
description: The DPMAC number
|
||||
|
||||
phy-handle: true
|
||||
|
||||
phy-connection-type: true
|
||||
|
||||
phy-mode: true
|
||||
|
||||
pcs-handle:
|
||||
maxItems: 1
|
||||
description:
|
||||
A reference to a node representing a PCS PHY device found on
|
||||
the internal MDIO bus.
|
||||
|
||||
managed: true
|
||||
|
||||
phys:
|
||||
description: A reference to the SerDes lane(s)
|
||||
maxItems: 1
|
||||
@ -45,7 +37,7 @@ properties:
|
||||
required:
|
||||
- reg
|
||||
|
||||
additionalProperties: false
|
||||
unevaluatedProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
|
@ -19,7 +19,7 @@ description:
|
||||
|
||||
properties:
|
||||
$nodename:
|
||||
pattern: "^mdio(@.*)?"
|
||||
pattern: '^mdio(-(bus|external))?(@.+|-([0-9]+))?$'
|
||||
|
||||
"#address-cells":
|
||||
const: 1
|
||||
|
@ -30,8 +30,13 @@ properties:
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
clocks: true
|
||||
clock-names: true
|
||||
clocks:
|
||||
minItems: 2
|
||||
maxItems: 24
|
||||
|
||||
clock-names:
|
||||
minItems: 2
|
||||
maxItems: 24
|
||||
|
||||
interrupts:
|
||||
minItems: 1
|
||||
@ -127,6 +132,7 @@ allOf:
|
||||
then:
|
||||
properties:
|
||||
interrupts:
|
||||
minItems: 3
|
||||
maxItems: 3
|
||||
|
||||
clocks:
|
||||
@ -183,6 +189,7 @@ allOf:
|
||||
then:
|
||||
properties:
|
||||
interrupts:
|
||||
minItems: 3
|
||||
maxItems: 3
|
||||
|
||||
clocks:
|
||||
@ -222,6 +229,7 @@ allOf:
|
||||
then:
|
||||
properties:
|
||||
interrupts:
|
||||
minItems: 3
|
||||
maxItems: 3
|
||||
|
||||
clocks:
|
||||
|
74
Documentation/devicetree/bindings/net/microchip,lan8650.yaml
Normal file
74
Documentation/devicetree/bindings/net/microchip,lan8650.yaml
Normal file
@ -0,0 +1,74 @@
|
||||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/net/microchip,lan8650.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Microchip LAN8650/1 10BASE-T1S MACPHY Ethernet Controllers
|
||||
|
||||
maintainers:
|
||||
- Parthiban Veerasooran <parthiban.veerasooran@microchip.com>
|
||||
|
||||
description:
|
||||
The LAN8650/1 combines a Media Access Controller (MAC) and an Ethernet
|
||||
PHY to enable 10BASE‑T1S networks. The Ethernet Media Access Controller
|
||||
(MAC) module implements a 10 Mbps half duplex Ethernet MAC, compatible
|
||||
with the IEEE 802.3 standard and a 10BASE-T1S physical layer transceiver
|
||||
integrated into the LAN8650/1. The communication between the Host and
|
||||
the MAC-PHY is specified in the OPEN Alliance 10BASE-T1x MACPHY Serial
|
||||
Interface (TC6).
|
||||
|
||||
allOf:
|
||||
- $ref: /schemas/net/ethernet-controller.yaml#
|
||||
- $ref: /schemas/spi/spi-peripheral-props.yaml#
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
oneOf:
|
||||
- const: microchip,lan8650
|
||||
- items:
|
||||
- const: microchip,lan8651
|
||||
- const: microchip,lan8650
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
interrupts:
|
||||
description:
|
||||
Interrupt from MAC-PHY asserted in the event of Receive Chunks
|
||||
Available, Transmit Chunk Credits Available and Extended Status
|
||||
Event.
|
||||
maxItems: 1
|
||||
|
||||
spi-max-frequency:
|
||||
minimum: 15000000
|
||||
maximum: 25000000
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- interrupts
|
||||
- spi-max-frequency
|
||||
|
||||
unevaluatedProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/interrupt-controller/irq.h>
|
||||
#include <dt-bindings/gpio/gpio.h>
|
||||
|
||||
spi {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
ethernet@0 {
|
||||
compatible = "microchip,lan8651", "microchip,lan8650";
|
||||
reg = <0>;
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <ð0_pins>;
|
||||
interrupt-parent = <&gpio>;
|
||||
interrupts = <6 IRQ_TYPE_EDGE_FALLING>;
|
||||
local-mac-address = [04 05 06 01 02 03];
|
||||
spi-max-frequency = <15000000>;
|
||||
};
|
||||
};
|
@ -23,6 +23,9 @@ properties:
|
||||
'#pse-cells':
|
||||
const: 1
|
||||
|
||||
reset-gpios:
|
||||
maxItems: 1
|
||||
|
||||
channels:
|
||||
description: each set of 8 ports can be assigned to one physical
|
||||
channels or two for PoE4. This parameter describes the configuration
|
||||
|
@ -62,15 +62,27 @@ properties:
|
||||
- renesas,r9a08g045-gbeth # RZ/G3S
|
||||
- const: renesas,rzg2l-gbeth # RZ/{G2L,G2UL,V2L} family
|
||||
|
||||
reg: true
|
||||
reg:
|
||||
minItems: 1
|
||||
items:
|
||||
- description: MAC register block
|
||||
- description: Stream buffer
|
||||
|
||||
interrupts: true
|
||||
interrupts:
|
||||
minItems: 1
|
||||
maxItems: 29
|
||||
|
||||
interrupt-names: true
|
||||
interrupt-names:
|
||||
minItems: 1
|
||||
maxItems: 29
|
||||
|
||||
clocks: true
|
||||
clocks:
|
||||
minItems: 1
|
||||
maxItems: 3
|
||||
|
||||
clock-names: true
|
||||
clock-names:
|
||||
minItems: 1
|
||||
maxItems: 3
|
||||
|
||||
iommus:
|
||||
maxItems: 1
|
||||
@ -150,14 +162,11 @@ allOf:
|
||||
then:
|
||||
properties:
|
||||
reg:
|
||||
items:
|
||||
- description: MAC register block
|
||||
- description: Stream buffer
|
||||
minItems: 2
|
||||
else:
|
||||
properties:
|
||||
reg:
|
||||
items:
|
||||
- description: MAC register block
|
||||
maxItems: 1
|
||||
|
||||
- if:
|
||||
properties:
|
||||
|
@ -25,6 +25,7 @@ select:
|
||||
- rockchip,rk3368-gmac
|
||||
- rockchip,rk3399-gmac
|
||||
- rockchip,rk3568-gmac
|
||||
- rockchip,rk3576-gmac
|
||||
- rockchip,rk3588-gmac
|
||||
- rockchip,rv1108-gmac
|
||||
- rockchip,rv1126-gmac
|
||||
@ -52,6 +53,7 @@ properties:
|
||||
- items:
|
||||
- enum:
|
||||
- rockchip,rk3568-gmac
|
||||
- rockchip,rk3576-gmac
|
||||
- rockchip,rk3588-gmac
|
||||
- rockchip,rv1126-gmac
|
||||
- const: snps,dwmac-4.20a
|
||||
|
@ -80,6 +80,7 @@ properties:
|
||||
- rockchip,rk3328-gmac
|
||||
- rockchip,rk3366-gmac
|
||||
- rockchip,rk3368-gmac
|
||||
- rockchip,rk3576-gmac
|
||||
- rockchip,rk3588-gmac
|
||||
- rockchip,rk3399-gmac
|
||||
- rockchip,rv1108-gmac
|
||||
|
@ -41,13 +41,17 @@ properties:
|
||||
minItems: 1
|
||||
maxItems: 4
|
||||
|
||||
clock-names: true
|
||||
clock-names:
|
||||
minItems: 1
|
||||
maxItems: 4
|
||||
|
||||
resets:
|
||||
minItems: 1
|
||||
maxItems: 2
|
||||
|
||||
reset-names: true
|
||||
reset-names:
|
||||
minItems: 1
|
||||
maxItems: 2
|
||||
|
||||
socionext,syscon-phy-mode:
|
||||
$ref: /schemas/types.yaml#/definitions/phandle-array
|
||||
|
@ -0,0 +1,93 @@
|
||||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/net/wireless/marvell,sd8787.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Marvell 8787/8897/8978/8997 (sd8787/sd8897/sd8978/sd8997/pcie8997) SDIO/PCIE devices
|
||||
|
||||
maintainers:
|
||||
- Brian Norris <briannorris@chromium.org>
|
||||
- Frank Li <Frank.Li@nxp.com>
|
||||
|
||||
description:
|
||||
This node provides properties for describing the Marvell SDIO/PCIE wireless device.
|
||||
The node is expected to be specified as a child node to the SDIO/PCIE controller that
|
||||
connects the device to the system.
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
enum:
|
||||
- marvell,sd8787
|
||||
- marvell,sd8897
|
||||
- marvell,sd8978
|
||||
- marvell,sd8997
|
||||
- nxp,iw416
|
||||
- pci11ab,2b42
|
||||
- pci1b4b,2b42
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
interrupts:
|
||||
maxItems: 1
|
||||
|
||||
wakeup-source: true
|
||||
|
||||
marvell,caldata-txpwrlimit-2g:
|
||||
$ref: /schemas/types.yaml#/definitions/uint8-array
|
||||
description: Calibration data for the 2GHz band.
|
||||
maxItems: 566
|
||||
|
||||
marvell,caldata-txpwrlimit-5g-sub0:
|
||||
$ref: /schemas/types.yaml#/definitions/uint8-array
|
||||
description: Calibration data for sub-band 0 in the 5GHz band.
|
||||
maxItems: 502
|
||||
|
||||
marvell,caldata-txpwrlimit-5g-sub1:
|
||||
$ref: /schemas/types.yaml#/definitions/uint8-array
|
||||
description: Calibration data for sub-band 1 in the 5GHz band.
|
||||
maxItems: 688
|
||||
|
||||
marvell,caldata-txpwrlimit-5g-sub2:
|
||||
$ref: /schemas/types.yaml#/definitions/uint8-array
|
||||
description: Calibration data for sub-band 2 in the 5GHz band.
|
||||
maxItems: 750
|
||||
|
||||
marvell,caldata-txpwrlimit-5g-sub3:
|
||||
$ref: /schemas/types.yaml#/definitions/uint8-array
|
||||
description: Calibration data for sub-band 3 in the 5GHz band.
|
||||
maxItems: 502
|
||||
|
||||
marvell,wakeup-pin:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
description:
|
||||
Provides the pin number for the wakeup pin from the device's point of
|
||||
view. The wakeup pin is used for the device to wake the host system
|
||||
from sleep. This property is only necessary if the wakeup pin is
|
||||
wired in a non-standard way, such that the default pin assignments
|
||||
are invalid.
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/interrupt-controller/irq.h>
|
||||
|
||||
mmc {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
wifi@1 {
|
||||
compatible = "marvell,sd8897";
|
||||
reg = <1>;
|
||||
interrupt-parent = <&pio>;
|
||||
interrupts = <38 IRQ_TYPE_LEVEL_LOW>;
|
||||
marvell,wakeup-pin = <3>;
|
||||
};
|
||||
};
|
||||
|
@ -1,70 +0,0 @@
|
||||
Marvell 8787/8897/8978/8997 (sd8787/sd8897/sd8978/sd8997/pcie8997) SDIO/PCIE devices
|
||||
------
|
||||
|
||||
This node provides properties for controlling the Marvell SDIO/PCIE wireless device.
|
||||
The node is expected to be specified as a child node to the SDIO/PCIE controller that
|
||||
connects the device to the system.
|
||||
|
||||
Required properties:
|
||||
|
||||
- compatible : should be one of the following:
|
||||
* "marvell,sd8787"
|
||||
* "marvell,sd8897"
|
||||
* "marvell,sd8978"
|
||||
* "marvell,sd8997"
|
||||
* "nxp,iw416"
|
||||
* "pci11ab,2b42"
|
||||
* "pci1b4b,2b42"
|
||||
|
||||
Optional properties:
|
||||
|
||||
- marvell,caldata* : A series of properties with marvell,caldata prefix,
|
||||
represent calibration data downloaded to the device during
|
||||
initialization. This is an array of unsigned 8-bit values.
|
||||
the properties should follow below property name and
|
||||
corresponding array length:
|
||||
"marvell,caldata-txpwrlimit-2g" (length = 566).
|
||||
"marvell,caldata-txpwrlimit-5g-sub0" (length = 502).
|
||||
"marvell,caldata-txpwrlimit-5g-sub1" (length = 688).
|
||||
"marvell,caldata-txpwrlimit-5g-sub2" (length = 750).
|
||||
"marvell,caldata-txpwrlimit-5g-sub3" (length = 502).
|
||||
- marvell,wakeup-pin : a wakeup pin number of wifi chip which will be configured
|
||||
to firmware. Firmware will wakeup the host using this pin
|
||||
during suspend/resume.
|
||||
- interrupts : interrupt pin number to the cpu. driver will request an irq based on
|
||||
this interrupt number. during system suspend, the irq will be enabled
|
||||
so that the wifi chip can wakeup host platform under certain condition.
|
||||
during system resume, the irq will be disabled to make sure
|
||||
unnecessary interrupt is not received.
|
||||
- vmmc-supply: a phandle of a regulator, supplying VCC to the card
|
||||
- mmc-pwrseq: phandle to the MMC power sequence node. See "mmc-pwrseq-*"
|
||||
for documentation of MMC power sequence bindings.
|
||||
|
||||
Example:
|
||||
|
||||
Tx power limit calibration data is configured in below example.
|
||||
The calibration data is an array of unsigned values, the length
|
||||
can vary between hw versions.
|
||||
IRQ pin 38 is used as system wakeup source interrupt. wakeup pin 3 is configured
|
||||
so that firmware can wakeup host using this device side pin.
|
||||
|
||||
&mmc3 {
|
||||
vmmc-supply = <&wlan_en_reg>;
|
||||
mmc-pwrseq = <&wifi_pwrseq>;
|
||||
bus-width = <4>;
|
||||
cap-power-off-card;
|
||||
keep-power-in-suspend;
|
||||
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
mwifiex: wifi@1 {
|
||||
compatible = "marvell,sd8897";
|
||||
reg = <1>;
|
||||
interrupt-parent = <&pio>;
|
||||
interrupts = <38 IRQ_TYPE_LEVEL_LOW>;
|
||||
|
||||
marvell,caldata_00_txpwrlimit_2g_cfg_set = /bits/ 8 <
|
||||
0x01 0x00 0x06 0x00 0x08 0x02 0x89 0x01>;
|
||||
marvell,wakeup-pin = <3>;
|
||||
};
|
||||
};
|
@ -11,11 +11,14 @@ maintainers:
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
enum:
|
||||
- fsl,etsec-ptp
|
||||
- fsl,fman-ptp-timer
|
||||
- fsl,dpaa2-ptp
|
||||
- fsl,enetc-ptp
|
||||
oneOf:
|
||||
- enum:
|
||||
- fsl,etsec-ptp
|
||||
- fsl,fman-ptp-timer
|
||||
- fsl,dpaa2-ptp
|
||||
- items:
|
||||
- const: pci1957,ee02
|
||||
- const: fsl,enetc-ptp
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
@ -123,6 +126,15 @@ required:
|
||||
- compatible
|
||||
- reg
|
||||
|
||||
allOf:
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
const: fsl,enetc-ptp
|
||||
then:
|
||||
$ref: /schemas/pci/pci-device.yaml
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
|
@ -278,6 +278,26 @@ patternProperties:
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
^pa-stats@[a-f0-9]+$:
|
||||
description: |
|
||||
PA-STATS sub-module represented as a SysCon. PA_STATS is a set of
|
||||
registers where different statistics related to ICSSG, are dumped by
|
||||
ICSSG firmware. This syscon sub-module will help the device to
|
||||
access/read/write those statistics.
|
||||
|
||||
type: object
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
items:
|
||||
- const: ti,pruss-pa-st
|
||||
- const: syscon
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
interrupt-controller@[a-f0-9]+$:
|
||||
description: |
|
||||
PRUSS INTC Node. Each PRUSS has a single interrupt controller instance
|
||||
|
@ -214,6 +214,27 @@ offset values are fractional with 3-digit decimal places and shell be
|
||||
divided with ``DPLL_PIN_PHASE_OFFSET_DIVIDER`` to get integer part and
|
||||
modulo divided to get fractional part.
|
||||
|
||||
Embedded SYNC
|
||||
=============
|
||||
|
||||
Device may provide ability to use Embedded SYNC feature. It allows
|
||||
to embed additional SYNC signal into the base frequency of a pin - a one
|
||||
special pulse of base frequency signal every time SYNC signal pulse
|
||||
happens. The user can configure the frequency of Embedded SYNC.
|
||||
The Embedded SYNC capability is always related to a given base frequency
|
||||
and HW capabilities. The user is provided a range of Embedded SYNC
|
||||
frequencies supported, depending on current base frequency configured for
|
||||
the pin.
|
||||
|
||||
========================================= =================================
|
||||
``DPLL_A_PIN_ESYNC_FREQUENCY`` current Embedded SYNC frequency
|
||||
``DPLL_A_PIN_ESYNC_FREQUENCY_SUPPORTED`` nest available Embedded SYNC
|
||||
frequency ranges
|
||||
``DPLL_A_PIN_FREQUENCY_MIN`` attr minimum value of frequency
|
||||
``DPLL_A_PIN_FREQUENCY_MAX`` attr maximum value of frequency
|
||||
``DPLL_A_PIN_ESYNC_PULSE`` pulse type of Embedded SYNC
|
||||
========================================= =================================
|
||||
|
||||
Configuration commands group
|
||||
============================
|
||||
|
||||
|
@ -345,6 +345,26 @@ attribute-sets:
|
||||
Value is in PPM (parts per million).
|
||||
This may be implemented for example for pin of type
|
||||
PIN_TYPE_SYNCE_ETH_PORT.
|
||||
-
|
||||
name: esync-frequency
|
||||
type: u64
|
||||
doc: |
|
||||
Frequency of Embedded SYNC signal. If provided, the pin is configured
|
||||
with a SYNC signal embedded into its base clock frequency.
|
||||
-
|
||||
name: esync-frequency-supported
|
||||
type: nest
|
||||
multi-attr: true
|
||||
nested-attributes: frequency-range
|
||||
doc: |
|
||||
If provided a pin is capable of embedding a SYNC signal (within given
|
||||
range) into its base frequency signal.
|
||||
-
|
||||
name: esync-pulse
|
||||
type: u32
|
||||
doc: |
|
||||
A ratio of high to low state of a SYNC signal pulse embedded
|
||||
into base clock frequency. Value is in percents.
|
||||
-
|
||||
name: pin-parent-device
|
||||
subset-of: pin
|
||||
@ -510,6 +530,9 @@ operations:
|
||||
- phase-adjust-max
|
||||
- phase-adjust
|
||||
- fractional-frequency-offset
|
||||
- esync-frequency
|
||||
- esync-frequency-supported
|
||||
- esync-pulse
|
||||
|
||||
dump:
|
||||
request:
|
||||
@ -536,6 +559,7 @@ operations:
|
||||
- parent-device
|
||||
- parent-pin
|
||||
- phase-adjust
|
||||
- esync-frequency
|
||||
-
|
||||
name: pin-create-ntf
|
||||
doc: Notification about pin appearing
|
||||
|
@ -39,6 +39,11 @@ definitions:
|
||||
- ovld-detected
|
||||
- power-not-available
|
||||
- short-detected
|
||||
-
|
||||
name: phy-upstream-type
|
||||
enum-name:
|
||||
type: enum
|
||||
entries: [ mac, phy ]
|
||||
|
||||
attribute-sets:
|
||||
-
|
||||
@ -54,6 +59,9 @@ attribute-sets:
|
||||
name: flags
|
||||
type: u32
|
||||
enum: header-flags
|
||||
-
|
||||
name: phy-index
|
||||
type: u32
|
||||
|
||||
-
|
||||
name: bitset-bit
|
||||
@ -659,6 +667,9 @@ attribute-sets:
|
||||
-
|
||||
name: code
|
||||
type: u8
|
||||
-
|
||||
name: src
|
||||
type: u32
|
||||
-
|
||||
name: cable-fault-length
|
||||
attributes:
|
||||
@ -668,6 +679,9 @@ attribute-sets:
|
||||
-
|
||||
name: cm
|
||||
type: u32
|
||||
-
|
||||
name: src
|
||||
type: u32
|
||||
-
|
||||
name: cable-nest
|
||||
attributes:
|
||||
@ -1022,12 +1036,16 @@ attribute-sets:
|
||||
-
|
||||
name: indir
|
||||
type: binary
|
||||
sub-type: u32
|
||||
-
|
||||
name: hkey
|
||||
type: binary
|
||||
-
|
||||
name: input_xfrm
|
||||
type: u32
|
||||
-
|
||||
name: start-context
|
||||
type: u32
|
||||
-
|
||||
name: plca
|
||||
attributes:
|
||||
@ -1085,6 +1103,35 @@ attribute-sets:
|
||||
-
|
||||
name: total
|
||||
type: uint
|
||||
-
|
||||
name: phy
|
||||
attributes:
|
||||
-
|
||||
name: header
|
||||
type: nest
|
||||
nested-attributes: header
|
||||
-
|
||||
name: index
|
||||
type: u32
|
||||
-
|
||||
name: drvname
|
||||
type: string
|
||||
-
|
||||
name: name
|
||||
type: string
|
||||
-
|
||||
name: upstream-type
|
||||
type: u32
|
||||
enum: phy-upstream-type
|
||||
-
|
||||
name: upstream-index
|
||||
type: u32
|
||||
-
|
||||
name: upstream-sfp-name
|
||||
type: string
|
||||
-
|
||||
name: downstream-sfp-name
|
||||
type: string
|
||||
|
||||
operations:
|
||||
enum-model: directional
|
||||
@ -1749,12 +1796,12 @@ operations:
|
||||
|
||||
attribute-set: rss
|
||||
|
||||
do: &rss-get-op
|
||||
do:
|
||||
request:
|
||||
attributes:
|
||||
- header
|
||||
- context
|
||||
reply:
|
||||
reply: &rss-reply
|
||||
attributes:
|
||||
- header
|
||||
- context
|
||||
@ -1762,6 +1809,12 @@ operations:
|
||||
- indir
|
||||
- hkey
|
||||
- input_xfrm
|
||||
dump:
|
||||
request:
|
||||
attributes:
|
||||
- header
|
||||
- start-context
|
||||
reply: *rss-reply
|
||||
-
|
||||
name: plca-get-cfg
|
||||
doc: Get PLCA params.
|
||||
@ -1877,3 +1930,24 @@ operations:
|
||||
- status-msg
|
||||
- done
|
||||
- total
|
||||
-
|
||||
name: phy-get
|
||||
doc: Get PHY devices attached to an interface
|
||||
|
||||
attribute-set: phy
|
||||
|
||||
do: &phy-get-op
|
||||
request:
|
||||
attributes:
|
||||
- header
|
||||
reply:
|
||||
attributes:
|
||||
- header
|
||||
- index
|
||||
- drvname
|
||||
- name
|
||||
- upstream-type
|
||||
- upstream-index
|
||||
- upstream-sfp-name
|
||||
- downstream-sfp-name
|
||||
dump: *phy-get-op
|
||||
|
@ -167,6 +167,10 @@ attribute-sets:
|
||||
"re-attached", they are just waiting to disappear.
|
||||
Attribute is absent if Page Pool has not been detached, and
|
||||
can still be used to allocate new memory.
|
||||
-
|
||||
name: dmabuf
|
||||
doc: ID of the dmabuf this page-pool is attached to.
|
||||
type: u32
|
||||
-
|
||||
name: page-pool-info
|
||||
subset-of: page-pool
|
||||
@ -268,6 +272,10 @@ attribute-sets:
|
||||
name: napi-id
|
||||
doc: ID of the NAPI instance which services this queue.
|
||||
type: u32
|
||||
-
|
||||
name: dmabuf
|
||||
doc: ID of the dmabuf attached to this queue, if any.
|
||||
type: u32
|
||||
|
||||
-
|
||||
name: qstats
|
||||
@ -457,6 +465,39 @@ attribute-sets:
|
||||
Number of times driver re-started accepting send
|
||||
requests to this queue from the stack.
|
||||
type: uint
|
||||
-
|
||||
name: queue-id
|
||||
subset-of: queue
|
||||
attributes:
|
||||
-
|
||||
name: id
|
||||
-
|
||||
name: type
|
||||
-
|
||||
name: dmabuf
|
||||
attributes:
|
||||
-
|
||||
name: ifindex
|
||||
doc: netdev ifindex to bind the dmabuf to.
|
||||
type: u32
|
||||
checks:
|
||||
min: 1
|
||||
-
|
||||
name: queues
|
||||
doc: receive queues to bind the dmabuf to.
|
||||
type: nest
|
||||
nested-attributes: queue-id
|
||||
multi-attr: true
|
||||
-
|
||||
name: fd
|
||||
doc: dmabuf file descriptor to bind.
|
||||
type: u32
|
||||
-
|
||||
name: id
|
||||
doc: id of the dmabuf binding
|
||||
type: u32
|
||||
checks:
|
||||
min: 1
|
||||
|
||||
operations:
|
||||
list:
|
||||
@ -510,6 +551,7 @@ operations:
|
||||
- inflight
|
||||
- inflight-mem
|
||||
- detach-time
|
||||
- dmabuf
|
||||
dump:
|
||||
reply: *pp-reply
|
||||
config-cond: page-pool
|
||||
@ -574,6 +616,7 @@ operations:
|
||||
- type
|
||||
- napi-id
|
||||
- ifindex
|
||||
- dmabuf
|
||||
dump:
|
||||
request:
|
||||
attributes:
|
||||
@ -619,6 +662,24 @@ operations:
|
||||
- rx-bytes
|
||||
- tx-packets
|
||||
- tx-bytes
|
||||
-
|
||||
name: bind-rx
|
||||
doc: Bind dmabuf to netdev
|
||||
attribute-set: dmabuf
|
||||
flags: [ admin-perm ]
|
||||
do:
|
||||
request:
|
||||
attributes:
|
||||
- ifindex
|
||||
- fd
|
||||
- queues
|
||||
reply:
|
||||
attributes:
|
||||
- id
|
||||
|
||||
kernel-family:
|
||||
headers: [ "linux/list.h"]
|
||||
sock-priv: struct list_head
|
||||
|
||||
mcast-groups:
|
||||
list:
|
||||
|
@ -62,6 +62,13 @@ definitions:
|
||||
- sdif
|
||||
- sdifname
|
||||
- bri-broute
|
||||
-
|
||||
name: bitwise-ops
|
||||
type: enum
|
||||
entries:
|
||||
- bool
|
||||
- lshift
|
||||
- rshift
|
||||
-
|
||||
name: cmp-ops
|
||||
type: enum
|
||||
@ -125,6 +132,99 @@ definitions:
|
||||
- object
|
||||
- concat
|
||||
- expr
|
||||
-
|
||||
name: lookup-flags
|
||||
type: flags
|
||||
entries:
|
||||
- invert
|
||||
-
|
||||
name: ct-keys
|
||||
type: enum
|
||||
entries:
|
||||
- state
|
||||
- direction
|
||||
- status
|
||||
- mark
|
||||
- secmark
|
||||
- expiration
|
||||
- helper
|
||||
- l3protocol
|
||||
- src
|
||||
- dst
|
||||
- protocol
|
||||
- proto-src
|
||||
- proto-dst
|
||||
- labels
|
||||
- pkts
|
||||
- bytes
|
||||
- avgpkt
|
||||
- zone
|
||||
- eventmask
|
||||
- src-ip
|
||||
- dst-ip
|
||||
- src-ip6
|
||||
- dst-ip6
|
||||
- ct-id
|
||||
-
|
||||
name: ct-direction
|
||||
type: enum
|
||||
entries:
|
||||
- original
|
||||
- reply
|
||||
-
|
||||
name: quota-flags
|
||||
type: flags
|
||||
entries:
|
||||
- invert
|
||||
- depleted
|
||||
-
|
||||
name: verdict-code
|
||||
type: enum
|
||||
entries:
|
||||
- name: continue
|
||||
value: 0xffffffff
|
||||
- name: break
|
||||
value: 0xfffffffe
|
||||
- name: jump
|
||||
value: 0xfffffffd
|
||||
- name: goto
|
||||
value: 0xfffffffc
|
||||
- name: return
|
||||
value: 0xfffffffb
|
||||
- name: drop
|
||||
value: 0
|
||||
- name: accept
|
||||
value: 1
|
||||
- name: stolen
|
||||
value: 2
|
||||
- name: queue
|
||||
value: 3
|
||||
- name: repeat
|
||||
value: 4
|
||||
-
|
||||
name: fib-result
|
||||
type: enum
|
||||
entries:
|
||||
- oif
|
||||
- oifname
|
||||
- addrtype
|
||||
-
|
||||
name: fib-flags
|
||||
type: flags
|
||||
entries:
|
||||
- saddr
|
||||
- daddr
|
||||
- mark
|
||||
- iif
|
||||
- oif
|
||||
- present
|
||||
-
|
||||
name: reject-types
|
||||
type: enum
|
||||
entries:
|
||||
- icmp-unreach
|
||||
- tcp-rst
|
||||
- icmpx-unreach
|
||||
|
||||
attribute-sets:
|
||||
-
|
||||
@ -611,9 +711,10 @@ attribute-sets:
|
||||
type: u64
|
||||
byte-order: big-endian
|
||||
-
|
||||
name: flags # TODO
|
||||
name: flags
|
||||
type: u32
|
||||
byte-order: big-endian
|
||||
enum: quota-flags
|
||||
-
|
||||
name: pad
|
||||
type: pad
|
||||
@ -664,6 +765,38 @@ attribute-sets:
|
||||
name: devs
|
||||
type: nest
|
||||
nested-attributes: hook-dev-attrs
|
||||
-
|
||||
name: expr-bitwise-attrs
|
||||
attributes:
|
||||
-
|
||||
name: sreg
|
||||
type: u32
|
||||
byte-order: big-endian
|
||||
-
|
||||
name: dreg
|
||||
type: u32
|
||||
byte-order: big-endian
|
||||
-
|
||||
name: len
|
||||
type: u32
|
||||
byte-order: big-endian
|
||||
-
|
||||
name: mask
|
||||
type: nest
|
||||
nested-attributes: data-attrs
|
||||
-
|
||||
name: xor
|
||||
type: nest
|
||||
nested-attributes: data-attrs
|
||||
-
|
||||
name: op
|
||||
type: u32
|
||||
byte-order: big-endian
|
||||
enum: bitwise-ops
|
||||
-
|
||||
name: data
|
||||
type: nest
|
||||
nested-attributes: data-attrs
|
||||
-
|
||||
name: expr-cmp-attrs
|
||||
attributes:
|
||||
@ -698,6 +831,7 @@ attribute-sets:
|
||||
name: code
|
||||
type: u32
|
||||
byte-order: big-endian
|
||||
enum: verdict-code
|
||||
-
|
||||
name: chain
|
||||
type: string
|
||||
@ -718,6 +852,43 @@ attribute-sets:
|
||||
-
|
||||
name: pad
|
||||
type: pad
|
||||
-
|
||||
name: expr-fib-attrs
|
||||
attributes:
|
||||
-
|
||||
name: dreg
|
||||
type: u32
|
||||
byte-order: big-endian
|
||||
-
|
||||
name: result
|
||||
type: u32
|
||||
byte-order: big-endian
|
||||
enum: fib-result
|
||||
-
|
||||
name: flags
|
||||
type: u32
|
||||
byte-order: big-endian
|
||||
enum: fib-flags
|
||||
-
|
||||
name: expr-ct-attrs
|
||||
attributes:
|
||||
-
|
||||
name: dreg
|
||||
type: u32
|
||||
byte-order: big-endian
|
||||
-
|
||||
name: key
|
||||
type: u32
|
||||
byte-order: big-endian
|
||||
enum: ct-keys
|
||||
-
|
||||
name: direction
|
||||
type: u8
|
||||
enum: ct-direction
|
||||
-
|
||||
name: sreg
|
||||
type: u32
|
||||
byte-order: big-endian
|
||||
-
|
||||
name: expr-flow-offload-attrs
|
||||
attributes:
|
||||
@ -736,6 +907,31 @@ attribute-sets:
|
||||
name: data
|
||||
type: nest
|
||||
nested-attributes: data-attrs
|
||||
-
|
||||
name: expr-lookup-attrs
|
||||
attributes:
|
||||
-
|
||||
name: set
|
||||
type: string
|
||||
doc: Name of set to use
|
||||
-
|
||||
name: set id
|
||||
type: u32
|
||||
byte-order: big-endian
|
||||
doc: ID of set to use
|
||||
-
|
||||
name: sreg
|
||||
type: u32
|
||||
byte-order: big-endian
|
||||
-
|
||||
name: dreg
|
||||
type: u32
|
||||
byte-order: big-endian
|
||||
-
|
||||
name: flags
|
||||
type: u32
|
||||
byte-order: big-endian
|
||||
enum: lookup-flags
|
||||
-
|
||||
name: expr-meta-attrs
|
||||
attributes:
|
||||
@ -820,6 +1016,30 @@ attribute-sets:
|
||||
name: csum-flags
|
||||
type: u32
|
||||
byte-order: big-endian
|
||||
-
|
||||
name: expr-reject-attrs
|
||||
attributes:
|
||||
-
|
||||
name: type
|
||||
type: u32
|
||||
byte-order: big-endian
|
||||
enum: reject-types
|
||||
-
|
||||
name: icmp-code
|
||||
type: u8
|
||||
-
|
||||
name: expr-target-attrs
|
||||
attributes:
|
||||
-
|
||||
name: name
|
||||
type: string
|
||||
-
|
||||
name: rev
|
||||
type: u32
|
||||
byte-order: big-endian
|
||||
-
|
||||
name: info
|
||||
type: binary
|
||||
-
|
||||
name: expr-tproxy-attrs
|
||||
attributes:
|
||||
@ -835,13 +1055,38 @@ attribute-sets:
|
||||
name: reg-port
|
||||
type: u32
|
||||
byte-order: big-endian
|
||||
-
|
||||
name: expr-objref-attrs
|
||||
attributes:
|
||||
-
|
||||
name: imm-type
|
||||
type: u32
|
||||
byte-order: big-endian
|
||||
-
|
||||
name: imm-name
|
||||
type: string
|
||||
doc: object name
|
||||
-
|
||||
name: set-sreg
|
||||
type: u32
|
||||
byte-order: big-endian
|
||||
-
|
||||
name: set-name
|
||||
type: string
|
||||
doc: name of object map
|
||||
-
|
||||
name: set-id
|
||||
type: u32
|
||||
byte-order: big-endian
|
||||
doc: id of object map
|
||||
|
||||
sub-messages:
|
||||
-
|
||||
name: expr-ops
|
||||
formats:
|
||||
-
|
||||
value: bitwise # TODO
|
||||
value: bitwise
|
||||
attribute-set: expr-bitwise-attrs
|
||||
-
|
||||
value: cmp
|
||||
attribute-set: expr-cmp-attrs
|
||||
@ -849,7 +1094,11 @@ sub-messages:
|
||||
value: counter
|
||||
attribute-set: expr-counter-attrs
|
||||
-
|
||||
value: ct # TODO
|
||||
value: ct
|
||||
attribute-set: expr-ct-attrs
|
||||
-
|
||||
value: fib
|
||||
attribute-set: expr-fib-attrs
|
||||
-
|
||||
value: flow_offload
|
||||
attribute-set: expr-flow-offload-attrs
|
||||
@ -857,16 +1106,29 @@ sub-messages:
|
||||
value: immediate
|
||||
attribute-set: expr-immediate-attrs
|
||||
-
|
||||
value: lookup # TODO
|
||||
value: lookup
|
||||
attribute-set: expr-lookup-attrs
|
||||
-
|
||||
value: meta
|
||||
attribute-set: expr-meta-attrs
|
||||
-
|
||||
value: nat
|
||||
attribute-set: expr-nat-attrs
|
||||
-
|
||||
value: objref
|
||||
attribute-set: expr-objref-attrs
|
||||
-
|
||||
value: payload
|
||||
attribute-set: expr-payload-attrs
|
||||
-
|
||||
value: quota
|
||||
attribute-set: quota-attrs
|
||||
-
|
||||
value: reject
|
||||
attribute-set: expr-reject-attrs
|
||||
-
|
||||
value: target
|
||||
attribute-set: expr-target-attrs
|
||||
-
|
||||
value: tproxy
|
||||
attribute-set: expr-tproxy-attrs
|
||||
|
@ -903,6 +903,22 @@ definitions:
|
||||
- cfm-config
|
||||
- cfm-status
|
||||
- mst
|
||||
-
|
||||
name: netkit-policy
|
||||
type: enum
|
||||
entries:
|
||||
-
|
||||
name: forward
|
||||
value: 0
|
||||
-
|
||||
name: blackhole
|
||||
value: 2
|
||||
-
|
||||
name: netkit-mode
|
||||
type: enum
|
||||
entries:
|
||||
- name: l2
|
||||
- name: l3
|
||||
|
||||
attribute-sets:
|
||||
-
|
||||
@ -2109,6 +2125,28 @@ attribute-sets:
|
||||
-
|
||||
name: id
|
||||
type: u32
|
||||
-
|
||||
name: linkinfo-netkit-attrs
|
||||
name-prefix: ifla-netkit-
|
||||
attributes:
|
||||
-
|
||||
name: peer-info
|
||||
type: binary
|
||||
-
|
||||
name: primary
|
||||
type: u8
|
||||
-
|
||||
name: policy
|
||||
type: u32
|
||||
enum: netkit-policy
|
||||
-
|
||||
name: peer-policy
|
||||
type: u32
|
||||
enum: netkit-policy
|
||||
-
|
||||
name: mode
|
||||
type: u32
|
||||
enum: netkit-mode
|
||||
|
||||
sub-messages:
|
||||
-
|
||||
@ -2147,6 +2185,9 @@ sub-messages:
|
||||
-
|
||||
value: vrf
|
||||
attribute-set: linkinfo-vrf-attrs
|
||||
-
|
||||
value: netkit
|
||||
attribute-set: linkinfo-netkit-attrs
|
||||
-
|
||||
name: linkinfo-member-data-msg
|
||||
formats:
|
||||
|
@ -230,6 +230,11 @@ per-queue stats) from the device.
|
||||
|
||||
In addition the driver logs the stats to syslog upon device reset.
|
||||
|
||||
On supported instance types, the statistics will also include the
|
||||
ENA Express data (fields prefixed with `ena_srd`). For a complete
|
||||
documentation of ENA Express data refer to
|
||||
https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ena-express.html#ena-express-monitor
|
||||
|
||||
MTU
|
||||
===
|
||||
|
||||
|
@ -44,6 +44,7 @@ Contents:
|
||||
marvell/octeon_ep
|
||||
marvell/octeon_ep_vf
|
||||
mellanox/mlx5/index
|
||||
meta/fbnic
|
||||
microsoft/netvsc
|
||||
neterion/s2io
|
||||
netronome/nfp
|
||||
|
@ -218,6 +218,22 @@ the software port.
|
||||
[#accel]_.
|
||||
- Informative
|
||||
|
||||
* - `rx[i]_hds_nosplit_packets`
|
||||
- Number of packets that were not split in header/data split mode. A
|
||||
packet will not get split when the hardware does not support its
|
||||
protocol splitting. An example such a protocol is ICMPv4/v6. Currently
|
||||
TCP and UDP with IPv4/IPv6 are supported for header/data split
|
||||
[#accel]_.
|
||||
- Informative
|
||||
|
||||
* - `rx[i]_hds_nosplit_bytes`
|
||||
- Number of bytes for packets that were not split in header/data split
|
||||
mode. A packet will not get split when the hardware does not support its
|
||||
protocol splitting. An example such a protocol is ICMPv4/v6. Currently
|
||||
TCP and UDP with IPv4/IPv6 are supported for header/data split
|
||||
[#accel]_.
|
||||
- Informative
|
||||
|
||||
* - `rx[i]_lro_packets`
|
||||
- The number of LRO packets received on ring i [#accel]_.
|
||||
- Acceleration
|
||||
|
@ -130,6 +130,9 @@ Enabling the driver and kconfig options
|
||||
|
||||
| Build support for software-managed steering in the NIC.
|
||||
|
||||
**CONFIG_MLX5_HW_STEERING=(y/n)**
|
||||
|
||||
| Build support for hardware-managed steering in the NIC.
|
||||
|
||||
**CONFIG_MLX5_TC_CT=(y/n)**
|
||||
|
||||
|
@ -0,0 +1,29 @@
|
||||
.. SPDX-License-Identifier: GPL-2.0+
|
||||
|
||||
=====================================
|
||||
Meta Platforms Host Network Interface
|
||||
=====================================
|
||||
|
||||
Firmware Versions
|
||||
-----------------
|
||||
|
||||
fbnic has three components stored on the flash which are provided in one PLDM
|
||||
image:
|
||||
|
||||
1. fw - The control firmware used to view and modify firmware settings, request
|
||||
firmware actions, and retrieve firmware counters outside of the data path.
|
||||
This is the firmware which fbnic_fw.c interacts with.
|
||||
2. bootloader - The firmware which validate firmware security and control basic
|
||||
operations including loading and updating the firmware. This is also known
|
||||
as the cmrt firmware.
|
||||
3. undi - This is the UEFI driver which is based on the Linux driver.
|
||||
|
||||
fbnic stores two copies of these three components on flash. This allows fbnic
|
||||
to fall back to an older version of firmware automatically in case firmware
|
||||
fails to boot. Version information for both is provided as running and stored.
|
||||
The undi is only provided in stored as it is not actively running once the Linux
|
||||
driver takes over.
|
||||
|
||||
devlink dev info provides version information for all three components. In
|
||||
addition to the version the hg commit hash of the build is included as a
|
||||
separate entry.
|
269
Documentation/networking/devmem.rst
Normal file
269
Documentation/networking/devmem.rst
Normal file
@ -0,0 +1,269 @@
|
||||
.. SPDX-License-Identifier: GPL-2.0
|
||||
|
||||
=================
|
||||
Device Memory TCP
|
||||
=================
|
||||
|
||||
|
||||
Intro
|
||||
=====
|
||||
|
||||
Device memory TCP (devmem TCP) enables receiving data directly into device
|
||||
memory (dmabuf). The feature is currently implemented for TCP sockets.
|
||||
|
||||
|
||||
Opportunity
|
||||
-----------
|
||||
|
||||
A large number of data transfers have device memory as the source and/or
|
||||
destination. Accelerators drastically increased the prevalence of such
|
||||
transfers. Some examples include:
|
||||
|
||||
- Distributed training, where ML accelerators, such as GPUs on different hosts,
|
||||
exchange data.
|
||||
|
||||
- Distributed raw block storage applications transfer large amounts of data with
|
||||
remote SSDs. Much of this data does not require host processing.
|
||||
|
||||
Typically the Device-to-Device data transfers in the network are implemented as
|
||||
the following low-level operations: Device-to-Host copy, Host-to-Host network
|
||||
transfer, and Host-to-Device copy.
|
||||
|
||||
The flow involving host copies is suboptimal, especially for bulk data transfers,
|
||||
and can put significant strains on system resources such as host memory
|
||||
bandwidth and PCIe bandwidth.
|
||||
|
||||
Devmem TCP optimizes this use case by implementing socket APIs that enable
|
||||
the user to receive incoming network packets directly into device memory.
|
||||
|
||||
Packet payloads go directly from the NIC to device memory.
|
||||
|
||||
Packet headers go to host memory and are processed by the TCP/IP stack
|
||||
normally. The NIC must support header split to achieve this.
|
||||
|
||||
Advantages:
|
||||
|
||||
- Alleviate host memory bandwidth pressure, compared to existing
|
||||
network-transfer + device-copy semantics.
|
||||
|
||||
- Alleviate PCIe bandwidth pressure, by limiting data transfer to the lowest
|
||||
level of the PCIe tree, compared to the traditional path which sends data
|
||||
through the root complex.
|
||||
|
||||
|
||||
More Info
|
||||
---------
|
||||
|
||||
slides, video
|
||||
https://netdevconf.org/0x17/sessions/talk/device-memory-tcp.html
|
||||
|
||||
patchset
|
||||
[PATCH net-next v24 00/13] Device Memory TCP
|
||||
https://lore.kernel.org/netdev/20240831004313.3713467-1-almasrymina@google.com/
|
||||
|
||||
|
||||
Interface
|
||||
=========
|
||||
|
||||
|
||||
Example
|
||||
-------
|
||||
|
||||
tools/testing/selftests/net/ncdevmem.c:do_server shows an example of setting up
|
||||
the RX path of this API.
|
||||
|
||||
|
||||
NIC Setup
|
||||
---------
|
||||
|
||||
Header split, flow steering, & RSS are required features for devmem TCP.
|
||||
|
||||
Header split is used to split incoming packets into a header buffer in host
|
||||
memory, and a payload buffer in device memory.
|
||||
|
||||
Flow steering & RSS are used to ensure that only flows targeting devmem land on
|
||||
an RX queue bound to devmem.
|
||||
|
||||
Enable header split & flow steering::
|
||||
|
||||
# enable header split
|
||||
ethtool -G eth1 tcp-data-split on
|
||||
|
||||
|
||||
# enable flow steering
|
||||
ethtool -K eth1 ntuple on
|
||||
|
||||
Configure RSS to steer all traffic away from the target RX queue (queue 15 in
|
||||
this example)::
|
||||
|
||||
ethtool --set-rxfh-indir eth1 equal 15
|
||||
|
||||
|
||||
The user must bind a dmabuf to any number of RX queues on a given NIC using
|
||||
the netlink API::
|
||||
|
||||
/* Bind dmabuf to NIC RX queue 15 */
|
||||
struct netdev_queue *queues;
|
||||
queues = malloc(sizeof(*queues) * 1);
|
||||
|
||||
queues[0]._present.type = 1;
|
||||
queues[0]._present.idx = 1;
|
||||
queues[0].type = NETDEV_RX_QUEUE_TYPE_RX;
|
||||
queues[0].idx = 15;
|
||||
|
||||
*ys = ynl_sock_create(&ynl_netdev_family, &yerr);
|
||||
|
||||
req = netdev_bind_rx_req_alloc();
|
||||
netdev_bind_rx_req_set_ifindex(req, 1 /* ifindex */);
|
||||
netdev_bind_rx_req_set_dmabuf_fd(req, dmabuf_fd);
|
||||
__netdev_bind_rx_req_set_queues(req, queues, n_queue_index);
|
||||
|
||||
rsp = netdev_bind_rx(*ys, req);
|
||||
|
||||
dmabuf_id = rsp->dmabuf_id;
|
||||
|
||||
|
||||
The netlink API returns a dmabuf_id: a unique ID that refers to this dmabuf
|
||||
that has been bound.
|
||||
|
||||
The user can unbind the dmabuf from the netdevice by closing the netlink socket
|
||||
that established the binding. We do this so that the binding is automatically
|
||||
unbound even if the userspace process crashes.
|
||||
|
||||
Note that any reasonably well-behaved dmabuf from any exporter should work with
|
||||
devmem TCP, even if the dmabuf is not actually backed by devmem. An example of
|
||||
this is udmabuf, which wraps user memory (non-devmem) in a dmabuf.
|
||||
|
||||
|
||||
Socket Setup
|
||||
------------
|
||||
|
||||
The socket must be flow steered to the dmabuf bound RX queue::
|
||||
|
||||
ethtool -N eth1 flow-type tcp4 ... queue 15
|
||||
|
||||
|
||||
Receiving data
|
||||
--------------
|
||||
|
||||
The user application must signal to the kernel that it is capable of receiving
|
||||
devmem data by passing the MSG_SOCK_DEVMEM flag to recvmsg::
|
||||
|
||||
ret = recvmsg(fd, &msg, MSG_SOCK_DEVMEM);
|
||||
|
||||
Applications that do not specify the MSG_SOCK_DEVMEM flag will receive an EFAULT
|
||||
on devmem data.
|
||||
|
||||
Devmem data is received directly into the dmabuf bound to the NIC in 'NIC
|
||||
Setup', and the kernel signals such to the user via the SCM_DEVMEM_* cmsgs::
|
||||
|
||||
for (cm = CMSG_FIRSTHDR(&msg); cm; cm = CMSG_NXTHDR(&msg, cm)) {
|
||||
if (cm->cmsg_level != SOL_SOCKET ||
|
||||
(cm->cmsg_type != SCM_DEVMEM_DMABUF &&
|
||||
cm->cmsg_type != SCM_DEVMEM_LINEAR))
|
||||
continue;
|
||||
|
||||
dmabuf_cmsg = (struct dmabuf_cmsg *)CMSG_DATA(cm);
|
||||
|
||||
if (cm->cmsg_type == SCM_DEVMEM_DMABUF) {
|
||||
/* Frag landed in dmabuf.
|
||||
*
|
||||
* dmabuf_cmsg->dmabuf_id is the dmabuf the
|
||||
* frag landed on.
|
||||
*
|
||||
* dmabuf_cmsg->frag_offset is the offset into
|
||||
* the dmabuf where the frag starts.
|
||||
*
|
||||
* dmabuf_cmsg->frag_size is the size of the
|
||||
* frag.
|
||||
*
|
||||
* dmabuf_cmsg->frag_token is a token used to
|
||||
* refer to this frag for later freeing.
|
||||
*/
|
||||
|
||||
struct dmabuf_token token;
|
||||
token.token_start = dmabuf_cmsg->frag_token;
|
||||
token.token_count = 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (cm->cmsg_type == SCM_DEVMEM_LINEAR)
|
||||
/* Frag landed in linear buffer.
|
||||
*
|
||||
* dmabuf_cmsg->frag_size is the size of the
|
||||
* frag.
|
||||
*/
|
||||
continue;
|
||||
|
||||
}
|
||||
|
||||
Applications may receive 2 cmsgs:
|
||||
|
||||
- SCM_DEVMEM_DMABUF: this indicates the fragment landed in the dmabuf indicated
|
||||
by dmabuf_id.
|
||||
|
||||
- SCM_DEVMEM_LINEAR: this indicates the fragment landed in the linear buffer.
|
||||
This typically happens when the NIC is unable to split the packet at the
|
||||
header boundary, such that part (or all) of the payload landed in host
|
||||
memory.
|
||||
|
||||
Applications may receive no SO_DEVMEM_* cmsgs. That indicates non-devmem,
|
||||
regular TCP data that landed on an RX queue not bound to a dmabuf.
|
||||
|
||||
|
||||
Freeing frags
|
||||
-------------
|
||||
|
||||
Frags received via SCM_DEVMEM_DMABUF are pinned by the kernel while the user
|
||||
processes the frag. The user must return the frag to the kernel via
|
||||
SO_DEVMEM_DONTNEED::
|
||||
|
||||
ret = setsockopt(client_fd, SOL_SOCKET, SO_DEVMEM_DONTNEED, &token,
|
||||
sizeof(token));
|
||||
|
||||
The user must ensure the tokens are returned to the kernel in a timely manner.
|
||||
Failure to do so will exhaust the limited dmabuf that is bound to the RX queue
|
||||
and will lead to packet drops.
|
||||
|
||||
|
||||
Implementation & Caveats
|
||||
========================
|
||||
|
||||
Unreadable skbs
|
||||
---------------
|
||||
|
||||
Devmem payloads are inaccessible to the kernel processing the packets. This
|
||||
results in a few quirks for payloads of devmem skbs:
|
||||
|
||||
- Loopback is not functional. Loopback relies on copying the payload, which is
|
||||
not possible with devmem skbs.
|
||||
|
||||
- Software checksum calculation fails.
|
||||
|
||||
- TCP Dump and bpf can't access devmem packet payloads.
|
||||
|
||||
|
||||
Testing
|
||||
=======
|
||||
|
||||
More realistic example code can be found in the kernel source under
|
||||
``tools/testing/selftests/net/ncdevmem.c``
|
||||
|
||||
ncdevmem is a devmem TCP netcat. It works very similarly to netcat, but
|
||||
receives data directly into a udmabuf.
|
||||
|
||||
To run ncdevmem, you need to run it on a server on the machine under test, and
|
||||
you need to run netcat on a peer to provide the TX data.
|
||||
|
||||
ncdevmem has a validation mode as well that expects a repeating pattern of
|
||||
incoming data and validates it as such. For example, you can launch
|
||||
ncdevmem on the server by::
|
||||
|
||||
ncdevmem -s <server IP> -c <client IP> -f eth1 -d 3 -n 0000:06:00.0 -l \
|
||||
-p 5201 -v 7
|
||||
|
||||
On client side, use regular netcat to send TX data to ncdevmem process
|
||||
on the server::
|
||||
|
||||
yes $(echo -e \\x01\\x02\\x03\\x04\\x05\\x06) | \
|
||||
tr \\n \\0 | head -c 5G | nc <server IP> 5201 -p 5201
|
@ -57,6 +57,7 @@ Structure of this header is
|
||||
``ETHTOOL_A_HEADER_DEV_INDEX`` u32 device ifindex
|
||||
``ETHTOOL_A_HEADER_DEV_NAME`` string device name
|
||||
``ETHTOOL_A_HEADER_FLAGS`` u32 flags common for all requests
|
||||
``ETHTOOL_A_HEADER_PHY_INDEX`` u32 phy device index
|
||||
============================== ====== =============================
|
||||
|
||||
``ETHTOOL_A_HEADER_DEV_INDEX`` and ``ETHTOOL_A_HEADER_DEV_NAME`` identify the
|
||||
@ -81,6 +82,12 @@ the behaviour is backward compatible, i.e. requests from old clients not aware
|
||||
of the flag should be interpreted the way the client expects. A client must
|
||||
not set flags it does not understand.
|
||||
|
||||
``ETHTOOL_A_HEADER_PHY_INDEX`` identifies the Ethernet PHY the message relates to.
|
||||
As there are numerous commands that are related to PHY configuration, and because
|
||||
there may be more than one PHY on the link, the PHY index can be passed in the
|
||||
request for the commands that needs it. It is, however, not mandatory, and if it
|
||||
is not passed for commands that target a PHY, the net_device.phydev pointer
|
||||
is used.
|
||||
|
||||
Bit sets
|
||||
========
|
||||
@ -934,18 +941,18 @@ Request contents:
|
||||
==================================== ====== ===========================
|
||||
|
||||
Kernel checks that requested ring sizes do not exceed limits reported by
|
||||
driver. Driver may impose additional constraints and may not suspport all
|
||||
driver. Driver may impose additional constraints and may not support all
|
||||
attributes.
|
||||
|
||||
|
||||
``ETHTOOL_A_RINGS_CQE_SIZE`` specifies the completion queue event size.
|
||||
Completion queue events(CQE) are the events posted by NIC to indicate the
|
||||
completion status of a packet when the packet is sent(like send success or
|
||||
error) or received(like pointers to packet fragments). The CQE size parameter
|
||||
Completion queue events (CQE) are the events posted by NIC to indicate the
|
||||
completion status of a packet when the packet is sent (like send success or
|
||||
error) or received (like pointers to packet fragments). The CQE size parameter
|
||||
enables to modify the CQE size other than default size if NIC supports it.
|
||||
A bigger CQE can have more receive buffer pointers inturn NIC can transfer
|
||||
a bigger frame from wire. Based on the NIC hardware, the overall completion
|
||||
queue size can be adjusted in the driver if CQE size is modified.
|
||||
A bigger CQE can have more receive buffer pointers, and in turn the NIC can
|
||||
transfer a bigger frame from wire. Based on the NIC hardware, the overall
|
||||
completion queue size can be adjusted in the driver if CQE size is modified.
|
||||
|
||||
CHANNELS_GET
|
||||
============
|
||||
@ -989,7 +996,7 @@ Request contents:
|
||||
===================================== ====== ==========================
|
||||
|
||||
Kernel checks that requested channel counts do not exceed limits reported by
|
||||
driver. Driver may impose additional constraints and may not suspport all
|
||||
driver. Driver may impose additional constraints and may not support all
|
||||
attributes.
|
||||
|
||||
|
||||
@ -1307,12 +1314,17 @@ information.
|
||||
+-+-+-----------------------------------------+--------+---------------------+
|
||||
| | | ``ETHTOOL_A_CABLE_RESULTS_CODE`` | u8 | result code |
|
||||
+-+-+-----------------------------------------+--------+---------------------+
|
||||
| | | ``ETHTOOL_A_CABLE_RESULT_SRC`` | u32 | information source |
|
||||
+-+-+-----------------------------------------+--------+---------------------+
|
||||
| | ``ETHTOOL_A_CABLE_NEST_FAULT_LENGTH`` | nested | cable length |
|
||||
+-+-+-----------------------------------------+--------+---------------------+
|
||||
| | | ``ETHTOOL_A_CABLE_FAULT_LENGTH_PAIR`` | u8 | pair number |
|
||||
+-+-+-----------------------------------------+--------+---------------------+
|
||||
| | | ``ETHTOOL_A_CABLE_FAULT_LENGTH_CM`` | u32 | length in cm |
|
||||
+-+-+-----------------------------------------+--------+---------------------+
|
||||
| | | ``ETHTOOL_A_CABLE_FAULT_LENGTH_SRC`` | u32 | information source |
|
||||
+-+-+-----------------------------------------+--------+---------------------+
|
||||
|
||||
|
||||
CABLE_TEST TDR
|
||||
==============
|
||||
@ -1756,7 +1768,7 @@ Kernel response contents:
|
||||
When set, the optional ``ETHTOOL_A_PODL_PSE_ADMIN_STATE`` attribute identifies
|
||||
the operational state of the PoDL PSE functions. The operational state of the
|
||||
PSE function can be changed using the ``ETHTOOL_A_PODL_PSE_ADMIN_CONTROL``
|
||||
action. This option is corresponding to ``IEEE 802.3-2018`` 30.15.1.1.2
|
||||
action. This attribute corresponds to ``IEEE 802.3-2018`` 30.15.1.1.2
|
||||
aPoDLPSEAdminState. Possible values are:
|
||||
|
||||
.. kernel-doc:: include/uapi/linux/ethtool.h
|
||||
@ -1770,8 +1782,8 @@ The same goes for ``ETHTOOL_A_C33_PSE_ADMIN_STATE`` implementing
|
||||
|
||||
When set, the optional ``ETHTOOL_A_PODL_PSE_PW_D_STATUS`` attribute identifies
|
||||
the power detection status of the PoDL PSE. The status depend on internal PSE
|
||||
state machine and automatic PD classification support. This option is
|
||||
corresponding to ``IEEE 802.3-2018`` 30.15.1.1.3 aPoDLPSEPowerDetectionStatus.
|
||||
state machine and automatic PD classification support. This attribute
|
||||
corresponds to ``IEEE 802.3-2018`` 30.15.1.1.3 aPoDLPSEPowerDetectionStatus.
|
||||
Possible values are:
|
||||
|
||||
.. kernel-doc:: include/uapi/linux/ethtool.h
|
||||
@ -1785,12 +1797,13 @@ The same goes for ``ETHTOOL_A_C33_PSE_ADMIN_PW_D_STATUS`` implementing
|
||||
|
||||
When set, the optional ``ETHTOOL_A_C33_PSE_PW_CLASS`` attribute identifies
|
||||
the power class of the C33 PSE. It depends on the class negotiated between
|
||||
the PSE and the PD. This option is corresponding to ``IEEE 802.3-2022``
|
||||
the PSE and the PD. This attribute corresponds to ``IEEE 802.3-2022``
|
||||
30.9.1.1.8 aPSEPowerClassification.
|
||||
|
||||
When set, the optional ``ETHTOOL_A_C33_PSE_ACTUAL_PW`` attribute identifies
|
||||
This option is corresponding to ``IEEE 802.3-2022`` 30.9.1.1.23 aPSEActualPower.
|
||||
Actual power is reported in mW.
|
||||
the actual power drawn by the C33 PSE. This attribute corresponds to
|
||||
``IEEE 802.3-2022`` 30.9.1.1.23 aPSEActualPower. Actual power is reported
|
||||
in mW.
|
||||
|
||||
When set, the optional ``ETHTOOL_A_C33_PSE_EXT_STATE`` attribute identifies
|
||||
the extended error state of the C33 PSE. Possible values are:
|
||||
@ -1839,7 +1852,7 @@ Request contents:
|
||||
====================================== ====== =============================
|
||||
|
||||
When set, the optional ``ETHTOOL_A_PODL_PSE_ADMIN_CONTROL`` attribute is used
|
||||
to control PoDL PSE Admin functions. This option is implementing
|
||||
to control PoDL PSE Admin functions. This option implements
|
||||
``IEEE 802.3-2018`` 30.15.1.2.1 acPoDLPSEAdminControl. See
|
||||
``ETHTOOL_A_PODL_PSE_ADMIN_STATE`` for supported values.
|
||||
|
||||
@ -1866,10 +1879,18 @@ RSS context of an interface similar to ``ETHTOOL_GRSSH`` ioctl request.
|
||||
|
||||
Request contents:
|
||||
|
||||
===================================== ====== ==========================
|
||||
===================================== ====== ============================
|
||||
``ETHTOOL_A_RSS_HEADER`` nested request header
|
||||
``ETHTOOL_A_RSS_CONTEXT`` u32 context number
|
||||
===================================== ====== ==========================
|
||||
``ETHTOOL_A_RSS_START_CONTEXT`` u32 start context number (dumps)
|
||||
===================================== ====== ============================
|
||||
|
||||
``ETHTOOL_A_RSS_CONTEXT`` specifies which RSS context number to query,
|
||||
if not set context 0 (the main context) is queried. Dumps can be filtered
|
||||
by device (only listing contexts of a given netdev). Filtering single
|
||||
context number is not supported but ``ETHTOOL_A_RSS_START_CONTEXT``
|
||||
can be used to start dumping context from the given number (primarily
|
||||
used to ignore context 0s and only dump additional contexts).
|
||||
|
||||
Kernel response contents:
|
||||
|
||||
@ -1927,7 +1948,7 @@ When set, the optional ``ETHTOOL_A_PLCA_VERSION`` attribute indicates which
|
||||
standard and version the PLCA management interface complies to. When not set,
|
||||
the interface is vendor-specific and (possibly) supplied by the driver.
|
||||
The OPEN Alliance SIG specifies a standard register map for 10BASE-T1S PHYs
|
||||
embedding the PLCA Reconcialiation Sublayer. See "10BASE-T1S PLCA Management
|
||||
embedding the PLCA Reconciliation Sublayer. See "10BASE-T1S PLCA Management
|
||||
Registers" at https://www.opensig.org/about/specifications/.
|
||||
|
||||
When set, the optional ``ETHTOOL_A_PLCA_ENABLED`` attribute indicates the
|
||||
@ -1989,7 +2010,7 @@ Request contents:
|
||||
``ETHTOOL_A_PLCA_ENABLED`` u8 PLCA Admin State
|
||||
``ETHTOOL_A_PLCA_NODE_ID`` u8 PLCA unique local node ID
|
||||
``ETHTOOL_A_PLCA_NODE_CNT`` u8 Number of PLCA nodes on the
|
||||
netkork, including the
|
||||
network, including the
|
||||
coordinator
|
||||
``ETHTOOL_A_PLCA_TO_TMR`` u8 Transmit Opportunity Timer
|
||||
value in bit-times (BT)
|
||||
@ -2176,6 +2197,49 @@ string.
|
||||
The ``ETHTOOL_A_MODULE_FW_FLASH_DONE`` and ``ETHTOOL_A_MODULE_FW_FLASH_TOTAL``
|
||||
attributes encode the completed and total amount of work, respectively.
|
||||
|
||||
PHY_GET
|
||||
=======
|
||||
|
||||
Retrieve information about a given Ethernet PHY sitting on the link. The DO
|
||||
operation returns all available information about dev->phydev. User can also
|
||||
specify a PHY_INDEX, in which case the DO request returns information about that
|
||||
specific PHY.
|
||||
|
||||
As there can be more than one PHY, the DUMP operation can be used to list the PHYs
|
||||
present on a given interface, by passing an interface index or name in
|
||||
the dump request.
|
||||
|
||||
For more information, refer to :ref:`phy_link_topology`
|
||||
|
||||
Request contents:
|
||||
|
||||
==================================== ====== ==========================
|
||||
``ETHTOOL_A_PHY_HEADER`` nested request header
|
||||
==================================== ====== ==========================
|
||||
|
||||
Kernel response contents:
|
||||
|
||||
===================================== ====== ===============================
|
||||
``ETHTOOL_A_PHY_HEADER`` nested request header
|
||||
``ETHTOOL_A_PHY_INDEX`` u32 the phy's unique index, that can
|
||||
be used for phy-specific
|
||||
requests
|
||||
``ETHTOOL_A_PHY_DRVNAME`` string the phy driver name
|
||||
``ETHTOOL_A_PHY_NAME`` string the phy device name
|
||||
``ETHTOOL_A_PHY_UPSTREAM_TYPE`` u32 the type of device this phy is
|
||||
connected to
|
||||
``ETHTOOL_A_PHY_UPSTREAM_INDEX`` u32 the PHY index of the upstream
|
||||
PHY
|
||||
``ETHTOOL_A_PHY_UPSTREAM_SFP_NAME`` string if this PHY is connected to
|
||||
its parent PHY through an SFP
|
||||
bus, the name of this sfp bus
|
||||
``ETHTOOL_A_PHY_DOWNSTREAM_SFP_NAME`` string if the phy controls an sfp bus,
|
||||
the name of the sfp bus
|
||||
===================================== ====== ===============================
|
||||
|
||||
When ``ETHTOOL_A_PHY_UPSTREAM_TYPE`` is PHY_UPSTREAM_PHY, the PHY's parent is
|
||||
another PHY.
|
||||
|
||||
Request translation
|
||||
===================
|
||||
|
||||
@ -2283,4 +2347,5 @@ are netlink only.
|
||||
n/a ``ETHTOOL_MSG_MM_GET``
|
||||
n/a ``ETHTOOL_MSG_MM_SET``
|
||||
n/a ``ETHTOOL_MSG_MODULE_FW_FLASH_ACT``
|
||||
n/a ``ETHTOOL_MSG_PHY_GET``
|
||||
=================================== =====================================
|
||||
|
@ -49,6 +49,7 @@ Contents:
|
||||
cdc_mbim
|
||||
dccp
|
||||
dctcp
|
||||
devmem
|
||||
dns_resolver
|
||||
driver
|
||||
eql
|
||||
@ -87,10 +88,12 @@ Contents:
|
||||
nexthop-group-resilient
|
||||
nf_conntrack-sysctl
|
||||
nf_flowtable
|
||||
oa-tc6-framework
|
||||
openvswitch
|
||||
operstates
|
||||
packet_mmap
|
||||
phonet
|
||||
phy-link-topology
|
||||
pktgen
|
||||
plip
|
||||
ppp_generic
|
||||
|
@ -2362,6 +2362,20 @@ ra_honor_pio_life - BOOLEAN
|
||||
|
||||
Default: 0 (disabled)
|
||||
|
||||
ra_honor_pio_pflag - BOOLEAN
|
||||
The Prefix Information Option P-flag indicates the network can
|
||||
allocate a unique IPv6 prefix per client using DHCPv6-PD.
|
||||
This sysctl can be enabled when a userspace DHCPv6-PD client
|
||||
is running to cause the P-flag to take effect: i.e. the
|
||||
P-flag suppresses any effects of the A-flag within the same
|
||||
PIO. For a given PIO, P=1 and A=1 is treated as A=0.
|
||||
|
||||
- If disabled, the P-flag is ignored.
|
||||
- If enabled, the P-flag will disable SLAAC autoconfiguration
|
||||
for the given Prefix Information Option.
|
||||
|
||||
Default: 0 (disabled)
|
||||
|
||||
accept_ra_rt_info_min_plen - INTEGER
|
||||
Minimum prefix length of Route Information in RA.
|
||||
|
||||
|
@ -638,9 +638,8 @@ Tunnels are identified by a unique tunnel id. The id is 16-bit for
|
||||
L2TPv2 and 32-bit for L2TPv3. Internally, the id is stored as a 32-bit
|
||||
value.
|
||||
|
||||
Tunnels are kept in a per-net list, indexed by tunnel id. The tunnel
|
||||
id namespace is shared by L2TPv2 and L2TPv3. The tunnel context can be
|
||||
derived from the socket's sk_user_data.
|
||||
Tunnels are kept in a per-net list, indexed by tunnel id. The
|
||||
tunnel id namespace is shared by L2TPv2 and L2TPv3.
|
||||
|
||||
Handling tunnel socket close is perhaps the most tricky part of the
|
||||
L2TP implementation. If userspace closes a tunnel socket, the L2TP
|
||||
@ -652,9 +651,7 @@ socket's encap_destroy handler is invoked, which L2TP uses to initiate
|
||||
its tunnel close actions. For L2TPIP sockets, the socket's close
|
||||
handler initiates the same tunnel close actions. All sessions are
|
||||
first closed. Each session drops its tunnel ref. When the tunnel ref
|
||||
reaches zero, the tunnel puts its socket ref. When the socket is
|
||||
eventually destroyed, its sk_destruct finally frees the L2TP tunnel
|
||||
context.
|
||||
reaches zero, the tunnel drops its socket ref.
|
||||
|
||||
Sessions
|
||||
--------
|
||||
@ -667,10 +664,7 @@ pseudowire) or other data types such as PPP, ATM, HDLC or Frame
|
||||
Relay. Linux currently implements only Ethernet and PPP session types.
|
||||
|
||||
Some L2TP session types also have a socket (PPP pseudowires) while
|
||||
others do not (Ethernet pseudowires). We can't therefore use the
|
||||
socket reference count as the reference count for session
|
||||
contexts. The L2TP implementation therefore has its own internal
|
||||
reference counts on the session contexts.
|
||||
others do not (Ethernet pseudowires).
|
||||
|
||||
Like tunnels, L2TP sessions are identified by a unique
|
||||
session id. Just as with tunnel ids, the session id is 16-bit for
|
||||
@ -680,21 +674,19 @@ value.
|
||||
Sessions hold a ref on their parent tunnel to ensure that the tunnel
|
||||
stays extant while one or more sessions references it.
|
||||
|
||||
Sessions are kept in a per-tunnel list, indexed by session id. L2TPv3
|
||||
sessions are also kept in a per-net list indexed by session id,
|
||||
because L2TPv3 session ids are unique across all tunnels and L2TPv3
|
||||
data packets do not contain a tunnel id in the header. This list is
|
||||
therefore needed to find the session context associated with a
|
||||
received data packet when the tunnel context cannot be derived from
|
||||
the tunnel socket.
|
||||
Sessions are kept in a per-net list. L2TPv2 sessions and L2TPv3
|
||||
sessions are stored in separate lists. L2TPv2 sessions are keyed
|
||||
by a 32-bit key made up of the 16-bit tunnel ID and 16-bit
|
||||
session ID. L2TPv3 sessions are keyed by the 32-bit session ID, since
|
||||
L2TPv3 session ids are unique across all tunnels.
|
||||
|
||||
Although the L2TPv3 RFC specifies that L2TPv3 session ids are not
|
||||
scoped by the tunnel, the kernel does not police this for L2TPv3 UDP
|
||||
tunnels and does not add sessions of L2TPv3 UDP tunnels into the
|
||||
per-net session list. In the UDP receive code, we must trust that the
|
||||
tunnel can be identified using the tunnel socket's sk_user_data and
|
||||
lookup the session in the tunnel's session list instead of the per-net
|
||||
session list.
|
||||
scoped by the tunnel, the Linux implementation has historically
|
||||
allowed this. Such session id collisions are supported using a per-net
|
||||
hash table keyed by sk and session ID. When looking up L2TPv3
|
||||
sessions, the list entry may link to multiple sessions with that
|
||||
session ID, in which case the session matching the given sk (tunnel)
|
||||
is used.
|
||||
|
||||
PPP
|
||||
---
|
||||
@ -714,10 +706,9 @@ The L2TP PPP implementation handles the closing of a PPPoL2TP socket
|
||||
by closing its corresponding L2TP session. This is complicated because
|
||||
it must consider racing with netlink session create/destroy requests
|
||||
and pppol2tp_connect trying to reconnect with a session that is in the
|
||||
process of being closed. Unlike tunnels, PPP sessions do not hold a
|
||||
ref on their associated socket, so code must be careful to sock_hold
|
||||
the socket where necessary. For all the details, see commit
|
||||
3d609342cc04129ff7568e19316ce3d7451a27e8.
|
||||
process of being closed. PPP sessions hold a ref on their associated
|
||||
socket in order that the socket remains extants while the session
|
||||
references it.
|
||||
|
||||
Ethernet
|
||||
--------
|
||||
@ -761,15 +752,10 @@ Limitations
|
||||
|
||||
The current implementation has a number of limitations:
|
||||
|
||||
1) Multiple UDP sockets with the same 5-tuple address cannot be
|
||||
used. The kernel's tunnel context is identified using private
|
||||
data associated with the socket so it is important that each
|
||||
socket is uniquely identified by its address.
|
||||
|
||||
2) Interfacing with openvswitch is not yet implemented. It may be
|
||||
1) Interfacing with openvswitch is not yet implemented. It may be
|
||||
useful to map OVS Ethernet and VLAN ports into L2TPv3 tunnels.
|
||||
|
||||
3) VLAN pseudowires are implemented using an ``l2tpethN`` interface
|
||||
2) VLAN pseudowires are implemented using an ``l2tpethN`` interface
|
||||
configured with a VLAN sub-interface. Since L2TPv3 VLAN
|
||||
pseudowires carry one and only one VLAN, it may be better to use
|
||||
a single netdevice rather than an ``l2tpethN`` and ``l2tpethN``:M
|
||||
|
@ -34,6 +34,17 @@ available_schedulers - STRING
|
||||
Shows the available schedulers choices that are registered. More packet
|
||||
schedulers may be available, but not loaded.
|
||||
|
||||
blackhole_timeout - INTEGER (seconds)
|
||||
Initial time period in second to disable MPTCP on active MPTCP sockets
|
||||
when a MPTCP firewall blackhole issue happens. This time period will
|
||||
grow exponentially when more blackhole issues get detected right after
|
||||
MPTCP is re-enabled and will reset to the initial value when the
|
||||
blackhole issue goes away.
|
||||
|
||||
0 to disable the blackhole detection.
|
||||
|
||||
Default: 3600
|
||||
|
||||
checksum_enabled - BOOLEAN
|
||||
Control whether DSS checksum can be enabled.
|
||||
|
||||
|
@ -111,11 +111,11 @@ The relation between PF, irq, napi, and queue can be observed via netlink spec::
|
||||
Here you can clearly observe our channels distribution policy::
|
||||
|
||||
$ ls /proc/irq/{36,39,40,41,42}/mlx5* -d -1
|
||||
/proc/irq/36/mlx5_comp1@pci:0000:08:00.0
|
||||
/proc/irq/39/mlx5_comp1@pci:0000:09:00.0
|
||||
/proc/irq/40/mlx5_comp2@pci:0000:08:00.0
|
||||
/proc/irq/41/mlx5_comp2@pci:0000:09:00.0
|
||||
/proc/irq/42/mlx5_comp3@pci:0000:08:00.0
|
||||
/proc/irq/36/mlx5_comp0@pci:0000:08:00.0
|
||||
/proc/irq/39/mlx5_comp0@pci:0000:09:00.0
|
||||
/proc/irq/40/mlx5_comp1@pci:0000:08:00.0
|
||||
/proc/irq/41/mlx5_comp1@pci:0000:09:00.0
|
||||
/proc/irq/42/mlx5_comp2@pci:0000:08:00.0
|
||||
|
||||
Steering
|
||||
========
|
||||
|
@ -7,6 +7,8 @@ net_device struct fast path usage breakdown
|
||||
|
||||
Type Name fastpath_tx_access fastpath_rx_access Comments
|
||||
..struct ..net_device
|
||||
unsigned_long:32 priv_flags read_mostly - __dev_queue_xmit(tx)
|
||||
unsigned_long:1 lltx read_mostly - HARD_TX_LOCK,HARD_TX_TRYLOCK,HARD_TX_UNLOCK(tx)
|
||||
char name[16] - -
|
||||
struct_netdev_name_node* name_node
|
||||
struct_dev_ifalias* ifalias
|
||||
@ -23,7 +25,6 @@ struct_list_head ptype_specific
|
||||
struct adj_list
|
||||
unsigned_int flags read_mostly read_mostly __dev_queue_xmit,__dev_xmit_skb,ip6_output,__ip6_finish_output(tx);ip6_rcv_core(rx)
|
||||
xdp_features_t xdp_features
|
||||
unsigned_long_long priv_flags read_mostly - __dev_queue_xmit(tx)
|
||||
struct_net_device_ops* netdev_ops read_mostly - netdev_core_pick_tx,netdev_start_xmit(tx)
|
||||
struct_xdp_metadata_ops* xdp_metadata_ops
|
||||
int ifindex - read_mostly ip6_rcv_core
|
||||
@ -98,7 +99,7 @@ unsigned_int num_rx_queues
|
||||
unsigned_int real_num_rx_queues - read_mostly get_rps_cpu
|
||||
struct_bpf_prog* xdp_prog - read_mostly netif_elide_gro()
|
||||
unsigned_long gro_flush_timeout - read_mostly napi_complete_done
|
||||
int napi_defer_hard_irqs - read_mostly napi_complete_done
|
||||
u32 napi_defer_hard_irqs - read_mostly napi_complete_done
|
||||
unsigned_int gro_max_size - read_mostly skb_gro_receive
|
||||
unsigned_int gro_ipv4_max_size - read_mostly skb_gro_receive
|
||||
rx_handler_func_t* rx_handler read_mostly - __netif_receive_skb_core
|
||||
@ -163,6 +164,10 @@ struct_lock_class_key* qdisc_tx_busylock
|
||||
bool proto_down
|
||||
unsigned:1 wol_enabled
|
||||
unsigned:1 threaded - - napi_poll(napi_enable,dev_set_threaded)
|
||||
unsigned_long:1 see_all_hwtstamp_requests
|
||||
unsigned_long:1 change_proto_down
|
||||
unsigned_long:1 netns_local
|
||||
unsigned_long:1 fcoe_mtu
|
||||
struct_list_head net_notifier_list
|
||||
struct_macsec_ops* macsec_ops
|
||||
struct_udp_tunnel_nic_info* udp_tunnel_nic_info
|
||||
@ -176,3 +181,5 @@ netdevice_tracker dev_registered_tracker
|
||||
struct_rtnl_hw_stats64* offload_xstats_l3
|
||||
struct_devlink_port* devlink_port
|
||||
struct_dpll_pin* dpll_pin
|
||||
struct hlist_head page_pools
|
||||
struct dim_irq_moder* irq_moder
|
||||
|
@ -139,21 +139,6 @@ chained skbs (skb->next/prev list).
|
||||
Features contained in NETIF_F_SOFT_FEATURES are features of networking
|
||||
stack. Driver should not change behaviour based on them.
|
||||
|
||||
* LLTX driver (deprecated for hardware drivers)
|
||||
|
||||
NETIF_F_LLTX is meant to be used by drivers that don't need locking at all,
|
||||
e.g. software tunnels.
|
||||
|
||||
This is also used in a few legacy drivers that implement their
|
||||
own locking, don't use it for new (hardware) drivers.
|
||||
|
||||
* netns-local device
|
||||
|
||||
NETIF_F_NETNS_LOCAL is set for devices that are not allowed to move between
|
||||
network namespaces (e.g. loopback).
|
||||
|
||||
Don't use it in drivers.
|
||||
|
||||
* VLAN challenged
|
||||
|
||||
NETIF_F_VLAN_CHALLENGED should be set for devices which can't cope with VLAN
|
||||
|
@ -258,11 +258,11 @@ ndo_get_stats:
|
||||
ndo_start_xmit:
|
||||
Synchronization: __netif_tx_lock spinlock.
|
||||
|
||||
When the driver sets NETIF_F_LLTX in dev->features this will be
|
||||
When the driver sets dev->lltx this will be
|
||||
called without holding netif_tx_lock. In this case the driver
|
||||
has to lock by itself when needed.
|
||||
The locking there should also properly protect against
|
||||
set_rx_mode. WARNING: use of NETIF_F_LLTX is deprecated.
|
||||
set_rx_mode. WARNING: use of dev->lltx is deprecated.
|
||||
Don't use it for new drivers.
|
||||
|
||||
Context: Process with BHs disabled or BH (timer),
|
||||
|
497
Documentation/networking/oa-tc6-framework.rst
Normal file
497
Documentation/networking/oa-tc6-framework.rst
Normal file
@ -0,0 +1,497 @@
|
||||
.. SPDX-License-Identifier: GPL-2.0+
|
||||
|
||||
=========================================================================
|
||||
OPEN Alliance 10BASE-T1x MAC-PHY Serial Interface (TC6) Framework Support
|
||||
=========================================================================
|
||||
|
||||
Introduction
|
||||
------------
|
||||
|
||||
The IEEE 802.3cg project defines two 10 Mbit/s PHYs operating over a
|
||||
single pair of conductors. The 10BASE-T1L (Clause 146) is a long reach
|
||||
PHY supporting full duplex point-to-point operation over 1 km of single
|
||||
balanced pair of conductors. The 10BASE-T1S (Clause 147) is a short reach
|
||||
PHY supporting full / half duplex point-to-point operation over 15 m of
|
||||
single balanced pair of conductors, or half duplex multidrop bus
|
||||
operation over 25 m of single balanced pair of conductors.
|
||||
|
||||
Furthermore, the IEEE 802.3cg project defines the new Physical Layer
|
||||
Collision Avoidance (PLCA) Reconciliation Sublayer (Clause 148) meant to
|
||||
provide improved determinism to the CSMA/CD media access method. PLCA
|
||||
works in conjunction with the 10BASE-T1S PHY operating in multidrop mode.
|
||||
|
||||
The aforementioned PHYs are intended to cover the low-speed / low-cost
|
||||
applications in industrial and automotive environment. The large number
|
||||
of pins (16) required by the MII interface, which is specified by the
|
||||
IEEE 802.3 in Clause 22, is one of the major cost factors that need to be
|
||||
addressed to fulfil this objective.
|
||||
|
||||
The MAC-PHY solution integrates an IEEE Clause 4 MAC and a 10BASE-T1x PHY
|
||||
exposing a low pin count Serial Peripheral Interface (SPI) to the host
|
||||
microcontroller. This also enables the addition of Ethernet functionality
|
||||
to existing low-end microcontrollers which do not integrate a MAC
|
||||
controller.
|
||||
|
||||
Overview
|
||||
--------
|
||||
|
||||
The MAC-PHY is specified to carry both data (Ethernet frames) and control
|
||||
(register access) transactions over a single full-duplex serial peripheral
|
||||
interface.
|
||||
|
||||
Protocol Overview
|
||||
-----------------
|
||||
|
||||
Two types of transactions are defined in the protocol: data transactions
|
||||
for Ethernet frame transfers and control transactions for register
|
||||
read/write transfers. A chunk is the basic element of data transactions
|
||||
and is composed of 4 bytes of overhead plus 64 bytes of payload size for
|
||||
each chunk. Ethernet frames are transferred over one or more data chunks.
|
||||
Control transactions consist of one or more register read/write control
|
||||
commands.
|
||||
|
||||
SPI transactions are initiated by the SPI host with the assertion of CSn
|
||||
low to the MAC-PHY and ends with the deassertion of CSn high. In between
|
||||
each SPI transaction, the SPI host may need time for additional
|
||||
processing and to setup the next SPI data or control transaction.
|
||||
|
||||
SPI data transactions consist of an equal number of transmit (TX) and
|
||||
receive (RX) chunks. Chunks in both transmit and receive directions may
|
||||
or may not contain valid frame data independent from each other, allowing
|
||||
for the simultaneous transmission and reception of different length
|
||||
frames.
|
||||
|
||||
Each transmit data chunk begins with a 32-bit data header followed by a
|
||||
data chunk payload on MOSI. The data header indicates whether transmit
|
||||
frame data is present and provides the information to determine which
|
||||
bytes of the payload contain valid frame data.
|
||||
|
||||
In parallel, receive data chunks are received on MISO. Each receive data
|
||||
chunk consists of a data chunk payload ending with a 32-bit data footer.
|
||||
The data footer indicates if there is receive frame data present within
|
||||
the payload or not and provides the information to determine which bytes
|
||||
of the payload contain valid frame data.
|
||||
|
||||
Reference
|
||||
---------
|
||||
|
||||
10BASE-T1x MAC-PHY Serial Interface Specification,
|
||||
|
||||
Link: https://opensig.org/download/document/OPEN_Alliance_10BASET1x_MAC-PHY_Serial_Interface_V1.1.pdf
|
||||
|
||||
Hardware Architecture
|
||||
---------------------
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
+----------+ +-------------------------------------+
|
||||
| | | MAC-PHY |
|
||||
| |<---->| +-----------+ +-------+ +-------+ |
|
||||
| SPI Host | | | SPI Slave | | MAC | | PHY | |
|
||||
| | | +-----------+ +-------+ +-------+ |
|
||||
+----------+ +-------------------------------------+
|
||||
|
||||
Software Architecture
|
||||
---------------------
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
+----------------------------------------------------------+
|
||||
| Networking Subsystem |
|
||||
+----------------------------------------------------------+
|
||||
/ \ / \
|
||||
| |
|
||||
| |
|
||||
\ / |
|
||||
+----------------------+ +-----------------------------+
|
||||
| MAC Driver |<--->| OPEN Alliance TC6 Framework |
|
||||
+----------------------+ +-----------------------------+
|
||||
/ \ / \
|
||||
| |
|
||||
| |
|
||||
| \ /
|
||||
+----------------------------------------------------------+
|
||||
| SPI Subsystem |
|
||||
+----------------------------------------------------------+
|
||||
/ \
|
||||
|
|
||||
|
|
||||
\ /
|
||||
+----------------------------------------------------------+
|
||||
| 10BASE-T1x MAC-PHY Device |
|
||||
+----------------------------------------------------------+
|
||||
|
||||
Implementation
|
||||
--------------
|
||||
|
||||
MAC Driver
|
||||
~~~~~~~~~~
|
||||
|
||||
- Probed by SPI subsystem.
|
||||
|
||||
- Initializes OA TC6 framework for the MAC-PHY.
|
||||
|
||||
- Registers and configures the network device.
|
||||
|
||||
- Sends the tx ethernet frames from n/w subsystem to OA TC6 framework.
|
||||
|
||||
OPEN Alliance TC6 Framework
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
- Initializes PHYLIB interface.
|
||||
|
||||
- Registers mac-phy interrupt.
|
||||
|
||||
- Performs mac-phy register read/write operation using the control
|
||||
transaction protocol specified in the OPEN Alliance 10BASE-T1x MAC-PHY
|
||||
Serial Interface specification.
|
||||
|
||||
- Performs Ethernet frames transaction using the data transaction protocol
|
||||
for Ethernet frames specified in the OPEN Alliance 10BASE-T1x MAC-PHY
|
||||
Serial Interface specification.
|
||||
|
||||
- Forwards the received Ethernet frame from 10Base-T1x MAC-PHY to n/w
|
||||
subsystem.
|
||||
|
||||
Data Transaction
|
||||
~~~~~~~~~~~~~~~~
|
||||
|
||||
The Ethernet frames that are typically transferred from the SPI host to
|
||||
the MAC-PHY will be converted into multiple transmit data chunks. Each
|
||||
transmit data chunk will have a 4 bytes header which contains the
|
||||
information needed to determine the validity and the location of the
|
||||
transmit frame data within the 64 bytes data chunk payload.
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
+---------------------------------------------------+
|
||||
| Tx Chunk |
|
||||
| +---------------------------+ +----------------+ | MOSI
|
||||
| | 64 bytes chunk payload | | 4 bytes header | |------------>
|
||||
| +---------------------------+ +----------------+ |
|
||||
+---------------------------------------------------+
|
||||
|
||||
4 bytes header contains the below fields,
|
||||
|
||||
DNC (Bit 31) - Data-Not-Control flag. This flag specifies the type of SPI
|
||||
transaction. For TX data chunks, this bit shall be ’1’.
|
||||
0 - Control command
|
||||
1 - Data chunk
|
||||
|
||||
SEQ (Bit 30) - Data Chunk Sequence. This bit is used to indicate an
|
||||
even/odd transmit data chunk sequence to the MAC-PHY.
|
||||
|
||||
NORX (Bit 29) - No Receive flag. The SPI host may set this bit to prevent
|
||||
the MAC-PHY from conveying RX data on the MISO for the
|
||||
current chunk (DV = 0 in the footer), indicating that the
|
||||
host would not process it. Typically, the SPI host should
|
||||
set NORX = 0 indicating that it will accept and process
|
||||
any receive frame data within the current chunk.
|
||||
|
||||
RSVD (Bit 28..24) - Reserved: All reserved bits shall be ‘0’.
|
||||
|
||||
VS (Bit 23..22) - Vendor Specific. These bits are implementation specific.
|
||||
If the MAC-PHY does not implement these bits, the host
|
||||
shall set them to ‘0’.
|
||||
|
||||
DV (Bit 21) - Data Valid flag. The SPI host uses this bit to indicate
|
||||
whether the current chunk contains valid transmit frame data
|
||||
(DV = 1) or not (DV = 0). When ‘0’, the MAC-PHY ignores the
|
||||
chunk payload. Note that the receive path is unaffected by
|
||||
the setting of the DV bit in the data header.
|
||||
|
||||
SV (Bit 20) - Start Valid flag. The SPI host shall set this bit when the
|
||||
beginning of an Ethernet frame is present in the current
|
||||
transmit data chunk payload. Otherwise, this bit shall be
|
||||
zero. This bit is not to be confused with the Start-of-Frame
|
||||
Delimiter (SFD) byte described in IEEE 802.3 [2].
|
||||
|
||||
SWO (Bit 19..16) - Start Word Offset. When SV = 1, this field shall
|
||||
contain the 32-bit word offset into the transmit data
|
||||
chunk payload that points to the start of a new
|
||||
Ethernet frame to be transmitted. The host shall write
|
||||
this field as zero when SV = 0.
|
||||
|
||||
RSVD (Bit 15) - Reserved: All reserved bits shall be ‘0’.
|
||||
|
||||
EV (Bit 14) - End Valid flag. The SPI host shall set this bit when the end
|
||||
of an Ethernet frame is present in the current transmit data
|
||||
chunk payload. Otherwise, this bit shall be zero.
|
||||
|
||||
EBO (Bit 13..8) - End Byte Offset. When EV = 1, this field shall contain
|
||||
the byte offset into the transmit data chunk payload
|
||||
that points to the last byte of the Ethernet frame to
|
||||
transmit. This field shall be zero when EV = 0.
|
||||
|
||||
TSC (Bit 7..6) - Timestamp Capture. Request a timestamp capture when the
|
||||
frame is transmitted onto the network.
|
||||
00 - Do not capture a timestamp
|
||||
01 - Capture timestamp into timestamp capture register A
|
||||
10 - Capture timestamp into timestamp capture register B
|
||||
11 - Capture timestamp into timestamp capture register C
|
||||
|
||||
RSVD (Bit 5..1) - Reserved: All reserved bits shall be ‘0’.
|
||||
|
||||
P (Bit 0) - Parity. Parity bit calculated over the transmit data header.
|
||||
Method used is odd parity.
|
||||
|
||||
The number of buffers available in the MAC-PHY to store the incoming
|
||||
transmit data chunk payloads is represented as transmit credits. The
|
||||
available transmit credits in the MAC-PHY can be read either from the
|
||||
Buffer Status Register or footer (Refer below for the footer info)
|
||||
received from the MAC-PHY. The SPI host should not write more data chunks
|
||||
than the available transmit credits as this will lead to transmit buffer
|
||||
overflow error.
|
||||
|
||||
In case the previous data footer had no transmit credits available and
|
||||
once the transmit credits become available for transmitting transmit data
|
||||
chunks, the MAC-PHY interrupt is asserted to SPI host. On reception of the
|
||||
first data header this interrupt will be deasserted and the received
|
||||
footer for the first data chunk will have the transmit credits available
|
||||
information.
|
||||
|
||||
The Ethernet frames that are typically transferred from MAC-PHY to SPI
|
||||
host will be sent as multiple receive data chunks. Each receive data
|
||||
chunk will have 64 bytes of data chunk payload followed by 4 bytes footer
|
||||
which contains the information needed to determine the validity and the
|
||||
location of the receive frame data within the 64 bytes data chunk payload.
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
+---------------------------------------------------+
|
||||
| Rx Chunk |
|
||||
| +----------------+ +---------------------------+ | MISO
|
||||
| | 4 bytes footer | | 64 bytes chunk payload | |------------>
|
||||
| +----------------+ +---------------------------+ |
|
||||
+---------------------------------------------------+
|
||||
|
||||
4 bytes footer contains the below fields,
|
||||
|
||||
EXST (Bit 31) - Extended Status. This bit is set when any bit in the
|
||||
STATUS0 or STATUS1 registers are set and not masked.
|
||||
|
||||
HDRB (Bit 30) - Received Header Bad. When set, indicates that the MAC-PHY
|
||||
received a control or data header with a parity error.
|
||||
|
||||
SYNC (Bit 29) - Configuration Synchronized flag. This bit reflects the
|
||||
state of the SYNC bit in the CONFIG0 configuration
|
||||
register (see Table 12). A zero indicates that the MAC-PHY
|
||||
configuration may not be as expected by the SPI host.
|
||||
Following configuration, the SPI host sets the
|
||||
corresponding bitin the configuration register which is
|
||||
reflected in this field.
|
||||
|
||||
RCA (Bit 28..24) - Receive Chunks Available. The RCA field indicates to
|
||||
the SPI host the minimum number of additional receive
|
||||
data chunks of frame data that are available for
|
||||
reading beyond the current receive data chunk. This
|
||||
field is zero when there is no receive frame data
|
||||
pending in the MAC-PHY’s buffer for reading.
|
||||
|
||||
VS (Bit 23..22) - Vendor Specific. These bits are implementation specific.
|
||||
If not implemented, the MAC-PHY shall set these bits to
|
||||
‘0’.
|
||||
|
||||
DV (Bit 21) - Data Valid flag. The MAC-PHY uses this bit to indicate
|
||||
whether the current receive data chunk contains valid
|
||||
receive frame data (DV = 1) or not (DV = 0). When ‘0’, the
|
||||
SPI host shall ignore the chunk payload.
|
||||
|
||||
SV (Bit 20) - Start Valid flag. The MAC-PHY sets this bit when the current
|
||||
chunk payload contains the start of an Ethernet frame.
|
||||
Otherwise, this bit is zero. The SV bit is not to be
|
||||
confused with the Start-of-Frame Delimiter (SFD) byte
|
||||
described in IEEE 802.3 [2].
|
||||
|
||||
SWO (Bit 19..16) - Start Word Offset. When SV = 1, this field contains the
|
||||
32-bit word offset into the receive data chunk payload
|
||||
containing the first byte of a new received Ethernet
|
||||
frame. When a receive timestamp has been added to the
|
||||
beginning of the received Ethernet frame (RTSA = 1)
|
||||
then SWO points to the most significant byte of the
|
||||
timestamp. This field will be zero when SV = 0.
|
||||
|
||||
FD (Bit 15) - Frame Drop. When set, this bit indicates that the MAC has
|
||||
detected a condition for which the SPI host should drop the
|
||||
received Ethernet frame. This bit is only valid at the end
|
||||
of a received Ethernet frame (EV = 1) and shall be zero at
|
||||
all other times.
|
||||
|
||||
EV (Bit 14) - End Valid flag. The MAC-PHY sets this bit when the end of a
|
||||
received Ethernet frame is present in this receive data
|
||||
chunk payload.
|
||||
|
||||
EBO (Bit 13..8) - End Byte Offset: When EV = 1, this field contains the
|
||||
byte offset into the receive data chunk payload that
|
||||
locates the last byte of the received Ethernet frame.
|
||||
This field is zero when EV = 0.
|
||||
|
||||
RTSA (Bit 7) - Receive Timestamp Added. This bit is set when a 32-bit or
|
||||
64-bit timestamp has been added to the beginning of the
|
||||
received Ethernet frame. The MAC-PHY shall set this bit to
|
||||
zero when SV = 0.
|
||||
|
||||
RTSP (Bit 6) - Receive Timestamp Parity. Parity bit calculated over the
|
||||
32-bit/64-bit timestamp added to the beginning of the
|
||||
received Ethernet frame. Method used is odd parity. The
|
||||
MAC-PHY shall set this bit to zero when RTSA = 0.
|
||||
|
||||
TXC (Bit 5..1) - Transmit Credits. This field contains the minimum number
|
||||
of transmit data chunks of frame data that the SPI host
|
||||
can write in a single transaction without incurring a
|
||||
transmit buffer overflow error.
|
||||
|
||||
P (Bit 0) - Parity. Parity bit calculated over the receive data footer.
|
||||
Method used is odd parity.
|
||||
|
||||
SPI host will initiate the data receive transaction based on the receive
|
||||
chunks available in the MAC-PHY which is provided in the receive chunk
|
||||
footer (RCA - Receive Chunks Available). SPI host will create data invalid
|
||||
transmit data chunks (empty chunks) or data valid transmit data chunks in
|
||||
case there are valid Ethernet frames to transmit to the MAC-PHY. The
|
||||
receive chunks available in MAC-PHY can be read either from the Buffer
|
||||
Status Register or footer.
|
||||
|
||||
In case the previous data footer had no receive data chunks available and
|
||||
once the receive data chunks become available again for reading, the
|
||||
MAC-PHY interrupt is asserted to SPI host. On reception of the first data
|
||||
header this interrupt will be deasserted and the received footer for the
|
||||
first data chunk will have the receive chunks available information.
|
||||
|
||||
MAC-PHY Interrupt
|
||||
~~~~~~~~~~~~~~~~~
|
||||
|
||||
The MAC-PHY interrupt is asserted when the following conditions are met.
|
||||
|
||||
Receive chunks available - This interrupt is asserted when the previous
|
||||
data footer had no receive data chunks available and once the receive
|
||||
data chunks become available for reading. On reception of the first data
|
||||
header this interrupt will be deasserted.
|
||||
|
||||
Transmit chunk credits available - This interrupt is asserted when the
|
||||
previous data footer indicated no transmit credits available and once the
|
||||
transmit credits become available for transmitting transmit data chunks.
|
||||
On reception of the first data header this interrupt will be deasserted.
|
||||
|
||||
Extended status event - This interrupt is asserted when the previous data
|
||||
footer indicated no extended status and once the extended event become
|
||||
available. In this case the host should read status #0 register to know
|
||||
the corresponding error/event. On reception of the first data header this
|
||||
interrupt will be deasserted.
|
||||
|
||||
Control Transaction
|
||||
~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
4 bytes control header contains the below fields,
|
||||
|
||||
DNC (Bit 31) - Data-Not-Control flag. This flag specifies the type of SPI
|
||||
transaction. For control commands, this bit shall be ‘0’.
|
||||
0 - Control command
|
||||
1 - Data chunk
|
||||
|
||||
HDRB (Bit 30) - Received Header Bad. When set by the MAC-PHY, indicates
|
||||
that a header was received with a parity error. The SPI
|
||||
host should always clear this bit. The MAC-PHY ignores the
|
||||
HDRB value sent by the SPI host on MOSI.
|
||||
|
||||
WNR (Bit 29) - Write-Not-Read. This bit indicates if data is to be written
|
||||
to registers (when set) or read from registers
|
||||
(when clear).
|
||||
|
||||
AID (Bit 28) - Address Increment Disable. When clear, the address will be
|
||||
automatically post-incremented by one following each
|
||||
register read or write. When set, address auto increment is
|
||||
disabled allowing successive reads and writes to occur at
|
||||
the same register address.
|
||||
|
||||
MMS (Bit 27..24) - Memory Map Selector. This field selects the specific
|
||||
register memory map to access.
|
||||
|
||||
ADDR (Bit 23..8) - Address. Address of the first register within the
|
||||
selected memory map to access.
|
||||
|
||||
LEN (Bit 7..1) - Length. Specifies the number of registers to read/write.
|
||||
This field is interpreted as the number of registers
|
||||
minus 1 allowing for up to 128 consecutive registers read
|
||||
or written starting at the address specified in ADDR. A
|
||||
length of zero shall read or write a single register.
|
||||
|
||||
P (Bit 0) - Parity. Parity bit calculated over the control command header.
|
||||
Method used is odd parity.
|
||||
|
||||
Control transactions consist of one or more control commands. Control
|
||||
commands are used by the SPI host to read and write registers within the
|
||||
MAC-PHY. Each control commands are composed of a 4 bytes control command
|
||||
header followed by register write data in case of control write command.
|
||||
|
||||
The MAC-PHY ignores the final 4 bytes of data from the SPI host at the end
|
||||
of the control write command. The control write command is also echoed
|
||||
from the MAC-PHY back to the SPI host to identify which register write
|
||||
failed in case of any bus errors. The echoed Control write command will
|
||||
have the first 4 bytes unused value to be ignored by the SPI host
|
||||
followed by 4 bytes echoed control header followed by echoed register
|
||||
write data. Control write commands can write either a single register or
|
||||
multiple consecutive registers. When multiple consecutive registers are
|
||||
written, the address is automatically post-incremented by the MAC-PHY.
|
||||
Writing to any unimplemented or undefined registers shall be ignored and
|
||||
yield no effect.
|
||||
|
||||
The MAC-PHY ignores all data from the SPI host following the control
|
||||
header for the remainder of the control read command. The control read
|
||||
command is also echoed from the MAC-PHY back to the SPI host to identify
|
||||
which register read is failed in case of any bus errors. The echoed
|
||||
Control read command will have the first 4 bytes of unused value to be
|
||||
ignored by the SPI host followed by 4 bytes echoed control header followed
|
||||
by register read data. Control read commands can read either a single
|
||||
register or multiple consecutive registers. When multiple consecutive
|
||||
registers are read, the address is automatically post-incremented by the
|
||||
MAC-PHY. Reading any unimplemented or undefined registers shall return
|
||||
zero.
|
||||
|
||||
Device drivers API
|
||||
==================
|
||||
|
||||
The include/linux/oa_tc6.h defines the following functions:
|
||||
|
||||
.. c:function:: struct oa_tc6 *oa_tc6_init(struct spi_device *spi, \
|
||||
struct net_device *netdev)
|
||||
|
||||
Initialize OA TC6 lib.
|
||||
|
||||
.. c:function:: void oa_tc6_exit(struct oa_tc6 *tc6)
|
||||
|
||||
Free allocated OA TC6 lib.
|
||||
|
||||
.. c:function:: int oa_tc6_write_register(struct oa_tc6 *tc6, u32 address, \
|
||||
u32 value)
|
||||
|
||||
Write a single register in the MAC-PHY.
|
||||
|
||||
.. c:function:: int oa_tc6_write_registers(struct oa_tc6 *tc6, u32 address, \
|
||||
u32 value[], u8 length)
|
||||
|
||||
Writing multiple consecutive registers starting from @address in the MAC-PHY.
|
||||
Maximum of 128 consecutive registers can be written starting at @address.
|
||||
|
||||
.. c:function:: int oa_tc6_read_register(struct oa_tc6 *tc6, u32 address, \
|
||||
u32 *value)
|
||||
|
||||
Read a single register in the MAC-PHY.
|
||||
|
||||
.. c:function:: int oa_tc6_read_registers(struct oa_tc6 *tc6, u32 address, \
|
||||
u32 value[], u8 length)
|
||||
|
||||
Reading multiple consecutive registers starting from @address in the MAC-PHY.
|
||||
Maximum of 128 consecutive registers can be read starting at @address.
|
||||
|
||||
.. c:function:: netdev_tx_t oa_tc6_start_xmit(struct oa_tc6 *tc6, \
|
||||
struct sk_buff *skb);
|
||||
|
||||
The transmit Ethernet frame in the skb is or going to be transmitted through
|
||||
the MAC-PHY.
|
||||
|
||||
.. c:function:: int oa_tc6_zero_align_receive_frame_enable(struct oa_tc6 *tc6);
|
||||
|
||||
Zero align receive frame feature can be enabled to align all receive ethernet
|
||||
frames data to start at the beginning of any receive data chunk payload with a
|
||||
start word offset (SWO) of zero.
|
121
Documentation/networking/phy-link-topology.rst
Normal file
121
Documentation/networking/phy-link-topology.rst
Normal file
@ -0,0 +1,121 @@
|
||||
.. SPDX-License-Identifier: GPL-2.0
|
||||
.. _phy_link_topology:
|
||||
|
||||
=================
|
||||
PHY link topology
|
||||
=================
|
||||
|
||||
Overview
|
||||
========
|
||||
|
||||
The PHY link topology representation in the networking stack aims at representing
|
||||
the hardware layout for any given Ethernet link.
|
||||
|
||||
An Ethernet interface from userspace's point of view is nothing but a
|
||||
:c:type:`struct net_device <net_device>`, which exposes configuration options
|
||||
through the legacy ioctls and the ethtool netlink commands. The base assumption
|
||||
when designing these configuration APIs were that the link looks something like ::
|
||||
|
||||
+-----------------------+ +----------+ +--------------+
|
||||
| Ethernet Controller / | | Ethernet | | Connector / |
|
||||
| MAC | ------ | PHY | ---- | Port | ---... to LP
|
||||
+-----------------------+ +----------+ +--------------+
|
||||
struct net_device struct phy_device
|
||||
|
||||
Commands that needs to configure the PHY will go through the net_device.phydev
|
||||
field to reach the PHY and perform the relevant configuration.
|
||||
|
||||
This assumption falls apart in more complex topologies that can arise when,
|
||||
for example, using SFP transceivers (although that's not the only specific case).
|
||||
|
||||
Here, we have 2 basic scenarios. Either the MAC is able to output a serialized
|
||||
interface, that can directly be fed to an SFP cage, such as SGMII, 1000BaseX,
|
||||
10GBaseR, etc.
|
||||
|
||||
The link topology then looks like this (when an SFP module is inserted) ::
|
||||
|
||||
+-----+ SGMII +------------+
|
||||
| MAC | ------- | SFP Module |
|
||||
+-----+ +------------+
|
||||
|
||||
Knowing that some modules embed a PHY, the actual link is more like ::
|
||||
|
||||
+-----+ SGMII +--------------+
|
||||
| MAC | -------- | PHY (on SFP) |
|
||||
+-----+ +--------------+
|
||||
|
||||
In this case, the SFP PHY is handled by phylib, and registered by phylink through
|
||||
its SFP upstream ops.
|
||||
|
||||
Now some Ethernet controllers aren't able to output a serialized interface, so
|
||||
we can't directly connect them to an SFP cage. However, some PHYs can be used
|
||||
as media-converters, to translate the non-serialized MAC MII interface to a
|
||||
serialized MII interface fed to the SFP ::
|
||||
|
||||
+-----+ RGMII +-----------------------+ SGMII +--------------+
|
||||
| MAC | ------- | PHY (media converter) | ------- | PHY (on SFP) |
|
||||
+-----+ +-----------------------+ +--------------+
|
||||
|
||||
This is where the model of having a single net_device.phydev pointer shows its
|
||||
limitations, as we now have 2 PHYs on the link.
|
||||
|
||||
The phy_link topology framework aims at providing a way to keep track of every
|
||||
PHY on the link, for use by both kernel drivers and subsystems, but also to
|
||||
report the topology to userspace, allowing to target individual PHYs in configuration
|
||||
commands.
|
||||
|
||||
API
|
||||
===
|
||||
|
||||
The :c:type:`struct phy_link_topology <phy_link_topology>` is a per-netdevice
|
||||
resource, that gets initialized at netdevice creation. Once it's initialized,
|
||||
it is then possible to register PHYs to the topology through :
|
||||
|
||||
:c:func:`phy_link_topo_add_phy`
|
||||
|
||||
Besides registering the PHY to the topology, this call will also assign a unique
|
||||
index to the PHY, which can then be reported to userspace to refer to this PHY
|
||||
(akin to the ifindex). This index is a u32, ranging from 1 to U32_MAX. The value
|
||||
0 is reserved to indicate the PHY doesn't belong to any topology yet.
|
||||
|
||||
The PHY can then be removed from the topology through
|
||||
|
||||
:c:func:`phy_link_topo_del_phy`
|
||||
|
||||
These function are already hooked into the phylib subsystem, so all PHYs that
|
||||
are linked to a net_device through :c:func:`phy_attach_direct` will automatically
|
||||
join the netdev's topology.
|
||||
|
||||
PHYs that are on a SFP module will also be automatically registered IF the SFP
|
||||
upstream is phylink (so, no media-converter).
|
||||
|
||||
PHY drivers that can be used as SFP upstream need to call :c:func:`phy_sfp_attach_phy`
|
||||
and :c:func:`phy_sfp_detach_phy`, which can be used as a
|
||||
.attach_phy / .detach_phy implementation for the
|
||||
:c:type:`struct sfp_upstream_ops <sfp_upstream_ops>`.
|
||||
|
||||
UAPI
|
||||
====
|
||||
|
||||
There exist a set of netlink commands to query the link topology from userspace,
|
||||
see ``Documentation/networking/ethtool-netlink.rst``.
|
||||
|
||||
The whole point of having a topology representation is to assign the phyindex
|
||||
field in :c:type:`struct phy_device <phy_device>`. This index is reported to
|
||||
userspace using the ``ETHTOOL_MSG_PHY_GET`` ethtnl command. Performing a DUMP operation
|
||||
will result in all PHYs from all net_device being listed. The DUMP command
|
||||
accepts either a ``ETHTOOL_A_HEADER_DEV_INDEX`` or ``ETHTOOL_A_HEADER_DEV_NAME``
|
||||
to be passed in the request to filter the DUMP to a single net_device.
|
||||
|
||||
The retrieved index can then be passed as a request parameter using the
|
||||
``ETHTOOL_A_HEADER_PHY_INDEX`` field in the following ethnl commands :
|
||||
|
||||
* ``ETHTOOL_MSG_STRSET_GET`` to get the stats string set from a given PHY
|
||||
* ``ETHTOOL_MSG_CABLE_TEST_ACT`` and ``ETHTOOL_MSG_CABLE_TEST_ACT``, to perform
|
||||
cable testing on a given PHY on the link (most likely the outermost PHY)
|
||||
* ``ETHTOOL_MSG_PSE_SET`` and ``ETHTOOL_MSG_PSE_GET`` for PHY-controlled PoE and PSE settings
|
||||
* ``ETHTOOL_MSG_PLCA_GET_CFG``, ``ETHTOOL_MSG_PLCA_SET_CFG`` and ``ETHTOOL_MSG_PLCA_GET_STATUS``
|
||||
to set the PLCA (Physical Layer Collision Avoidance) parameters
|
||||
|
||||
Note that the PHY index can be passed to other requests, which will silently
|
||||
ignore it if present and irrelevant.
|
@ -137,10 +137,10 @@ would be sub-port 0 on port 1 on switch 1.
|
||||
Port Features
|
||||
^^^^^^^^^^^^^
|
||||
|
||||
NETIF_F_NETNS_LOCAL
|
||||
dev->netns_local
|
||||
|
||||
If the switchdev driver (and device) only supports offloading of the default
|
||||
network namespace (netns), the driver should set this feature flag to prevent
|
||||
network namespace (netns), the driver should set this private flag to prevent
|
||||
the port netdev from being moved out of the default netns. A netns-aware
|
||||
driver/device would not set this flag and be responsible for partitioning
|
||||
hardware to preserve netns containment. This means hardware cannot forward
|
||||
|
@ -158,7 +158,8 @@ SOF_TIMESTAMPING_SYS_HARDWARE:
|
||||
|
||||
SOF_TIMESTAMPING_RAW_HARDWARE:
|
||||
Report hardware timestamps as generated by
|
||||
SOF_TIMESTAMPING_TX_HARDWARE when available.
|
||||
SOF_TIMESTAMPING_TX_HARDWARE or SOF_TIMESTAMPING_RX_HARDWARE
|
||||
when available.
|
||||
|
||||
|
||||
1.3.3 Timestamp Options
|
||||
@ -266,6 +267,23 @@ SOF_TIMESTAMPING_OPT_TX_SWHW:
|
||||
two separate messages will be looped to the socket's error queue,
|
||||
each containing just one timestamp.
|
||||
|
||||
SOF_TIMESTAMPING_OPT_RX_FILTER:
|
||||
Filter out spurious receive timestamps: report a receive timestamp
|
||||
only if the matching timestamp generation flag is enabled.
|
||||
|
||||
Receive timestamps are generated early in the ingress path, before a
|
||||
packet's destination socket is known. If any socket enables receive
|
||||
timestamps, packets for all socket will receive timestamped packets.
|
||||
Including those that request timestamp reporting with
|
||||
SOF_TIMESTAMPING_SOFTWARE and/or SOF_TIMESTAMPING_RAW_HARDWARE, but
|
||||
do not request receive timestamp generation. This can happen when
|
||||
requesting transmit timestamps only.
|
||||
|
||||
Receiving spurious timestamps is generally benign. A process can
|
||||
ignore the unexpected non-zero value. But it makes behavior subtly
|
||||
dependent on other sockets. This flag isolates the socket for more
|
||||
deterministic behavior.
|
||||
|
||||
New applications are encouraged to pass SOF_TIMESTAMPING_OPT_ID to
|
||||
disambiguate timestamps and SOF_TIMESTAMPING_OPT_TSONLY to operate
|
||||
regardless of the setting of sysctl net.core.tstamp_allow_data.
|
||||
|
69
MAINTAINERS
69
MAINTAINERS
@ -1153,6 +1153,13 @@ S: Supported
|
||||
F: arch/arm64/boot/dts/amd/amd-seattle-xgbe*.dtsi
|
||||
F: drivers/net/ethernet/amd/xgbe/
|
||||
|
||||
AMLOGIC BLUETOOTH DRIVER
|
||||
M: Yang Li <yang.li@amlogic.com>
|
||||
L: linux-bluetooth@vger.kernel.org
|
||||
S: Maintained
|
||||
F: Documentation/devicetree/bindings/net/bluetooth/amlogic,w155s2-bt.yaml
|
||||
F: drivers/bluetooth/hci_aml.c
|
||||
|
||||
AMLOGIC DDR PMU DRIVER
|
||||
M: Jiucheng Xu <jiucheng.xu@amlogic.com>
|
||||
L: linux-amlogic@lists.infradead.org
|
||||
@ -1609,6 +1616,14 @@ F: Documentation/admin-guide/perf/xgene-pmu.rst
|
||||
F: Documentation/devicetree/bindings/perf/apm-xgene-pmu.txt
|
||||
F: drivers/perf/xgene_pmu.c
|
||||
|
||||
APPLIED MICRO QT2025 PHY DRIVER
|
||||
M: FUJITA Tomonori <fujita.tomonori@gmail.com>
|
||||
R: Trevor Gross <tmgross@umich.edu>
|
||||
L: netdev@vger.kernel.org
|
||||
L: rust-for-linux@vger.kernel.org
|
||||
S: Maintained
|
||||
F: drivers/net/phy/qt2025.rs
|
||||
|
||||
APTINA CAMERA SENSOR PLL
|
||||
M: Laurent Pinchart <Laurent.pinchart@ideasonboard.com>
|
||||
L: linux-media@vger.kernel.org
|
||||
@ -8345,6 +8360,7 @@ F: include/linux/mii.h
|
||||
F: include/linux/of_net.h
|
||||
F: include/linux/phy.h
|
||||
F: include/linux/phy_fixed.h
|
||||
F: include/linux/phy_link_topology.h
|
||||
F: include/linux/phylib_stubs.h
|
||||
F: include/linux/platform_data/mdio-bcm-unimac.h
|
||||
F: include/linux/platform_data/mdio-gpio.h
|
||||
@ -8360,6 +8376,7 @@ L: netdev@vger.kernel.org
|
||||
L: rust-for-linux@vger.kernel.org
|
||||
S: Maintained
|
||||
F: rust/kernel/net/phy.rs
|
||||
F: rust/kernel/net/phy/reg.rs
|
||||
|
||||
EXEC & BINFMT API, ELF
|
||||
R: Eric Biederman <ebiederm@xmission.com>
|
||||
@ -13576,7 +13593,6 @@ M: Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>
|
||||
L: netdev@vger.kernel.org
|
||||
S: Maintained
|
||||
F: drivers/net/ethernet/marvell/mv643xx_eth.*
|
||||
F: include/linux/mv643xx.h
|
||||
|
||||
MARVELL MV88X3310 PHY DRIVER
|
||||
M: Russell King <linux@armlinux.org.uk>
|
||||
@ -14507,7 +14523,7 @@ MELLANOX ETHERNET DRIVER (mlx4_en)
|
||||
M: Tariq Toukan <tariqt@nvidia.com>
|
||||
L: netdev@vger.kernel.org
|
||||
S: Supported
|
||||
W: http://www.mellanox.com
|
||||
W: https://www.nvidia.com/networking/
|
||||
Q: https://patchwork.kernel.org/project/netdevbpf/list/
|
||||
F: drivers/net/ethernet/mellanox/mlx4/en_*
|
||||
|
||||
@ -14516,7 +14532,7 @@ M: Saeed Mahameed <saeedm@nvidia.com>
|
||||
M: Tariq Toukan <tariqt@nvidia.com>
|
||||
L: netdev@vger.kernel.org
|
||||
S: Supported
|
||||
W: http://www.mellanox.com
|
||||
W: https://www.nvidia.com/networking/
|
||||
Q: https://patchwork.kernel.org/project/netdevbpf/list/
|
||||
F: drivers/net/ethernet/mellanox/mlx5/core/en_*
|
||||
|
||||
@ -14524,7 +14540,7 @@ MELLANOX ETHERNET INNOVA DRIVERS
|
||||
R: Boris Pismenny <borisp@nvidia.com>
|
||||
L: netdev@vger.kernel.org
|
||||
S: Supported
|
||||
W: http://www.mellanox.com
|
||||
W: https://www.nvidia.com/networking/
|
||||
Q: https://patchwork.kernel.org/project/netdevbpf/list/
|
||||
F: drivers/net/ethernet/mellanox/mlx5/core/en_accel/*
|
||||
F: drivers/net/ethernet/mellanox/mlx5/core/fpga/*
|
||||
@ -14535,7 +14551,7 @@ M: Ido Schimmel <idosch@nvidia.com>
|
||||
M: Petr Machata <petrm@nvidia.com>
|
||||
L: netdev@vger.kernel.org
|
||||
S: Supported
|
||||
W: http://www.mellanox.com
|
||||
W: https://www.nvidia.com/networking/
|
||||
Q: https://patchwork.kernel.org/project/netdevbpf/list/
|
||||
F: drivers/net/ethernet/mellanox/mlxsw/
|
||||
F: tools/testing/selftests/drivers/net/mlxsw/
|
||||
@ -14544,7 +14560,7 @@ MELLANOX FIRMWARE FLASH LIBRARY (mlxfw)
|
||||
M: mlxsw@nvidia.com
|
||||
L: netdev@vger.kernel.org
|
||||
S: Supported
|
||||
W: http://www.mellanox.com
|
||||
W: https://www.nvidia.com/networking/
|
||||
Q: https://patchwork.kernel.org/project/netdevbpf/list/
|
||||
F: drivers/net/ethernet/mellanox/mlxfw/
|
||||
|
||||
@ -14563,7 +14579,7 @@ M: Tariq Toukan <tariqt@nvidia.com>
|
||||
L: netdev@vger.kernel.org
|
||||
L: linux-rdma@vger.kernel.org
|
||||
S: Supported
|
||||
W: http://www.mellanox.com
|
||||
W: https://www.nvidia.com/networking/
|
||||
Q: https://patchwork.kernel.org/project/netdevbpf/list/
|
||||
F: drivers/net/ethernet/mellanox/mlx4/
|
||||
F: include/linux/mlx4/
|
||||
@ -14572,7 +14588,7 @@ MELLANOX MLX4 IB driver
|
||||
M: Yishai Hadas <yishaih@nvidia.com>
|
||||
L: linux-rdma@vger.kernel.org
|
||||
S: Supported
|
||||
W: http://www.mellanox.com
|
||||
W: https://www.nvidia.com/networking/
|
||||
Q: http://patchwork.kernel.org/project/linux-rdma/list/
|
||||
F: drivers/infiniband/hw/mlx4/
|
||||
F: include/linux/mlx4/
|
||||
@ -14585,7 +14601,7 @@ M: Tariq Toukan <tariqt@nvidia.com>
|
||||
L: netdev@vger.kernel.org
|
||||
L: linux-rdma@vger.kernel.org
|
||||
S: Supported
|
||||
W: http://www.mellanox.com
|
||||
W: https://www.nvidia.com/networking/
|
||||
Q: https://patchwork.kernel.org/project/netdevbpf/list/
|
||||
F: Documentation/networking/device_drivers/ethernet/mellanox/
|
||||
F: drivers/net/ethernet/mellanox/mlx5/core/
|
||||
@ -14595,7 +14611,7 @@ MELLANOX MLX5 IB driver
|
||||
M: Leon Romanovsky <leonro@nvidia.com>
|
||||
L: linux-rdma@vger.kernel.org
|
||||
S: Supported
|
||||
W: http://www.mellanox.com
|
||||
W: https://www.nvidia.com/networking/
|
||||
Q: http://patchwork.kernel.org/project/linux-rdma/list/
|
||||
F: drivers/infiniband/hw/mlx5/
|
||||
F: include/linux/mlx5/
|
||||
@ -14823,6 +14839,7 @@ M: Alexander Duyck <alexanderduyck@fb.com>
|
||||
M: Jakub Kicinski <kuba@kernel.org>
|
||||
R: kernel-team@meta.com
|
||||
S: Supported
|
||||
F: Documentation/networking/device_drivers/ethernet/meta/
|
||||
F: drivers/net/ethernet/meta/
|
||||
|
||||
METHODE UDPU SUPPORT
|
||||
@ -14969,6 +14986,13 @@ L: netdev@vger.kernel.org
|
||||
S: Maintained
|
||||
F: drivers/net/ethernet/microchip/lan743x_*
|
||||
|
||||
MICROCHIP LAN8650/1 10BASE-T1S MACPHY ETHERNET DRIVER
|
||||
M: Parthiban Veerasooran <parthiban.veerasooran@microchip.com>
|
||||
L: netdev@vger.kernel.org
|
||||
S: Maintained
|
||||
F: Documentation/devicetree/bindings/net/microchip,lan8650.yaml
|
||||
F: drivers/net/ethernet/microchip/lan865x/lan865x.c
|
||||
|
||||
MICROCHIP LAN87xx/LAN937x T1 PHY DRIVER
|
||||
M: Arun Ramadoss <arun.ramadoss@microchip.com>
|
||||
R: UNGLinuxDriver@microchip.com
|
||||
@ -15788,6 +15812,7 @@ M: Breno Leitao <leitao@debian.org>
|
||||
S: Maintained
|
||||
F: Documentation/networking/netconsole.rst
|
||||
F: drivers/net/netconsole.c
|
||||
F: tools/testing/selftests/drivers/net/netcons_basic.sh
|
||||
|
||||
NETDEVSIM
|
||||
M: Jakub Kicinski <kuba@kernel.org>
|
||||
@ -17101,6 +17126,14 @@ L: linux-rdma@vger.kernel.org
|
||||
S: Supported
|
||||
F: drivers/infiniband/ulp/opa_vnic
|
||||
|
||||
OPEN ALLIANCE 10BASE-T1S MACPHY SERIAL INTERFACE FRAMEWORK
|
||||
M: Parthiban Veerasooran <parthiban.veerasooran@microchip.com>
|
||||
L: netdev@vger.kernel.org
|
||||
S: Maintained
|
||||
F: Documentation/networking/oa-tc6-framework.rst
|
||||
F: drivers/include/linux/oa_tc6.h
|
||||
F: drivers/net/ethernet/oa_tc6.c
|
||||
|
||||
OPEN FIRMWARE AND FLATTENED DEVICE TREE
|
||||
M: Rob Herring <robh@kernel.org>
|
||||
M: Saravana Kannan <saravanak@google.com>
|
||||
@ -19237,6 +19270,7 @@ S: Supported
|
||||
W: https://oss.oracle.com/projects/rds/
|
||||
F: Documentation/networking/rds.rst
|
||||
F: net/rds/
|
||||
F: tools/testing/selftests/net/rds/
|
||||
|
||||
RDT - RESOURCE ALLOCATION
|
||||
M: Fenghua Yu <fenghua.yu@intel.com>
|
||||
@ -19739,6 +19773,14 @@ F: Documentation/ABI/*/sysfs-driver-hid-roccat*
|
||||
F: drivers/hid/hid-roccat*
|
||||
F: include/linux/hid-roccat*
|
||||
|
||||
ROCKCHIP CAN-FD DRIVER
|
||||
M: Marc Kleine-Budde <mkl@pengutronix.de>
|
||||
R: kernel@pengutronix.de
|
||||
L: linux-can@vger.kernel.org
|
||||
S: Maintained
|
||||
F: Documentation/devicetree/bindings/net/can/rockchip,rk3568v2-canfd.yaml
|
||||
F: drivers/net/can/rockchip/
|
||||
|
||||
ROCKCHIP CRYPTO DRIVERS
|
||||
M: Corentin Labbe <clabbe@baylibre.com>
|
||||
L: linux-crypto@vger.kernel.org
|
||||
@ -19887,6 +19929,13 @@ L: linux-remoteproc@vger.kernel.org
|
||||
S: Maintained
|
||||
F: drivers/tty/rpmsg_tty.c
|
||||
|
||||
RTASE ETHERNET DRIVER
|
||||
M: Justin Lai <justinlai0215@realtek.com>
|
||||
M: Larry Chiu <larry.chiu@realtek.com>
|
||||
L: netdev@vger.kernel.org
|
||||
S: Maintained
|
||||
F: drivers/net/ethernet/realtek/rtase/
|
||||
|
||||
RTL2830 MEDIA DRIVER
|
||||
L: linux-media@vger.kernel.org
|
||||
S: Orphan
|
||||
|
@ -140,6 +140,12 @@
|
||||
#define SO_PASSPIDFD 76
|
||||
#define SO_PEERPIDFD 77
|
||||
|
||||
#define SO_DEVMEM_LINEAR 78
|
||||
#define SCM_DEVMEM_LINEAR SO_DEVMEM_LINEAR
|
||||
#define SO_DEVMEM_DMABUF 79
|
||||
#define SCM_DEVMEM_DMABUF SO_DEVMEM_DMABUF
|
||||
#define SO_DEVMEM_DONTNEED 80
|
||||
|
||||
#if !defined(__KERNEL__)
|
||||
|
||||
#if __BITS_PER_LONG == 64
|
||||
|
@ -151,6 +151,12 @@
|
||||
#define SO_PASSPIDFD 76
|
||||
#define SO_PEERPIDFD 77
|
||||
|
||||
#define SO_DEVMEM_LINEAR 78
|
||||
#define SCM_DEVMEM_LINEAR SO_DEVMEM_LINEAR
|
||||
#define SO_DEVMEM_DMABUF 79
|
||||
#define SCM_DEVMEM_DMABUF SO_DEVMEM_DMABUF
|
||||
#define SO_DEVMEM_DONTNEED 80
|
||||
|
||||
#if !defined(__KERNEL__)
|
||||
|
||||
#if __BITS_PER_LONG == 64
|
||||
|
@ -132,6 +132,12 @@
|
||||
#define SO_PASSPIDFD 0x404A
|
||||
#define SO_PEERPIDFD 0x404B
|
||||
|
||||
#define SO_DEVMEM_LINEAR 78
|
||||
#define SCM_DEVMEM_LINEAR SO_DEVMEM_LINEAR
|
||||
#define SO_DEVMEM_DMABUF 79
|
||||
#define SCM_DEVMEM_DMABUF SO_DEVMEM_DMABUF
|
||||
#define SO_DEVMEM_DONTNEED 80
|
||||
|
||||
#if !defined(__KERNEL__)
|
||||
|
||||
#if __BITS_PER_LONG == 64
|
||||
|
@ -14,7 +14,7 @@
|
||||
#include <linux/ioport.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/mv643xx.h>
|
||||
#include <linux/mv643xx_eth.h>
|
||||
#include <linux/pci.h>
|
||||
|
||||
#define PEGASOS2_MARVELL_REGBASE (0xf1000000)
|
||||
@ -25,12 +25,15 @@
|
||||
#define PEGASOS2_SRAM_BASE_ETH_PORT0 (PEGASOS2_SRAM_BASE)
|
||||
#define PEGASOS2_SRAM_BASE_ETH_PORT1 (PEGASOS2_SRAM_BASE_ETH_PORT0 + (PEGASOS2_SRAM_SIZE / 2) )
|
||||
|
||||
|
||||
#define PEGASOS2_SRAM_RXRING_SIZE (PEGASOS2_SRAM_SIZE/4)
|
||||
#define PEGASOS2_SRAM_TXRING_SIZE (PEGASOS2_SRAM_SIZE/4)
|
||||
|
||||
#undef BE_VERBOSE
|
||||
|
||||
#define MV64340_BASE_ADDR_ENABLE 0x278
|
||||
#define MV64340_INTEGRATED_SRAM_BASE_ADDR 0x268
|
||||
#define MV64340_SRAM_CONFIG 0x380
|
||||
|
||||
static struct resource mv643xx_eth_shared_resources[] = {
|
||||
[0] = {
|
||||
.name = "ethernet shared base",
|
||||
|
@ -133,6 +133,12 @@
|
||||
#define SO_PASSPIDFD 0x0055
|
||||
#define SO_PEERPIDFD 0x0056
|
||||
|
||||
#define SO_DEVMEM_LINEAR 0x0057
|
||||
#define SCM_DEVMEM_LINEAR SO_DEVMEM_LINEAR
|
||||
#define SO_DEVMEM_DMABUF 0x0058
|
||||
#define SCM_DEVMEM_DMABUF SO_DEVMEM_DMABUF
|
||||
#define SO_DEVMEM_DONTNEED 0x0059
|
||||
|
||||
#if !defined(__KERNEL__)
|
||||
|
||||
|
||||
|
@ -274,6 +274,18 @@ config BT_HCIUART_MRVL
|
||||
|
||||
Say Y here to compile support for HCI MRVL protocol.
|
||||
|
||||
config BT_HCIUART_AML
|
||||
bool "Amlogic protocol support"
|
||||
depends on BT_HCIUART
|
||||
depends on BT_HCIUART_SERDEV
|
||||
select BT_HCIUART_H4
|
||||
select FW_LOADER
|
||||
help
|
||||
The Amlogic protocol support enables Bluetooth HCI over serial
|
||||
port interface for Amlogic Bluetooth controllers.
|
||||
|
||||
Say Y here to compile support for HCI AML protocol.
|
||||
|
||||
config BT_HCIBCM203X
|
||||
tristate "HCI BCM203x USB driver"
|
||||
depends on USB
|
||||
|
@ -51,4 +51,5 @@ hci_uart-$(CONFIG_BT_HCIUART_BCM) += hci_bcm.o
|
||||
hci_uart-$(CONFIG_BT_HCIUART_QCA) += hci_qca.o
|
||||
hci_uart-$(CONFIG_BT_HCIUART_AG6XX) += hci_ag6xx.o
|
||||
hci_uart-$(CONFIG_BT_HCIUART_MRVL) += hci_mrvl.o
|
||||
hci_uart-$(CONFIG_BT_HCIUART_AML) += hci_aml.o
|
||||
hci_uart-objs := $(hci_uart-y)
|
||||
|
@ -46,6 +46,7 @@ MODULE_DEVICE_TABLE(pci, btintel_pcie_table);
|
||||
#define BTINTEL_PCIE_HCI_ACL_PKT 0x00000002
|
||||
#define BTINTEL_PCIE_HCI_SCO_PKT 0x00000003
|
||||
#define BTINTEL_PCIE_HCI_EVT_PKT 0x00000004
|
||||
#define BTINTEL_PCIE_HCI_ISO_PKT 0x00000005
|
||||
|
||||
static inline void ipc_print_ia_ring(struct hci_dev *hdev, struct ia *ia,
|
||||
u16 queue_num)
|
||||
@ -423,6 +424,18 @@ static int btintel_pcie_recv_frame(struct btintel_pcie_data *data,
|
||||
goto exit_error;
|
||||
}
|
||||
break;
|
||||
|
||||
case BTINTEL_PCIE_HCI_ISO_PKT:
|
||||
if (skb->len >= HCI_ISO_HDR_SIZE) {
|
||||
plen = HCI_ISO_HDR_SIZE + __le16_to_cpu(hci_iso_hdr(skb)->dlen);
|
||||
pkt_type = HCI_ISODATA_PKT;
|
||||
} else {
|
||||
bt_dev_err(hdev, "ISO packet is too short");
|
||||
ret = -EILSEQ;
|
||||
goto exit_error;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
bt_dev_err(hdev, "Invalid packet type received: 0x%4.4x",
|
||||
pcie_pkt_type);
|
||||
@ -1082,6 +1095,9 @@ static int btintel_pcie_send_frame(struct hci_dev *hdev,
|
||||
type = BTINTEL_PCIE_HCI_SCO_PKT;
|
||||
hdev->stat.sco_tx++;
|
||||
break;
|
||||
case HCI_ISODATA_PKT:
|
||||
type = BTINTEL_PCIE_HCI_ISO_PKT;
|
||||
break;
|
||||
default:
|
||||
bt_dev_err(hdev, "Unknown HCI packet type");
|
||||
return -EILSEQ;
|
||||
@ -1208,7 +1224,7 @@ static int btintel_pcie_setup_hdev(struct btintel_pcie_data *data)
|
||||
int err;
|
||||
struct hci_dev *hdev;
|
||||
|
||||
hdev = hci_alloc_dev();
|
||||
hdev = hci_alloc_dev_priv(sizeof(struct btintel_data));
|
||||
if (!hdev)
|
||||
return -ENOMEM;
|
||||
|
||||
|
@ -1412,6 +1412,7 @@ static const struct h4_recv_pkt nxp_recv_pkts[] = {
|
||||
{ H4_RECV_ACL, .recv = hci_recv_frame },
|
||||
{ H4_RECV_SCO, .recv = hci_recv_frame },
|
||||
{ H4_RECV_EVENT, .recv = hci_recv_frame },
|
||||
{ H4_RECV_ISO, .recv = hci_recv_frame },
|
||||
{ NXP_RECV_CHIP_VER_V1, .recv = nxp_recv_chip_ver_v1 },
|
||||
{ NXP_RECV_FW_REQ_V1, .recv = nxp_recv_fw_req_v1 },
|
||||
{ NXP_RECV_CHIP_VER_V3, .recv = nxp_recv_chip_ver_v3 },
|
||||
|
@ -30,6 +30,7 @@
|
||||
#define RTL_ROM_LMP_8822B 0x8822
|
||||
#define RTL_ROM_LMP_8852A 0x8852
|
||||
#define RTL_ROM_LMP_8851B 0x8851
|
||||
#define RTL_ROM_LMP_8922A 0x8922
|
||||
#define RTL_CONFIG_MAGIC 0x8723ab55
|
||||
|
||||
#define RTL_VSC_OP_COREDUMP 0xfcff
|
||||
@ -69,6 +70,7 @@ enum btrtl_chip_id {
|
||||
CHIP_ID_8852B = 20,
|
||||
CHIP_ID_8852C = 25,
|
||||
CHIP_ID_8851B = 36,
|
||||
CHIP_ID_8922A = 44,
|
||||
CHIP_ID_8852BT = 47,
|
||||
};
|
||||
|
||||
@ -309,6 +311,15 @@ static const struct id_table ic_id_table[] = {
|
||||
.cfg_name = "rtl_bt/rtl8851bu_config",
|
||||
.hw_info = "rtl8851bu" },
|
||||
|
||||
/* 8922A */
|
||||
{ IC_INFO(RTL_ROM_LMP_8922A, 0xa, 0xc, HCI_USB),
|
||||
.config_needed = false,
|
||||
.has_rom_version = true,
|
||||
.has_msft_ext = true,
|
||||
.fw_name = "rtl_bt/rtl8922au_fw",
|
||||
.cfg_name = "rtl_bt/rtl8922au_config",
|
||||
.hw_info = "rtl8922au" },
|
||||
|
||||
/* 8852BT/8852BE-VT */
|
||||
{ IC_INFO(RTL_ROM_LMP_8852A, 0x87, 0xc, HCI_USB),
|
||||
.config_needed = false,
|
||||
@ -655,6 +666,7 @@ static int rtlbt_parse_firmware(struct hci_dev *hdev,
|
||||
{ RTL_ROM_LMP_8852A, 20 }, /* 8852B */
|
||||
{ RTL_ROM_LMP_8852A, 25 }, /* 8852C */
|
||||
{ RTL_ROM_LMP_8851B, 36 }, /* 8851B */
|
||||
{ RTL_ROM_LMP_8922A, 44 }, /* 8922A */
|
||||
{ RTL_ROM_LMP_8852A, 47 }, /* 8852BT */
|
||||
};
|
||||
|
||||
@ -878,10 +890,8 @@ static int rtl_load_file(struct hci_dev *hdev, const char *name, u8 **buff)
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
ret = fw->size;
|
||||
*buff = kvmalloc(fw->size, GFP_KERNEL);
|
||||
if (*buff)
|
||||
memcpy(*buff, fw->data, ret);
|
||||
else
|
||||
*buff = kvmemdup(fw->data, fw->size, GFP_KERNEL);
|
||||
if (!*buff)
|
||||
ret = -ENOMEM;
|
||||
|
||||
release_firmware(fw);
|
||||
@ -1255,6 +1265,7 @@ int btrtl_download_firmware(struct hci_dev *hdev,
|
||||
case RTL_ROM_LMP_8852A:
|
||||
case RTL_ROM_LMP_8703B:
|
||||
case RTL_ROM_LMP_8851B:
|
||||
case RTL_ROM_LMP_8922A:
|
||||
err = btrtl_setup_rtl8723b(hdev, btrtl_dev);
|
||||
break;
|
||||
default:
|
||||
@ -1286,6 +1297,7 @@ void btrtl_set_quirks(struct hci_dev *hdev, struct btrtl_device_info *btrtl_dev)
|
||||
case CHIP_ID_8852B:
|
||||
case CHIP_ID_8852C:
|
||||
case CHIP_ID_8851B:
|
||||
case CHIP_ID_8922A:
|
||||
case CHIP_ID_8852BT:
|
||||
set_bit(HCI_QUIRK_WIDEBAND_SPEECH_SUPPORTED, &hdev->quirks);
|
||||
|
||||
@ -1296,6 +1308,7 @@ void btrtl_set_quirks(struct hci_dev *hdev, struct btrtl_device_info *btrtl_dev)
|
||||
btrealtek_set_flag(hdev, REALTEK_ALT6_CONTINUOUS_TX_CHIP);
|
||||
|
||||
if (btrtl_dev->project_id == CHIP_ID_8852A ||
|
||||
btrtl_dev->project_id == CHIP_ID_8852B ||
|
||||
btrtl_dev->project_id == CHIP_ID_8852C)
|
||||
set_bit(HCI_QUIRK_USE_MSFT_EXT_ADDRESS_FILTER, &hdev->quirks);
|
||||
|
||||
@ -1528,3 +1541,5 @@ MODULE_FIRMWARE("rtl_bt/rtl8852btu_config.bin");
|
||||
MODULE_FIRMWARE("rtl_bt/rtl8852cu_fw.bin");
|
||||
MODULE_FIRMWARE("rtl_bt/rtl8852cu_fw_v2.bin");
|
||||
MODULE_FIRMWARE("rtl_bt/rtl8852cu_config.bin");
|
||||
MODULE_FIRMWARE("rtl_bt/rtl8922au_fw.bin");
|
||||
MODULE_FIRMWARE("rtl_bt/rtl8922au_config.bin");
|
||||
|
@ -295,6 +295,7 @@ static int btsdio_probe(struct sdio_func *func,
|
||||
case SDIO_DEVICE_ID_BROADCOM_4345:
|
||||
case SDIO_DEVICE_ID_BROADCOM_43455:
|
||||
case SDIO_DEVICE_ID_BROADCOM_4356:
|
||||
case SDIO_DEVICE_ID_BROADCOM_CYPRESS_4373:
|
||||
return -ENODEV;
|
||||
}
|
||||
}
|
||||
|
@ -59,7 +59,7 @@ static struct usb_driver btusb_driver;
|
||||
#define BTUSB_CW6622 BIT(19)
|
||||
#define BTUSB_MEDIATEK BIT(20)
|
||||
#define BTUSB_WIDEBAND_SPEECH BIT(21)
|
||||
#define BTUSB_VALID_LE_STATES BIT(22)
|
||||
#define BTUSB_INVALID_LE_STATES BIT(22)
|
||||
#define BTUSB_QCA_WCN6855 BIT(23)
|
||||
#define BTUSB_INTEL_BROKEN_SHUTDOWN_LED BIT(24)
|
||||
#define BTUSB_INTEL_BROKEN_INITIAL_NCMD BIT(25)
|
||||
@ -298,115 +298,79 @@ static const struct usb_device_id quirks_table[] = {
|
||||
|
||||
/* QCA WCN6855 chipset */
|
||||
{ USB_DEVICE(0x0cf3, 0xe600), .driver_info = BTUSB_QCA_WCN6855 |
|
||||
BTUSB_WIDEBAND_SPEECH |
|
||||
BTUSB_VALID_LE_STATES },
|
||||
BTUSB_WIDEBAND_SPEECH },
|
||||
{ USB_DEVICE(0x0489, 0xe0cc), .driver_info = BTUSB_QCA_WCN6855 |
|
||||
BTUSB_WIDEBAND_SPEECH |
|
||||
BTUSB_VALID_LE_STATES },
|
||||
BTUSB_WIDEBAND_SPEECH },
|
||||
{ USB_DEVICE(0x0489, 0xe0d6), .driver_info = BTUSB_QCA_WCN6855 |
|
||||
BTUSB_WIDEBAND_SPEECH |
|
||||
BTUSB_VALID_LE_STATES },
|
||||
BTUSB_WIDEBAND_SPEECH },
|
||||
{ USB_DEVICE(0x0489, 0xe0e3), .driver_info = BTUSB_QCA_WCN6855 |
|
||||
BTUSB_WIDEBAND_SPEECH |
|
||||
BTUSB_VALID_LE_STATES },
|
||||
BTUSB_WIDEBAND_SPEECH },
|
||||
{ USB_DEVICE(0x10ab, 0x9309), .driver_info = BTUSB_QCA_WCN6855 |
|
||||
BTUSB_WIDEBAND_SPEECH |
|
||||
BTUSB_VALID_LE_STATES },
|
||||
BTUSB_WIDEBAND_SPEECH },
|
||||
{ USB_DEVICE(0x10ab, 0x9409), .driver_info = BTUSB_QCA_WCN6855 |
|
||||
BTUSB_WIDEBAND_SPEECH |
|
||||
BTUSB_VALID_LE_STATES },
|
||||
BTUSB_WIDEBAND_SPEECH },
|
||||
{ USB_DEVICE(0x0489, 0xe0d0), .driver_info = BTUSB_QCA_WCN6855 |
|
||||
BTUSB_WIDEBAND_SPEECH |
|
||||
BTUSB_VALID_LE_STATES },
|
||||
BTUSB_WIDEBAND_SPEECH },
|
||||
{ USB_DEVICE(0x10ab, 0x9108), .driver_info = BTUSB_QCA_WCN6855 |
|
||||
BTUSB_WIDEBAND_SPEECH |
|
||||
BTUSB_VALID_LE_STATES },
|
||||
BTUSB_WIDEBAND_SPEECH },
|
||||
{ USB_DEVICE(0x10ab, 0x9109), .driver_info = BTUSB_QCA_WCN6855 |
|
||||
BTUSB_WIDEBAND_SPEECH |
|
||||
BTUSB_VALID_LE_STATES },
|
||||
BTUSB_WIDEBAND_SPEECH },
|
||||
{ USB_DEVICE(0x10ab, 0x9208), .driver_info = BTUSB_QCA_WCN6855 |
|
||||
BTUSB_WIDEBAND_SPEECH |
|
||||
BTUSB_VALID_LE_STATES },
|
||||
BTUSB_WIDEBAND_SPEECH },
|
||||
{ USB_DEVICE(0x10ab, 0x9209), .driver_info = BTUSB_QCA_WCN6855 |
|
||||
BTUSB_WIDEBAND_SPEECH |
|
||||
BTUSB_VALID_LE_STATES },
|
||||
BTUSB_WIDEBAND_SPEECH },
|
||||
{ USB_DEVICE(0x10ab, 0x9308), .driver_info = BTUSB_QCA_WCN6855 |
|
||||
BTUSB_WIDEBAND_SPEECH |
|
||||
BTUSB_VALID_LE_STATES },
|
||||
BTUSB_WIDEBAND_SPEECH },
|
||||
{ USB_DEVICE(0x10ab, 0x9408), .driver_info = BTUSB_QCA_WCN6855 |
|
||||
BTUSB_WIDEBAND_SPEECH |
|
||||
BTUSB_VALID_LE_STATES },
|
||||
BTUSB_WIDEBAND_SPEECH },
|
||||
{ USB_DEVICE(0x10ab, 0x9508), .driver_info = BTUSB_QCA_WCN6855 |
|
||||
BTUSB_WIDEBAND_SPEECH |
|
||||
BTUSB_VALID_LE_STATES },
|
||||
BTUSB_WIDEBAND_SPEECH },
|
||||
{ USB_DEVICE(0x10ab, 0x9509), .driver_info = BTUSB_QCA_WCN6855 |
|
||||
BTUSB_WIDEBAND_SPEECH |
|
||||
BTUSB_VALID_LE_STATES },
|
||||
BTUSB_WIDEBAND_SPEECH },
|
||||
{ USB_DEVICE(0x10ab, 0x9608), .driver_info = BTUSB_QCA_WCN6855 |
|
||||
BTUSB_WIDEBAND_SPEECH |
|
||||
BTUSB_VALID_LE_STATES },
|
||||
BTUSB_WIDEBAND_SPEECH },
|
||||
{ USB_DEVICE(0x10ab, 0x9609), .driver_info = BTUSB_QCA_WCN6855 |
|
||||
BTUSB_WIDEBAND_SPEECH |
|
||||
BTUSB_VALID_LE_STATES },
|
||||
BTUSB_WIDEBAND_SPEECH },
|
||||
{ USB_DEVICE(0x10ab, 0x9f09), .driver_info = BTUSB_QCA_WCN6855 |
|
||||
BTUSB_WIDEBAND_SPEECH |
|
||||
BTUSB_VALID_LE_STATES },
|
||||
BTUSB_WIDEBAND_SPEECH },
|
||||
{ USB_DEVICE(0x04ca, 0x3022), .driver_info = BTUSB_QCA_WCN6855 |
|
||||
BTUSB_WIDEBAND_SPEECH |
|
||||
BTUSB_VALID_LE_STATES },
|
||||
BTUSB_WIDEBAND_SPEECH },
|
||||
{ USB_DEVICE(0x0489, 0xe0c7), .driver_info = BTUSB_QCA_WCN6855 |
|
||||
BTUSB_WIDEBAND_SPEECH |
|
||||
BTUSB_VALID_LE_STATES },
|
||||
BTUSB_WIDEBAND_SPEECH },
|
||||
{ USB_DEVICE(0x0489, 0xe0c9), .driver_info = BTUSB_QCA_WCN6855 |
|
||||
BTUSB_WIDEBAND_SPEECH |
|
||||
BTUSB_VALID_LE_STATES },
|
||||
BTUSB_WIDEBAND_SPEECH },
|
||||
{ USB_DEVICE(0x0489, 0xe0ca), .driver_info = BTUSB_QCA_WCN6855 |
|
||||
BTUSB_WIDEBAND_SPEECH |
|
||||
BTUSB_VALID_LE_STATES },
|
||||
BTUSB_WIDEBAND_SPEECH },
|
||||
{ USB_DEVICE(0x0489, 0xe0cb), .driver_info = BTUSB_QCA_WCN6855 |
|
||||
BTUSB_WIDEBAND_SPEECH |
|
||||
BTUSB_VALID_LE_STATES },
|
||||
BTUSB_WIDEBAND_SPEECH },
|
||||
{ USB_DEVICE(0x0489, 0xe0ce), .driver_info = BTUSB_QCA_WCN6855 |
|
||||
BTUSB_WIDEBAND_SPEECH |
|
||||
BTUSB_VALID_LE_STATES },
|
||||
BTUSB_WIDEBAND_SPEECH },
|
||||
{ USB_DEVICE(0x0489, 0xe0de), .driver_info = BTUSB_QCA_WCN6855 |
|
||||
BTUSB_WIDEBAND_SPEECH |
|
||||
BTUSB_VALID_LE_STATES },
|
||||
BTUSB_WIDEBAND_SPEECH },
|
||||
{ USB_DEVICE(0x0489, 0xe0df), .driver_info = BTUSB_QCA_WCN6855 |
|
||||
BTUSB_WIDEBAND_SPEECH |
|
||||
BTUSB_VALID_LE_STATES },
|
||||
BTUSB_WIDEBAND_SPEECH },
|
||||
{ USB_DEVICE(0x0489, 0xe0e1), .driver_info = BTUSB_QCA_WCN6855 |
|
||||
BTUSB_WIDEBAND_SPEECH |
|
||||
BTUSB_VALID_LE_STATES },
|
||||
BTUSB_WIDEBAND_SPEECH },
|
||||
{ USB_DEVICE(0x0489, 0xe0ea), .driver_info = BTUSB_QCA_WCN6855 |
|
||||
BTUSB_WIDEBAND_SPEECH |
|
||||
BTUSB_VALID_LE_STATES },
|
||||
BTUSB_WIDEBAND_SPEECH },
|
||||
{ USB_DEVICE(0x0489, 0xe0ec), .driver_info = BTUSB_QCA_WCN6855 |
|
||||
BTUSB_WIDEBAND_SPEECH |
|
||||
BTUSB_VALID_LE_STATES },
|
||||
BTUSB_WIDEBAND_SPEECH },
|
||||
{ USB_DEVICE(0x04ca, 0x3023), .driver_info = BTUSB_QCA_WCN6855 |
|
||||
BTUSB_WIDEBAND_SPEECH |
|
||||
BTUSB_VALID_LE_STATES },
|
||||
BTUSB_WIDEBAND_SPEECH },
|
||||
{ USB_DEVICE(0x04ca, 0x3024), .driver_info = BTUSB_QCA_WCN6855 |
|
||||
BTUSB_WIDEBAND_SPEECH |
|
||||
BTUSB_VALID_LE_STATES },
|
||||
BTUSB_WIDEBAND_SPEECH },
|
||||
{ USB_DEVICE(0x04ca, 0x3a22), .driver_info = BTUSB_QCA_WCN6855 |
|
||||
BTUSB_WIDEBAND_SPEECH |
|
||||
BTUSB_VALID_LE_STATES },
|
||||
BTUSB_WIDEBAND_SPEECH },
|
||||
{ USB_DEVICE(0x04ca, 0x3a24), .driver_info = BTUSB_QCA_WCN6855 |
|
||||
BTUSB_WIDEBAND_SPEECH |
|
||||
BTUSB_VALID_LE_STATES },
|
||||
BTUSB_WIDEBAND_SPEECH },
|
||||
{ USB_DEVICE(0x04ca, 0x3a26), .driver_info = BTUSB_QCA_WCN6855 |
|
||||
BTUSB_WIDEBAND_SPEECH |
|
||||
BTUSB_VALID_LE_STATES },
|
||||
BTUSB_WIDEBAND_SPEECH },
|
||||
{ USB_DEVICE(0x04ca, 0x3a27), .driver_info = BTUSB_QCA_WCN6855 |
|
||||
BTUSB_WIDEBAND_SPEECH |
|
||||
BTUSB_VALID_LE_STATES },
|
||||
BTUSB_WIDEBAND_SPEECH },
|
||||
|
||||
/* QCA WCN785x chipset */
|
||||
{ USB_DEVICE(0x0cf3, 0xe700), .driver_info = BTUSB_QCA_WCN6855 |
|
||||
BTUSB_WIDEBAND_SPEECH |
|
||||
BTUSB_VALID_LE_STATES },
|
||||
BTUSB_WIDEBAND_SPEECH },
|
||||
|
||||
/* Broadcom BCM2035 */
|
||||
{ USB_DEVICE(0x0a5c, 0x2009), .driver_info = BTUSB_BCM92035 },
|
||||
@ -540,6 +504,8 @@ static const struct usb_device_id quirks_table[] = {
|
||||
BTUSB_WIDEBAND_SPEECH },
|
||||
{ USB_DEVICE(0x13d3, 0x3592), .driver_info = BTUSB_REALTEK |
|
||||
BTUSB_WIDEBAND_SPEECH },
|
||||
{ USB_DEVICE(0x0489, 0xe122), .driver_info = BTUSB_REALTEK |
|
||||
BTUSB_WIDEBAND_SPEECH },
|
||||
|
||||
/* Realtek 8852BE Bluetooth devices */
|
||||
{ USB_DEVICE(0x0cb8, 0xc559), .driver_info = BTUSB_REALTEK |
|
||||
@ -564,6 +530,17 @@ static const struct usb_device_id quirks_table[] = {
|
||||
/* Realtek 8852BT/8852BE-VT Bluetooth devices */
|
||||
{ USB_DEVICE(0x0bda, 0x8520), .driver_info = BTUSB_REALTEK |
|
||||
BTUSB_WIDEBAND_SPEECH },
|
||||
|
||||
/* Realtek 8922AE Bluetooth devices */
|
||||
{ USB_DEVICE(0x0bda, 0x8922), .driver_info = BTUSB_REALTEK |
|
||||
BTUSB_WIDEBAND_SPEECH },
|
||||
{ USB_DEVICE(0x13d3, 0x3617), .driver_info = BTUSB_REALTEK |
|
||||
BTUSB_WIDEBAND_SPEECH },
|
||||
{ USB_DEVICE(0x13d3, 0x3616), .driver_info = BTUSB_REALTEK |
|
||||
BTUSB_WIDEBAND_SPEECH },
|
||||
{ USB_DEVICE(0x0489, 0xe130), .driver_info = BTUSB_REALTEK |
|
||||
BTUSB_WIDEBAND_SPEECH },
|
||||
|
||||
/* Realtek Bluetooth devices */
|
||||
{ USB_VENDOR_AND_INTERFACE_INFO(0x0bda, 0xe0, 0x01, 0x01),
|
||||
.driver_info = BTUSB_REALTEK },
|
||||
@ -571,131 +548,102 @@ static const struct usb_device_id quirks_table[] = {
|
||||
/* MediaTek Bluetooth devices */
|
||||
{ USB_VENDOR_AND_INTERFACE_INFO(0x0e8d, 0xe0, 0x01, 0x01),
|
||||
.driver_info = BTUSB_MEDIATEK |
|
||||
BTUSB_WIDEBAND_SPEECH |
|
||||
BTUSB_VALID_LE_STATES },
|
||||
BTUSB_WIDEBAND_SPEECH },
|
||||
|
||||
/* Additional MediaTek MT7615E Bluetooth devices */
|
||||
{ USB_DEVICE(0x13d3, 0x3560), .driver_info = BTUSB_MEDIATEK},
|
||||
|
||||
/* Additional MediaTek MT7663 Bluetooth devices */
|
||||
{ USB_DEVICE(0x043e, 0x310c), .driver_info = BTUSB_MEDIATEK |
|
||||
BTUSB_WIDEBAND_SPEECH |
|
||||
BTUSB_VALID_LE_STATES },
|
||||
BTUSB_WIDEBAND_SPEECH },
|
||||
{ USB_DEVICE(0x04ca, 0x3801), .driver_info = BTUSB_MEDIATEK |
|
||||
BTUSB_WIDEBAND_SPEECH |
|
||||
BTUSB_VALID_LE_STATES },
|
||||
BTUSB_WIDEBAND_SPEECH },
|
||||
|
||||
/* Additional MediaTek MT7668 Bluetooth devices */
|
||||
{ USB_DEVICE(0x043e, 0x3109), .driver_info = BTUSB_MEDIATEK |
|
||||
BTUSB_WIDEBAND_SPEECH |
|
||||
BTUSB_VALID_LE_STATES },
|
||||
BTUSB_WIDEBAND_SPEECH },
|
||||
|
||||
/* Additional MediaTek MT7921 Bluetooth devices */
|
||||
{ USB_DEVICE(0x0489, 0xe0c8), .driver_info = BTUSB_MEDIATEK |
|
||||
BTUSB_WIDEBAND_SPEECH |
|
||||
BTUSB_VALID_LE_STATES },
|
||||
BTUSB_WIDEBAND_SPEECH },
|
||||
{ USB_DEVICE(0x0489, 0xe0cd), .driver_info = BTUSB_MEDIATEK |
|
||||
BTUSB_WIDEBAND_SPEECH |
|
||||
BTUSB_VALID_LE_STATES },
|
||||
BTUSB_WIDEBAND_SPEECH },
|
||||
{ USB_DEVICE(0x0489, 0xe0e0), .driver_info = BTUSB_MEDIATEK |
|
||||
BTUSB_WIDEBAND_SPEECH |
|
||||
BTUSB_VALID_LE_STATES },
|
||||
BTUSB_WIDEBAND_SPEECH },
|
||||
{ USB_DEVICE(0x0489, 0xe0f2), .driver_info = BTUSB_MEDIATEK |
|
||||
BTUSB_WIDEBAND_SPEECH |
|
||||
BTUSB_VALID_LE_STATES },
|
||||
BTUSB_WIDEBAND_SPEECH },
|
||||
{ USB_DEVICE(0x04ca, 0x3802), .driver_info = BTUSB_MEDIATEK |
|
||||
BTUSB_WIDEBAND_SPEECH |
|
||||
BTUSB_VALID_LE_STATES },
|
||||
BTUSB_WIDEBAND_SPEECH },
|
||||
{ USB_DEVICE(0x0e8d, 0x0608), .driver_info = BTUSB_MEDIATEK |
|
||||
BTUSB_WIDEBAND_SPEECH |
|
||||
BTUSB_VALID_LE_STATES },
|
||||
BTUSB_WIDEBAND_SPEECH },
|
||||
{ USB_DEVICE(0x13d3, 0x3563), .driver_info = BTUSB_MEDIATEK |
|
||||
BTUSB_WIDEBAND_SPEECH |
|
||||
BTUSB_VALID_LE_STATES },
|
||||
BTUSB_WIDEBAND_SPEECH },
|
||||
{ USB_DEVICE(0x13d3, 0x3564), .driver_info = BTUSB_MEDIATEK |
|
||||
BTUSB_WIDEBAND_SPEECH |
|
||||
BTUSB_VALID_LE_STATES },
|
||||
BTUSB_WIDEBAND_SPEECH },
|
||||
{ USB_DEVICE(0x13d3, 0x3567), .driver_info = BTUSB_MEDIATEK |
|
||||
BTUSB_WIDEBAND_SPEECH |
|
||||
BTUSB_VALID_LE_STATES },
|
||||
BTUSB_WIDEBAND_SPEECH },
|
||||
{ USB_DEVICE(0x13d3, 0x3578), .driver_info = BTUSB_MEDIATEK |
|
||||
BTUSB_WIDEBAND_SPEECH |
|
||||
BTUSB_VALID_LE_STATES },
|
||||
BTUSB_WIDEBAND_SPEECH },
|
||||
{ USB_DEVICE(0x13d3, 0x3583), .driver_info = BTUSB_MEDIATEK |
|
||||
BTUSB_WIDEBAND_SPEECH |
|
||||
BTUSB_VALID_LE_STATES },
|
||||
BTUSB_WIDEBAND_SPEECH },
|
||||
{ USB_DEVICE(0x13d3, 0x3606), .driver_info = BTUSB_MEDIATEK |
|
||||
BTUSB_WIDEBAND_SPEECH |
|
||||
BTUSB_VALID_LE_STATES },
|
||||
BTUSB_WIDEBAND_SPEECH },
|
||||
|
||||
/* MediaTek MT7922 Bluetooth devices */
|
||||
{ USB_DEVICE(0x13d3, 0x3585), .driver_info = BTUSB_MEDIATEK |
|
||||
BTUSB_WIDEBAND_SPEECH |
|
||||
BTUSB_VALID_LE_STATES },
|
||||
BTUSB_WIDEBAND_SPEECH },
|
||||
|
||||
/* MediaTek MT7922A Bluetooth devices */
|
||||
{ USB_DEVICE(0x0489, 0xe0d8), .driver_info = BTUSB_MEDIATEK |
|
||||
BTUSB_WIDEBAND_SPEECH |
|
||||
BTUSB_VALID_LE_STATES },
|
||||
BTUSB_WIDEBAND_SPEECH },
|
||||
{ USB_DEVICE(0x0489, 0xe0d9), .driver_info = BTUSB_MEDIATEK |
|
||||
BTUSB_WIDEBAND_SPEECH |
|
||||
BTUSB_VALID_LE_STATES },
|
||||
BTUSB_WIDEBAND_SPEECH },
|
||||
{ USB_DEVICE(0x0489, 0xe0e2), .driver_info = BTUSB_MEDIATEK |
|
||||
BTUSB_WIDEBAND_SPEECH |
|
||||
BTUSB_VALID_LE_STATES },
|
||||
BTUSB_WIDEBAND_SPEECH },
|
||||
{ USB_DEVICE(0x0489, 0xe0e4), .driver_info = BTUSB_MEDIATEK |
|
||||
BTUSB_WIDEBAND_SPEECH |
|
||||
BTUSB_VALID_LE_STATES },
|
||||
BTUSB_WIDEBAND_SPEECH },
|
||||
{ USB_DEVICE(0x0489, 0xe0f1), .driver_info = BTUSB_MEDIATEK |
|
||||
BTUSB_WIDEBAND_SPEECH |
|
||||
BTUSB_VALID_LE_STATES },
|
||||
BTUSB_WIDEBAND_SPEECH },
|
||||
{ USB_DEVICE(0x0489, 0xe0f2), .driver_info = BTUSB_MEDIATEK |
|
||||
BTUSB_WIDEBAND_SPEECH |
|
||||
BTUSB_VALID_LE_STATES },
|
||||
BTUSB_WIDEBAND_SPEECH },
|
||||
{ USB_DEVICE(0x0489, 0xe0f5), .driver_info = BTUSB_MEDIATEK |
|
||||
BTUSB_WIDEBAND_SPEECH |
|
||||
BTUSB_VALID_LE_STATES },
|
||||
BTUSB_WIDEBAND_SPEECH },
|
||||
{ USB_DEVICE(0x0489, 0xe0f6), .driver_info = BTUSB_MEDIATEK |
|
||||
BTUSB_WIDEBAND_SPEECH |
|
||||
BTUSB_VALID_LE_STATES },
|
||||
BTUSB_WIDEBAND_SPEECH },
|
||||
{ USB_DEVICE(0x0489, 0xe102), .driver_info = BTUSB_MEDIATEK |
|
||||
BTUSB_WIDEBAND_SPEECH |
|
||||
BTUSB_VALID_LE_STATES },
|
||||
BTUSB_WIDEBAND_SPEECH },
|
||||
{ USB_DEVICE(0x04ca, 0x3804), .driver_info = BTUSB_MEDIATEK |
|
||||
BTUSB_WIDEBAND_SPEECH |
|
||||
BTUSB_VALID_LE_STATES },
|
||||
BTUSB_WIDEBAND_SPEECH },
|
||||
{ USB_DEVICE(0x04ca, 0x38e4), .driver_info = BTUSB_MEDIATEK |
|
||||
BTUSB_WIDEBAND_SPEECH |
|
||||
BTUSB_VALID_LE_STATES },
|
||||
BTUSB_WIDEBAND_SPEECH },
|
||||
{ USB_DEVICE(0x13d3, 0x3568), .driver_info = BTUSB_MEDIATEK |
|
||||
BTUSB_WIDEBAND_SPEECH |
|
||||
BTUSB_VALID_LE_STATES },
|
||||
BTUSB_WIDEBAND_SPEECH },
|
||||
{ USB_DEVICE(0x13d3, 0x3605), .driver_info = BTUSB_MEDIATEK |
|
||||
BTUSB_WIDEBAND_SPEECH |
|
||||
BTUSB_VALID_LE_STATES },
|
||||
BTUSB_WIDEBAND_SPEECH },
|
||||
{ USB_DEVICE(0x13d3, 0x3607), .driver_info = BTUSB_MEDIATEK |
|
||||
BTUSB_WIDEBAND_SPEECH |
|
||||
BTUSB_VALID_LE_STATES },
|
||||
BTUSB_WIDEBAND_SPEECH },
|
||||
{ USB_DEVICE(0x13d3, 0x3614), .driver_info = BTUSB_MEDIATEK |
|
||||
BTUSB_WIDEBAND_SPEECH |
|
||||
BTUSB_VALID_LE_STATES },
|
||||
BTUSB_WIDEBAND_SPEECH },
|
||||
{ USB_DEVICE(0x13d3, 0x3615), .driver_info = BTUSB_MEDIATEK |
|
||||
BTUSB_WIDEBAND_SPEECH |
|
||||
BTUSB_VALID_LE_STATES },
|
||||
BTUSB_WIDEBAND_SPEECH },
|
||||
{ USB_DEVICE(0x35f5, 0x7922), .driver_info = BTUSB_MEDIATEK |
|
||||
BTUSB_WIDEBAND_SPEECH |
|
||||
BTUSB_VALID_LE_STATES },
|
||||
BTUSB_WIDEBAND_SPEECH },
|
||||
|
||||
/* Additional MediaTek MT7925 Bluetooth devices */
|
||||
{ USB_DEVICE(0x0489, 0xe113), .driver_info = BTUSB_MEDIATEK |
|
||||
BTUSB_WIDEBAND_SPEECH |
|
||||
BTUSB_VALID_LE_STATES },
|
||||
BTUSB_WIDEBAND_SPEECH },
|
||||
{ USB_DEVICE(0x0489, 0xe118), .driver_info = BTUSB_MEDIATEK |
|
||||
BTUSB_WIDEBAND_SPEECH },
|
||||
{ USB_DEVICE(0x0489, 0xe11e), .driver_info = BTUSB_MEDIATEK |
|
||||
BTUSB_WIDEBAND_SPEECH },
|
||||
{ USB_DEVICE(0x13d3, 0x3602), .driver_info = BTUSB_MEDIATEK |
|
||||
BTUSB_WIDEBAND_SPEECH |
|
||||
BTUSB_VALID_LE_STATES },
|
||||
BTUSB_WIDEBAND_SPEECH },
|
||||
{ USB_DEVICE(0x13d3, 0x3603), .driver_info = BTUSB_MEDIATEK |
|
||||
BTUSB_WIDEBAND_SPEECH |
|
||||
BTUSB_VALID_LE_STATES },
|
||||
BTUSB_WIDEBAND_SPEECH },
|
||||
{ USB_DEVICE(0x13d3, 0x3604), .driver_info = BTUSB_MEDIATEK |
|
||||
BTUSB_WIDEBAND_SPEECH },
|
||||
{ USB_DEVICE(0x13d3, 0x3608), .driver_info = BTUSB_MEDIATEK |
|
||||
BTUSB_WIDEBAND_SPEECH },
|
||||
|
||||
/* Additional Realtek 8723AE Bluetooth devices */
|
||||
{ USB_DEVICE(0x0930, 0x021d), .driver_info = BTUSB_REALTEK },
|
||||
@ -1397,7 +1345,10 @@ static int btusb_submit_intr_urb(struct hci_dev *hdev, gfp_t mem_flags)
|
||||
if (!urb)
|
||||
return -ENOMEM;
|
||||
|
||||
size = le16_to_cpu(data->intr_ep->wMaxPacketSize);
|
||||
/* Use maximum HCI Event size so the USB stack handles
|
||||
* ZPL/short-transfer automatically.
|
||||
*/
|
||||
size = HCI_MAX_EVENT_SIZE;
|
||||
|
||||
buf = kmalloc(size, mem_flags);
|
||||
if (!buf) {
|
||||
@ -3956,7 +3907,7 @@ static int btusb_probe(struct usb_interface *intf,
|
||||
if (id->driver_info & BTUSB_WIDEBAND_SPEECH)
|
||||
set_bit(HCI_QUIRK_WIDEBAND_SPEECH_SUPPORTED, &hdev->quirks);
|
||||
|
||||
if (!(id->driver_info & BTUSB_VALID_LE_STATES))
|
||||
if (id->driver_info & BTUSB_INVALID_LE_STATES)
|
||||
set_bit(HCI_QUIRK_BROKEN_LE_STATES, &hdev->quirks);
|
||||
|
||||
if (id->driver_info & BTUSB_DIGIANSWER) {
|
||||
|
@ -38,6 +38,13 @@ struct h4_recv_pkt {
|
||||
.lsize = 1, \
|
||||
.maxlen = HCI_MAX_EVENT_SIZE
|
||||
|
||||
#define H4_RECV_ISO \
|
||||
.type = HCI_ISODATA_PKT, \
|
||||
.hlen = HCI_ISO_HDR_SIZE, \
|
||||
.loff = 2, \
|
||||
.lsize = 2, \
|
||||
.maxlen = HCI_MAX_FRAME_SIZE
|
||||
|
||||
static inline struct sk_buff *h4_recv_buf(struct hci_dev *hdev,
|
||||
struct sk_buff *skb,
|
||||
const unsigned char *buffer,
|
||||
|
755
drivers/bluetooth/hci_aml.c
Normal file
755
drivers/bluetooth/hci_aml.c
Normal file
@ -0,0 +1,755 @@
|
||||
// SPDX-License-Identifier: (GPL-2.0-only OR MIT)
|
||||
/*
|
||||
* Copyright (C) 2024 Amlogic, Inc. All rights reserved
|
||||
*/
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/property.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/serdev.h>
|
||||
#include <linux/clk.h>
|
||||
#include <linux/firmware.h>
|
||||
#include <linux/gpio/consumer.h>
|
||||
#include <linux/regulator/consumer.h>
|
||||
#include <net/bluetooth/bluetooth.h>
|
||||
#include <net/bluetooth/hci_core.h>
|
||||
#include <net/bluetooth/hci.h>
|
||||
|
||||
#include "hci_uart.h"
|
||||
|
||||
#define AML_EVT_HEAD_SIZE 4
|
||||
#define AML_BDADDR_DEFAULT (&(bdaddr_t) {{ 0x00, 0xff, 0x00, 0x22, 0x2d, 0xae }})
|
||||
|
||||
#define AML_FIRMWARE_OPERATION_SIZE (248)
|
||||
#define AML_FIRMWARE_MAX_SIZE (512 * 1024)
|
||||
|
||||
/* TCI command */
|
||||
#define AML_TCI_CMD_READ 0xFEF0
|
||||
#define AML_TCI_CMD_WRITE 0xFEF1
|
||||
#define AML_TCI_CMD_UPDATE_BAUDRATE 0xFEF2
|
||||
#define AML_TCI_CMD_HARDWARE_RESET 0xFEF2
|
||||
#define AML_TCI_CMD_DOWNLOAD_BT_FW 0xFEF3
|
||||
|
||||
/* Vendor command */
|
||||
#define AML_BT_HCI_VENDOR_CMD 0xFC1A
|
||||
|
||||
/* TCI operation parameter in controller chip */
|
||||
#define AML_OP_UART_MODE 0x00A30128
|
||||
#define AML_OP_EVT_ENABLE 0x00A70014
|
||||
#define AML_OP_MEM_HARD_TRANS_EN 0x00A7000C
|
||||
#define AML_OP_RF_CFG 0x00F03040
|
||||
#define AML_OP_RAM_POWER_CTR 0x00F03050
|
||||
#define AML_OP_HARDWARE_RST 0x00F03058
|
||||
#define AML_OP_ICCM_RAM_BASE 0x00000000
|
||||
#define AML_OP_DCCM_RAM_BASE 0x00D00000
|
||||
|
||||
/* UART configuration */
|
||||
#define AML_UART_XMIT_EN BIT(12)
|
||||
#define AML_UART_RECV_EN BIT(13)
|
||||
#define AML_UART_TIMEOUT_INT_EN BIT(14)
|
||||
#define AML_UART_CLK_SOURCE 40000000
|
||||
|
||||
/* Controller event */
|
||||
#define AML_EVT_EN BIT(24)
|
||||
|
||||
/* RAM power control */
|
||||
#define AML_RAM_POWER_ON (0)
|
||||
#define AML_RAM_POWER_OFF (1)
|
||||
|
||||
/* RF configuration */
|
||||
#define AML_RF_ANT_SINGLE BIT(28)
|
||||
#define AML_RF_ANT_DOUBLE BIT(29)
|
||||
|
||||
/* Memory transaction */
|
||||
#define AML_MM_CTR_HARD_TRAS_EN BIT(27)
|
||||
|
||||
/* Controller reset */
|
||||
#define AML_CTR_CPU_RESET BIT(8)
|
||||
#define AML_CTR_MAC_RESET BIT(9)
|
||||
#define AML_CTR_PHY_RESET BIT(10)
|
||||
|
||||
enum {
|
||||
FW_ICCM,
|
||||
FW_DCCM
|
||||
};
|
||||
|
||||
struct aml_fw_len {
|
||||
u32 iccm_len;
|
||||
u32 dccm_len;
|
||||
};
|
||||
|
||||
struct aml_tci_rsp {
|
||||
u8 num_cmd_packet;
|
||||
u16 opcode;
|
||||
u8 status;
|
||||
} __packed;
|
||||
|
||||
struct aml_device_data {
|
||||
int iccm_offset;
|
||||
int dccm_offset;
|
||||
bool is_coex;
|
||||
};
|
||||
|
||||
struct aml_serdev {
|
||||
struct hci_uart serdev_hu;
|
||||
struct device *dev;
|
||||
struct gpio_desc *bt_en_gpio;
|
||||
struct regulator *bt_supply;
|
||||
struct clk *lpo_clk;
|
||||
const struct aml_device_data *aml_dev_data;
|
||||
const char *firmware_name;
|
||||
};
|
||||
|
||||
struct aml_data {
|
||||
struct sk_buff *rx_skb;
|
||||
struct sk_buff_head txq;
|
||||
};
|
||||
|
||||
static const struct h4_recv_pkt aml_recv_pkts[] = {
|
||||
{ H4_RECV_ACL, .recv = hci_recv_frame },
|
||||
{ H4_RECV_SCO, .recv = hci_recv_frame },
|
||||
{ H4_RECV_EVENT, .recv = hci_recv_frame },
|
||||
{ H4_RECV_ISO, .recv = hci_recv_frame },
|
||||
};
|
||||
|
||||
/* The TCI command is a private command, which is for setting baud rate,
|
||||
* downloading firmware, initiating RAM.
|
||||
*
|
||||
* op_code | op_len | op_addr | parameter |
|
||||
* --------|-----------------------|---------|-------------|
|
||||
* 2B | 1B len(addr+param) | 4B | len(param) |
|
||||
*/
|
||||
static int aml_send_tci_cmd(struct hci_dev *hdev, u16 op_code, u32 op_addr,
|
||||
u32 *param, u32 param_len)
|
||||
{
|
||||
struct aml_tci_rsp *rsp = NULL;
|
||||
struct sk_buff *skb = NULL;
|
||||
size_t buf_len = 0;
|
||||
u8 *buf = NULL;
|
||||
int err = 0;
|
||||
|
||||
buf_len = sizeof(op_addr) + param_len;
|
||||
buf = kmalloc(buf_len, GFP_KERNEL);
|
||||
if (!buf)
|
||||
return -ENOMEM;
|
||||
|
||||
memcpy(buf, &op_addr, sizeof(op_addr));
|
||||
if (param && param_len > 0)
|
||||
memcpy(buf + sizeof(op_addr), param, param_len);
|
||||
|
||||
skb = __hci_cmd_sync_ev(hdev, op_code, buf_len, buf,
|
||||
HCI_EV_CMD_COMPLETE, HCI_INIT_TIMEOUT);
|
||||
if (IS_ERR(skb)) {
|
||||
err = PTR_ERR(skb);
|
||||
bt_dev_err(hdev, "Failed to send TCI cmd (error: %d)", err);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
rsp = skb_pull_data(skb, sizeof(struct aml_tci_rsp));
|
||||
if (!rsp)
|
||||
goto skb_free;
|
||||
|
||||
if (rsp->opcode != op_code || rsp->status != 0x00) {
|
||||
bt_dev_err(hdev, "send TCI cmd (0x%04X), response (0x%04X):(%d)",
|
||||
op_code, rsp->opcode, rsp->status);
|
||||
err = -EINVAL;
|
||||
goto skb_free;
|
||||
}
|
||||
|
||||
skb_free:
|
||||
kfree_skb(skb);
|
||||
|
||||
exit:
|
||||
kfree(buf);
|
||||
return err;
|
||||
}
|
||||
|
||||
static int aml_update_chip_baudrate(struct hci_dev *hdev, u32 baud)
|
||||
{
|
||||
u32 value;
|
||||
|
||||
value = ((AML_UART_CLK_SOURCE / baud) - 1) & 0x0FFF;
|
||||
value |= AML_UART_XMIT_EN | AML_UART_RECV_EN | AML_UART_TIMEOUT_INT_EN;
|
||||
|
||||
return aml_send_tci_cmd(hdev, AML_TCI_CMD_UPDATE_BAUDRATE,
|
||||
AML_OP_UART_MODE, &value, sizeof(value));
|
||||
}
|
||||
|
||||
static int aml_start_chip(struct hci_dev *hdev)
|
||||
{
|
||||
u32 value = 0;
|
||||
int ret;
|
||||
|
||||
value = AML_MM_CTR_HARD_TRAS_EN;
|
||||
ret = aml_send_tci_cmd(hdev, AML_TCI_CMD_WRITE,
|
||||
AML_OP_MEM_HARD_TRANS_EN,
|
||||
&value, sizeof(value));
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* controller hardware reset */
|
||||
value = AML_CTR_CPU_RESET | AML_CTR_MAC_RESET | AML_CTR_PHY_RESET;
|
||||
ret = aml_send_tci_cmd(hdev, AML_TCI_CMD_HARDWARE_RESET,
|
||||
AML_OP_HARDWARE_RST,
|
||||
&value, sizeof(value));
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int aml_send_firmware_segment(struct hci_dev *hdev,
|
||||
u8 fw_type,
|
||||
u8 *seg,
|
||||
u32 seg_size,
|
||||
u32 offset)
|
||||
{
|
||||
u32 op_addr = 0;
|
||||
|
||||
if (fw_type == FW_ICCM)
|
||||
op_addr = AML_OP_ICCM_RAM_BASE + offset;
|
||||
else if (fw_type == FW_DCCM)
|
||||
op_addr = AML_OP_DCCM_RAM_BASE + offset;
|
||||
|
||||
return aml_send_tci_cmd(hdev, AML_TCI_CMD_DOWNLOAD_BT_FW,
|
||||
op_addr, (u32 *)seg, seg_size);
|
||||
}
|
||||
|
||||
static int aml_send_firmware(struct hci_dev *hdev, u8 fw_type,
|
||||
u8 *fw, u32 fw_size, u32 offset)
|
||||
{
|
||||
u32 seg_size = 0;
|
||||
u32 seg_off = 0;
|
||||
|
||||
if (fw_size > AML_FIRMWARE_MAX_SIZE) {
|
||||
bt_dev_err(hdev,
|
||||
"Firmware size %d kB is larger than the maximum of 512 kB. Aborting.",
|
||||
fw_size);
|
||||
return -EINVAL;
|
||||
}
|
||||
while (fw_size > 0) {
|
||||
seg_size = (fw_size > AML_FIRMWARE_OPERATION_SIZE) ?
|
||||
AML_FIRMWARE_OPERATION_SIZE : fw_size;
|
||||
if (aml_send_firmware_segment(hdev, fw_type, (fw + seg_off),
|
||||
seg_size, offset)) {
|
||||
bt_dev_err(hdev, "Failed send firmware, type: %d, offset: 0x%x",
|
||||
fw_type, offset);
|
||||
return -EINVAL;
|
||||
}
|
||||
seg_off += seg_size;
|
||||
fw_size -= seg_size;
|
||||
offset += seg_size;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int aml_download_firmware(struct hci_dev *hdev, const char *fw_name)
|
||||
{
|
||||
struct hci_uart *hu = hci_get_drvdata(hdev);
|
||||
struct aml_serdev *amldev = serdev_device_get_drvdata(hu->serdev);
|
||||
const struct firmware *firmware = NULL;
|
||||
struct aml_fw_len *fw_len = NULL;
|
||||
u8 *iccm_start = NULL, *dccm_start = NULL;
|
||||
u32 iccm_len, dccm_len;
|
||||
u32 value = 0;
|
||||
int ret = 0;
|
||||
|
||||
/* Enable firmware download event */
|
||||
value = AML_EVT_EN;
|
||||
ret = aml_send_tci_cmd(hdev, AML_TCI_CMD_WRITE,
|
||||
AML_OP_EVT_ENABLE,
|
||||
&value, sizeof(value));
|
||||
if (ret)
|
||||
goto exit;
|
||||
|
||||
/* RAM power on */
|
||||
value = AML_RAM_POWER_ON;
|
||||
ret = aml_send_tci_cmd(hdev, AML_TCI_CMD_WRITE,
|
||||
AML_OP_RAM_POWER_CTR,
|
||||
&value, sizeof(value));
|
||||
if (ret)
|
||||
goto exit;
|
||||
|
||||
/* Check RAM power status */
|
||||
ret = aml_send_tci_cmd(hdev, AML_TCI_CMD_READ,
|
||||
AML_OP_RAM_POWER_CTR, NULL, 0);
|
||||
if (ret)
|
||||
goto exit;
|
||||
|
||||
ret = request_firmware(&firmware, fw_name, &hdev->dev);
|
||||
if (ret < 0) {
|
||||
bt_dev_err(hdev, "Failed to load <%s>:(%d)", fw_name, ret);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
fw_len = (struct aml_fw_len *)firmware->data;
|
||||
|
||||
/* Download ICCM */
|
||||
iccm_start = (u8 *)(firmware->data) + sizeof(struct aml_fw_len)
|
||||
+ amldev->aml_dev_data->iccm_offset;
|
||||
iccm_len = fw_len->iccm_len - amldev->aml_dev_data->iccm_offset;
|
||||
ret = aml_send_firmware(hdev, FW_ICCM, iccm_start, iccm_len,
|
||||
amldev->aml_dev_data->iccm_offset);
|
||||
if (ret) {
|
||||
bt_dev_err(hdev, "Failed to send FW_ICCM (%d)", ret);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
/* Download DCCM */
|
||||
dccm_start = (u8 *)(firmware->data) + sizeof(struct aml_fw_len) + fw_len->iccm_len;
|
||||
dccm_len = fw_len->dccm_len;
|
||||
ret = aml_send_firmware(hdev, FW_DCCM, dccm_start, dccm_len,
|
||||
amldev->aml_dev_data->dccm_offset);
|
||||
if (ret) {
|
||||
bt_dev_err(hdev, "Failed to send FW_DCCM (%d)", ret);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
/* Disable firmware download event */
|
||||
value = 0;
|
||||
ret = aml_send_tci_cmd(hdev, AML_TCI_CMD_WRITE,
|
||||
AML_OP_EVT_ENABLE,
|
||||
&value, sizeof(value));
|
||||
if (ret)
|
||||
goto exit;
|
||||
|
||||
exit:
|
||||
if (firmware)
|
||||
release_firmware(firmware);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int aml_send_reset(struct hci_dev *hdev)
|
||||
{
|
||||
struct sk_buff *skb;
|
||||
int err;
|
||||
|
||||
skb = __hci_cmd_sync_ev(hdev, HCI_OP_RESET, 0, NULL,
|
||||
HCI_EV_CMD_COMPLETE, HCI_INIT_TIMEOUT);
|
||||
if (IS_ERR(skb)) {
|
||||
err = PTR_ERR(skb);
|
||||
bt_dev_err(hdev, "Failed to send hci reset cmd (%d)", err);
|
||||
return err;
|
||||
}
|
||||
|
||||
kfree_skb(skb);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int aml_dump_fw_version(struct hci_dev *hdev)
|
||||
{
|
||||
struct aml_tci_rsp *rsp = NULL;
|
||||
struct sk_buff *skb;
|
||||
u8 value[6] = {0};
|
||||
u8 *fw_ver = NULL;
|
||||
int err = 0;
|
||||
|
||||
skb = __hci_cmd_sync_ev(hdev, AML_BT_HCI_VENDOR_CMD, sizeof(value), value,
|
||||
HCI_EV_CMD_COMPLETE, HCI_INIT_TIMEOUT);
|
||||
if (IS_ERR(skb)) {
|
||||
err = PTR_ERR(skb);
|
||||
bt_dev_err(hdev, "Failed to get fw version (error: %d)", err);
|
||||
return err;
|
||||
}
|
||||
|
||||
rsp = skb_pull_data(skb, sizeof(struct aml_tci_rsp));
|
||||
if (!rsp)
|
||||
goto exit;
|
||||
|
||||
if (rsp->opcode != AML_BT_HCI_VENDOR_CMD || rsp->status != 0x00) {
|
||||
bt_dev_err(hdev, "dump version, error response (0x%04X):(%d)",
|
||||
rsp->opcode, rsp->status);
|
||||
err = -EINVAL;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
fw_ver = (u8 *)rsp + AML_EVT_HEAD_SIZE;
|
||||
bt_dev_info(hdev, "fw_version: date = %02x.%02x, number = 0x%02x%02x",
|
||||
*(fw_ver + 1), *fw_ver, *(fw_ver + 3), *(fw_ver + 2));
|
||||
|
||||
exit:
|
||||
kfree_skb(skb);
|
||||
return err;
|
||||
}
|
||||
|
||||
static int aml_set_bdaddr(struct hci_dev *hdev, const bdaddr_t *bdaddr)
|
||||
{
|
||||
struct aml_tci_rsp *rsp = NULL;
|
||||
struct sk_buff *skb;
|
||||
int err = 0;
|
||||
|
||||
bt_dev_info(hdev, "set bdaddr (%pM)", bdaddr);
|
||||
skb = __hci_cmd_sync_ev(hdev, AML_BT_HCI_VENDOR_CMD,
|
||||
sizeof(bdaddr_t), bdaddr,
|
||||
HCI_EV_CMD_COMPLETE, HCI_INIT_TIMEOUT);
|
||||
if (IS_ERR(skb)) {
|
||||
err = PTR_ERR(skb);
|
||||
bt_dev_err(hdev, "Failed to set bdaddr (error: %d)", err);
|
||||
return err;
|
||||
}
|
||||
|
||||
rsp = skb_pull_data(skb, sizeof(struct aml_tci_rsp));
|
||||
if (!rsp)
|
||||
goto exit;
|
||||
|
||||
if (rsp->opcode != AML_BT_HCI_VENDOR_CMD || rsp->status != 0x00) {
|
||||
bt_dev_err(hdev, "error response (0x%x):(%d)", rsp->opcode, rsp->status);
|
||||
err = -EINVAL;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
exit:
|
||||
kfree_skb(skb);
|
||||
return err;
|
||||
}
|
||||
|
||||
static int aml_check_bdaddr(struct hci_dev *hdev)
|
||||
{
|
||||
struct hci_rp_read_bd_addr *paddr;
|
||||
struct sk_buff *skb;
|
||||
int err;
|
||||
|
||||
if (bacmp(&hdev->public_addr, BDADDR_ANY))
|
||||
return 0;
|
||||
|
||||
skb = __hci_cmd_sync(hdev, HCI_OP_READ_BD_ADDR, 0, NULL,
|
||||
HCI_INIT_TIMEOUT);
|
||||
if (IS_ERR(skb)) {
|
||||
err = PTR_ERR(skb);
|
||||
bt_dev_err(hdev, "Failed to read bdaddr (error: %d)", err);
|
||||
return err;
|
||||
}
|
||||
|
||||
paddr = skb_pull_data(skb, sizeof(struct hci_rp_read_bd_addr));
|
||||
if (!paddr)
|
||||
goto exit;
|
||||
|
||||
if (!bacmp(&paddr->bdaddr, AML_BDADDR_DEFAULT)) {
|
||||
bt_dev_info(hdev, "amlbt using default bdaddr (%pM)", &paddr->bdaddr);
|
||||
set_bit(HCI_QUIRK_INVALID_BDADDR, &hdev->quirks);
|
||||
}
|
||||
|
||||
exit:
|
||||
kfree_skb(skb);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int aml_config_rf(struct hci_dev *hdev, bool is_coex)
|
||||
{
|
||||
u32 value = AML_RF_ANT_DOUBLE;
|
||||
|
||||
/* Use a single antenna when co-existing with wifi */
|
||||
if (is_coex)
|
||||
value = AML_RF_ANT_SINGLE;
|
||||
|
||||
return aml_send_tci_cmd(hdev, AML_TCI_CMD_WRITE,
|
||||
AML_OP_RF_CFG,
|
||||
&value, sizeof(value));
|
||||
}
|
||||
|
||||
static int aml_parse_dt(struct aml_serdev *amldev)
|
||||
{
|
||||
struct device *pdev = amldev->dev;
|
||||
|
||||
amldev->bt_en_gpio = devm_gpiod_get(pdev, "enable",
|
||||
GPIOD_OUT_LOW);
|
||||
if (IS_ERR(amldev->bt_en_gpio)) {
|
||||
dev_err(pdev, "Failed to acquire enable gpios");
|
||||
return PTR_ERR(amldev->bt_en_gpio);
|
||||
}
|
||||
|
||||
if (device_property_read_string(pdev, "firmware-name",
|
||||
&amldev->firmware_name)) {
|
||||
dev_err(pdev, "Failed to acquire firmware path");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
amldev->bt_supply = devm_regulator_get(pdev, "vddio");
|
||||
if (IS_ERR(amldev->bt_supply)) {
|
||||
dev_err(pdev, "Failed to acquire regulator");
|
||||
return PTR_ERR(amldev->bt_supply);
|
||||
}
|
||||
|
||||
amldev->lpo_clk = devm_clk_get(pdev, NULL);
|
||||
if (IS_ERR(amldev->lpo_clk)) {
|
||||
dev_err(pdev, "Failed to acquire clock source");
|
||||
return PTR_ERR(amldev->lpo_clk);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int aml_power_on(struct aml_serdev *amldev)
|
||||
{
|
||||
int err;
|
||||
|
||||
err = regulator_enable(amldev->bt_supply);
|
||||
if (err) {
|
||||
dev_err(amldev->dev, "Failed to enable regulator: (%d)", err);
|
||||
return err;
|
||||
}
|
||||
|
||||
err = clk_prepare_enable(amldev->lpo_clk);
|
||||
if (err) {
|
||||
dev_err(amldev->dev, "Failed to enable lpo clock: (%d)", err);
|
||||
return err;
|
||||
}
|
||||
|
||||
gpiod_set_value_cansleep(amldev->bt_en_gpio, 1);
|
||||
|
||||
/* Wait 20ms for bluetooth controller power on */
|
||||
msleep(20);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int aml_power_off(struct aml_serdev *amldev)
|
||||
{
|
||||
gpiod_set_value_cansleep(amldev->bt_en_gpio, 0);
|
||||
|
||||
clk_disable_unprepare(amldev->lpo_clk);
|
||||
|
||||
regulator_disable(amldev->bt_supply);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int aml_set_baudrate(struct hci_uart *hu, unsigned int speed)
|
||||
{
|
||||
/* update controller baudrate */
|
||||
if (aml_update_chip_baudrate(hu->hdev, speed) != 0) {
|
||||
bt_dev_err(hu->hdev, "Failed to update baud rate");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* update local baudrate */
|
||||
serdev_device_set_baudrate(hu->serdev, speed);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Initialize protocol */
|
||||
static int aml_open(struct hci_uart *hu)
|
||||
{
|
||||
struct aml_serdev *amldev = serdev_device_get_drvdata(hu->serdev);
|
||||
struct aml_data *aml_data;
|
||||
int err;
|
||||
|
||||
err = aml_parse_dt(amldev);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
if (!hci_uart_has_flow_control(hu)) {
|
||||
bt_dev_err(hu->hdev, "no flow control");
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
aml_data = kzalloc(sizeof(*aml_data), GFP_KERNEL);
|
||||
if (!aml_data)
|
||||
return -ENOMEM;
|
||||
|
||||
skb_queue_head_init(&aml_data->txq);
|
||||
|
||||
hu->priv = aml_data;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int aml_close(struct hci_uart *hu)
|
||||
{
|
||||
struct aml_serdev *amldev = serdev_device_get_drvdata(hu->serdev);
|
||||
struct aml_data *aml_data = hu->priv;
|
||||
|
||||
skb_queue_purge(&aml_data->txq);
|
||||
kfree_skb(aml_data->rx_skb);
|
||||
kfree(aml_data);
|
||||
|
||||
hu->priv = NULL;
|
||||
|
||||
return aml_power_off(amldev);
|
||||
}
|
||||
|
||||
static int aml_flush(struct hci_uart *hu)
|
||||
{
|
||||
struct aml_data *aml_data = hu->priv;
|
||||
|
||||
skb_queue_purge(&aml_data->txq);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int aml_setup(struct hci_uart *hu)
|
||||
{
|
||||
struct aml_serdev *amldev = serdev_device_get_drvdata(hu->serdev);
|
||||
struct hci_dev *hdev = amldev->serdev_hu.hdev;
|
||||
int err;
|
||||
|
||||
/* Setup bdaddr */
|
||||
hdev->set_bdaddr = aml_set_bdaddr;
|
||||
|
||||
err = aml_power_on(amldev);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
err = aml_set_baudrate(hu, amldev->serdev_hu.proto->oper_speed);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
err = aml_download_firmware(hdev, amldev->firmware_name);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
err = aml_config_rf(hdev, amldev->aml_dev_data->is_coex);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
err = aml_start_chip(hdev);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
/* Wait 60ms for controller startup */
|
||||
msleep(60);
|
||||
|
||||
err = aml_dump_fw_version(hdev);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
err = aml_send_reset(hdev);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
err = aml_check_bdaddr(hdev);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int aml_enqueue(struct hci_uart *hu, struct sk_buff *skb)
|
||||
{
|
||||
struct aml_data *aml_data = hu->priv;
|
||||
|
||||
skb_queue_tail(&aml_data->txq, skb);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct sk_buff *aml_dequeue(struct hci_uart *hu)
|
||||
{
|
||||
struct aml_data *aml_data = hu->priv;
|
||||
struct sk_buff *skb;
|
||||
|
||||
skb = skb_dequeue(&aml_data->txq);
|
||||
|
||||
/* Prepend skb with frame type */
|
||||
if (skb)
|
||||
memcpy(skb_push(skb, 1), &bt_cb(skb)->pkt_type, 1);
|
||||
|
||||
return skb;
|
||||
}
|
||||
|
||||
static int aml_recv(struct hci_uart *hu, const void *data, int count)
|
||||
{
|
||||
struct aml_data *aml_data = hu->priv;
|
||||
int err;
|
||||
|
||||
aml_data->rx_skb = h4_recv_buf(hu->hdev, aml_data->rx_skb, data, count,
|
||||
aml_recv_pkts,
|
||||
ARRAY_SIZE(aml_recv_pkts));
|
||||
if (IS_ERR(aml_data->rx_skb)) {
|
||||
err = PTR_ERR(aml_data->rx_skb);
|
||||
bt_dev_err(hu->hdev, "Frame reassembly failed (%d)", err);
|
||||
aml_data->rx_skb = NULL;
|
||||
return err;
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
static const struct hci_uart_proto aml_hci_proto = {
|
||||
.id = HCI_UART_AML,
|
||||
.name = "AML",
|
||||
.init_speed = 115200,
|
||||
.oper_speed = 4000000,
|
||||
.open = aml_open,
|
||||
.close = aml_close,
|
||||
.setup = aml_setup,
|
||||
.flush = aml_flush,
|
||||
.recv = aml_recv,
|
||||
.enqueue = aml_enqueue,
|
||||
.dequeue = aml_dequeue,
|
||||
};
|
||||
|
||||
static void aml_device_driver_shutdown(struct device *dev)
|
||||
{
|
||||
struct aml_serdev *amldev = dev_get_drvdata(dev);
|
||||
|
||||
aml_power_off(amldev);
|
||||
}
|
||||
|
||||
static int aml_serdev_probe(struct serdev_device *serdev)
|
||||
{
|
||||
struct aml_serdev *amldev;
|
||||
int err;
|
||||
|
||||
amldev = devm_kzalloc(&serdev->dev, sizeof(*amldev), GFP_KERNEL);
|
||||
if (!amldev)
|
||||
return -ENOMEM;
|
||||
|
||||
amldev->serdev_hu.serdev = serdev;
|
||||
amldev->dev = &serdev->dev;
|
||||
serdev_device_set_drvdata(serdev, amldev);
|
||||
|
||||
err = hci_uart_register_device(&amldev->serdev_hu, &aml_hci_proto);
|
||||
if (err)
|
||||
return dev_err_probe(amldev->dev, err,
|
||||
"Failed to register hci uart device");
|
||||
|
||||
amldev->aml_dev_data = device_get_match_data(&serdev->dev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void aml_serdev_remove(struct serdev_device *serdev)
|
||||
{
|
||||
struct aml_serdev *amldev = serdev_device_get_drvdata(serdev);
|
||||
|
||||
hci_uart_unregister_device(&amldev->serdev_hu);
|
||||
}
|
||||
|
||||
static const struct aml_device_data data_w155s2 = {
|
||||
.iccm_offset = 256 * 1024,
|
||||
};
|
||||
|
||||
static const struct aml_device_data data_w265s2 = {
|
||||
.iccm_offset = 384 * 1024,
|
||||
};
|
||||
|
||||
static const struct of_device_id aml_bluetooth_of_match[] = {
|
||||
{ .compatible = "amlogic,w155s2-bt", .data = &data_w155s2 },
|
||||
{ .compatible = "amlogic,w265s2-bt", .data = &data_w265s2 },
|
||||
{ /* sentinel */ },
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, aml_bluetooth_of_match);
|
||||
|
||||
static struct serdev_device_driver aml_serdev_driver = {
|
||||
.probe = aml_serdev_probe,
|
||||
.remove = aml_serdev_remove,
|
||||
.driver = {
|
||||
.name = "hci_uart_aml",
|
||||
.of_match_table = aml_bluetooth_of_match,
|
||||
.shutdown = aml_device_driver_shutdown,
|
||||
},
|
||||
};
|
||||
|
||||
int __init aml_init(void)
|
||||
{
|
||||
serdev_device_driver_register(&aml_serdev_driver);
|
||||
|
||||
return hci_uart_register_proto(&aml_hci_proto);
|
||||
}
|
||||
|
||||
int __exit aml_deinit(void)
|
||||
{
|
||||
serdev_device_driver_unregister(&aml_serdev_driver);
|
||||
|
||||
return hci_uart_unregister_proto(&aml_hci_proto);
|
||||
}
|
@ -507,6 +507,9 @@ static int hci_uart_tty_open(struct tty_struct *tty)
|
||||
hu->alignment = 1;
|
||||
hu->padding = 0;
|
||||
|
||||
/* Use serial port speed as oper_speed */
|
||||
hu->oper_speed = tty->termios.c_ospeed;
|
||||
|
||||
INIT_WORK(&hu->init_ready, hci_uart_init_work);
|
||||
INIT_WORK(&hu->write_work, hci_uart_write_work);
|
||||
|
||||
@ -870,7 +873,9 @@ static int __init hci_uart_init(void)
|
||||
#ifdef CONFIG_BT_HCIUART_MRVL
|
||||
mrvl_init();
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_BT_HCIUART_AML
|
||||
aml_init();
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -906,7 +911,9 @@ static void __exit hci_uart_exit(void)
|
||||
#ifdef CONFIG_BT_HCIUART_MRVL
|
||||
mrvl_deinit();
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_BT_HCIUART_AML
|
||||
aml_deinit();
|
||||
#endif
|
||||
tty_unregister_ldisc(&hci_uart_ldisc);
|
||||
}
|
||||
|
||||
|
@ -20,7 +20,7 @@
|
||||
#define HCIUARTGETFLAGS _IOR('U', 204, int)
|
||||
|
||||
/* UART protocols */
|
||||
#define HCI_UART_MAX_PROTO 12
|
||||
#define HCI_UART_MAX_PROTO 13
|
||||
|
||||
#define HCI_UART_H4 0
|
||||
#define HCI_UART_BCSP 1
|
||||
@ -34,6 +34,7 @@
|
||||
#define HCI_UART_AG6XX 9
|
||||
#define HCI_UART_NOKIA 10
|
||||
#define HCI_UART_MRVL 11
|
||||
#define HCI_UART_AML 12
|
||||
|
||||
#define HCI_UART_RAW_DEVICE 0
|
||||
#define HCI_UART_RESET_ON_INIT 1
|
||||
@ -209,3 +210,8 @@ int ag6xx_deinit(void);
|
||||
int mrvl_init(void);
|
||||
int mrvl_deinit(void);
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_BT_HCIUART_AML
|
||||
int aml_init(void);
|
||||
int aml_deinit(void);
|
||||
#endif
|
||||
|
@ -342,6 +342,51 @@ dpll_msg_add_pin_freq(struct sk_buff *msg, struct dpll_pin *pin,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
dpll_msg_add_pin_esync(struct sk_buff *msg, struct dpll_pin *pin,
|
||||
struct dpll_pin_ref *ref, struct netlink_ext_ack *extack)
|
||||
{
|
||||
const struct dpll_pin_ops *ops = dpll_pin_ops(ref);
|
||||
struct dpll_device *dpll = ref->dpll;
|
||||
struct dpll_pin_esync esync;
|
||||
struct nlattr *nest;
|
||||
int ret, i;
|
||||
|
||||
if (!ops->esync_get)
|
||||
return 0;
|
||||
ret = ops->esync_get(pin, dpll_pin_on_dpll_priv(dpll, pin), dpll,
|
||||
dpll_priv(dpll), &esync, extack);
|
||||
if (ret == -EOPNOTSUPP)
|
||||
return 0;
|
||||
else if (ret)
|
||||
return ret;
|
||||
if (nla_put_64bit(msg, DPLL_A_PIN_ESYNC_FREQUENCY, sizeof(esync.freq),
|
||||
&esync.freq, DPLL_A_PIN_PAD))
|
||||
return -EMSGSIZE;
|
||||
if (nla_put_u32(msg, DPLL_A_PIN_ESYNC_PULSE, esync.pulse))
|
||||
return -EMSGSIZE;
|
||||
for (i = 0; i < esync.range_num; i++) {
|
||||
nest = nla_nest_start(msg,
|
||||
DPLL_A_PIN_ESYNC_FREQUENCY_SUPPORTED);
|
||||
if (!nest)
|
||||
return -EMSGSIZE;
|
||||
if (nla_put_64bit(msg, DPLL_A_PIN_FREQUENCY_MIN,
|
||||
sizeof(esync.range[i].min),
|
||||
&esync.range[i].min, DPLL_A_PIN_PAD))
|
||||
goto nest_cancel;
|
||||
if (nla_put_64bit(msg, DPLL_A_PIN_FREQUENCY_MAX,
|
||||
sizeof(esync.range[i].max),
|
||||
&esync.range[i].max, DPLL_A_PIN_PAD))
|
||||
goto nest_cancel;
|
||||
nla_nest_end(msg, nest);
|
||||
}
|
||||
return 0;
|
||||
|
||||
nest_cancel:
|
||||
nla_nest_cancel(msg, nest);
|
||||
return -EMSGSIZE;
|
||||
}
|
||||
|
||||
static bool dpll_pin_is_freq_supported(struct dpll_pin *pin, u32 freq)
|
||||
{
|
||||
int fs;
|
||||
@ -481,6 +526,9 @@ dpll_cmd_pin_get_one(struct sk_buff *msg, struct dpll_pin *pin,
|
||||
if (ret)
|
||||
return ret;
|
||||
ret = dpll_msg_add_ffo(msg, pin, ref, extack);
|
||||
if (ret)
|
||||
return ret;
|
||||
ret = dpll_msg_add_pin_esync(msg, pin, ref, extack);
|
||||
if (ret)
|
||||
return ret;
|
||||
if (xa_empty(&pin->parent_refs))
|
||||
@ -738,6 +786,83 @@ dpll_pin_freq_set(struct dpll_pin *pin, struct nlattr *a,
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int
|
||||
dpll_pin_esync_set(struct dpll_pin *pin, struct nlattr *a,
|
||||
struct netlink_ext_ack *extack)
|
||||
{
|
||||
struct dpll_pin_ref *ref, *failed;
|
||||
const struct dpll_pin_ops *ops;
|
||||
struct dpll_pin_esync esync;
|
||||
u64 freq = nla_get_u64(a);
|
||||
struct dpll_device *dpll;
|
||||
bool supported = false;
|
||||
unsigned long i;
|
||||
int ret;
|
||||
|
||||
xa_for_each(&pin->dpll_refs, i, ref) {
|
||||
ops = dpll_pin_ops(ref);
|
||||
if (!ops->esync_set || !ops->esync_get) {
|
||||
NL_SET_ERR_MSG(extack,
|
||||
"embedded sync feature is not supported by this device");
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
}
|
||||
ref = dpll_xa_ref_dpll_first(&pin->dpll_refs);
|
||||
ops = dpll_pin_ops(ref);
|
||||
dpll = ref->dpll;
|
||||
ret = ops->esync_get(pin, dpll_pin_on_dpll_priv(dpll, pin), dpll,
|
||||
dpll_priv(dpll), &esync, extack);
|
||||
if (ret) {
|
||||
NL_SET_ERR_MSG(extack, "unable to get current embedded sync frequency value");
|
||||
return ret;
|
||||
}
|
||||
if (freq == esync.freq)
|
||||
return 0;
|
||||
for (i = 0; i < esync.range_num; i++)
|
||||
if (freq <= esync.range[i].max && freq >= esync.range[i].min)
|
||||
supported = true;
|
||||
if (!supported) {
|
||||
NL_SET_ERR_MSG_ATTR(extack, a,
|
||||
"requested embedded sync frequency value is not supported by this device");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
xa_for_each(&pin->dpll_refs, i, ref) {
|
||||
void *pin_dpll_priv;
|
||||
|
||||
ops = dpll_pin_ops(ref);
|
||||
dpll = ref->dpll;
|
||||
pin_dpll_priv = dpll_pin_on_dpll_priv(dpll, pin);
|
||||
ret = ops->esync_set(pin, pin_dpll_priv, dpll, dpll_priv(dpll),
|
||||
freq, extack);
|
||||
if (ret) {
|
||||
failed = ref;
|
||||
NL_SET_ERR_MSG_FMT(extack,
|
||||
"embedded sync frequency set failed for dpll_id: %u",
|
||||
dpll->id);
|
||||
goto rollback;
|
||||
}
|
||||
}
|
||||
__dpll_pin_change_ntf(pin);
|
||||
|
||||
return 0;
|
||||
|
||||
rollback:
|
||||
xa_for_each(&pin->dpll_refs, i, ref) {
|
||||
void *pin_dpll_priv;
|
||||
|
||||
if (ref == failed)
|
||||
break;
|
||||
ops = dpll_pin_ops(ref);
|
||||
dpll = ref->dpll;
|
||||
pin_dpll_priv = dpll_pin_on_dpll_priv(dpll, pin);
|
||||
if (ops->esync_set(pin, pin_dpll_priv, dpll, dpll_priv(dpll),
|
||||
esync.freq, extack))
|
||||
NL_SET_ERR_MSG(extack, "set embedded sync frequency rollback failed");
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int
|
||||
dpll_pin_on_pin_state_set(struct dpll_pin *pin, u32 parent_idx,
|
||||
enum dpll_pin_state state,
|
||||
@ -1039,6 +1164,11 @@ dpll_pin_set_from_nlattr(struct dpll_pin *pin, struct genl_info *info)
|
||||
if (ret)
|
||||
return ret;
|
||||
break;
|
||||
case DPLL_A_PIN_ESYNC_FREQUENCY:
|
||||
ret = dpll_pin_esync_set(pin, a, info->extack);
|
||||
if (ret)
|
||||
return ret;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -62,7 +62,7 @@ static const struct nla_policy dpll_pin_get_dump_nl_policy[DPLL_A_PIN_ID + 1] =
|
||||
};
|
||||
|
||||
/* DPLL_CMD_PIN_SET - do */
|
||||
static const struct nla_policy dpll_pin_set_nl_policy[DPLL_A_PIN_PHASE_ADJUST + 1] = {
|
||||
static const struct nla_policy dpll_pin_set_nl_policy[DPLL_A_PIN_ESYNC_FREQUENCY + 1] = {
|
||||
[DPLL_A_PIN_ID] = { .type = NLA_U32, },
|
||||
[DPLL_A_PIN_FREQUENCY] = { .type = NLA_U64, },
|
||||
[DPLL_A_PIN_DIRECTION] = NLA_POLICY_RANGE(NLA_U32, 1, 2),
|
||||
@ -71,6 +71,7 @@ static const struct nla_policy dpll_pin_set_nl_policy[DPLL_A_PIN_PHASE_ADJUST +
|
||||
[DPLL_A_PIN_PARENT_DEVICE] = NLA_POLICY_NESTED(dpll_pin_parent_device_nl_policy),
|
||||
[DPLL_A_PIN_PARENT_PIN] = NLA_POLICY_NESTED(dpll_pin_parent_pin_nl_policy),
|
||||
[DPLL_A_PIN_PHASE_ADJUST] = { .type = NLA_S32, },
|
||||
[DPLL_A_PIN_ESYNC_FREQUENCY] = { .type = NLA_U64, },
|
||||
};
|
||||
|
||||
/* Ops table for dpll */
|
||||
@ -138,7 +139,7 @@ static const struct genl_split_ops dpll_nl_ops[] = {
|
||||
.doit = dpll_nl_pin_set_doit,
|
||||
.post_doit = dpll_pin_post_doit,
|
||||
.policy = dpll_pin_set_nl_policy,
|
||||
.maxattr = DPLL_A_PIN_PHASE_ADJUST,
|
||||
.maxattr = DPLL_A_PIN_ESYNC_FREQUENCY,
|
||||
.flags = GENL_ADMIN_PERM | GENL_CMD_CAP_DO,
|
||||
},
|
||||
};
|
||||
|
@ -3098,9 +3098,9 @@ static void amt_link_setup(struct net_device *dev)
|
||||
dev->hard_header_len = 0;
|
||||
dev->addr_len = 0;
|
||||
dev->priv_flags |= IFF_NO_QUEUE;
|
||||
dev->features |= NETIF_F_LLTX;
|
||||
dev->lltx = true;
|
||||
dev->netns_local = true;
|
||||
dev->features |= NETIF_F_GSO_SOFTWARE;
|
||||
dev->features |= NETIF_F_NETNS_LOCAL;
|
||||
dev->hw_features |= NETIF_F_SG | NETIF_F_HW_CSUM;
|
||||
dev->hw_features |= NETIF_F_FRAGLIST | NETIF_F_RXCSUM;
|
||||
dev->hw_features |= NETIF_F_GSO_SOFTWARE;
|
||||
|
@ -68,6 +68,7 @@ static int bareudp_udp_encap_recv(struct sock *sk, struct sk_buff *skb)
|
||||
__be16 proto;
|
||||
void *oiph;
|
||||
int err;
|
||||
int nh;
|
||||
|
||||
bareudp = rcu_dereference_sk_user_data(sk);
|
||||
if (!bareudp)
|
||||
@ -148,10 +149,25 @@ static int bareudp_udp_encap_recv(struct sock *sk, struct sk_buff *skb)
|
||||
}
|
||||
skb_dst_set(skb, &tun_dst->dst);
|
||||
skb->dev = bareudp->dev;
|
||||
oiph = skb_network_header(skb);
|
||||
skb_reset_network_header(skb);
|
||||
skb_reset_mac_header(skb);
|
||||
|
||||
/* Save offset of outer header relative to skb->head,
|
||||
* because we are going to reset the network header to the inner header
|
||||
* and might change skb->head.
|
||||
*/
|
||||
nh = skb_network_header(skb) - skb->head;
|
||||
|
||||
skb_reset_network_header(skb);
|
||||
|
||||
if (!pskb_inet_may_pull(skb)) {
|
||||
DEV_STATS_INC(bareudp->dev, rx_length_errors);
|
||||
DEV_STATS_INC(bareudp->dev, rx_errors);
|
||||
goto drop;
|
||||
}
|
||||
|
||||
/* Get the outer header. */
|
||||
oiph = skb->head + nh;
|
||||
|
||||
if (!ipv6_mod_enabled() || family == AF_INET)
|
||||
err = IP_ECN_decapsulate(oiph, skb);
|
||||
else
|
||||
@ -301,6 +317,9 @@ static int bareudp_xmit_skb(struct sk_buff *skb, struct net_device *dev,
|
||||
__be32 saddr;
|
||||
int err;
|
||||
|
||||
if (!skb_vlan_inet_prepare(skb, skb->protocol != htons(ETH_P_TEB)))
|
||||
return -EINVAL;
|
||||
|
||||
if (!sock)
|
||||
return -ESHUTDOWN;
|
||||
|
||||
@ -368,6 +387,9 @@ static int bareudp6_xmit_skb(struct sk_buff *skb, struct net_device *dev,
|
||||
__be16 sport;
|
||||
int err;
|
||||
|
||||
if (!skb_vlan_inet_prepare(skb, skb->protocol != htons(ETH_P_TEB)))
|
||||
return -EINVAL;
|
||||
|
||||
if (!sock)
|
||||
return -ESHUTDOWN;
|
||||
|
||||
@ -553,7 +575,6 @@ static void bareudp_setup(struct net_device *dev)
|
||||
SET_NETDEV_DEVTYPE(dev, &bareudp_type);
|
||||
dev->features |= NETIF_F_SG | NETIF_F_HW_CSUM | NETIF_F_FRAGLIST;
|
||||
dev->features |= NETIF_F_RXCSUM;
|
||||
dev->features |= NETIF_F_LLTX;
|
||||
dev->features |= NETIF_F_GSO_SOFTWARE;
|
||||
dev->hw_features |= NETIF_F_SG | NETIF_F_HW_CSUM | NETIF_F_FRAGLIST;
|
||||
dev->hw_features |= NETIF_F_RXCSUM;
|
||||
@ -566,6 +587,7 @@ static void bareudp_setup(struct net_device *dev)
|
||||
dev->type = ARPHRD_NONE;
|
||||
netif_keep_dst(dev);
|
||||
dev->priv_flags |= IFF_NO_QUEUE;
|
||||
dev->lltx = true;
|
||||
dev->flags = IFF_POINTOPOINT | IFF_NOARP | IFF_MULTICAST;
|
||||
dev->pcpu_stat_type = NETDEV_PCPU_STAT_TSTATS;
|
||||
}
|
||||
|
@ -418,6 +418,41 @@ static int bond_vlan_rx_kill_vid(struct net_device *bond_dev,
|
||||
/*---------------------------------- XFRM -----------------------------------*/
|
||||
|
||||
#ifdef CONFIG_XFRM_OFFLOAD
|
||||
/**
|
||||
* bond_ipsec_dev - Get active device for IPsec offload
|
||||
* @xs: pointer to transformer state struct
|
||||
*
|
||||
* Context: caller must hold rcu_read_lock.
|
||||
*
|
||||
* Return: the device for ipsec offload, or NULL if not exist.
|
||||
**/
|
||||
static struct net_device *bond_ipsec_dev(struct xfrm_state *xs)
|
||||
{
|
||||
struct net_device *bond_dev = xs->xso.dev;
|
||||
struct bonding *bond;
|
||||
struct slave *slave;
|
||||
|
||||
if (!bond_dev)
|
||||
return NULL;
|
||||
|
||||
bond = netdev_priv(bond_dev);
|
||||
if (BOND_MODE(bond) != BOND_MODE_ACTIVEBACKUP)
|
||||
return NULL;
|
||||
|
||||
slave = rcu_dereference(bond->curr_active_slave);
|
||||
if (!slave)
|
||||
return NULL;
|
||||
|
||||
if (!xs->xso.real_dev)
|
||||
return NULL;
|
||||
|
||||
if (xs->xso.real_dev != slave->dev)
|
||||
pr_warn_ratelimited("%s: (slave %s): not same with IPsec offload real dev %s\n",
|
||||
bond_dev->name, slave->dev->name, xs->xso.real_dev->name);
|
||||
|
||||
return slave->dev;
|
||||
}
|
||||
|
||||
/**
|
||||
* bond_ipsec_add_sa - program device with a security association
|
||||
* @xs: pointer to transformer state struct
|
||||
@ -640,23 +675,12 @@ static void bond_ipsec_free_sa(struct xfrm_state *xs)
|
||||
**/
|
||||
static bool bond_ipsec_offload_ok(struct sk_buff *skb, struct xfrm_state *xs)
|
||||
{
|
||||
struct net_device *bond_dev = xs->xso.dev;
|
||||
struct net_device *real_dev;
|
||||
struct slave *curr_active;
|
||||
struct bonding *bond;
|
||||
bool ok = false;
|
||||
|
||||
bond = netdev_priv(bond_dev);
|
||||
rcu_read_lock();
|
||||
curr_active = rcu_dereference(bond->curr_active_slave);
|
||||
if (!curr_active)
|
||||
goto out;
|
||||
real_dev = curr_active->dev;
|
||||
|
||||
if (BOND_MODE(bond) != BOND_MODE_ACTIVEBACKUP)
|
||||
goto out;
|
||||
|
||||
if (!xs->xso.real_dev)
|
||||
real_dev = bond_ipsec_dev(xs);
|
||||
if (!real_dev)
|
||||
goto out;
|
||||
|
||||
if (!real_dev->xfrmdev_ops ||
|
||||
@ -670,11 +694,61 @@ static bool bond_ipsec_offload_ok(struct sk_buff *skb, struct xfrm_state *xs)
|
||||
return ok;
|
||||
}
|
||||
|
||||
/**
|
||||
* bond_advance_esn_state - ESN support for IPSec HW offload
|
||||
* @xs: pointer to transformer state struct
|
||||
**/
|
||||
static void bond_advance_esn_state(struct xfrm_state *xs)
|
||||
{
|
||||
struct net_device *real_dev;
|
||||
|
||||
rcu_read_lock();
|
||||
real_dev = bond_ipsec_dev(xs);
|
||||
if (!real_dev)
|
||||
goto out;
|
||||
|
||||
if (!real_dev->xfrmdev_ops ||
|
||||
!real_dev->xfrmdev_ops->xdo_dev_state_advance_esn) {
|
||||
pr_warn_ratelimited("%s: %s doesn't support xdo_dev_state_advance_esn\n", __func__, real_dev->name);
|
||||
goto out;
|
||||
}
|
||||
|
||||
real_dev->xfrmdev_ops->xdo_dev_state_advance_esn(xs);
|
||||
out:
|
||||
rcu_read_unlock();
|
||||
}
|
||||
|
||||
/**
|
||||
* bond_xfrm_update_stats - Update xfrm state
|
||||
* @xs: pointer to transformer state struct
|
||||
**/
|
||||
static void bond_xfrm_update_stats(struct xfrm_state *xs)
|
||||
{
|
||||
struct net_device *real_dev;
|
||||
|
||||
rcu_read_lock();
|
||||
real_dev = bond_ipsec_dev(xs);
|
||||
if (!real_dev)
|
||||
goto out;
|
||||
|
||||
if (!real_dev->xfrmdev_ops ||
|
||||
!real_dev->xfrmdev_ops->xdo_dev_state_update_stats) {
|
||||
pr_warn_ratelimited("%s: %s doesn't support xdo_dev_state_update_stats\n", __func__, real_dev->name);
|
||||
goto out;
|
||||
}
|
||||
|
||||
real_dev->xfrmdev_ops->xdo_dev_state_update_stats(xs);
|
||||
out:
|
||||
rcu_read_unlock();
|
||||
}
|
||||
|
||||
static const struct xfrmdev_ops bond_xfrmdev_ops = {
|
||||
.xdo_dev_state_add = bond_ipsec_add_sa,
|
||||
.xdo_dev_state_delete = bond_ipsec_del_sa,
|
||||
.xdo_dev_state_free = bond_ipsec_free_sa,
|
||||
.xdo_dev_offload_ok = bond_ipsec_offload_ok,
|
||||
.xdo_dev_state_advance_esn = bond_advance_esn_state,
|
||||
.xdo_dev_state_update_stats = bond_xfrm_update_stats,
|
||||
};
|
||||
#endif /* CONFIG_XFRM_OFFLOAD */
|
||||
|
||||
@ -2300,7 +2374,7 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev,
|
||||
goto err_sysfs_del;
|
||||
}
|
||||
|
||||
res = slave_dev->netdev_ops->ndo_bpf(slave_dev, &xdp);
|
||||
res = dev_xdp_propagate(slave_dev, &xdp);
|
||||
if (res < 0) {
|
||||
/* ndo_bpf() sets extack error message */
|
||||
slave_dbg(bond_dev, slave_dev, "Error %d calling ndo_bpf\n", res);
|
||||
@ -2436,7 +2510,7 @@ static int __bond_release_one(struct net_device *bond_dev,
|
||||
.prog = NULL,
|
||||
.extack = NULL,
|
||||
};
|
||||
if (slave_dev->netdev_ops->ndo_bpf(slave_dev, &xdp))
|
||||
if (dev_xdp_propagate(slave_dev, &xdp))
|
||||
slave_warn(bond_dev, slave_dev, "failed to unload XDP program\n");
|
||||
}
|
||||
|
||||
@ -5626,7 +5700,7 @@ static int bond_xdp_set(struct net_device *dev, struct bpf_prog *prog,
|
||||
goto err;
|
||||
}
|
||||
|
||||
err = slave_dev->netdev_ops->ndo_bpf(slave_dev, &xdp);
|
||||
err = dev_xdp_propagate(slave_dev, &xdp);
|
||||
if (err < 0) {
|
||||
/* ndo_bpf() sets extack error message */
|
||||
slave_err(dev, slave_dev, "Error %d calling ndo_bpf\n", err);
|
||||
@ -5658,7 +5732,7 @@ static int bond_xdp_set(struct net_device *dev, struct bpf_prog *prog,
|
||||
if (slave == rollback_slave)
|
||||
break;
|
||||
|
||||
err_unwind = slave_dev->netdev_ops->ndo_bpf(slave_dev, &xdp);
|
||||
err_unwind = dev_xdp_propagate(slave_dev, &xdp);
|
||||
if (err_unwind < 0)
|
||||
slave_err(dev, slave_dev,
|
||||
"Error %d when unwinding XDP program change\n", err_unwind);
|
||||
@ -5812,9 +5886,6 @@ static int bond_ethtool_get_ts_info(struct net_device *bond_dev,
|
||||
if (real_dev) {
|
||||
ret = ethtool_get_ts_info_by_layer(real_dev, info);
|
||||
} else {
|
||||
info->phc_index = -1;
|
||||
info->so_timestamping = SOF_TIMESTAMPING_RX_SOFTWARE |
|
||||
SOF_TIMESTAMPING_SOFTWARE;
|
||||
/* Check if all slaves support software tx timestamping */
|
||||
rcu_read_lock();
|
||||
bond_for_each_slave_rcu(bond, slave, iter) {
|
||||
@ -5928,7 +5999,10 @@ void bond_setup(struct net_device *bond_dev)
|
||||
#endif /* CONFIG_XFRM_OFFLOAD */
|
||||
|
||||
/* don't acquire bond device's netif_tx_lock when transmitting */
|
||||
bond_dev->features |= NETIF_F_LLTX;
|
||||
bond_dev->lltx = true;
|
||||
|
||||
/* Don't allow bond devices to change network namespaces. */
|
||||
bond_dev->netns_local = true;
|
||||
|
||||
/* By default, we declare the bond to be fully
|
||||
* VLAN hardware accelerated capable. Special
|
||||
@ -5937,9 +6011,6 @@ void bond_setup(struct net_device *bond_dev)
|
||||
* capable
|
||||
*/
|
||||
|
||||
/* Don't allow bond devices to change network namespaces. */
|
||||
bond_dev->features |= NETIF_F_NETNS_LOCAL;
|
||||
|
||||
bond_dev->hw_features = BOND_VLAN_FEATURES |
|
||||
NETIF_F_HW_VLAN_CTAG_RX |
|
||||
NETIF_F_HW_VLAN_CTAG_FILTER |
|
||||
@ -6384,7 +6455,8 @@ static int bond_init(struct net_device *bond_dev)
|
||||
|
||||
netdev_dbg(bond_dev, "Begin bond_init\n");
|
||||
|
||||
bond->wq = alloc_ordered_workqueue(bond_dev->name, WQ_MEM_RECLAIM);
|
||||
bond->wq = alloc_ordered_workqueue("%s", WQ_MEM_RECLAIM,
|
||||
bond_dev->name);
|
||||
if (!bond->wq)
|
||||
return -ENOMEM;
|
||||
|
||||
|
@ -225,6 +225,7 @@ source "drivers/net/can/m_can/Kconfig"
|
||||
source "drivers/net/can/mscan/Kconfig"
|
||||
source "drivers/net/can/peak_canfd/Kconfig"
|
||||
source "drivers/net/can/rcar/Kconfig"
|
||||
source "drivers/net/can/rockchip/Kconfig"
|
||||
source "drivers/net/can/sja1000/Kconfig"
|
||||
source "drivers/net/can/softing/Kconfig"
|
||||
source "drivers/net/can/spi/Kconfig"
|
||||
|
@ -10,6 +10,7 @@ obj-$(CONFIG_CAN_SLCAN) += slcan/
|
||||
obj-y += dev/
|
||||
obj-y += esd/
|
||||
obj-y += rcar/
|
||||
obj-y += rockchip/
|
||||
obj-y += spi/
|
||||
obj-y += usb/
|
||||
obj-y += softing/
|
||||
|
@ -1191,7 +1191,7 @@ MODULE_DEVICE_TABLE(platform, at91_can_id_table);
|
||||
|
||||
static struct platform_driver at91_can_driver = {
|
||||
.probe = at91_can_probe,
|
||||
.remove_new = at91_can_remove,
|
||||
.remove = at91_can_remove,
|
||||
.driver = {
|
||||
.name = KBUILD_MODNAME,
|
||||
.of_match_table = of_match_ptr(at91_can_dt_ids),
|
||||
|
@ -1092,7 +1092,7 @@ static struct platform_driver bxcan_driver = {
|
||||
.of_match_table = bxcan_of_match,
|
||||
},
|
||||
.probe = bxcan_probe,
|
||||
.remove_new = bxcan_remove,
|
||||
.remove = bxcan_remove,
|
||||
};
|
||||
|
||||
module_platform_driver(bxcan_driver);
|
||||
|
@ -476,7 +476,7 @@ static struct platform_driver c_can_plat_driver = {
|
||||
.of_match_table = c_can_of_table,
|
||||
},
|
||||
.probe = c_can_plat_probe,
|
||||
.remove_new = c_can_plat_remove,
|
||||
.remove = c_can_plat_remove,
|
||||
.suspend = c_can_suspend,
|
||||
.resume = c_can_resume,
|
||||
.id_table = c_can_id_table,
|
||||
|
@ -307,7 +307,7 @@ static void cc770_isa_remove(struct platform_device *pdev)
|
||||
|
||||
static struct platform_driver cc770_isa_driver = {
|
||||
.probe = cc770_isa_probe,
|
||||
.remove_new = cc770_isa_remove,
|
||||
.remove = cc770_isa_remove,
|
||||
.driver = {
|
||||
.name = KBUILD_MODNAME,
|
||||
},
|
||||
|
@ -70,17 +70,10 @@ static void cc770_platform_write_reg(const struct cc770_priv *priv, int reg,
|
||||
static int cc770_get_of_node_data(struct platform_device *pdev,
|
||||
struct cc770_priv *priv)
|
||||
{
|
||||
u32 clkext = CC770_PLATFORM_CAN_CLOCK, clkout = 0;
|
||||
struct device_node *np = pdev->dev.of_node;
|
||||
const u32 *prop;
|
||||
int prop_size;
|
||||
u32 clkext;
|
||||
|
||||
prop = of_get_property(np, "bosch,external-clock-frequency",
|
||||
&prop_size);
|
||||
if (prop && (prop_size == sizeof(u32)))
|
||||
clkext = *prop;
|
||||
else
|
||||
clkext = CC770_PLATFORM_CAN_CLOCK; /* default */
|
||||
of_property_read_u32(np, "bosch,external-clock-frequency", &clkext);
|
||||
priv->can.clock.freq = clkext;
|
||||
|
||||
/* The system clock may not exceed 10 MHz */
|
||||
@ -98,7 +91,7 @@ static int cc770_get_of_node_data(struct platform_device *pdev,
|
||||
if (of_property_read_bool(np, "bosch,iso-low-speed-mux"))
|
||||
priv->cpu_interface |= CPUIF_MUX;
|
||||
|
||||
if (!of_get_property(np, "bosch,no-comperator-bypass", NULL))
|
||||
if (!of_property_read_bool(np, "bosch,no-comperator-bypass"))
|
||||
priv->bus_config |= BUSCFG_CBY;
|
||||
if (of_property_read_bool(np, "bosch,disconnect-rx0-input"))
|
||||
priv->bus_config |= BUSCFG_DR0;
|
||||
@ -109,25 +102,22 @@ static int cc770_get_of_node_data(struct platform_device *pdev,
|
||||
if (of_property_read_bool(np, "bosch,polarity-dominant"))
|
||||
priv->bus_config |= BUSCFG_POL;
|
||||
|
||||
prop = of_get_property(np, "bosch,clock-out-frequency", &prop_size);
|
||||
if (prop && (prop_size == sizeof(u32)) && *prop > 0) {
|
||||
u32 cdv = clkext / *prop;
|
||||
int slew;
|
||||
of_property_read_u32(np, "bosch,clock-out-frequency", &clkout);
|
||||
if (clkout > 0) {
|
||||
u32 cdv = clkext / clkout;
|
||||
|
||||
if (cdv > 0 && cdv < 16) {
|
||||
u32 slew;
|
||||
|
||||
priv->cpu_interface |= CPUIF_CEN;
|
||||
priv->clkout |= (cdv - 1) & CLKOUT_CD_MASK;
|
||||
|
||||
prop = of_get_property(np, "bosch,slew-rate",
|
||||
&prop_size);
|
||||
if (prop && (prop_size == sizeof(u32))) {
|
||||
slew = *prop;
|
||||
} else {
|
||||
if (of_property_read_u32(np, "bosch,slew-rate", &slew)) {
|
||||
/* Determine default slew rate */
|
||||
slew = (CLKOUT_SL_MASK >>
|
||||
CLKOUT_SL_SHIFT) -
|
||||
((cdv * clkext - 1) / 8000000);
|
||||
if (slew < 0)
|
||||
if (slew > (CLKOUT_SL_MASK >> CLKOUT_SL_SHIFT))
|
||||
slew = 0;
|
||||
}
|
||||
priv->clkout |= (slew << CLKOUT_SL_SHIFT) &
|
||||
@ -257,7 +247,7 @@ static struct platform_driver cc770_platform_driver = {
|
||||
.of_match_table = cc770_platform_table,
|
||||
},
|
||||
.probe = cc770_platform_probe,
|
||||
.remove_new = cc770_platform_remove,
|
||||
.remove = cc770_platform_remove,
|
||||
};
|
||||
|
||||
module_platform_driver(cc770_platform_driver);
|
||||
|
@ -111,7 +111,7 @@ MODULE_DEVICE_TABLE(of, ctucan_of_match);
|
||||
|
||||
static struct platform_driver ctucanfd_driver = {
|
||||
.probe = ctucan_platform_probe,
|
||||
.remove_new = ctucan_platform_remove,
|
||||
.remove = ctucan_platform_remove,
|
||||
.driver = {
|
||||
.name = DRV_NAME,
|
||||
.pm = &ctucan_platform_pm_ops,
|
||||
|
@ -380,12 +380,9 @@ int can_ethtool_op_get_ts_info_hwts(struct net_device *dev,
|
||||
{
|
||||
info->so_timestamping =
|
||||
SOF_TIMESTAMPING_TX_SOFTWARE |
|
||||
SOF_TIMESTAMPING_RX_SOFTWARE |
|
||||
SOF_TIMESTAMPING_SOFTWARE |
|
||||
SOF_TIMESTAMPING_TX_HARDWARE |
|
||||
SOF_TIMESTAMPING_RX_HARDWARE |
|
||||
SOF_TIMESTAMPING_RAW_HARDWARE;
|
||||
info->phc_index = -1;
|
||||
info->tx_types = BIT(HWTSTAMP_TX_ON);
|
||||
info->rx_filters = BIT(HWTSTAMP_FILTER_ALL);
|
||||
|
||||
|
@ -65,15 +65,6 @@ static int can_validate(struct nlattr *tb[], struct nlattr *data[],
|
||||
if (!data)
|
||||
return 0;
|
||||
|
||||
if (data[IFLA_CAN_BITTIMING]) {
|
||||
struct can_bittiming bt;
|
||||
|
||||
memcpy(&bt, nla_data(data[IFLA_CAN_BITTIMING]), sizeof(bt));
|
||||
err = can_validate_bittiming(&bt, extack);
|
||||
if (err)
|
||||
return err;
|
||||
}
|
||||
|
||||
if (data[IFLA_CAN_CTRLMODE]) {
|
||||
struct can_ctrlmode *cm = nla_data(data[IFLA_CAN_CTRLMODE]);
|
||||
u32 tdc_flags = cm->flags & CAN_CTRLMODE_TDC_MASK;
|
||||
@ -114,6 +105,15 @@ static int can_validate(struct nlattr *tb[], struct nlattr *data[],
|
||||
}
|
||||
}
|
||||
|
||||
if (data[IFLA_CAN_BITTIMING]) {
|
||||
struct can_bittiming bt;
|
||||
|
||||
memcpy(&bt, nla_data(data[IFLA_CAN_BITTIMING]), sizeof(bt));
|
||||
err = can_validate_bittiming(&bt, extack);
|
||||
if (err)
|
||||
return err;
|
||||
}
|
||||
|
||||
if (is_can_fd) {
|
||||
if (!data[IFLA_CAN_BITTIMING] || !data[IFLA_CAN_DATA_BITTIMING])
|
||||
return -EOPNOTSUPP;
|
||||
@ -195,48 +195,6 @@ static int can_changelink(struct net_device *dev, struct nlattr *tb[],
|
||||
/* We need synchronization with dev->stop() */
|
||||
ASSERT_RTNL();
|
||||
|
||||
if (data[IFLA_CAN_BITTIMING]) {
|
||||
struct can_bittiming bt;
|
||||
|
||||
/* Do not allow changing bittiming while running */
|
||||
if (dev->flags & IFF_UP)
|
||||
return -EBUSY;
|
||||
|
||||
/* Calculate bittiming parameters based on
|
||||
* bittiming_const if set, otherwise pass bitrate
|
||||
* directly via do_set_bitrate(). Bail out if neither
|
||||
* is given.
|
||||
*/
|
||||
if (!priv->bittiming_const && !priv->do_set_bittiming &&
|
||||
!priv->bitrate_const)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
memcpy(&bt, nla_data(data[IFLA_CAN_BITTIMING]), sizeof(bt));
|
||||
err = can_get_bittiming(dev, &bt,
|
||||
priv->bittiming_const,
|
||||
priv->bitrate_const,
|
||||
priv->bitrate_const_cnt,
|
||||
extack);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
if (priv->bitrate_max && bt.bitrate > priv->bitrate_max) {
|
||||
NL_SET_ERR_MSG_FMT(extack,
|
||||
"arbitration bitrate %u bps surpasses transceiver capabilities of %u bps",
|
||||
bt.bitrate, priv->bitrate_max);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
memcpy(&priv->bittiming, &bt, sizeof(bt));
|
||||
|
||||
if (priv->do_set_bittiming) {
|
||||
/* Finally, set the bit-timing registers */
|
||||
err = priv->do_set_bittiming(dev);
|
||||
if (err)
|
||||
return err;
|
||||
}
|
||||
}
|
||||
|
||||
if (data[IFLA_CAN_CTRLMODE]) {
|
||||
struct can_ctrlmode *cm;
|
||||
u32 ctrlstatic;
|
||||
@ -284,6 +242,48 @@ static int can_changelink(struct net_device *dev, struct nlattr *tb[],
|
||||
priv->ctrlmode &= cm->flags | ~CAN_CTRLMODE_TDC_MASK;
|
||||
}
|
||||
|
||||
if (data[IFLA_CAN_BITTIMING]) {
|
||||
struct can_bittiming bt;
|
||||
|
||||
/* Do not allow changing bittiming while running */
|
||||
if (dev->flags & IFF_UP)
|
||||
return -EBUSY;
|
||||
|
||||
/* Calculate bittiming parameters based on
|
||||
* bittiming_const if set, otherwise pass bitrate
|
||||
* directly via do_set_bitrate(). Bail out if neither
|
||||
* is given.
|
||||
*/
|
||||
if (!priv->bittiming_const && !priv->do_set_bittiming &&
|
||||
!priv->bitrate_const)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
memcpy(&bt, nla_data(data[IFLA_CAN_BITTIMING]), sizeof(bt));
|
||||
err = can_get_bittiming(dev, &bt,
|
||||
priv->bittiming_const,
|
||||
priv->bitrate_const,
|
||||
priv->bitrate_const_cnt,
|
||||
extack);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
if (priv->bitrate_max && bt.bitrate > priv->bitrate_max) {
|
||||
NL_SET_ERR_MSG_FMT(extack,
|
||||
"arbitration bitrate %u bps surpasses transceiver capabilities of %u bps",
|
||||
bt.bitrate, priv->bitrate_max);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
memcpy(&priv->bittiming, &bt, sizeof(bt));
|
||||
|
||||
if (priv->do_set_bittiming) {
|
||||
/* Finally, set the bit-timing registers */
|
||||
err = priv->do_set_bittiming(dev);
|
||||
if (err)
|
||||
return err;
|
||||
}
|
||||
}
|
||||
|
||||
if (data[IFLA_CAN_RESTART_MS]) {
|
||||
/* Do not allow changing restart delay while running */
|
||||
if (dev->flags & IFF_UP)
|
||||
|
@ -369,12 +369,13 @@ static int pci402_init_cores(struct pci_dev *pdev)
|
||||
SET_NETDEV_DEV(netdev, &pdev->dev);
|
||||
|
||||
priv = netdev_priv(netdev);
|
||||
priv->can.clock.freq = card->ov.core_frequency;
|
||||
priv->can.ctrlmode_supported = CAN_CTRLMODE_LOOPBACK |
|
||||
CAN_CTRLMODE_LISTENONLY |
|
||||
CAN_CTRLMODE_BERR_REPORTING |
|
||||
CAN_CTRLMODE_CC_LEN8_DLC;
|
||||
|
||||
priv->can.clock.freq = card->ov.core_frequency;
|
||||
if (card->ov.features & ACC_OV_REG_FEAT_MASK_DAR)
|
||||
priv->can.ctrlmode_supported |= CAN_CTRLMODE_ONE_SHOT;
|
||||
if (card->ov.features & ACC_OV_REG_FEAT_MASK_CANFD)
|
||||
priv->can.bittiming_const = &pci402_bittiming_const_canfd;
|
||||
else
|
||||
|
@ -17,6 +17,9 @@
|
||||
/* esdACC DLC register layout */
|
||||
#define ACC_DLC_DLC_MASK GENMASK(3, 0)
|
||||
#define ACC_DLC_RTR_FLAG BIT(4)
|
||||
#define ACC_DLC_SSTX_FLAG BIT(24) /* Single Shot TX */
|
||||
|
||||
/* esdACC DLC in struct acc_bmmsg_rxtxdone::acc_dlc.len only! */
|
||||
#define ACC_DLC_TXD_FLAG BIT(5)
|
||||
|
||||
/* ecc value of esdACC equals SJA1000's ECC register */
|
||||
@ -43,8 +46,8 @@
|
||||
|
||||
static void acc_resetmode_enter(struct acc_core *core)
|
||||
{
|
||||
acc_set_bits(core, ACC_CORE_OF_CTRL_MODE,
|
||||
ACC_REG_CONTROL_MASK_MODE_RESETMODE);
|
||||
acc_set_bits(core, ACC_CORE_OF_CTRL,
|
||||
ACC_REG_CTRL_MASK_RESETMODE);
|
||||
|
||||
/* Read back reset mode bit to flush PCI write posting */
|
||||
acc_resetmode_entered(core);
|
||||
@ -52,14 +55,14 @@ static void acc_resetmode_enter(struct acc_core *core)
|
||||
|
||||
static void acc_resetmode_leave(struct acc_core *core)
|
||||
{
|
||||
acc_clear_bits(core, ACC_CORE_OF_CTRL_MODE,
|
||||
ACC_REG_CONTROL_MASK_MODE_RESETMODE);
|
||||
acc_clear_bits(core, ACC_CORE_OF_CTRL,
|
||||
ACC_REG_CTRL_MASK_RESETMODE);
|
||||
|
||||
/* Read back reset mode bit to flush PCI write posting */
|
||||
acc_resetmode_entered(core);
|
||||
}
|
||||
|
||||
static void acc_txq_put(struct acc_core *core, u32 acc_id, u8 acc_dlc,
|
||||
static void acc_txq_put(struct acc_core *core, u32 acc_id, u32 acc_dlc,
|
||||
const void *data)
|
||||
{
|
||||
acc_write32_noswap(core, ACC_CORE_OF_TXFIFO_DATA_1,
|
||||
@ -172,7 +175,7 @@ int acc_open(struct net_device *netdev)
|
||||
struct acc_net_priv *priv = netdev_priv(netdev);
|
||||
struct acc_core *core = priv->core;
|
||||
u32 tx_fifo_status;
|
||||
u32 ctrl_mode;
|
||||
u32 ctrl;
|
||||
int err;
|
||||
|
||||
/* Retry to enter RESET mode if out of sync. */
|
||||
@ -187,19 +190,19 @@ int acc_open(struct net_device *netdev)
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
ctrl_mode = ACC_REG_CONTROL_MASK_IE_RXTX |
|
||||
ACC_REG_CONTROL_MASK_IE_TXERROR |
|
||||
ACC_REG_CONTROL_MASK_IE_ERRWARN |
|
||||
ACC_REG_CONTROL_MASK_IE_OVERRUN |
|
||||
ACC_REG_CONTROL_MASK_IE_ERRPASS;
|
||||
ctrl = ACC_REG_CTRL_MASK_IE_RXTX |
|
||||
ACC_REG_CTRL_MASK_IE_TXERROR |
|
||||
ACC_REG_CTRL_MASK_IE_ERRWARN |
|
||||
ACC_REG_CTRL_MASK_IE_OVERRUN |
|
||||
ACC_REG_CTRL_MASK_IE_ERRPASS;
|
||||
|
||||
if (priv->can.ctrlmode & CAN_CTRLMODE_BERR_REPORTING)
|
||||
ctrl_mode |= ACC_REG_CONTROL_MASK_IE_BUSERR;
|
||||
ctrl |= ACC_REG_CTRL_MASK_IE_BUSERR;
|
||||
|
||||
if (priv->can.ctrlmode & CAN_CTRLMODE_LISTENONLY)
|
||||
ctrl_mode |= ACC_REG_CONTROL_MASK_MODE_LOM;
|
||||
ctrl |= ACC_REG_CTRL_MASK_LOM;
|
||||
|
||||
acc_set_bits(core, ACC_CORE_OF_CTRL_MODE, ctrl_mode);
|
||||
acc_set_bits(core, ACC_CORE_OF_CTRL, ctrl);
|
||||
|
||||
acc_resetmode_leave(core);
|
||||
priv->can.state = CAN_STATE_ERROR_ACTIVE;
|
||||
@ -218,13 +221,13 @@ int acc_close(struct net_device *netdev)
|
||||
struct acc_net_priv *priv = netdev_priv(netdev);
|
||||
struct acc_core *core = priv->core;
|
||||
|
||||
acc_clear_bits(core, ACC_CORE_OF_CTRL_MODE,
|
||||
ACC_REG_CONTROL_MASK_IE_RXTX |
|
||||
ACC_REG_CONTROL_MASK_IE_TXERROR |
|
||||
ACC_REG_CONTROL_MASK_IE_ERRWARN |
|
||||
ACC_REG_CONTROL_MASK_IE_OVERRUN |
|
||||
ACC_REG_CONTROL_MASK_IE_ERRPASS |
|
||||
ACC_REG_CONTROL_MASK_IE_BUSERR);
|
||||
acc_clear_bits(core, ACC_CORE_OF_CTRL,
|
||||
ACC_REG_CTRL_MASK_IE_RXTX |
|
||||
ACC_REG_CTRL_MASK_IE_TXERROR |
|
||||
ACC_REG_CTRL_MASK_IE_ERRWARN |
|
||||
ACC_REG_CTRL_MASK_IE_OVERRUN |
|
||||
ACC_REG_CTRL_MASK_IE_ERRPASS |
|
||||
ACC_REG_CTRL_MASK_IE_BUSERR);
|
||||
|
||||
netif_stop_queue(netdev);
|
||||
acc_resetmode_enter(core);
|
||||
@ -233,9 +236,9 @@ int acc_close(struct net_device *netdev)
|
||||
/* Mark pending TX requests to be aborted after controller restart. */
|
||||
acc_write32(core, ACC_CORE_OF_TX_ABORT_MASK, 0xffff);
|
||||
|
||||
/* ACC_REG_CONTROL_MASK_MODE_LOM is only accessible in RESET mode */
|
||||
acc_clear_bits(core, ACC_CORE_OF_CTRL_MODE,
|
||||
ACC_REG_CONTROL_MASK_MODE_LOM);
|
||||
/* ACC_REG_CTRL_MASK_LOM is only accessible in RESET mode */
|
||||
acc_clear_bits(core, ACC_CORE_OF_CTRL,
|
||||
ACC_REG_CTRL_MASK_LOM);
|
||||
|
||||
close_candev(netdev);
|
||||
return 0;
|
||||
@ -249,7 +252,7 @@ netdev_tx_t acc_start_xmit(struct sk_buff *skb, struct net_device *netdev)
|
||||
u8 tx_fifo_head = core->tx_fifo_head;
|
||||
int fifo_usage;
|
||||
u32 acc_id;
|
||||
u8 acc_dlc;
|
||||
u32 acc_dlc;
|
||||
|
||||
if (can_dropped_invalid_skb(netdev, skb))
|
||||
return NETDEV_TX_OK;
|
||||
@ -274,6 +277,8 @@ netdev_tx_t acc_start_xmit(struct sk_buff *skb, struct net_device *netdev)
|
||||
acc_dlc = can_get_cc_dlc(cf, priv->can.ctrlmode);
|
||||
if (cf->can_id & CAN_RTR_FLAG)
|
||||
acc_dlc |= ACC_DLC_RTR_FLAG;
|
||||
if (priv->can.ctrlmode & CAN_CTRLMODE_ONE_SHOT)
|
||||
acc_dlc |= ACC_DLC_SSTX_FLAG;
|
||||
|
||||
if (cf->can_id & CAN_EFF_FLAG) {
|
||||
acc_id = cf->can_id & CAN_EFF_MASK;
|
||||
|
@ -35,6 +35,7 @@
|
||||
*/
|
||||
#define ACC_OV_REG_FEAT_MASK_CANFD BIT(27 - 16)
|
||||
#define ACC_OV_REG_FEAT_MASK_NEW_PSC BIT(28 - 16)
|
||||
#define ACC_OV_REG_FEAT_MASK_DAR BIT(30 - 16)
|
||||
|
||||
#define ACC_OV_REG_MODE_MASK_ENDIAN_LITTLE BIT(0)
|
||||
#define ACC_OV_REG_MODE_MASK_BM_ENABLE BIT(1)
|
||||
@ -50,7 +51,7 @@
|
||||
#define ACC_OV_REG_MODE_MASK_FPGA_RESET BIT(31)
|
||||
|
||||
/* esdACC CAN Core Module */
|
||||
#define ACC_CORE_OF_CTRL_MODE 0x0000
|
||||
#define ACC_CORE_OF_CTRL 0x0000
|
||||
#define ACC_CORE_OF_STATUS_IRQ 0x0008
|
||||
#define ACC_CORE_OF_BRP 0x000c
|
||||
#define ACC_CORE_OF_BTR 0x0010
|
||||
@ -66,21 +67,22 @@
|
||||
#define ACC_CORE_OF_TXFIFO_DATA_0 0x00c8
|
||||
#define ACC_CORE_OF_TXFIFO_DATA_1 0x00cc
|
||||
|
||||
#define ACC_REG_CONTROL_MASK_MODE_RESETMODE BIT(0)
|
||||
#define ACC_REG_CONTROL_MASK_MODE_LOM BIT(1)
|
||||
#define ACC_REG_CONTROL_MASK_MODE_STM BIT(2)
|
||||
#define ACC_REG_CONTROL_MASK_MODE_TRANSEN BIT(5)
|
||||
#define ACC_REG_CONTROL_MASK_MODE_TS BIT(6)
|
||||
#define ACC_REG_CONTROL_MASK_MODE_SCHEDULE BIT(7)
|
||||
/* CTRL register layout */
|
||||
#define ACC_REG_CTRL_MASK_RESETMODE BIT(0)
|
||||
#define ACC_REG_CTRL_MASK_LOM BIT(1)
|
||||
#define ACC_REG_CTRL_MASK_STM BIT(2)
|
||||
#define ACC_REG_CTRL_MASK_TRANSEN BIT(5)
|
||||
#define ACC_REG_CTRL_MASK_TS BIT(6)
|
||||
#define ACC_REG_CTRL_MASK_SCHEDULE BIT(7)
|
||||
|
||||
#define ACC_REG_CONTROL_MASK_IE_RXTX BIT(8)
|
||||
#define ACC_REG_CONTROL_MASK_IE_TXERROR BIT(9)
|
||||
#define ACC_REG_CONTROL_MASK_IE_ERRWARN BIT(10)
|
||||
#define ACC_REG_CONTROL_MASK_IE_OVERRUN BIT(11)
|
||||
#define ACC_REG_CONTROL_MASK_IE_TSI BIT(12)
|
||||
#define ACC_REG_CONTROL_MASK_IE_ERRPASS BIT(13)
|
||||
#define ACC_REG_CONTROL_MASK_IE_ALI BIT(14)
|
||||
#define ACC_REG_CONTROL_MASK_IE_BUSERR BIT(15)
|
||||
#define ACC_REG_CTRL_MASK_IE_RXTX BIT(8)
|
||||
#define ACC_REG_CTRL_MASK_IE_TXERROR BIT(9)
|
||||
#define ACC_REG_CTRL_MASK_IE_ERRWARN BIT(10)
|
||||
#define ACC_REG_CTRL_MASK_IE_OVERRUN BIT(11)
|
||||
#define ACC_REG_CTRL_MASK_IE_TSI BIT(12)
|
||||
#define ACC_REG_CTRL_MASK_IE_ERRPASS BIT(13)
|
||||
#define ACC_REG_CTRL_MASK_IE_ALI BIT(14)
|
||||
#define ACC_REG_CTRL_MASK_IE_BUSERR BIT(15)
|
||||
|
||||
/* BRP and BTR register layout for CAN-Classic version */
|
||||
#define ACC_REG_BRP_CL_MASK_BRP GENMASK(8, 0)
|
||||
@ -300,9 +302,9 @@ static inline void acc_clear_bits(struct acc_core *core,
|
||||
|
||||
static inline int acc_resetmode_entered(struct acc_core *core)
|
||||
{
|
||||
u32 ctrl = acc_read32(core, ACC_CORE_OF_CTRL_MODE);
|
||||
u32 ctrl = acc_read32(core, ACC_CORE_OF_CTRL);
|
||||
|
||||
return (ctrl & ACC_REG_CONTROL_MASK_MODE_RESETMODE) != 0;
|
||||
return (ctrl & ACC_REG_CTRL_MASK_RESETMODE) != 0;
|
||||
}
|
||||
|
||||
static inline u32 acc_ov_read32(struct acc_ov *ov, unsigned short offs)
|
||||
|
@ -354,6 +354,14 @@ static struct flexcan_devtype_data fsl_imx93_devtype_data = {
|
||||
FLEXCAN_QUIRK_SUPPORT_RX_MAILBOX_RTR,
|
||||
};
|
||||
|
||||
static const struct flexcan_devtype_data fsl_imx95_devtype_data = {
|
||||
.quirks = FLEXCAN_QUIRK_DISABLE_RXFG | FLEXCAN_QUIRK_ENABLE_EACEN_RRS |
|
||||
FLEXCAN_QUIRK_DISABLE_MECR | FLEXCAN_QUIRK_USE_RX_MAILBOX |
|
||||
FLEXCAN_QUIRK_BROKEN_PERR_STATE | FLEXCAN_QUIRK_SUPPORT_FD |
|
||||
FLEXCAN_QUIRK_SUPPORT_ECC | FLEXCAN_QUIRK_SUPPORT_RX_MAILBOX |
|
||||
FLEXCAN_QUIRK_SUPPORT_RX_MAILBOX_RTR | FLEXCAN_QUIRK_SETUP_STOP_MODE_SCMI,
|
||||
};
|
||||
|
||||
static const struct flexcan_devtype_data fsl_vf610_devtype_data = {
|
||||
.quirks = FLEXCAN_QUIRK_DISABLE_RXFG | FLEXCAN_QUIRK_ENABLE_EACEN_RRS |
|
||||
FLEXCAN_QUIRK_DISABLE_MECR | FLEXCAN_QUIRK_USE_RX_MAILBOX |
|
||||
@ -544,6 +552,13 @@ static inline int flexcan_enter_stop_mode(struct flexcan_priv *priv)
|
||||
} else if (priv->devtype_data.quirks & FLEXCAN_QUIRK_SETUP_STOP_MODE_GPR) {
|
||||
regmap_update_bits(priv->stm.gpr, priv->stm.req_gpr,
|
||||
1 << priv->stm.req_bit, 1 << priv->stm.req_bit);
|
||||
} else if (priv->devtype_data.quirks & FLEXCAN_QUIRK_SETUP_STOP_MODE_SCMI) {
|
||||
/* For the SCMI mode, driver do nothing, ATF will send request to
|
||||
* SM(system manager, M33 core) through SCMI protocol after linux
|
||||
* suspend. Once SM get this request, it will send IPG_STOP signal
|
||||
* to Flex_CAN, let CAN in STOP mode.
|
||||
*/
|
||||
return 0;
|
||||
}
|
||||
|
||||
return flexcan_low_power_enter_ack(priv);
|
||||
@ -555,7 +570,11 @@ static inline int flexcan_exit_stop_mode(struct flexcan_priv *priv)
|
||||
u32 reg_mcr;
|
||||
int ret;
|
||||
|
||||
/* remove stop request */
|
||||
/* Remove stop request, for FLEXCAN_QUIRK_SETUP_STOP_MODE_SCMI,
|
||||
* do nothing here, because ATF already send request to SM before
|
||||
* linux resume. Once SM get this request, it will deassert the
|
||||
* IPG_STOP signal to Flex_CAN.
|
||||
*/
|
||||
if (priv->devtype_data.quirks & FLEXCAN_QUIRK_SETUP_STOP_MODE_SCFW) {
|
||||
ret = flexcan_stop_mode_enable_scfw(priv, false);
|
||||
if (ret < 0)
|
||||
@ -1983,6 +2002,9 @@ static int flexcan_setup_stop_mode(struct platform_device *pdev)
|
||||
ret = flexcan_setup_stop_mode_scfw(pdev);
|
||||
else if (priv->devtype_data.quirks & FLEXCAN_QUIRK_SETUP_STOP_MODE_GPR)
|
||||
ret = flexcan_setup_stop_mode_gpr(pdev);
|
||||
else if (priv->devtype_data.quirks & FLEXCAN_QUIRK_SETUP_STOP_MODE_SCMI)
|
||||
/* ATF will handle all STOP_IPG related work */
|
||||
ret = 0;
|
||||
else
|
||||
/* return 0 directly if doesn't support stop mode feature */
|
||||
return 0;
|
||||
@ -2009,6 +2031,7 @@ static const struct of_device_id flexcan_of_match[] = {
|
||||
{ .compatible = "fsl,imx8qm-flexcan", .data = &fsl_imx8qm_devtype_data, },
|
||||
{ .compatible = "fsl,imx8mp-flexcan", .data = &fsl_imx8mp_devtype_data, },
|
||||
{ .compatible = "fsl,imx93-flexcan", .data = &fsl_imx93_devtype_data, },
|
||||
{ .compatible = "fsl,imx95-flexcan", .data = &fsl_imx95_devtype_data, },
|
||||
{ .compatible = "fsl,imx6q-flexcan", .data = &fsl_imx6q_devtype_data, },
|
||||
{ .compatible = "fsl,imx28-flexcan", .data = &fsl_imx28_devtype_data, },
|
||||
{ .compatible = "fsl,imx53-flexcan", .data = &fsl_imx25_devtype_data, },
|
||||
@ -2309,9 +2332,19 @@ static int __maybe_unused flexcan_noirq_suspend(struct device *device)
|
||||
if (device_may_wakeup(device))
|
||||
flexcan_enable_wakeup_irq(priv, true);
|
||||
|
||||
err = pm_runtime_force_suspend(device);
|
||||
if (err)
|
||||
return err;
|
||||
/* For FLEXCAN_QUIRK_SETUP_STOP_MODE_SCMI, it need ATF to send
|
||||
* to SM through SCMI protocol, SM will assert the IPG_STOP
|
||||
* signal. But all this works need the CAN clocks keep on.
|
||||
* After the CAN module get the IPG_STOP mode, and switch to
|
||||
* STOP mode, whether still keep the CAN clocks on or gate them
|
||||
* off depend on the Hardware design.
|
||||
*/
|
||||
if (!(device_may_wakeup(device) &&
|
||||
priv->devtype_data.quirks & FLEXCAN_QUIRK_SETUP_STOP_MODE_SCMI)) {
|
||||
err = pm_runtime_force_suspend(device);
|
||||
if (err)
|
||||
return err;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
@ -2325,9 +2358,12 @@ static int __maybe_unused flexcan_noirq_resume(struct device *device)
|
||||
if (netif_running(dev)) {
|
||||
int err;
|
||||
|
||||
err = pm_runtime_force_resume(device);
|
||||
if (err)
|
||||
return err;
|
||||
if (!(device_may_wakeup(device) &&
|
||||
priv->devtype_data.quirks & FLEXCAN_QUIRK_SETUP_STOP_MODE_SCMI)) {
|
||||
err = pm_runtime_force_resume(device);
|
||||
if (err)
|
||||
return err;
|
||||
}
|
||||
|
||||
if (device_may_wakeup(device))
|
||||
flexcan_enable_wakeup_irq(priv, false);
|
||||
@ -2349,7 +2385,7 @@ static struct platform_driver flexcan_driver = {
|
||||
.of_match_table = flexcan_of_match,
|
||||
},
|
||||
.probe = flexcan_probe,
|
||||
.remove_new = flexcan_remove,
|
||||
.remove = flexcan_remove,
|
||||
.id_table = flexcan_id_table,
|
||||
};
|
||||
|
||||
|
@ -68,6 +68,8 @@
|
||||
#define FLEXCAN_QUIRK_SUPPORT_RX_MAILBOX_RTR BIT(15)
|
||||
/* Device supports RX via FIFO */
|
||||
#define FLEXCAN_QUIRK_SUPPORT_RX_FIFO BIT(16)
|
||||
/* Setup stop mode with ATF SCMI protocol to support wakeup */
|
||||
#define FLEXCAN_QUIRK_SETUP_STOP_MODE_SCMI BIT(17)
|
||||
|
||||
struct flexcan_devtype_data {
|
||||
u32 quirks; /* quirks needed for different IP cores */
|
||||
|
@ -1725,7 +1725,7 @@ static struct platform_driver grcan_driver = {
|
||||
.of_match_table = grcan_match,
|
||||
},
|
||||
.probe = grcan_probe,
|
||||
.remove_new = grcan_remove,
|
||||
.remove = grcan_remove,
|
||||
};
|
||||
|
||||
module_platform_driver(grcan_driver);
|
||||
|
@ -1033,7 +1033,7 @@ static struct platform_driver ifi_canfd_plat_driver = {
|
||||
.of_match_table = ifi_canfd_of_table,
|
||||
},
|
||||
.probe = ifi_canfd_plat_probe,
|
||||
.remove_new = ifi_canfd_plat_remove,
|
||||
.remove = ifi_canfd_plat_remove,
|
||||
};
|
||||
|
||||
module_platform_driver(ifi_canfd_plat_driver);
|
||||
|
@ -2049,7 +2049,7 @@ static struct platform_driver ican3_driver = {
|
||||
.name = DRV_NAME,
|
||||
},
|
||||
.probe = ican3_probe,
|
||||
.remove_new = ican3_remove,
|
||||
.remove = ican3_remove,
|
||||
};
|
||||
|
||||
module_platform_driver(ican3_driver);
|
||||
|
@ -1053,13 +1053,13 @@ static void kvaser_pciefd_write_dma_map_altera(struct kvaser_pciefd *pcie,
|
||||
void __iomem *serdes_base;
|
||||
u32 word1, word2;
|
||||
|
||||
#ifdef CONFIG_ARCH_DMA_ADDR_T_64BIT
|
||||
word1 = addr | KVASER_PCIEFD_ALTERA_DMA_64BIT;
|
||||
word2 = addr >> 32;
|
||||
#else
|
||||
word1 = addr;
|
||||
word2 = 0;
|
||||
#endif
|
||||
if (IS_ENABLED(CONFIG_ARCH_DMA_ADDR_T_64BIT)) {
|
||||
word1 = lower_32_bits(addr) | KVASER_PCIEFD_ALTERA_DMA_64BIT;
|
||||
word2 = upper_32_bits(addr);
|
||||
} else {
|
||||
word1 = addr;
|
||||
word2 = 0;
|
||||
}
|
||||
serdes_base = KVASER_PCIEFD_SERDES_ADDR(pcie) + 0x8 * index;
|
||||
iowrite32(word1, serdes_base);
|
||||
iowrite32(word2, serdes_base + 0x4);
|
||||
@ -1072,9 +1072,9 @@ static void kvaser_pciefd_write_dma_map_sf2(struct kvaser_pciefd *pcie,
|
||||
u32 lsb = addr & KVASER_PCIEFD_SF2_DMA_LSB_MASK;
|
||||
u32 msb = 0x0;
|
||||
|
||||
#ifdef CONFIG_ARCH_DMA_ADDR_T_64BIT
|
||||
msb = addr >> 32;
|
||||
#endif
|
||||
if (IS_ENABLED(CONFIG_ARCH_DMA_ADDR_T_64BIT))
|
||||
msb = upper_32_bits(addr);
|
||||
|
||||
serdes_base = KVASER_PCIEFD_SERDES_ADDR(pcie) + 0x10 * index;
|
||||
iowrite32(lsb, serdes_base);
|
||||
iowrite32(msb, serdes_base + 0x4);
|
||||
@ -1087,9 +1087,9 @@ static void kvaser_pciefd_write_dma_map_xilinx(struct kvaser_pciefd *pcie,
|
||||
u32 lsb = addr & KVASER_PCIEFD_XILINX_DMA_LSB_MASK;
|
||||
u32 msb = 0x0;
|
||||
|
||||
#ifdef CONFIG_ARCH_DMA_ADDR_T_64BIT
|
||||
msb = addr >> 32;
|
||||
#endif
|
||||
if (IS_ENABLED(CONFIG_ARCH_DMA_ADDR_T_64BIT))
|
||||
msb = upper_32_bits(addr);
|
||||
|
||||
serdes_base = KVASER_PCIEFD_SERDES_ADDR(pcie) + 0x8 * index;
|
||||
iowrite32(msb, serdes_base);
|
||||
iowrite32(lsb, serdes_base + 0x4);
|
||||
@ -1104,6 +1104,9 @@ static int kvaser_pciefd_setup_dma(struct kvaser_pciefd *pcie)
|
||||
|
||||
/* Disable the DMA */
|
||||
iowrite32(0, KVASER_PCIEFD_SRB_ADDR(pcie) + KVASER_PCIEFD_SRB_CTRL_REG);
|
||||
|
||||
dma_set_mask_and_coherent(&pcie->pci->dev, DMA_BIT_MASK(64));
|
||||
|
||||
for (i = 0; i < KVASER_PCIEFD_DMA_COUNT; i++) {
|
||||
pcie->dma_data[i] = dmam_alloc_coherent(&pcie->pci->dev,
|
||||
KVASER_PCIEFD_DMA_SIZE,
|
||||
|
@ -1434,7 +1434,8 @@ static int m_can_chip_config(struct net_device *dev)
|
||||
|
||||
/* Disable unused interrupts */
|
||||
interrupts &= ~(IR_ARA | IR_ELO | IR_DRX | IR_TEFF | IR_TFE | IR_TCF |
|
||||
IR_HPM | IR_RF1F | IR_RF1W | IR_RF1N | IR_RF0F);
|
||||
IR_HPM | IR_RF1F | IR_RF1W | IR_RF1N | IR_RF0F |
|
||||
IR_TSW);
|
||||
|
||||
err = m_can_config_enable(cdev);
|
||||
if (err)
|
||||
@ -1763,11 +1764,7 @@ static int m_can_close(struct net_device *dev)
|
||||
|
||||
netif_stop_queue(dev);
|
||||
|
||||
if (!cdev->is_peripheral)
|
||||
napi_disable(&cdev->napi);
|
||||
|
||||
m_can_stop(dev);
|
||||
m_can_clk_stop(cdev);
|
||||
free_irq(dev->irq, dev);
|
||||
|
||||
m_can_clean(dev);
|
||||
@ -1776,10 +1773,13 @@ static int m_can_close(struct net_device *dev)
|
||||
destroy_workqueue(cdev->tx_wq);
|
||||
cdev->tx_wq = NULL;
|
||||
can_rx_offload_disable(&cdev->offload);
|
||||
} else {
|
||||
napi_disable(&cdev->napi);
|
||||
}
|
||||
|
||||
close_candev(dev);
|
||||
|
||||
m_can_clk_stop(cdev);
|
||||
phy_power_off(cdev->transceiver);
|
||||
|
||||
return 0;
|
||||
@ -2030,6 +2030,8 @@ static int m_can_open(struct net_device *dev)
|
||||
|
||||
if (cdev->is_peripheral)
|
||||
can_rx_offload_enable(&cdev->offload);
|
||||
else
|
||||
napi_enable(&cdev->napi);
|
||||
|
||||
/* register interrupt handler */
|
||||
if (cdev->is_peripheral) {
|
||||
@ -2063,9 +2065,6 @@ static int m_can_open(struct net_device *dev)
|
||||
if (err)
|
||||
goto exit_start_fail;
|
||||
|
||||
if (!cdev->is_peripheral)
|
||||
napi_enable(&cdev->napi);
|
||||
|
||||
netif_start_queue(dev);
|
||||
|
||||
return 0;
|
||||
@ -2079,6 +2078,8 @@ static int m_can_open(struct net_device *dev)
|
||||
out_wq_fail:
|
||||
if (cdev->is_peripheral)
|
||||
can_rx_offload_disable(&cdev->offload);
|
||||
else
|
||||
napi_disable(&cdev->napi);
|
||||
close_candev(dev);
|
||||
exit_disable_clks:
|
||||
m_can_clk_stop(cdev);
|
||||
|
@ -231,7 +231,7 @@ static struct platform_driver m_can_plat_driver = {
|
||||
.pm = &m_can_pmops,
|
||||
},
|
||||
.probe = m_can_plat_probe,
|
||||
.remove_new = m_can_plat_remove,
|
||||
.remove = m_can_plat_remove,
|
||||
};
|
||||
|
||||
module_platform_driver(m_can_plat_driver);
|
||||
|
@ -435,7 +435,7 @@ static struct platform_driver mpc5xxx_can_driver = {
|
||||
.of_match_table = mpc5xxx_can_table,
|
||||
},
|
||||
.probe = mpc5xxx_can_probe,
|
||||
.remove_new = mpc5xxx_can_remove,
|
||||
.remove = mpc5xxx_can_remove,
|
||||
#ifdef CONFIG_PM
|
||||
.suspend = mpc5xxx_can_suspend,
|
||||
.resume = mpc5xxx_can_resume,
|
||||
|
@ -781,11 +781,8 @@ static int peak_get_ts_info(struct net_device *dev,
|
||||
{
|
||||
info->so_timestamping =
|
||||
SOF_TIMESTAMPING_TX_SOFTWARE |
|
||||
SOF_TIMESTAMPING_RX_SOFTWARE |
|
||||
SOF_TIMESTAMPING_SOFTWARE |
|
||||
SOF_TIMESTAMPING_RX_HARDWARE |
|
||||
SOF_TIMESTAMPING_RAW_HARDWARE;
|
||||
info->phc_index = -1;
|
||||
info->tx_types = BIT(HWTSTAMP_TX_OFF);
|
||||
info->rx_filters = BIT(HWTSTAMP_FILTER_ALL);
|
||||
|
||||
|
@ -907,7 +907,7 @@ static struct platform_driver rcar_can_driver = {
|
||||
.pm = &rcar_can_pm_ops,
|
||||
},
|
||||
.probe = rcar_can_probe,
|
||||
.remove_new = rcar_can_remove,
|
||||
.remove = rcar_can_remove,
|
||||
};
|
||||
|
||||
module_platform_driver(rcar_can_driver);
|
||||
|
@ -2118,7 +2118,7 @@ static struct platform_driver rcar_canfd_driver = {
|
||||
.pm = &rcar_canfd_pm_ops,
|
||||
},
|
||||
.probe = rcar_canfd_probe,
|
||||
.remove_new = rcar_canfd_remove,
|
||||
.remove = rcar_canfd_remove,
|
||||
};
|
||||
|
||||
module_platform_driver(rcar_canfd_driver);
|
||||
|
9
drivers/net/can/rockchip/Kconfig
Normal file
9
drivers/net/can/rockchip/Kconfig
Normal file
@ -0,0 +1,9 @@
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
|
||||
config CAN_ROCKCHIP_CANFD
|
||||
tristate "Rockchip CAN-FD controller"
|
||||
depends on OF || COMPILE_TEST
|
||||
select CAN_RX_OFFLOAD
|
||||
help
|
||||
Say Y here if you want to use CAN-FD controller found on
|
||||
Rockchip SoCs.
|
10
drivers/net/can/rockchip/Makefile
Normal file
10
drivers/net/can/rockchip/Makefile
Normal file
@ -0,0 +1,10 @@
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
|
||||
obj-$(CONFIG_CAN_ROCKCHIP_CANFD) += rockchip_canfd.o
|
||||
|
||||
rockchip_canfd-objs :=
|
||||
rockchip_canfd-objs += rockchip_canfd-core.o
|
||||
rockchip_canfd-objs += rockchip_canfd-ethtool.o
|
||||
rockchip_canfd-objs += rockchip_canfd-rx.o
|
||||
rockchip_canfd-objs += rockchip_canfd-timestamp.o
|
||||
rockchip_canfd-objs += rockchip_canfd-tx.o
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user