mirror of
https://github.com/torvalds/linux.git
synced 2025-12-07 20:06:24 +00:00
Merge tag 'net-next-6.15' of git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net-next
Pull networking updates from Jakub Kicinski:
"Core & protocols:
- Continue Netlink conversions to per-namespace RTNL lock
(IPv4 routing, routing rules, routing next hops, ARP ioctls)
- Continue extending the use of netdev instance locks. As a driver
opt-in protect queue operations and (in due course) ethtool
operations with the instance lock and not RTNL lock.
- Support collecting TCP timestamps (data submitted, sent, acked) in
BPF, allowing for transparent (to the application) and lower
overhead tracking of TCP RPC performance.
- Tweak existing networking Rx zero-copy infra to support zero-copy
Rx via io_uring.
- Optimize MPTCP performance in single subflow mode by 29%.
- Enable GRO on packets which went thru XDP CPU redirect (were queued
for processing on a different CPU). Improving TCP stream
performance up to 2x.
- Improve performance of contended connect() by 200% by searching for
an available 4-tuple under RCU rather than a spin lock. Bring an
additional 229% improvement by tweaking hash distribution.
- Avoid unconditionally touching sk_tsflags on RX, improving
performance under UDP flood by as much as 10%.
- Avoid skb_clone() dance in ping_rcv() to improve performance under
ping flood.
- Avoid FIB lookup in netfilter if socket is available, 20% perf win.
- Rework network device creation (in-kernel) API to more clearly
identify network namespaces and their roles. There are up to 4
namespace roles but we used to have just 2 netns pointer arguments,
interpreted differently based on context.
- Use sysfs_break_active_protection() instead of trylock to avoid
deadlocks between unregistering objects and sysfs access.
- Add a new sysctl and sockopt for capping max retransmit timeout in
TCP.
- Support masking port and DSCP in routing rule matches.
- Support dumping IPv4 multicast addresses with RTM_GETMULTICAST.
- Support specifying at what time packet should be sent on AF_XDP
sockets.
- Expose TCP ULP diagnostic info (for TLS and MPTCP) to non-admin
users.
- Add Netlink YAML spec for WiFi (nl80211) and conntrack.
- Introduce EXPORT_IPV6_MOD() and EXPORT_IPV6_MOD_GPL() for symbols
which only need to be exported when IPv6 support is built as a
module.
- Age FDB entries based on Rx not Tx traffic in VxLAN, similar to
normal bridging.
- Allow users to specify source port range for GENEVE tunnels.
- netconsole: allow attaching kernel release, CPU ID and task name to
messages as metadata
Driver API:
- Continue rework / fixing of Energy Efficient Ethernet (EEE) across
the SW layers. Delegate the responsibilities to phylink where
possible. Improve its handling in phylib.
- Support symmetric OR-XOR RSS hashing algorithm.
- Support tracking and preserving IRQ affinity by NAPI itself.
- Support loopback mode speed selection for interface selftests.
Device drivers:
- Remove the IBM LCS driver for s390
- Remove the sb1000 cable modem driver
- Add support for SFP module access over SMBus
- Add MCTP transport driver for MCTP-over-USB
- Enable XDP metadata support in multiple drivers
- Ethernet high-speed NICs:
- Broadcom (bnxt):
- add PCIe TLP Processing Hints (TPH) support for new AMD
platforms
- support dumping RoCE queue state for debug
- opt into instance locking
- Intel (100G, ice, idpf):
- ice: rework MSI-X IRQ management and distribution
- ice: support for E830 devices
- iavf: add support for Rx timestamping
- iavf: opt into instance locking
- nVidia/Mellanox:
- mlx4: use page pool memory allocator for Rx
- mlx5: support for one PTP device per hardware clock
- mlx5: support for 200Gbps per-lane link modes
- mlx5: move IPSec policy check after decryption
- AMD/Solarflare:
- support FW flashing via devlink
- Cisco (enic):
- use page pool memory allocator for Rx
- enable 32, 64 byte CQEs
- get max rx/tx ring size from the device
- Meta (fbnic):
- support flow steering and RSS configuration
- report queue stats
- support TCP segmentation
- support IRQ coalescing
- support ring size configuration
- Marvell/Cavium:
- support AF_XDP
- Wangxun:
- support for PTP clock and timestamping
- Huawei (hibmcge):
- checksum offload
- add more statistics
- Ethernet virtual:
- VirtIO net:
- aggressively suppress Tx completions, improve perf by 96%
with 1 CPU and 55% with 2 CPUs
- expose NAPI to IRQ mapping and persist NAPI settings
- Google (gve):
- support XDP in DQO RDA Queue Format
- opt into instance locking
- Microsoft vNIC:
- support BIG TCP
- Ethernet NICs consumer, and embedded:
- Synopsys (stmmac):
- cleanup Tx and Tx clock setting and other link-focused
cleanups
- enable SGMII and 2500BASEX mode switching for Intel platforms
- support Sophgo SG2044
- Broadcom switches (b53):
- support for BCM53101
- TI:
- iep: add perout configuration support
- icssg: support XDP
- Cadence (macb):
- implement BQL
- Xilinx (axinet):
- support dynamic IRQ moderation and changing coalescing at
runtime
- implement BQL
- report standard stats
- MediaTek:
- support phylink managed EEE
- Intel:
- igc: don't restart the interface on every XDP program change
- RealTek (r8169):
- support reading registers of internal PHYs directly
- increase max jumbo packet size on RTL8125/RTL8126
- Airoha:
- support for RISC-V NPU packet processing unit
- enable scatter-gather and support MTU up to 9kB
- Tehuti (tn40xx):
- support cards with TN4010 MAC and an Aquantia AQR105 PHY
- Ethernet PHYs:
- support for TJA1102S, TJA1121
- dp83tg720: add randomized polling intervals for link detection
- dp83822: support changing the transmit amplitude voltage
- support for LEDs on 88q2xxx
- CAN:
- canxl: support Remote Request Substitution bit access
- flexcan: add S32G2/S32G3 SoC
- WiFi:
- remove cooked monitor support
- strict mode for better AP testing
- basic EPCS support
- OMI RX bandwidth reduction support
- batman-adv: add support for jumbo frames
- WiFi drivers:
- RealTek (rtw88):
- support RTL8814AE and RTL8814AU
- RealTek (rtw89):
- switch using wiphy_lock and wiphy_work
- add BB context to manipulate two PHY as preparation of MLO
- improve BT-coexistence mechanism to play A2DP smoothly
- Intel (iwlwifi):
- add new iwlmld sub-driver for latest HW/FW combinations
- MediaTek (mt76):
- preparation for mt7996 Multi-Link Operation (MLO) support
- Qualcomm/Atheros (ath12k):
- continued work on MLO
- Silabs (wfx):
- Wake-on-WLAN support
- Bluetooth:
- add support for skb TX SND/COMPLETION timestamping
- hci_core: enable buffer flow control for SCO/eSCO
- coredump: log devcd dumps into the monitor
- Bluetooth drivers:
- intel: add support to configure TX power
- nxp: handle bootloader error during cmd5 and cmd7"
* tag 'net-next-6.15' of git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net-next: (1681 commits)
unix: fix up for "apparmor: add fine grained af_unix mediation"
mctp: Fix incorrect tx flow invalidation condition in mctp-i2c
net: usb: asix: ax88772: Increase phy_name size
net: phy: Introduce PHY_ID_SIZE — minimum size for PHY ID string
net: libwx: fix Tx L4 checksum
net: libwx: fix Tx descriptor content for some tunnel packets
atm: Fix NULL pointer dereference
net: tn40xx: add pci-id of the aqr105-based Tehuti TN4010 cards
net: tn40xx: prepare tn40xx driver to find phy of the TN9510 card
net: tn40xx: create swnode for mdio and aqr105 phy and add to mdiobus
net: phy: aquantia: add essential functions to aqr105 driver
net: phy: aquantia: search for firmware-name in fwnode
net: phy: aquantia: add probe function to aqr105 for firmware loading
net: phy: Add swnode support to mdiobus_scan
gve: add XDP DROP and PASS support for DQ
gve: update XDP allocation path support RX buffer posting
gve: merge packet buffer size fields
gve: update GQ RX to use buf_size
gve: introduce config-based allocation for XDP
gve: remove xdp_xsk_done and xdp_xsk_wakeup statistics
...
This commit is contained in:
4
CREDITS
4
CREDITS
@@ -3233,6 +3233,10 @@ N: Rui Prior
|
||||
E: rprior@inescn.pt
|
||||
D: ATM device driver for NICStAR based cards
|
||||
|
||||
N: Roopa Prabhu
|
||||
E: roopa@nvidia.com
|
||||
D: Bridge co-maintainer, vxlan and networking contributor
|
||||
|
||||
N: Stefan Probst
|
||||
E: sp@caldera.de
|
||||
D: The Linux Support Team Erlangen, 1993-97
|
||||
|
||||
@@ -244,7 +244,7 @@ information about the interrupt from the irb parameter.
|
||||
--------------------
|
||||
|
||||
The ccwgroup mechanism is designed to handle devices consisting of multiple ccw
|
||||
devices, like lcs or ctc.
|
||||
devices, like qeth or ctc.
|
||||
|
||||
The ccw driver provides a 'group' attribute. Piping bus ids of ccw devices to
|
||||
this attributes creates a ccwgroup device consisting of these ccw devices (if
|
||||
|
||||
@@ -63,6 +63,14 @@ properties:
|
||||
"#size-cells":
|
||||
const: 0
|
||||
|
||||
airoha,npu:
|
||||
$ref: /schemas/types.yaml#/definitions/phandle
|
||||
description:
|
||||
Phandle to the node used to configure the NPU module.
|
||||
The Airoha Network Processor Unit (NPU) provides a configuration
|
||||
interface to implement hardware flow offloading programming Packet
|
||||
Processor Engine (PPE) flow table.
|
||||
|
||||
patternProperties:
|
||||
"^ethernet@[1-4]$":
|
||||
type: object
|
||||
@@ -132,6 +140,8 @@ examples:
|
||||
<GIC_SPI 49 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 64 IRQ_TYPE_LEVEL_HIGH>;
|
||||
|
||||
airoha,npu = <&npu>;
|
||||
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
|
||||
84
Documentation/devicetree/bindings/net/airoha,en7581-npu.yaml
Normal file
84
Documentation/devicetree/bindings/net/airoha,en7581-npu.yaml
Normal file
@@ -0,0 +1,84 @@
|
||||
# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/net/airoha,en7581-npu.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Airoha Network Processor Unit for EN7581 SoC
|
||||
|
||||
maintainers:
|
||||
- Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
|
||||
description:
|
||||
The Airoha Network Processor Unit (NPU) provides a configuration interface
|
||||
to implement wired and wireless hardware flow offloading programming Packet
|
||||
Processor Engine (PPE) flow table.
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
enum:
|
||||
- airoha,en7581-npu
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
interrupts:
|
||||
items:
|
||||
- description: mbox host irq line
|
||||
- description: watchdog0 irq line
|
||||
- description: watchdog1 irq line
|
||||
- description: watchdog2 irq line
|
||||
- description: watchdog3 irq line
|
||||
- description: watchdog4 irq line
|
||||
- description: watchdog5 irq line
|
||||
- description: watchdog6 irq line
|
||||
- description: watchdog7 irq line
|
||||
- description: wlan irq line0
|
||||
- description: wlan irq line1
|
||||
- description: wlan irq line2
|
||||
- description: wlan irq line3
|
||||
- description: wlan irq line4
|
||||
- description: wlan irq line5
|
||||
|
||||
memory-region:
|
||||
maxItems: 1
|
||||
description:
|
||||
Memory used to store NPU firmware binary.
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- interrupts
|
||||
- memory-region
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/interrupt-controller/arm-gic.h>
|
||||
#include <dt-bindings/interrupt-controller/irq.h>
|
||||
soc {
|
||||
#address-cells = <2>;
|
||||
#size-cells = <2>;
|
||||
|
||||
npu@1e900000 {
|
||||
compatible = "airoha,en7581-npu";
|
||||
reg = <0 0x1e900000 0 0x313000>;
|
||||
interrupts = <GIC_SPI 125 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 103 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 109 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 113 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 117 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 134 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 135 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 136 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 137 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 118 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 119 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 120 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 121 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 122 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 123 IRQ_TYPE_LEVEL_HIGH>;
|
||||
memory-region = <&npu_binary>;
|
||||
};
|
||||
};
|
||||
@@ -152,6 +152,12 @@ properties:
|
||||
The second range is is for the Amlogic specific configuration
|
||||
(for example the PRG_ETHERNET register range on Meson8b and newer)
|
||||
|
||||
interrupts:
|
||||
maxItems: 1
|
||||
|
||||
interrupt-names:
|
||||
const: macirq
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
|
||||
@@ -17,6 +17,9 @@ description:
|
||||
maintainers:
|
||||
- Neeraj Sanjay Kale <neeraj.sanjaykale@nxp.com>
|
||||
|
||||
allOf:
|
||||
- $ref: bluetooth-controller.yaml#
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
enum:
|
||||
@@ -40,10 +43,20 @@ properties:
|
||||
Host-To-Chip power save mechanism is driven by this GPIO
|
||||
connected to BT_WAKE_IN pin of the NXP chipset.
|
||||
|
||||
nxp,wakein-pin:
|
||||
$ref: /schemas/types.yaml#/definitions/uint8
|
||||
description:
|
||||
The GPIO number of the NXP chipset used for BT_WAKE_IN.
|
||||
|
||||
nxp,wakeout-pin:
|
||||
$ref: /schemas/types.yaml#/definitions/uint8
|
||||
description:
|
||||
The GPIO number of the NXP chipset used for BT_WAKE_OUT.
|
||||
|
||||
required:
|
||||
- compatible
|
||||
|
||||
additionalProperties: false
|
||||
unevaluatedProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
@@ -54,5 +67,8 @@ examples:
|
||||
fw-init-baudrate = <3000000>;
|
||||
firmware-name = "uartuart8987_bt_v0.bin";
|
||||
device-wakeup-gpios = <&gpio 11 GPIO_ACTIVE_HIGH>;
|
||||
nxp,wakein-pin = /bits/ 8 <18>;
|
||||
nxp,wakeout-pin = /bits/ 8 <19>;
|
||||
local-bd-address = [66 55 44 33 22 11];
|
||||
};
|
||||
};
|
||||
|
||||
@@ -19,6 +19,7 @@ properties:
|
||||
- qcom,qca2066-bt
|
||||
- qcom,qca6174-bt
|
||||
- qcom,qca9377-bt
|
||||
- qcom,wcn3950-bt
|
||||
- qcom,wcn3988-bt
|
||||
- qcom,wcn3990-bt
|
||||
- qcom,wcn3991-bt
|
||||
@@ -138,6 +139,7 @@ allOf:
|
||||
compatible:
|
||||
contains:
|
||||
enum:
|
||||
- qcom,wcn3950-bt
|
||||
- qcom,wcn3988-bt
|
||||
- qcom,wcn3990-bt
|
||||
- qcom,wcn3991-bt
|
||||
|
||||
@@ -10,9 +10,6 @@ title:
|
||||
maintainers:
|
||||
- Marc Kleine-Budde <mkl@pengutronix.de>
|
||||
|
||||
allOf:
|
||||
- $ref: can-controller.yaml#
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
oneOf:
|
||||
@@ -28,6 +25,7 @@ properties:
|
||||
- fsl,vf610-flexcan
|
||||
- fsl,ls1021ar2-flexcan
|
||||
- fsl,lx2160ar1-flexcan
|
||||
- nxp,s32g2-flexcan
|
||||
- items:
|
||||
- enum:
|
||||
- fsl,imx53-flexcan
|
||||
@@ -43,12 +41,25 @@ properties:
|
||||
- enum:
|
||||
- fsl,ls1028ar1-flexcan
|
||||
- const: fsl,lx2160ar1-flexcan
|
||||
- items:
|
||||
- enum:
|
||||
- nxp,s32g3-flexcan
|
||||
- const: nxp,s32g2-flexcan
|
||||
- items:
|
||||
- enum:
|
||||
- fsl,imx94-flexcan
|
||||
- const: fsl,imx95-flexcan
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
interrupts:
|
||||
maxItems: 1
|
||||
minItems: 1
|
||||
maxItems: 4
|
||||
|
||||
interrupt-names:
|
||||
minItems: 1
|
||||
maxItems: 4
|
||||
|
||||
clocks:
|
||||
maxItems: 2
|
||||
@@ -70,6 +81,9 @@ properties:
|
||||
xceiver-supply:
|
||||
description: Regulator that powers the CAN transceiver.
|
||||
|
||||
phys:
|
||||
maxItems: 1
|
||||
|
||||
big-endian:
|
||||
$ref: /schemas/types.yaml#/definitions/flag
|
||||
description: |
|
||||
@@ -136,6 +150,41 @@ required:
|
||||
- reg
|
||||
- interrupts
|
||||
|
||||
allOf:
|
||||
- $ref: can-controller.yaml#
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
const: nxp,s32g2-flexcan
|
||||
then:
|
||||
properties:
|
||||
interrupts:
|
||||
items:
|
||||
- description: Message Buffer interrupt for mailboxes 0-7 and Enhanced RX FIFO
|
||||
- description: Device state change
|
||||
- description: Bus Error detection
|
||||
- description: Message Buffer interrupt for mailboxes 8-127
|
||||
interrupt-names:
|
||||
items:
|
||||
- const: mb-0
|
||||
- const: state
|
||||
- const: berr
|
||||
- const: mb-1
|
||||
required:
|
||||
- interrupt-names
|
||||
else:
|
||||
properties:
|
||||
interrupts:
|
||||
maxItems: 1
|
||||
interrupt-names: false
|
||||
- if:
|
||||
required:
|
||||
- xceiver-supply
|
||||
then:
|
||||
properties:
|
||||
phys: false
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
|
||||
@@ -16,6 +16,7 @@ properties:
|
||||
compatible:
|
||||
oneOf:
|
||||
- const: brcm,bcm5325
|
||||
- const: brcm,bcm53101
|
||||
- const: brcm,bcm53115
|
||||
- const: brcm,bcm53125
|
||||
- const: brcm,bcm53128
|
||||
@@ -77,6 +78,7 @@ allOf:
|
||||
contains:
|
||||
enum:
|
||||
- brcm,bcm5325
|
||||
- brcm,bcm53101
|
||||
- brcm,bcm53115
|
||||
- brcm,bcm53125
|
||||
- brcm,bcm53128
|
||||
|
||||
@@ -232,6 +232,12 @@ properties:
|
||||
PHY's that have configurable TX internal delays. If this property is
|
||||
present then the PHY applies the TX delay.
|
||||
|
||||
tx-amplitude-100base-tx-percent:
|
||||
description:
|
||||
Transmit amplitude gain applied for 100BASE-TX. 100% matches 2V
|
||||
peak-to-peak specified in ANSI X3.263. When omitted, the PHYs default
|
||||
will be left as is.
|
||||
|
||||
leds:
|
||||
type: object
|
||||
|
||||
|
||||
@@ -44,6 +44,9 @@ properties:
|
||||
phy-mode:
|
||||
enum:
|
||||
- rgmii
|
||||
- rgmii-id
|
||||
- rgmii-rxid
|
||||
- rgmii-txid
|
||||
- rmii
|
||||
|
||||
phy-handle: true
|
||||
|
||||
112
Documentation/devicetree/bindings/net/fsl,gianfar-mdio.yaml
Normal file
112
Documentation/devicetree/bindings/net/fsl,gianfar-mdio.yaml
Normal file
@@ -0,0 +1,112 @@
|
||||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/net/fsl,gianfar-mdio.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Freescale Gianfar (TSEC) MDIO Device
|
||||
|
||||
description:
|
||||
This binding describes the MDIO is a bus to which the PHY devices are
|
||||
connected. For each device that exists on this bus, a child node should be
|
||||
created.
|
||||
|
||||
Some TSECs are associated with an internal Ten-Bit Interface (TBI) PHY. This
|
||||
PHY is accessed through the local MDIO bus. These buses are defined similarly
|
||||
to the mdio buses, except they are compatible with "fsl,gianfar-tbi". The TBI
|
||||
PHYs underneath them are similar to normal PHYs, but the reg property is
|
||||
considered instructive, rather than descriptive. The reg property should be
|
||||
chosen so it doesn't interfere with other PHYs on the bus.
|
||||
|
||||
maintainers:
|
||||
- J. Neuschäfer <j.ne@posteo.net>
|
||||
|
||||
# This is needed to distinguish gianfar.yaml and gianfar-mdio.yaml, because
|
||||
# both use compatible = "gianfar" (with different device_type values)
|
||||
select:
|
||||
oneOf:
|
||||
- properties:
|
||||
compatible:
|
||||
contains:
|
||||
const: gianfar
|
||||
device_type:
|
||||
const: mdio
|
||||
required:
|
||||
- device_type
|
||||
|
||||
- properties:
|
||||
compatible:
|
||||
contains:
|
||||
enum:
|
||||
- fsl,gianfar-tbi
|
||||
- fsl,gianfar-mdio
|
||||
- fsl,etsec2-tbi
|
||||
- fsl,etsec2-mdio
|
||||
- fsl,ucc-mdio
|
||||
- ucc_geth_phy
|
||||
|
||||
required:
|
||||
- compatible
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
enum:
|
||||
- fsl,gianfar-tbi
|
||||
- fsl,gianfar-mdio
|
||||
- fsl,etsec2-tbi
|
||||
- fsl,etsec2-mdio
|
||||
- fsl,ucc-mdio
|
||||
- gianfar
|
||||
- ucc_geth_phy
|
||||
|
||||
reg:
|
||||
minItems: 1
|
||||
items:
|
||||
- description:
|
||||
Offset and length of the register set for the device
|
||||
|
||||
- description:
|
||||
Optionally, the offset and length of the TBIPA register (TBI PHY
|
||||
address register). If TBIPA register is not specified, the driver
|
||||
will attempt to infer it from the register set specified (your
|
||||
mileage may vary).
|
||||
|
||||
device_type:
|
||||
const: mdio
|
||||
|
||||
required:
|
||||
- reg
|
||||
- "#address-cells"
|
||||
- "#size-cells"
|
||||
|
||||
allOf:
|
||||
- $ref: mdio.yaml#
|
||||
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
const: ucc_geth_phy
|
||||
then:
|
||||
required:
|
||||
- device_type
|
||||
|
||||
unevaluatedProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
soc {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
|
||||
mdio@24520 {
|
||||
reg = <0x24520 0x20>;
|
||||
compatible = "fsl,gianfar-mdio";
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
ethernet-phy@0 {
|
||||
reg = <0>;
|
||||
};
|
||||
};
|
||||
};
|
||||
248
Documentation/devicetree/bindings/net/fsl,gianfar.yaml
Normal file
248
Documentation/devicetree/bindings/net/fsl,gianfar.yaml
Normal file
@@ -0,0 +1,248 @@
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/net/fsl,gianfar.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Freescale Three-Speed Ethernet Controller (TSEC), "Gianfar"
|
||||
|
||||
maintainers:
|
||||
- J. Neuschäfer <j.ne@posteo.net>
|
||||
|
||||
# This is needed to distinguish gianfar.yaml and gianfar-mdio.yaml, because
|
||||
# both use compatible = "gianfar" (with different device_type values)
|
||||
select:
|
||||
oneOf:
|
||||
- properties:
|
||||
compatible:
|
||||
contains:
|
||||
const: gianfar
|
||||
device_type:
|
||||
const: network
|
||||
required:
|
||||
- device_type
|
||||
|
||||
- properties:
|
||||
compatible:
|
||||
const: fsl,etsec2
|
||||
|
||||
required:
|
||||
- compatible
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
enum:
|
||||
- gianfar
|
||||
- fsl,etsec2
|
||||
|
||||
device_type:
|
||||
const: network
|
||||
|
||||
model:
|
||||
enum:
|
||||
- FEC
|
||||
- TSEC
|
||||
- eTSEC
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
ranges: true
|
||||
|
||||
"#address-cells":
|
||||
enum: [ 1, 2 ]
|
||||
|
||||
"#size-cells":
|
||||
enum: [ 1, 2 ]
|
||||
|
||||
cell-index:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
|
||||
interrupts:
|
||||
minItems: 1
|
||||
items:
|
||||
- description: Transmit interrupt or single combined interrupt
|
||||
- description: Receive interrupt
|
||||
- description: Error interrupt
|
||||
|
||||
dma-coherent: true
|
||||
|
||||
fsl,magic-packet:
|
||||
type: boolean
|
||||
description:
|
||||
If present, indicates that the hardware supports waking up via magic packet.
|
||||
|
||||
fsl,wake-on-filer:
|
||||
type: boolean
|
||||
description:
|
||||
If present, indicates that the hardware supports waking up by Filer
|
||||
General Purpose Interrupt (FGPI) asserted on the Rx int line. This is
|
||||
an advanced power management capability allowing certain packet types
|
||||
(user) defined by filer rules to wake up the system.
|
||||
|
||||
bd-stash:
|
||||
type: boolean
|
||||
description:
|
||||
If present, indicates that the hardware supports stashing buffer
|
||||
descriptors in the L2.
|
||||
|
||||
rx-stash-len:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
description:
|
||||
Denotes the number of bytes of a received buffer to stash in the L2.
|
||||
|
||||
rx-stash-idx:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
description:
|
||||
Denotes the index of the first byte from the received buffer to stash in
|
||||
the L2.
|
||||
|
||||
fsl,num_rx_queues:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
description: Number of receive queues
|
||||
const: 8
|
||||
|
||||
fsl,num_tx_queues:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
description: Number of transmit queues
|
||||
const: 8
|
||||
|
||||
tbi-handle:
|
||||
$ref: /schemas/types.yaml#/definitions/phandle
|
||||
description: Reference (phandle) to the TBI node
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- model
|
||||
|
||||
patternProperties:
|
||||
"^mdio@[0-9a-f]+$":
|
||||
$ref: /schemas/net/fsl,gianfar-mdio.yaml#
|
||||
|
||||
allOf:
|
||||
- $ref: ethernet-controller.yaml#
|
||||
|
||||
# eTSEC2 controller nodes have "queue group" subnodes and don't need a "reg"
|
||||
# property.
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
const: fsl,etsec2
|
||||
then:
|
||||
patternProperties:
|
||||
"^queue-group@[0-9a-f]+$":
|
||||
type: object
|
||||
|
||||
properties:
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
interrupts:
|
||||
items:
|
||||
- description: Transmit interrupt
|
||||
- description: Receive interrupt
|
||||
- description: Error interrupt
|
||||
|
||||
required:
|
||||
- reg
|
||||
- interrupts
|
||||
|
||||
additionalProperties: false
|
||||
else:
|
||||
required:
|
||||
- reg
|
||||
|
||||
# TSEC and eTSEC devices require three interrupts
|
||||
- if:
|
||||
properties:
|
||||
model:
|
||||
contains:
|
||||
enum: [ TSEC, eTSEC ]
|
||||
then:
|
||||
properties:
|
||||
interrupts:
|
||||
items:
|
||||
- description: Transmit interrupt
|
||||
- description: Receive interrupt
|
||||
- description: Error interrupt
|
||||
|
||||
|
||||
|
||||
unevaluatedProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
ethernet@24000 {
|
||||
device_type = "network";
|
||||
model = "TSEC";
|
||||
compatible = "gianfar";
|
||||
reg = <0x24000 0x1000>;
|
||||
local-mac-address = [ 00 00 00 00 00 00 ];
|
||||
interrupts = <29 2>, <30 2>, <34 2>;
|
||||
interrupt-parent = <&mpic>;
|
||||
phy-handle = <&phy0>;
|
||||
};
|
||||
|
||||
- |
|
||||
#include <dt-bindings/interrupt-controller/irq.h>
|
||||
|
||||
ethernet@24000 {
|
||||
compatible = "gianfar";
|
||||
reg = <0x24000 0x1000>;
|
||||
ranges = <0x0 0x24000 0x1000>;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
cell-index = <0>;
|
||||
device_type = "network";
|
||||
model = "eTSEC";
|
||||
local-mac-address = [ 00 00 00 00 00 00 ];
|
||||
interrupts = <32 IRQ_TYPE_LEVEL_LOW>,
|
||||
<33 IRQ_TYPE_LEVEL_LOW>,
|
||||
<34 IRQ_TYPE_LEVEL_LOW>;
|
||||
interrupt-parent = <&ipic>;
|
||||
|
||||
mdio@520 {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
compatible = "fsl,gianfar-mdio";
|
||||
reg = <0x520 0x20>;
|
||||
};
|
||||
};
|
||||
|
||||
- |
|
||||
#include <dt-bindings/interrupt-controller/irq.h>
|
||||
#include <dt-bindings/interrupt-controller/arm-gic.h>
|
||||
|
||||
bus {
|
||||
#address-cells = <2>;
|
||||
#size-cells = <2>;
|
||||
|
||||
ethernet {
|
||||
compatible = "fsl,etsec2";
|
||||
ranges;
|
||||
device_type = "network";
|
||||
#address-cells = <2>;
|
||||
#size-cells = <2>;
|
||||
interrupt-parent = <&gic>;
|
||||
model = "eTSEC";
|
||||
fsl,magic-packet;
|
||||
dma-coherent;
|
||||
|
||||
queue-group@2d10000 {
|
||||
reg = <0x0 0x2d10000 0x0 0x1000>;
|
||||
interrupts = <GIC_SPI 144 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 145 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 146 IRQ_TYPE_LEVEL_HIGH>;
|
||||
};
|
||||
|
||||
queue-group@2d14000 {
|
||||
reg = <0x0 0x2d14000 0x0 0x1000>;
|
||||
interrupts = <GIC_SPI 147 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 148 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 149 IRQ_TYPE_LEVEL_HIGH>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
...
|
||||
@@ -1,88 +1,14 @@
|
||||
* MDIO IO device
|
||||
|
||||
The MDIO is a bus to which the PHY devices are connected. For each
|
||||
device that exists on this bus, a child node should be created. See
|
||||
the definition of the PHY node in booting-without-of.txt for an example
|
||||
of how to define a PHY.
|
||||
|
||||
Required properties:
|
||||
- reg : Offset and length of the register set for the device, and optionally
|
||||
the offset and length of the TBIPA register (TBI PHY address
|
||||
register). If TBIPA register is not specified, the driver will
|
||||
attempt to infer it from the register set specified (your mileage may
|
||||
vary).
|
||||
- compatible : Should define the compatible device type for the
|
||||
mdio. Currently supported strings/devices are:
|
||||
- "fsl,gianfar-tbi"
|
||||
- "fsl,gianfar-mdio"
|
||||
- "fsl,etsec2-tbi"
|
||||
- "fsl,etsec2-mdio"
|
||||
- "fsl,ucc-mdio"
|
||||
- "fsl,fman-mdio"
|
||||
When device_type is "mdio", the following strings are also considered:
|
||||
- "gianfar"
|
||||
- "ucc_geth_phy"
|
||||
|
||||
Example:
|
||||
|
||||
mdio@24520 {
|
||||
reg = <24520 20>;
|
||||
compatible = "fsl,gianfar-mdio";
|
||||
|
||||
ethernet-phy@0 {
|
||||
......
|
||||
};
|
||||
};
|
||||
Refer to Documentation/devicetree/bindings/net/fsl,gianfar-mdio.yaml
|
||||
|
||||
* TBI Internal MDIO bus
|
||||
|
||||
As of this writing, every tsec is associated with an internal TBI PHY.
|
||||
This PHY is accessed through the local MDIO bus. These buses are defined
|
||||
similarly to the mdio buses, except they are compatible with "fsl,gianfar-tbi".
|
||||
The TBI PHYs underneath them are similar to normal PHYs, but the reg property
|
||||
is considered instructive, rather than descriptive. The reg property should
|
||||
be chosen so it doesn't interfere with other PHYs on the bus.
|
||||
Refer to Documentation/devicetree/bindings/net/fsl,gianfar-mdio.yaml
|
||||
|
||||
* Gianfar-compatible ethernet nodes
|
||||
|
||||
Properties:
|
||||
|
||||
- device_type : Should be "network"
|
||||
- model : Model of the device. Can be "TSEC", "eTSEC", or "FEC"
|
||||
- compatible : Should be "gianfar"
|
||||
- reg : Offset and length of the register set for the device
|
||||
- interrupts : For FEC devices, the first interrupt is the device's
|
||||
interrupt. For TSEC and eTSEC devices, the first interrupt is
|
||||
transmit, the second is receive, and the third is error.
|
||||
- phy-handle : See ethernet.txt file in the same directory.
|
||||
- fixed-link : See fixed-link.txt in the same directory.
|
||||
- phy-connection-type : See ethernet.txt file in the same directory.
|
||||
This property is only really needed if the connection is of type
|
||||
"rgmii-id", as all other connection types are detected by hardware.
|
||||
- fsl,magic-packet : If present, indicates that the hardware supports
|
||||
waking up via magic packet.
|
||||
- fsl,wake-on-filer : If present, indicates that the hardware supports
|
||||
waking up by Filer General Purpose Interrupt (FGPI) asserted on the
|
||||
Rx int line. This is an advanced power management capability allowing
|
||||
certain packet types (user) defined by filer rules to wake up the system.
|
||||
- bd-stash : If present, indicates that the hardware supports stashing
|
||||
buffer descriptors in the L2.
|
||||
- rx-stash-len : Denotes the number of bytes of a received buffer to stash
|
||||
in the L2.
|
||||
- rx-stash-idx : Denotes the index of the first byte from the received
|
||||
buffer to stash in the L2.
|
||||
|
||||
Example:
|
||||
ethernet@24000 {
|
||||
device_type = "network";
|
||||
model = "TSEC";
|
||||
compatible = "gianfar";
|
||||
reg = <0x24000 0x1000>;
|
||||
local-mac-address = [ 00 E0 0C 00 73 00 ];
|
||||
interrupts = <29 2 30 2 34 2>;
|
||||
interrupt-parent = <&mpic>;
|
||||
phy-handle = <&phy0>
|
||||
};
|
||||
Refer to Documentation/devicetree/bindings/net/fsl,gianfar.yaml
|
||||
|
||||
* Gianfar PTP clock nodes
|
||||
|
||||
|
||||
@@ -20,7 +20,7 @@ Example:
|
||||
reg = <0>;
|
||||
spi-max-frequency = <3000000>;
|
||||
spi-cpol;
|
||||
reset-gpio = <&gpio1 1 GPIO_ACTIVE_HIGH>;
|
||||
reset-gpio = <&gpio1 1 GPIO_ACTIVE_LOW>;
|
||||
irq-gpio = <&gpio1 2 GPIO_ACTIVE_HIGH>;
|
||||
extclock-enable;
|
||||
extclock-freq = 16000000;
|
||||
|
||||
@@ -41,6 +41,12 @@ properties:
|
||||
- const: ptp_ref
|
||||
- const: tx_clk
|
||||
|
||||
interrupts:
|
||||
maxItems: 1
|
||||
|
||||
interrupt-names:
|
||||
const: macirq
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- clocks
|
||||
|
||||
@@ -64,6 +64,12 @@ properties:
|
||||
- const: rmii_internal
|
||||
- const: mac_cg
|
||||
|
||||
interrupts:
|
||||
maxItems: 1
|
||||
|
||||
interrupt-names:
|
||||
const: macirq
|
||||
|
||||
power-domains:
|
||||
maxItems: 1
|
||||
|
||||
|
||||
@@ -56,6 +56,14 @@ properties:
|
||||
- tx
|
||||
- mem
|
||||
|
||||
interrupts:
|
||||
maxItems: 2
|
||||
|
||||
interrupt-names:
|
||||
items:
|
||||
- const: macirq
|
||||
- const: eth_wake_irq
|
||||
|
||||
intf_mode:
|
||||
$ref: /schemas/types.yaml#/definitions/phandle-array
|
||||
items:
|
||||
|
||||
@@ -210,70 +210,70 @@ additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/interrupt-controller/arm-gic.h>
|
||||
#include <dt-bindings/clock/qcom,rpmh.h>
|
||||
#include <dt-bindings/interconnect/qcom,sdm845.h>
|
||||
#include <dt-bindings/interrupt-controller/arm-gic.h>
|
||||
#include <dt-bindings/clock/qcom,rpmh.h>
|
||||
#include <dt-bindings/interconnect/qcom,sdm845.h>
|
||||
|
||||
smp2p-mpss {
|
||||
compatible = "qcom,smp2p";
|
||||
interrupts = <GIC_SPI 576 IRQ_TYPE_EDGE_RISING>;
|
||||
mboxes = <&apss_shared 6>;
|
||||
qcom,smem = <94>, <432>;
|
||||
qcom,local-pid = <0>;
|
||||
qcom,remote-pid = <5>;
|
||||
smp2p-mpss {
|
||||
compatible = "qcom,smp2p";
|
||||
interrupts = <GIC_SPI 576 IRQ_TYPE_EDGE_RISING>;
|
||||
mboxes = <&apss_shared 6>;
|
||||
qcom,smem = <94>, <432>;
|
||||
qcom,local-pid = <0>;
|
||||
qcom,remote-pid = <5>;
|
||||
|
||||
ipa_smp2p_out: ipa-ap-to-modem {
|
||||
qcom,entry-name = "ipa";
|
||||
#qcom,smem-state-cells = <1>;
|
||||
};
|
||||
|
||||
ipa_smp2p_in: ipa-modem-to-ap {
|
||||
qcom,entry-name = "ipa";
|
||||
interrupt-controller;
|
||||
#interrupt-cells = <2>;
|
||||
};
|
||||
ipa_smp2p_out: ipa-ap-to-modem {
|
||||
qcom,entry-name = "ipa";
|
||||
#qcom,smem-state-cells = <1>;
|
||||
};
|
||||
|
||||
ipa@1e40000 {
|
||||
compatible = "qcom,sc7180-ipa";
|
||||
|
||||
qcom,gsi-loader = "self";
|
||||
memory-region = <&ipa_fw_mem>;
|
||||
firmware-name = "qcom/sc7180-trogdor/modem/modem.mbn";
|
||||
|
||||
iommus = <&apps_smmu 0x440 0x0>,
|
||||
<&apps_smmu 0x442 0x0>;
|
||||
reg = <0x1e40000 0x7000>,
|
||||
<0x1e47000 0x2000>,
|
||||
<0x1e04000 0x2c000>;
|
||||
reg-names = "ipa-reg",
|
||||
"ipa-shared",
|
||||
"gsi";
|
||||
|
||||
interrupts-extended = <&intc GIC_SPI 311 IRQ_TYPE_EDGE_RISING>,
|
||||
<&intc GIC_SPI 432 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<&ipa_smp2p_in 0 IRQ_TYPE_EDGE_RISING>,
|
||||
<&ipa_smp2p_in 1 IRQ_TYPE_EDGE_RISING>;
|
||||
interrupt-names = "ipa",
|
||||
"gsi",
|
||||
"ipa-clock-query",
|
||||
"ipa-setup-ready";
|
||||
|
||||
clocks = <&rpmhcc RPMH_IPA_CLK>;
|
||||
clock-names = "core";
|
||||
|
||||
interconnects =
|
||||
<&aggre2_noc MASTER_IPA 0 &mc_virt SLAVE_EBI1 0>,
|
||||
<&aggre2_noc MASTER_IPA 0 &system_noc SLAVE_IMEM 0>,
|
||||
<&gem_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_IPA_CFG 0>;
|
||||
interconnect-names = "memory",
|
||||
"imem",
|
||||
"config";
|
||||
|
||||
qcom,qmp = <&aoss_qmp>;
|
||||
|
||||
qcom,smem-states = <&ipa_smp2p_out 0>,
|
||||
<&ipa_smp2p_out 1>;
|
||||
qcom,smem-state-names = "ipa-clock-enabled-valid",
|
||||
"ipa-clock-enabled";
|
||||
ipa_smp2p_in: ipa-modem-to-ap {
|
||||
qcom,entry-name = "ipa";
|
||||
interrupt-controller;
|
||||
#interrupt-cells = <2>;
|
||||
};
|
||||
};
|
||||
|
||||
ipa@1e40000 {
|
||||
compatible = "qcom,sc7180-ipa";
|
||||
|
||||
qcom,gsi-loader = "self";
|
||||
memory-region = <&ipa_fw_mem>;
|
||||
firmware-name = "qcom/sc7180-trogdor/modem/modem.mbn";
|
||||
|
||||
iommus = <&apps_smmu 0x440 0x0>,
|
||||
<&apps_smmu 0x442 0x0>;
|
||||
reg = <0x1e40000 0x7000>,
|
||||
<0x1e47000 0x2000>,
|
||||
<0x1e04000 0x2c000>;
|
||||
reg-names = "ipa-reg",
|
||||
"ipa-shared",
|
||||
"gsi";
|
||||
|
||||
interrupts-extended = <&intc GIC_SPI 311 IRQ_TYPE_EDGE_RISING>,
|
||||
<&intc GIC_SPI 432 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<&ipa_smp2p_in 0 IRQ_TYPE_EDGE_RISING>,
|
||||
<&ipa_smp2p_in 1 IRQ_TYPE_EDGE_RISING>;
|
||||
interrupt-names = "ipa",
|
||||
"gsi",
|
||||
"ipa-clock-query",
|
||||
"ipa-setup-ready";
|
||||
|
||||
clocks = <&rpmhcc RPMH_IPA_CLK>;
|
||||
clock-names = "core";
|
||||
|
||||
interconnects =
|
||||
<&aggre2_noc MASTER_IPA 0 &mc_virt SLAVE_EBI1 0>,
|
||||
<&aggre2_noc MASTER_IPA 0 &system_noc SLAVE_IMEM 0>,
|
||||
<&gem_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_IPA_CFG 0>;
|
||||
interconnect-names = "memory",
|
||||
"imem",
|
||||
"config";
|
||||
|
||||
qcom,qmp = <&aoss_qmp>;
|
||||
|
||||
qcom,smem-states = <&ipa_smp2p_out 0>,
|
||||
<&ipa_smp2p_out 1>;
|
||||
qcom,smem-state-names = "ipa-clock-enabled-valid",
|
||||
"ipa-clock-enabled";
|
||||
};
|
||||
|
||||
@@ -0,0 +1,86 @@
|
||||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/net/realtek,rtl9301-mdio.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Realtek RTL9300 MDIO Controller
|
||||
|
||||
maintainers:
|
||||
- Chris Packham <chris.packham@alliedtelesis.co.nz>
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
oneOf:
|
||||
- items:
|
||||
- enum:
|
||||
- realtek,rtl9302b-mdio
|
||||
- realtek,rtl9302c-mdio
|
||||
- realtek,rtl9303-mdio
|
||||
- const: realtek,rtl9301-mdio
|
||||
- const: realtek,rtl9301-mdio
|
||||
|
||||
'#address-cells':
|
||||
const: 1
|
||||
|
||||
'#size-cells':
|
||||
const: 0
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
patternProperties:
|
||||
'^mdio-bus@[0-3]$':
|
||||
$ref: mdio.yaml#
|
||||
|
||||
properties:
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
required:
|
||||
- reg
|
||||
|
||||
patternProperties:
|
||||
'^ethernet-phy@[a-f0-9]+$':
|
||||
type: object
|
||||
$ref: ethernet-phy.yaml#
|
||||
unevaluatedProperties: false
|
||||
|
||||
unevaluatedProperties: false
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
|
||||
unevaluatedProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
mdio-controller@ca00 {
|
||||
compatible = "realtek,rtl9301-mdio";
|
||||
reg = <0xca00 0x200>;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
mdio-bus@0 {
|
||||
reg = <0>;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
ethernet-phy@0 {
|
||||
compatible = "ethernet-phy-ieee802.3-c45";
|
||||
reg = <0>;
|
||||
};
|
||||
};
|
||||
|
||||
mdio-bus@1 {
|
||||
reg = <1>;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
ethernet-phy@0 {
|
||||
compatible = "ethernet-phy-ieee802.3-c45";
|
||||
reg = <0>;
|
||||
};
|
||||
};
|
||||
};
|
||||
@@ -1,7 +1,7 @@
|
||||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/mfd/realtek,rtl9301-switch.yaml#
|
||||
$id: http://devicetree.org/schemas/net/realtek,rtl9301-switch.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Realtek Switch with Internal CPU
|
||||
@@ -14,6 +14,8 @@ description:
|
||||
number of different peripherals are accessed through a common register block,
|
||||
represented here as a syscon node.
|
||||
|
||||
$ref: ethernet-switch.yaml#/$defs/ethernet-ports
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
items:
|
||||
@@ -28,12 +30,23 @@ properties:
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
interrupts:
|
||||
maxItems: 2
|
||||
|
||||
interrupt-names:
|
||||
items:
|
||||
- const: switch
|
||||
- const: nic
|
||||
|
||||
'#address-cells':
|
||||
const: 1
|
||||
|
||||
'#size-cells':
|
||||
const: 1
|
||||
|
||||
ethernet-ports:
|
||||
type: object
|
||||
|
||||
patternProperties:
|
||||
'reboot@[0-9a-f]+$':
|
||||
$ref: /schemas/power/reset/syscon-reboot.yaml#
|
||||
@@ -41,9 +54,14 @@ patternProperties:
|
||||
'i2c@[0-9a-f]+$':
|
||||
$ref: /schemas/i2c/realtek,rtl9301-i2c.yaml#
|
||||
|
||||
'mdio-controller@[0-9a-f]+$':
|
||||
$ref: realtek,rtl9301-mdio.yaml#
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- interrupts
|
||||
- interrupt-names
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
@@ -52,6 +70,9 @@ examples:
|
||||
ethernet-switch@1b000000 {
|
||||
compatible = "realtek,rtl9301-switch", "syscon", "simple-mfd";
|
||||
reg = <0x1b000000 0x10000>;
|
||||
interrupt-parent = <&intc>;
|
||||
interrupts = <23>, <24>;
|
||||
interrupt-names = "switch", "nic";
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
|
||||
@@ -110,5 +131,45 @@ examples:
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
mdio-controller@ca00 {
|
||||
compatible = "realtek,rtl9301-mdio";
|
||||
reg = <0xca00 0x200>;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
mdio-bus@0 {
|
||||
reg = <0>;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
phy1: ethernet-phy@0 {
|
||||
reg = <0>;
|
||||
};
|
||||
};
|
||||
mdio-bus@1 {
|
||||
reg = <1>;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
phy2: ethernet-phy@0 {
|
||||
reg = <0>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
ethernet-ports {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
port@0 {
|
||||
reg = <0>;
|
||||
phy-handle = <&phy1>;
|
||||
};
|
||||
port@1 {
|
||||
reg = <1>;
|
||||
phy-handle = <&phy2>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
@@ -32,6 +32,10 @@ properties:
|
||||
shutdown-gpios:
|
||||
maxItems: 1
|
||||
|
||||
default-blocked:
|
||||
$ref: /schemas/types.yaml#/definitions/flag
|
||||
description: configure rfkill state as blocked at boot
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- radio-type
|
||||
@@ -48,4 +52,5 @@ examples:
|
||||
label = "rfkill-pcie-wlan";
|
||||
radio-type = "wlan";
|
||||
shutdown-gpios = <&gpio2 25 GPIO_ACTIVE_HIGH>;
|
||||
default-blocked;
|
||||
};
|
||||
|
||||
@@ -24,6 +24,7 @@ select:
|
||||
- rockchip,rk3366-gmac
|
||||
- rockchip,rk3368-gmac
|
||||
- rockchip,rk3399-gmac
|
||||
- rockchip,rk3528-gmac
|
||||
- rockchip,rk3568-gmac
|
||||
- rockchip,rk3576-gmac
|
||||
- rockchip,rk3588-gmac
|
||||
@@ -32,9 +33,6 @@ select:
|
||||
required:
|
||||
- compatible
|
||||
|
||||
allOf:
|
||||
- $ref: snps,dwmac.yaml#
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
oneOf:
|
||||
@@ -52,14 +50,25 @@ properties:
|
||||
- rockchip,rv1108-gmac
|
||||
- items:
|
||||
- enum:
|
||||
- rockchip,rk3528-gmac
|
||||
- rockchip,rk3568-gmac
|
||||
- rockchip,rk3576-gmac
|
||||
- rockchip,rk3588-gmac
|
||||
- rockchip,rv1126-gmac
|
||||
- const: snps,dwmac-4.20a
|
||||
|
||||
interrupts:
|
||||
minItems: 1
|
||||
maxItems: 2
|
||||
|
||||
interrupt-names:
|
||||
minItems: 1
|
||||
items:
|
||||
- const: macirq
|
||||
- const: eth_wake_irq
|
||||
|
||||
clocks:
|
||||
minItems: 5
|
||||
minItems: 4
|
||||
maxItems: 8
|
||||
|
||||
clock-names:
|
||||
@@ -114,6 +123,36 @@ required:
|
||||
- compatible
|
||||
- clocks
|
||||
- clock-names
|
||||
- rockchip,grf
|
||||
|
||||
allOf:
|
||||
- $ref: snps,dwmac.yaml#
|
||||
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
enum:
|
||||
- rockchip,rk3576-gmac
|
||||
- rockchip,rk3588-gmac
|
||||
then:
|
||||
required:
|
||||
- rockchip,php-grf
|
||||
else:
|
||||
properties:
|
||||
rockchip,php-grf: false
|
||||
|
||||
- if:
|
||||
not:
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
enum:
|
||||
- rockchip,rk3528-gmac
|
||||
then:
|
||||
properties:
|
||||
clocks:
|
||||
minItems: 5
|
||||
|
||||
unevaluatedProperties: false
|
||||
|
||||
|
||||
@@ -32,6 +32,7 @@ select:
|
||||
- snps,dwmac-4.20a
|
||||
- snps,dwmac-5.10a
|
||||
- snps,dwmac-5.20
|
||||
- snps,dwmac-5.30a
|
||||
- snps,dwxgmac
|
||||
- snps,dwxgmac-2.10
|
||||
|
||||
@@ -98,10 +99,13 @@ properties:
|
||||
- snps,dwmac-4.20a
|
||||
- snps,dwmac-5.10a
|
||||
- snps,dwmac-5.20
|
||||
- snps,dwmac-5.30a
|
||||
- snps,dwxgmac
|
||||
- snps,dwxgmac-2.10
|
||||
- sophgo,sg2044-dwmac
|
||||
- starfive,jh7100-dwmac
|
||||
- starfive,jh7110-dwmac
|
||||
- tesla,fsd-ethqos
|
||||
- thead,th1520-gmac
|
||||
|
||||
reg:
|
||||
@@ -126,7 +130,7 @@ properties:
|
||||
|
||||
clocks:
|
||||
minItems: 1
|
||||
maxItems: 8
|
||||
maxItems: 10
|
||||
additionalItems: true
|
||||
items:
|
||||
- description: GMAC main clock
|
||||
@@ -138,7 +142,7 @@ properties:
|
||||
|
||||
clock-names:
|
||||
minItems: 1
|
||||
maxItems: 8
|
||||
maxItems: 10
|
||||
additionalItems: true
|
||||
contains:
|
||||
enum:
|
||||
@@ -490,6 +494,7 @@ properties:
|
||||
|
||||
snps,en-tx-lpi-clockgating:
|
||||
$ref: /schemas/types.yaml#/definitions/flag
|
||||
deprecated: true
|
||||
description:
|
||||
Enable gating of the MAC TX clock during TX low-power mode
|
||||
|
||||
@@ -631,6 +636,7 @@ allOf:
|
||||
- snps,dwmac-4.20a
|
||||
- snps,dwmac-5.10a
|
||||
- snps,dwmac-5.20
|
||||
- snps,dwmac-5.30a
|
||||
- snps,dwxgmac
|
||||
- snps,dwxgmac-2.10
|
||||
- st,spear600-gmac
|
||||
|
||||
126
Documentation/devicetree/bindings/net/sophgo,sg2044-dwmac.yaml
Normal file
126
Documentation/devicetree/bindings/net/sophgo,sg2044-dwmac.yaml
Normal file
@@ -0,0 +1,126 @@
|
||||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/net/sophgo,sg2044-dwmac.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Sophgo SG2044 DWMAC glue layer
|
||||
|
||||
maintainers:
|
||||
- Inochi Amaoto <inochiama@gmail.com>
|
||||
|
||||
select:
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
enum:
|
||||
- sophgo,sg2044-dwmac
|
||||
required:
|
||||
- compatible
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
items:
|
||||
- const: sophgo,sg2044-dwmac
|
||||
- const: snps,dwmac-5.30a
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
clocks:
|
||||
items:
|
||||
- description: GMAC main clock
|
||||
- description: PTP clock
|
||||
- description: TX clock
|
||||
|
||||
clock-names:
|
||||
items:
|
||||
- const: stmmaceth
|
||||
- const: ptp_ref
|
||||
- const: tx
|
||||
|
||||
dma-noncoherent: true
|
||||
|
||||
interrupts:
|
||||
maxItems: 1
|
||||
|
||||
interrupt-names:
|
||||
maxItems: 1
|
||||
|
||||
resets:
|
||||
maxItems: 1
|
||||
|
||||
reset-names:
|
||||
const: stmmaceth
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- clocks
|
||||
- clock-names
|
||||
- interrupts
|
||||
- interrupt-names
|
||||
- resets
|
||||
- reset-names
|
||||
|
||||
allOf:
|
||||
- $ref: snps,dwmac.yaml#
|
||||
|
||||
unevaluatedProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/interrupt-controller/irq.h>
|
||||
|
||||
ethernet@30006000 {
|
||||
compatible = "sophgo,sg2044-dwmac", "snps,dwmac-5.30a";
|
||||
reg = <0x30006000 0x4000>;
|
||||
clocks = <&clk 151>, <&clk 152>, <&clk 154>;
|
||||
clock-names = "stmmaceth", "ptp_ref", "tx";
|
||||
interrupt-parent = <&intc>;
|
||||
interrupts = <296 IRQ_TYPE_LEVEL_HIGH>;
|
||||
interrupt-names = "macirq";
|
||||
resets = <&rst 30>;
|
||||
reset-names = "stmmaceth";
|
||||
snps,multicast-filter-bins = <0>;
|
||||
snps,perfect-filter-entries = <1>;
|
||||
snps,aal;
|
||||
snps,tso;
|
||||
snps,txpbl = <32>;
|
||||
snps,rxpbl = <32>;
|
||||
snps,mtl-rx-config = <&gmac0_mtl_rx_setup>;
|
||||
snps,mtl-tx-config = <&gmac0_mtl_tx_setup>;
|
||||
snps,axi-config = <&gmac0_stmmac_axi_setup>;
|
||||
status = "disabled";
|
||||
|
||||
gmac0_mtl_rx_setup: rx-queues-config {
|
||||
snps,rx-queues-to-use = <8>;
|
||||
snps,rx-sched-wsp;
|
||||
queue0 {};
|
||||
queue1 {};
|
||||
queue2 {};
|
||||
queue3 {};
|
||||
queue4 {};
|
||||
queue5 {};
|
||||
queue6 {};
|
||||
queue7 {};
|
||||
};
|
||||
|
||||
gmac0_mtl_tx_setup: tx-queues-config {
|
||||
snps,tx-queues-to-use = <8>;
|
||||
queue0 {};
|
||||
queue1 {};
|
||||
queue2 {};
|
||||
queue3 {};
|
||||
queue4 {};
|
||||
queue5 {};
|
||||
queue6 {};
|
||||
queue7 {};
|
||||
};
|
||||
|
||||
gmac0_stmmac_axi_setup: stmmac-axi-config {
|
||||
snps,blen = <16 8 4 0 0 0 0>;
|
||||
snps,wr_osr_lmt = <1>;
|
||||
snps,rd_osr_lmt = <2>;
|
||||
};
|
||||
};
|
||||
@@ -54,6 +54,16 @@ properties:
|
||||
items:
|
||||
- const: stmmaceth
|
||||
|
||||
interrupts:
|
||||
minItems: 1
|
||||
maxItems: 2
|
||||
|
||||
interrupt-names:
|
||||
minItems: 1
|
||||
items:
|
||||
- const: macirq
|
||||
- const: eth_wake_irq
|
||||
|
||||
clocks:
|
||||
minItems: 3
|
||||
items:
|
||||
|
||||
118
Documentation/devicetree/bindings/net/tesla,fsd-ethqos.yaml
Normal file
118
Documentation/devicetree/bindings/net/tesla,fsd-ethqos.yaml
Normal file
@@ -0,0 +1,118 @@
|
||||
# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/net/tesla,fsd-ethqos.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: FSD Ethernet Quality of Service
|
||||
|
||||
maintainers:
|
||||
- Swathi K S <swathi.ks@samsung.com>
|
||||
|
||||
description:
|
||||
Tesla ethernet devices based on dwmmac support Gigabit ethernet.
|
||||
|
||||
allOf:
|
||||
- $ref: snps,dwmac.yaml#
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
const: tesla,fsd-ethqos
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
interrupts:
|
||||
maxItems: 1
|
||||
|
||||
interrupt-names:
|
||||
items:
|
||||
- const: macirq
|
||||
|
||||
clocks:
|
||||
minItems: 5
|
||||
items:
|
||||
- description: PTP clock
|
||||
- description: Master bus clock
|
||||
- description: Slave bus clock
|
||||
- description: MAC TX clock
|
||||
- description: MAC RX clock
|
||||
- description: Master2 bus clock
|
||||
- description: Slave2 bus clock
|
||||
- description: RX MUX clock
|
||||
- description: PHY RX clock
|
||||
- description: PERIC RGMII clock
|
||||
|
||||
clock-names:
|
||||
minItems: 5
|
||||
items:
|
||||
- const: ptp_ref
|
||||
- const: master_bus
|
||||
- const: slave_bus
|
||||
- const: tx
|
||||
- const: rx
|
||||
- const: master2_bus
|
||||
- const: slave2_bus
|
||||
- const: eqos_rxclk_mux
|
||||
- const: eqos_phyrxclk
|
||||
- const: dout_peric_rgmii_clk
|
||||
|
||||
iommus:
|
||||
maxItems: 1
|
||||
|
||||
phy-mode:
|
||||
enum:
|
||||
- rgmii
|
||||
- rgmii-id
|
||||
- rgmii-rxid
|
||||
- rgmii-txid
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- interrupts
|
||||
- clocks
|
||||
- clock-names
|
||||
- iommus
|
||||
- phy-mode
|
||||
|
||||
unevaluatedProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/clock/fsd-clk.h>
|
||||
#include <dt-bindings/interrupt-controller/arm-gic.h>
|
||||
soc {
|
||||
#address-cells = <2>;
|
||||
#size-cells = <2>;
|
||||
ethernet1: ethernet@14300000 {
|
||||
compatible = "tesla,fsd-ethqos";
|
||||
reg = <0x0 0x14300000 0x0 0x10000>;
|
||||
interrupts = <GIC_SPI 176 IRQ_TYPE_LEVEL_HIGH>;
|
||||
interrupt-names = "macirq";
|
||||
clocks = <&clock_peric PERIC_EQOS_TOP_IPCLKPORT_CLK_PTP_REF_I>,
|
||||
<&clock_peric PERIC_EQOS_TOP_IPCLKPORT_ACLK_I>,
|
||||
<&clock_peric PERIC_EQOS_TOP_IPCLKPORT_HCLK_I>,
|
||||
<&clock_peric PERIC_EQOS_TOP_IPCLKPORT_RGMII_CLK_I>,
|
||||
<&clock_peric PERIC_EQOS_TOP_IPCLKPORT_CLK_RX_I>,
|
||||
<&clock_peric PERIC_BUS_D_PERIC_IPCLKPORT_EQOSCLK>,
|
||||
<&clock_peric PERIC_BUS_P_PERIC_IPCLKPORT_EQOSCLK>,
|
||||
<&clock_peric PERIC_EQOS_PHYRXCLK_MUX>,
|
||||
<&clock_peric PERIC_EQOS_PHYRXCLK>,
|
||||
<&clock_peric PERIC_DOUT_RGMII_CLK>;
|
||||
clock-names = "ptp_ref", "master_bus", "slave_bus","tx",
|
||||
"rx", "master2_bus", "slave2_bus", "eqos_rxclk_mux",
|
||||
"eqos_phyrxclk","dout_peric_rgmii_clk";
|
||||
assigned-clocks = <&clock_peric PERIC_EQOS_PHYRXCLK_MUX>,
|
||||
<&clock_peric PERIC_EQOS_PHYRXCLK>;
|
||||
assigned-clock-parents = <&clock_peric PERIC_EQOS_PHYRXCLK>;
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <ð1_tx_clk>, <ð1_tx_data>, <ð1_tx_ctrl>,
|
||||
<ð1_phy_intr>, <ð1_rx_clk>, <ð1_rx_data>,
|
||||
<ð1_rx_ctrl>, <ð1_mdio>;
|
||||
iommus = <&smmu_peric 0x0 0x1>;
|
||||
phy-mode = "rgmii-id";
|
||||
};
|
||||
};
|
||||
|
||||
...
|
||||
@@ -42,6 +42,12 @@ properties:
|
||||
- const: stmmaceth
|
||||
- const: phy_ref_clk
|
||||
|
||||
interrupts:
|
||||
maxItems: 1
|
||||
|
||||
interrupt-names:
|
||||
const: macirq
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
|
||||
@@ -92,20 +92,41 @@ properties:
|
||||
|
||||
ieee80211-freq-limit: true
|
||||
|
||||
qcom,ath10k-calibration-data:
|
||||
qcom,calibration-data:
|
||||
$ref: /schemas/types.yaml#/definitions/uint8-array
|
||||
description:
|
||||
Calibration data + board-specific data as a byte array. The length
|
||||
can vary between hardware versions.
|
||||
|
||||
qcom,ath10k-calibration-variant:
|
||||
qcom,ath10k-calibration-data:
|
||||
$ref: /schemas/types.yaml#/definitions/uint8-array
|
||||
deprecated: true
|
||||
description:
|
||||
Calibration data + board-specific data as a byte array. The length
|
||||
can vary between hardware versions.
|
||||
|
||||
qcom,calibration-variant:
|
||||
$ref: /schemas/types.yaml#/definitions/string
|
||||
description:
|
||||
Unique variant identifier of the calibration data in board-2.bin
|
||||
for designs with colliding bus and device specific ids
|
||||
|
||||
qcom,ath10k-calibration-variant:
|
||||
$ref: /schemas/types.yaml#/definitions/string
|
||||
deprecated: true
|
||||
description:
|
||||
Unique variant identifier of the calibration data in board-2.bin
|
||||
for designs with colliding bus and device specific ids
|
||||
|
||||
qcom,pre-calibration-data:
|
||||
$ref: /schemas/types.yaml#/definitions/uint8-array
|
||||
description:
|
||||
Pre-calibration data as a byte array. The length can vary between
|
||||
hardware versions.
|
||||
|
||||
qcom,ath10k-pre-calibration-data:
|
||||
$ref: /schemas/types.yaml#/definitions/uint8-array
|
||||
deprecated: true
|
||||
description:
|
||||
Pre-calibration data as a byte array. The length can vary between
|
||||
hardware versions.
|
||||
|
||||
@@ -22,8 +22,15 @@ properties:
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
qcom,calibration-variant:
|
||||
$ref: /schemas/types.yaml#/definitions/string
|
||||
description: |
|
||||
string to uniquely identify variant of the calibration data for designs
|
||||
with colliding bus and device ids
|
||||
|
||||
qcom,ath11k-calibration-variant:
|
||||
$ref: /schemas/types.yaml#/definitions/string
|
||||
deprecated: true
|
||||
description: |
|
||||
string to uniquely identify variant of the calibration data for designs
|
||||
with colliding bus and device ids
|
||||
@@ -127,7 +134,7 @@ examples:
|
||||
vddrfa1p2-supply = <&vreg_pmu_rfa_1p2>;
|
||||
vddrfa1p8-supply = <&vreg_pmu_rfa_1p7>;
|
||||
|
||||
qcom,ath11k-calibration-variant = "LE_X13S";
|
||||
qcom,calibration-variant = "LE_X13S";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
@@ -41,8 +41,15 @@ properties:
|
||||
* reg
|
||||
* reg-names
|
||||
|
||||
qcom,calibration-variant:
|
||||
$ref: /schemas/types.yaml#/definitions/string
|
||||
description:
|
||||
string to uniquely identify variant of the calibration data in the
|
||||
board-2.bin for designs with colliding bus and device specific ids
|
||||
|
||||
qcom,ath11k-calibration-variant:
|
||||
$ref: /schemas/types.yaml#/definitions/string
|
||||
deprecated: true
|
||||
description:
|
||||
string to uniquely identify variant of the calibration data in the
|
||||
board-2.bin for designs with colliding bus and device specific ids
|
||||
|
||||
@@ -52,8 +52,15 @@ properties:
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
qcom,calibration-variant:
|
||||
$ref: /schemas/types.yaml#/definitions/string
|
||||
description:
|
||||
String to uniquely identify variant of the calibration data for designs
|
||||
with colliding bus and device ids
|
||||
|
||||
qcom,ath12k-calibration-variant:
|
||||
$ref: /schemas/types.yaml#/definitions/string
|
||||
deprecated: true
|
||||
description:
|
||||
String to uniquely identify variant of the calibration data for designs
|
||||
with colliding bus and device ids
|
||||
@@ -103,7 +110,7 @@ examples:
|
||||
compatible = "pci17cb,1109";
|
||||
reg = <0x0 0x0 0x0 0x0 0x0>;
|
||||
|
||||
qcom,ath12k-calibration-variant = "RDP433_1";
|
||||
qcom,calibration-variant = "RDP433_1";
|
||||
|
||||
ports {
|
||||
#address-cells = <1>;
|
||||
@@ -139,7 +146,7 @@ examples:
|
||||
compatible = "pci17cb,1109";
|
||||
reg = <0x0 0x0 0x0 0x0 0x0>;
|
||||
|
||||
qcom,ath12k-calibration-variant = "RDP433_2";
|
||||
qcom,calibration-variant = "RDP433_2";
|
||||
qcom,wsi-controller;
|
||||
|
||||
ports {
|
||||
@@ -176,7 +183,7 @@ examples:
|
||||
compatible = "pci17cb,1109";
|
||||
reg = <0x0 0x0 0x0 0x0 0x0>;
|
||||
|
||||
qcom,ath12k-calibration-variant = "RDP433_3";
|
||||
qcom,calibration-variant = "RDP433_3";
|
||||
|
||||
ports {
|
||||
#address-cells = <1>;
|
||||
|
||||
@@ -14,9 +14,10 @@ $defs:
|
||||
pattern: ^[0-9A-Za-z_-]+( - 1)?$
|
||||
minimum: 0
|
||||
len-or-limit:
|
||||
# literal int or limit based on fixed-width type e.g. u8-min, u16-max, etc.
|
||||
# literal int, const name, or limit based on fixed-width type
|
||||
# e.g. u8-min, u16-max, etc.
|
||||
type: [ string, integer ]
|
||||
pattern: ^[su](8|16|32|64)-(min|max)$
|
||||
pattern: ^[0-9A-Za-z_-]+$
|
||||
minimum: 0
|
||||
|
||||
# Schema for specs
|
||||
@@ -160,7 +161,7 @@ properties:
|
||||
type: string
|
||||
type: &attr-type
|
||||
enum: [ unused, pad, flag, binary,
|
||||
uint, sint, u8, u16, u32, u64, s32, s64,
|
||||
uint, sint, u8, u16, u32, u64, s8, s16, s32, s64,
|
||||
string, nest, indexed-array, nest-type-value ]
|
||||
doc:
|
||||
description: Documentation of the attribute.
|
||||
|
||||
@@ -14,9 +14,10 @@ $defs:
|
||||
pattern: ^[0-9A-Za-z_-]+( - 1)?$
|
||||
minimum: 0
|
||||
len-or-limit:
|
||||
# literal int or limit based on fixed-width type e.g. u8-min, u16-max, etc.
|
||||
# literal int, const name, or limit based on fixed-width type
|
||||
# e.g. u8-min, u16-max, etc.
|
||||
type: [ string, integer ]
|
||||
pattern: ^[su](8|16|32|64)-(min|max)$
|
||||
pattern: ^[0-9A-Za-z_-]+$
|
||||
minimum: 0
|
||||
|
||||
# Schema for specs
|
||||
@@ -151,6 +152,9 @@ properties:
|
||||
the right formatting mechanism when displaying values of this
|
||||
type.
|
||||
enum: [ hex, mac, fddi, ipv4, ipv6, uuid ]
|
||||
struct:
|
||||
description: Name of the nested struct type.
|
||||
type: string
|
||||
# End genetlink-legacy
|
||||
|
||||
attribute-sets:
|
||||
@@ -203,7 +207,7 @@ properties:
|
||||
type: &attr-type
|
||||
description: The netlink attribute type
|
||||
enum: [ unused, pad, flag, binary, bitfield32,
|
||||
uint, sint, u8, u16, u32, u64, s32, s64,
|
||||
uint, sint, u8, u16, u32, u64, s8, s16, s32, s64,
|
||||
string, nest, indexed-array, nest-type-value ]
|
||||
doc:
|
||||
description: Documentation of the attribute.
|
||||
|
||||
@@ -14,9 +14,10 @@ $defs:
|
||||
pattern: ^[0-9A-Za-z_-]+( - 1)?$
|
||||
minimum: 0
|
||||
len-or-limit:
|
||||
# literal int or limit based on fixed-width type e.g. u8-min, u16-max, etc.
|
||||
# literal int, const name, or limit based on fixed-width type
|
||||
# e.g. u8-min, u16-max, etc.
|
||||
type: [ string, integer ]
|
||||
pattern: ^[su](8|16|32|64)-(min|max)$
|
||||
pattern: ^[0-9A-Za-z_-]+$
|
||||
minimum: 0
|
||||
|
||||
# Schema for specs
|
||||
@@ -123,7 +124,7 @@ properties:
|
||||
type: string
|
||||
type: &attr-type
|
||||
enum: [ unused, pad, flag, binary,
|
||||
uint, sint, u8, u16, u32, u64, s32, s64,
|
||||
uint, sint, u8, u16, u32, u64, s8, s16, s32, s64,
|
||||
string, nest, indexed-array, nest-type-value ]
|
||||
doc:
|
||||
description: Documentation of the attribute.
|
||||
|
||||
643
Documentation/netlink/specs/conntrack.yaml
Normal file
643
Documentation/netlink/specs/conntrack.yaml
Normal file
@@ -0,0 +1,643 @@
|
||||
# SPDX-License-Identifier: ((GPL-2.0 WITH Linux-syscall-note) OR BSD-3-Clause)
|
||||
|
||||
name: conntrack
|
||||
protocol: netlink-raw
|
||||
protonum: 12
|
||||
|
||||
doc:
|
||||
Netfilter connection tracking subsystem over nfnetlink
|
||||
|
||||
definitions:
|
||||
-
|
||||
name: nfgenmsg
|
||||
type: struct
|
||||
members:
|
||||
-
|
||||
name: nfgen-family
|
||||
type: u8
|
||||
-
|
||||
name: version
|
||||
type: u8
|
||||
-
|
||||
name: res-id
|
||||
byte-order: big-endian
|
||||
type: u16
|
||||
-
|
||||
name: nf-ct-tcp-flags-mask
|
||||
type: struct
|
||||
members:
|
||||
-
|
||||
name: flags
|
||||
type: u8
|
||||
enum: nf-ct-tcp-flags
|
||||
enum-as-flags: true
|
||||
-
|
||||
name: mask
|
||||
type: u8
|
||||
enum: nf-ct-tcp-flags
|
||||
enum-as-flags: true
|
||||
-
|
||||
name: nf-ct-tcp-flags
|
||||
type: flags
|
||||
entries:
|
||||
- window-scale
|
||||
- sack-perm
|
||||
- close-init
|
||||
- be-liberal
|
||||
- unacked
|
||||
- maxack
|
||||
- challenge-ack
|
||||
- simultaneous-open
|
||||
-
|
||||
name: nf-ct-tcp-state
|
||||
type: enum
|
||||
entries:
|
||||
- none
|
||||
- syn-sent
|
||||
- syn-recv
|
||||
- established
|
||||
- fin-wait
|
||||
- close-wait
|
||||
- last-ack
|
||||
- time-wait
|
||||
- close
|
||||
- syn-sent2
|
||||
- max
|
||||
- ignore
|
||||
- retrans
|
||||
- unack
|
||||
- timeout-max
|
||||
-
|
||||
name: nf-ct-sctp-state
|
||||
type: enum
|
||||
entries:
|
||||
- none
|
||||
- cloned
|
||||
- cookie-wait
|
||||
- cookie-echoed
|
||||
- established
|
||||
- shutdown-sent
|
||||
- shutdown-received
|
||||
- shutdown-ack-sent
|
||||
- shutdown-heartbeat-sent
|
||||
-
|
||||
name: nf-ct-status
|
||||
type: flags
|
||||
entries:
|
||||
- expected
|
||||
- seen-reply
|
||||
- assured
|
||||
- confirmed
|
||||
- src-nat
|
||||
- dst-nat
|
||||
- seq-adj
|
||||
- src-nat-done
|
||||
- dst-nat-done
|
||||
- dying
|
||||
- fixed-timeout
|
||||
- template
|
||||
- nat-clash
|
||||
- helper
|
||||
- offload
|
||||
- hw-offload
|
||||
|
||||
attribute-sets:
|
||||
-
|
||||
name: counter-attrs
|
||||
attributes:
|
||||
-
|
||||
name: packets
|
||||
type: u64
|
||||
byte-order: big-endian
|
||||
-
|
||||
name: bytes
|
||||
type: u64
|
||||
byte-order: big-endian
|
||||
-
|
||||
name: packets-old
|
||||
type: u32
|
||||
-
|
||||
name: bytes-old
|
||||
type: u32
|
||||
-
|
||||
name: pad
|
||||
type: pad
|
||||
-
|
||||
name: tuple-proto-attrs
|
||||
attributes:
|
||||
-
|
||||
name: proto-num
|
||||
type: u8
|
||||
doc: l4 protocol number
|
||||
-
|
||||
name: proto-src-port
|
||||
type: u16
|
||||
byte-order: big-endian
|
||||
doc: l4 source port
|
||||
-
|
||||
name: proto-dst-port
|
||||
type: u16
|
||||
byte-order: big-endian
|
||||
doc: l4 source port
|
||||
-
|
||||
name: proto-icmp-id
|
||||
type: u16
|
||||
byte-order: big-endian
|
||||
doc: l4 icmp id
|
||||
-
|
||||
name: proto-icmp-type
|
||||
type: u8
|
||||
-
|
||||
name: proto-icmp-code
|
||||
type: u8
|
||||
-
|
||||
name: proto-icmpv6-id
|
||||
type: u16
|
||||
byte-order: big-endian
|
||||
doc: l4 icmp id
|
||||
-
|
||||
name: proto-icmpv6-type
|
||||
type: u8
|
||||
-
|
||||
name: proto-icmpv6-code
|
||||
type: u8
|
||||
-
|
||||
name: tuple-ip-attrs
|
||||
attributes:
|
||||
-
|
||||
name: ip-v4-src
|
||||
type: u32
|
||||
byte-order: big-endian
|
||||
display-hint: ipv4
|
||||
doc: ipv4 source address
|
||||
-
|
||||
name: ip-v4-dst
|
||||
type: u32
|
||||
byte-order: big-endian
|
||||
display-hint: ipv4
|
||||
doc: ipv4 destination address
|
||||
-
|
||||
name: ip-v6-src
|
||||
type: binary
|
||||
checks:
|
||||
min-len: 16
|
||||
byte-order: big-endian
|
||||
display-hint: ipv6
|
||||
doc: ipv6 source address
|
||||
-
|
||||
name: ip-v6-dst
|
||||
type: binary
|
||||
checks:
|
||||
min-len: 16
|
||||
byte-order: big-endian
|
||||
display-hint: ipv6
|
||||
doc: ipv6 destination address
|
||||
-
|
||||
name: tuple-attrs
|
||||
attributes:
|
||||
-
|
||||
name: tuple-ip
|
||||
type: nest
|
||||
nested-attributes: tuple-ip-attrs
|
||||
doc: conntrack l3 information
|
||||
-
|
||||
name: tuple-proto
|
||||
type: nest
|
||||
nested-attributes: tuple-proto-attrs
|
||||
doc: conntrack l4 information
|
||||
-
|
||||
name: tuple-zone
|
||||
type: u16
|
||||
byte-order: big-endian
|
||||
doc: conntrack zone id
|
||||
-
|
||||
name: protoinfo-tcp-attrs
|
||||
attributes:
|
||||
-
|
||||
name: tcp-state
|
||||
type: u8
|
||||
enum: nf-ct-tcp-state
|
||||
doc: tcp connection state
|
||||
-
|
||||
name: tcp-wscale-original
|
||||
type: u8
|
||||
doc: window scaling factor in original direction
|
||||
-
|
||||
name: tcp-wscale-reply
|
||||
type: u8
|
||||
doc: window scaling factor in reply direction
|
||||
-
|
||||
name: tcp-flags-original
|
||||
type: binary
|
||||
struct: nf-ct-tcp-flags-mask
|
||||
-
|
||||
name: tcp-flags-reply
|
||||
type: binary
|
||||
struct: nf-ct-tcp-flags-mask
|
||||
-
|
||||
name: protoinfo-dccp-attrs
|
||||
attributes:
|
||||
-
|
||||
name: dccp-state
|
||||
type: u8
|
||||
doc: dccp connection state
|
||||
-
|
||||
name: dccp-role
|
||||
type: u8
|
||||
-
|
||||
name: dccp-handshake-seq
|
||||
type: u64
|
||||
byte-order: big-endian
|
||||
-
|
||||
name: dccp-pad
|
||||
type: pad
|
||||
-
|
||||
name: protoinfo-sctp-attrs
|
||||
attributes:
|
||||
-
|
||||
name: sctp-state
|
||||
type: u8
|
||||
doc: sctp connection state
|
||||
enum: nf-ct-sctp-state
|
||||
-
|
||||
name: vtag-original
|
||||
type: u32
|
||||
byte-order: big-endian
|
||||
-
|
||||
name: vtag-reply
|
||||
type: u32
|
||||
byte-order: big-endian
|
||||
-
|
||||
name: protoinfo-attrs
|
||||
attributes:
|
||||
-
|
||||
name: protoinfo-tcp
|
||||
type: nest
|
||||
nested-attributes: protoinfo-tcp-attrs
|
||||
doc: conntrack tcp state information
|
||||
-
|
||||
name: protoinfo-dccp
|
||||
type: nest
|
||||
nested-attributes: protoinfo-dccp-attrs
|
||||
doc: conntrack dccp state information
|
||||
-
|
||||
name: protoinfo-sctp
|
||||
type: nest
|
||||
nested-attributes: protoinfo-sctp-attrs
|
||||
doc: conntrack sctp state information
|
||||
-
|
||||
name: help-attrs
|
||||
attributes:
|
||||
-
|
||||
name: help-name
|
||||
type: string
|
||||
doc: helper name
|
||||
-
|
||||
name: nat-proto-attrs
|
||||
attributes:
|
||||
-
|
||||
name: nat-port-min
|
||||
type: u16
|
||||
byte-order: big-endian
|
||||
-
|
||||
name: nat-port-max
|
||||
type: u16
|
||||
byte-order: big-endian
|
||||
-
|
||||
name: nat-attrs
|
||||
attributes:
|
||||
-
|
||||
name: nat-v4-minip
|
||||
type: u32
|
||||
byte-order: big-endian
|
||||
-
|
||||
name: nat-v4-maxip
|
||||
type: u32
|
||||
byte-order: big-endian
|
||||
-
|
||||
name: nat-v6-minip
|
||||
type: binary
|
||||
-
|
||||
name: nat-v6-maxip
|
||||
type: binary
|
||||
-
|
||||
name: nat-proto
|
||||
type: nest
|
||||
nested-attributes: nat-proto-attrs
|
||||
-
|
||||
name: seqadj-attrs
|
||||
attributes:
|
||||
-
|
||||
name: correction-pos
|
||||
type: u32
|
||||
byte-order: big-endian
|
||||
-
|
||||
name: offset-before
|
||||
type: u32
|
||||
byte-order: big-endian
|
||||
-
|
||||
name: offset-after
|
||||
type: u32
|
||||
byte-order: big-endian
|
||||
-
|
||||
name: secctx-attrs
|
||||
attributes:
|
||||
-
|
||||
name: secctx-name
|
||||
type: string
|
||||
-
|
||||
name: synproxy-attrs
|
||||
attributes:
|
||||
-
|
||||
name: isn
|
||||
type: u32
|
||||
byte-order: big-endian
|
||||
-
|
||||
name: its
|
||||
type: u32
|
||||
byte-order: big-endian
|
||||
-
|
||||
name: tsoff
|
||||
type: u32
|
||||
byte-order: big-endian
|
||||
-
|
||||
name: conntrack-attrs
|
||||
attributes:
|
||||
-
|
||||
name: tuple-orig
|
||||
type: nest
|
||||
nested-attributes: tuple-attrs
|
||||
doc: conntrack l3+l4 protocol information, original direction
|
||||
-
|
||||
name: tuple-reply
|
||||
type: nest
|
||||
nested-attributes: tuple-attrs
|
||||
doc: conntrack l3+l4 protocol information, reply direction
|
||||
-
|
||||
name: status
|
||||
type: u32
|
||||
byte-order: big-endian
|
||||
enum: nf-ct-status
|
||||
enum-as-flags: true
|
||||
doc: conntrack flag bits
|
||||
-
|
||||
name: protoinfo
|
||||
type: nest
|
||||
nested-attributes: protoinfo-attrs
|
||||
-
|
||||
name: help
|
||||
type: nest
|
||||
nested-attributes: help-attrs
|
||||
-
|
||||
name: nat-src
|
||||
type: nest
|
||||
nested-attributes: nat-attrs
|
||||
-
|
||||
name: timeout
|
||||
type: u32
|
||||
byte-order: big-endian
|
||||
-
|
||||
name: mark
|
||||
type: u32
|
||||
byte-order: big-endian
|
||||
-
|
||||
name: counters-orig
|
||||
type: nest
|
||||
nested-attributes: counter-attrs
|
||||
-
|
||||
name: counters-reply
|
||||
type: nest
|
||||
nested-attributes: counter-attrs
|
||||
-
|
||||
name: use
|
||||
type: u32
|
||||
byte-order: big-endian
|
||||
-
|
||||
name: id
|
||||
type: u32
|
||||
byte-order: big-endian
|
||||
-
|
||||
name: nat-dst
|
||||
type: nest
|
||||
nested-attributes: nat-attrs
|
||||
-
|
||||
name: tuple-master
|
||||
type: nest
|
||||
nested-attributes: tuple-attrs
|
||||
-
|
||||
name: seq-adj-orig
|
||||
type: nest
|
||||
nested-attributes: seqadj-attrs
|
||||
-
|
||||
name: seq-adj-reply
|
||||
type: nest
|
||||
nested-attributes: seqadj-attrs
|
||||
-
|
||||
name: secmark
|
||||
type: binary
|
||||
doc: obsolete
|
||||
-
|
||||
name: zone
|
||||
type: u16
|
||||
byte-order: big-endian
|
||||
doc: conntrack zone id
|
||||
-
|
||||
name: secctx
|
||||
type: nest
|
||||
nested-attributes: secctx-attrs
|
||||
-
|
||||
name: timestamp
|
||||
type: u64
|
||||
byte-order: big-endian
|
||||
-
|
||||
name: mark-mask
|
||||
type: u32
|
||||
byte-order: big-endian
|
||||
-
|
||||
name: labels
|
||||
type: binary
|
||||
-
|
||||
name: labels mask
|
||||
type: binary
|
||||
-
|
||||
name: synproxy
|
||||
type: nest
|
||||
nested-attributes: synproxy-attrs
|
||||
-
|
||||
name: filter
|
||||
type: nest
|
||||
nested-attributes: tuple-attrs
|
||||
-
|
||||
name: status-mask
|
||||
type: u32
|
||||
byte-order: big-endian
|
||||
enum: nf-ct-status
|
||||
enum-as-flags: true
|
||||
doc: conntrack flag bits to change
|
||||
-
|
||||
name: timestamp-event
|
||||
type: u64
|
||||
byte-order: big-endian
|
||||
-
|
||||
name: conntrack-stats-attrs
|
||||
attributes:
|
||||
-
|
||||
name: searched
|
||||
type: u32
|
||||
byte-order: big-endian
|
||||
doc: obsolete
|
||||
-
|
||||
name: found
|
||||
type: u32
|
||||
byte-order: big-endian
|
||||
-
|
||||
name: new
|
||||
type: u32
|
||||
byte-order: big-endian
|
||||
doc: obsolete
|
||||
-
|
||||
name: invalid
|
||||
type: u32
|
||||
byte-order: big-endian
|
||||
doc: obsolete
|
||||
-
|
||||
name: ignore
|
||||
type: u32
|
||||
byte-order: big-endian
|
||||
doc: obsolete
|
||||
-
|
||||
name: delete
|
||||
type: u32
|
||||
byte-order: big-endian
|
||||
doc: obsolete
|
||||
-
|
||||
name: delete-list
|
||||
type: u32
|
||||
byte-order: big-endian
|
||||
doc: obsolete
|
||||
-
|
||||
name: insert
|
||||
type: u32
|
||||
byte-order: big-endian
|
||||
-
|
||||
name: insert-failed
|
||||
type: u32
|
||||
byte-order: big-endian
|
||||
-
|
||||
name: drop
|
||||
type: u32
|
||||
byte-order: big-endian
|
||||
-
|
||||
name: early-drop
|
||||
type: u32
|
||||
byte-order: big-endian
|
||||
-
|
||||
name: error
|
||||
type: u32
|
||||
byte-order: big-endian
|
||||
-
|
||||
name: search-restart
|
||||
type: u32
|
||||
byte-order: big-endian
|
||||
-
|
||||
name: clash-resolve
|
||||
type: u32
|
||||
byte-order: big-endian
|
||||
-
|
||||
name: chain-toolong
|
||||
type: u32
|
||||
byte-order: big-endian
|
||||
|
||||
operations:
|
||||
enum-model: directional
|
||||
list:
|
||||
-
|
||||
name: get
|
||||
doc: get / dump entries
|
||||
attribute-set: conntrack-attrs
|
||||
fixed-header: nfgenmsg
|
||||
do:
|
||||
request:
|
||||
value: 0x101
|
||||
attributes:
|
||||
- tuple-orig
|
||||
- tuple-reply
|
||||
- zone
|
||||
reply:
|
||||
value: 0x100
|
||||
attributes:
|
||||
- tuple-orig
|
||||
- tuple-reply
|
||||
- status
|
||||
- protoinfo
|
||||
- help
|
||||
- nat-src
|
||||
- nat-dst
|
||||
- timeout
|
||||
- mark
|
||||
- counter-orig
|
||||
- counter-reply
|
||||
- use
|
||||
- id
|
||||
- nat-dst
|
||||
- tuple-master
|
||||
- seq-adj-orig
|
||||
- seq-adj-reply
|
||||
- zone
|
||||
- secctx
|
||||
- labels
|
||||
- synproxy
|
||||
dump:
|
||||
request:
|
||||
value: 0x101
|
||||
attributes:
|
||||
- nfgen-family
|
||||
- mark
|
||||
- filter
|
||||
- status
|
||||
- zone
|
||||
reply:
|
||||
value: 0x100
|
||||
attributes:
|
||||
- tuple-orig
|
||||
- tuple-reply
|
||||
- status
|
||||
- protoinfo
|
||||
- help
|
||||
- nat-src
|
||||
- nat-dst
|
||||
- timeout
|
||||
- mark
|
||||
- counter-orig
|
||||
- counter-reply
|
||||
- use
|
||||
- id
|
||||
- nat-dst
|
||||
- tuple-master
|
||||
- seq-adj-orig
|
||||
- seq-adj-reply
|
||||
- zone
|
||||
- secctx
|
||||
- labels
|
||||
- synproxy
|
||||
-
|
||||
name: get-stats
|
||||
doc: dump pcpu conntrack stats
|
||||
attribute-set: conntrack-stats-attrs
|
||||
fixed-header: nfgenmsg
|
||||
dump:
|
||||
request:
|
||||
value: 0x104
|
||||
reply:
|
||||
value: 0x104
|
||||
attributes:
|
||||
- searched
|
||||
- found
|
||||
- insert
|
||||
- insert-failed
|
||||
- drop
|
||||
- early-drop
|
||||
- error
|
||||
- search-restart
|
||||
- clash-resolve
|
||||
- chain-toolong
|
||||
@@ -1868,6 +1868,7 @@ operations:
|
||||
- info-version-fixed
|
||||
- info-version-running
|
||||
- info-version-stored
|
||||
- info-board-serial-number
|
||||
dump:
|
||||
reply: *info-get-reply
|
||||
|
||||
|
||||
@@ -70,6 +70,10 @@ definitions:
|
||||
name: tx-checksum
|
||||
doc:
|
||||
L3 checksum HW offload is supported by the driver.
|
||||
-
|
||||
name: tx-launch-time-fifo
|
||||
doc:
|
||||
Launch time HW offload is supported by the driver.
|
||||
-
|
||||
name: queue-type
|
||||
type: enum
|
||||
@@ -114,6 +118,9 @@ attribute-sets:
|
||||
doc: Bitmask of enabled AF_XDP features.
|
||||
type: u64
|
||||
enum: xsk-flags
|
||||
-
|
||||
name: io-uring-provider-info
|
||||
attributes: []
|
||||
-
|
||||
name: page-pool
|
||||
attributes:
|
||||
@@ -171,6 +178,11 @@ attribute-sets:
|
||||
name: dmabuf
|
||||
doc: ID of the dmabuf this page-pool is attached to.
|
||||
type: u32
|
||||
-
|
||||
name: io-uring
|
||||
doc: io-uring memory provider information.
|
||||
type: nest
|
||||
nested-attributes: io-uring-provider-info
|
||||
-
|
||||
name: page-pool-info
|
||||
subset-of: page-pool
|
||||
@@ -268,6 +280,9 @@ attribute-sets:
|
||||
doc: The timeout, in nanoseconds, of how long to suspend irq
|
||||
processing, if event polling finds events
|
||||
type: uint
|
||||
-
|
||||
name: xsk-info
|
||||
attributes: []
|
||||
-
|
||||
name: queue
|
||||
attributes:
|
||||
@@ -286,6 +301,9 @@ attribute-sets:
|
||||
-
|
||||
name: type
|
||||
doc: Queue type as rx, tx. Each queue type defines a separate ID space.
|
||||
XDP TX queues allocated in the kernel are not linked to NAPIs and
|
||||
thus not listed. AF_XDP queues will have more information set in
|
||||
the xsk attribute.
|
||||
type: u32
|
||||
enum: queue-type
|
||||
-
|
||||
@@ -296,7 +314,16 @@ attribute-sets:
|
||||
name: dmabuf
|
||||
doc: ID of the dmabuf attached to this queue, if any.
|
||||
type: u32
|
||||
|
||||
-
|
||||
name: io-uring
|
||||
doc: io_uring memory provider information.
|
||||
type: nest
|
||||
nested-attributes: io-uring-provider-info
|
||||
-
|
||||
name: xsk
|
||||
doc: XSK information for this queue, if any.
|
||||
type: nest
|
||||
nested-attributes: xsk-info
|
||||
-
|
||||
name: qstats
|
||||
doc: |
|
||||
@@ -444,6 +471,8 @@ attribute-sets:
|
||||
name: tx-needs-csum
|
||||
doc: |
|
||||
Number of packets that required the device to calculate the checksum.
|
||||
This counter includes the number of GSO wire packets for which device
|
||||
calculated the L4 checksum.
|
||||
type: uint
|
||||
-
|
||||
name: tx-hw-gso-packets
|
||||
@@ -572,6 +601,7 @@ operations:
|
||||
- inflight-mem
|
||||
- detach-time
|
||||
- dmabuf
|
||||
- io-uring
|
||||
dump:
|
||||
reply: *pp-reply
|
||||
config-cond: page-pool
|
||||
@@ -637,6 +667,8 @@ operations:
|
||||
- napi-id
|
||||
- ifindex
|
||||
- dmabuf
|
||||
- io-uring
|
||||
- xsk
|
||||
dump:
|
||||
request:
|
||||
attributes:
|
||||
@@ -713,8 +745,8 @@ operations:
|
||||
- irq-suspend-timeout
|
||||
|
||||
kernel-family:
|
||||
headers: [ "linux/list.h"]
|
||||
sock-priv: struct list_head
|
||||
headers: [ "net/netdev_netlink.h"]
|
||||
sock-priv: struct netdev_nl_sock
|
||||
|
||||
mcast-groups:
|
||||
list:
|
||||
|
||||
2000
Documentation/netlink/specs/nl80211.yaml
Normal file
2000
Documentation/netlink/specs/nl80211.yaml
Normal file
File diff suppressed because it is too large
Load Diff
@@ -168,6 +168,29 @@ operations:
|
||||
reply:
|
||||
value: 20
|
||||
attributes: *ifaddr-all
|
||||
-
|
||||
name: getmaddrs
|
||||
doc: Get / dump IPv4/IPv6 multicast addresses.
|
||||
attribute-set: addr-attrs
|
||||
fixed-header: ifaddrmsg
|
||||
do:
|
||||
request:
|
||||
value: 58
|
||||
attributes:
|
||||
- ifa-family
|
||||
- ifa-index
|
||||
reply:
|
||||
value: 58
|
||||
attributes: &mcaddr-attrs
|
||||
- ifa-multicast
|
||||
- ifa-cacheinfo
|
||||
dump:
|
||||
request:
|
||||
value: 58
|
||||
- ifa-family
|
||||
reply:
|
||||
value: 58
|
||||
attributes: *mcaddr-attrs
|
||||
|
||||
mcast-groups:
|
||||
list:
|
||||
|
||||
@@ -770,6 +770,18 @@ definitions:
|
||||
-
|
||||
name: to
|
||||
type: u32
|
||||
-
|
||||
name: ifla-geneve-port-range
|
||||
type: struct
|
||||
members:
|
||||
-
|
||||
name: low
|
||||
type: u16
|
||||
byte-order: big-endian
|
||||
-
|
||||
name: high
|
||||
type: u16
|
||||
byte-order: big-endian
|
||||
-
|
||||
name: ifla-vf-mac
|
||||
type: struct
|
||||
@@ -1148,6 +1160,9 @@ attribute-sets:
|
||||
name: max-pacing-offload-horizon
|
||||
type: uint
|
||||
doc: EDT offload horizon supported by the device (in nsec).
|
||||
-
|
||||
name: netns-immutable
|
||||
type: u8
|
||||
-
|
||||
name: af-spec-attrs
|
||||
attributes:
|
||||
@@ -1915,6 +1930,10 @@ attribute-sets:
|
||||
-
|
||||
name: inner-proto-inherit
|
||||
type: flag
|
||||
-
|
||||
name: port-range
|
||||
type: binary
|
||||
struct: ifla-geneve-port-range
|
||||
-
|
||||
name: linkinfo-iptun-attrs
|
||||
name-prefix: ifla-iptun-
|
||||
|
||||
@@ -182,6 +182,18 @@ attribute-sets:
|
||||
type: u32
|
||||
byte-order: big-endian
|
||||
display-hint: hex
|
||||
-
|
||||
name: sport-mask
|
||||
type: u16
|
||||
display-hint: hex
|
||||
-
|
||||
name: dport-mask
|
||||
type: u16
|
||||
display-hint: hex
|
||||
-
|
||||
name: dscp-mask
|
||||
type: u8
|
||||
display-hint: hex
|
||||
|
||||
operations:
|
||||
enum-model: directional
|
||||
@@ -215,6 +227,9 @@ operations:
|
||||
- dscp
|
||||
- flowlabel
|
||||
- flowlabel-mask
|
||||
- sport-mask
|
||||
- dport-mask
|
||||
- dscp-mask
|
||||
-
|
||||
name: newrule-ntf
|
||||
doc: Notify a rule creation
|
||||
|
||||
@@ -27,7 +27,7 @@ Load the batman-adv module into your kernel::
|
||||
$ insmod batman-adv.ko
|
||||
|
||||
The module is now waiting for activation. You must add some interfaces on which
|
||||
batman-adv can operate. The batman-adv soft-interface can be created using the
|
||||
batman-adv can operate. The batman-adv mesh-interface can be created using the
|
||||
iproute2 tool ``ip``::
|
||||
|
||||
$ ip link add name bat0 type batadv
|
||||
|
||||
@@ -1,18 +0,0 @@
|
||||
.. SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
|
||||
Cable Modem Device Drivers
|
||||
==========================
|
||||
|
||||
Contents:
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 2
|
||||
|
||||
sb1000
|
||||
|
||||
.. only:: subproject and html
|
||||
|
||||
Indices
|
||||
=======
|
||||
|
||||
* :ref:`genindex`
|
||||
@@ -1,222 +0,0 @@
|
||||
.. SPDX-License-Identifier: GPL-2.0
|
||||
|
||||
===================
|
||||
SB100 device driver
|
||||
===================
|
||||
|
||||
sb1000 is a module network device driver for the General Instrument (also known
|
||||
as NextLevel) SURFboard1000 internal cable modem board. This is an ISA card
|
||||
which is used by a number of cable TV companies to provide cable modem access.
|
||||
It's a one-way downstream-only cable modem, meaning that your upstream net link
|
||||
is provided by your regular phone modem.
|
||||
|
||||
This driver was written by Franco Venturi <fventuri@mediaone.net>. He deserves
|
||||
a great deal of thanks for this wonderful piece of code!
|
||||
|
||||
Needed tools
|
||||
============
|
||||
|
||||
Support for this device is now a part of the standard Linux kernel. The
|
||||
driver source code file is drivers/net/sb1000.c. In addition to this
|
||||
you will need:
|
||||
|
||||
1. The "cmconfig" program. This is a utility which supplements "ifconfig"
|
||||
to configure the cable modem and network interface (usually called "cm0");
|
||||
|
||||
2. Several PPP scripts which live in /etc/ppp to make connecting via your
|
||||
cable modem easy.
|
||||
|
||||
These utilities can be obtained from:
|
||||
|
||||
http://www.jacksonville.net/~fventuri/
|
||||
|
||||
in Franco's original source code distribution .tar.gz file. Support for
|
||||
the sb1000 driver can be found at:
|
||||
|
||||
- http://web.archive.org/web/%2E/http://home.adelphia.net/~siglercm/sb1000.html
|
||||
- http://web.archive.org/web/%2E/http://linuxpower.cx/~cable/
|
||||
|
||||
along with these utilities.
|
||||
|
||||
3. The standard isapnp tools. These are necessary to configure your SB1000
|
||||
card at boot time (or afterwards by hand) since it's a PnP card.
|
||||
|
||||
If you don't have these installed as a standard part of your Linux
|
||||
distribution, you can find them at:
|
||||
|
||||
http://www.roestock.demon.co.uk/isapnptools/
|
||||
|
||||
or check your Linux distribution binary CD or their web site. For help with
|
||||
isapnp, pnpdump, or /etc/isapnp.conf, go to:
|
||||
|
||||
http://www.roestock.demon.co.uk/isapnptools/isapnpfaq.html
|
||||
|
||||
Using the driver
|
||||
================
|
||||
|
||||
To make the SB1000 card work, follow these steps:
|
||||
|
||||
1. Run ``make config``, or ``make menuconfig``, or ``make xconfig``, whichever
|
||||
you prefer, in the top kernel tree directory to set up your kernel
|
||||
configuration. Make sure to say "Y" to "Prompt for development drivers"
|
||||
and to say "M" to the sb1000 driver. Also say "Y" or "M" to all the standard
|
||||
networking questions to get TCP/IP and PPP networking support.
|
||||
|
||||
2. **BEFORE** you build the kernel, edit drivers/net/sb1000.c. Make sure
|
||||
to redefine the value of READ_DATA_PORT to match the I/O address used
|
||||
by isapnp to access your PnP cards. This is the value of READPORT in
|
||||
/etc/isapnp.conf or given by the output of pnpdump.
|
||||
|
||||
3. Build and install the kernel and modules as usual.
|
||||
|
||||
4. Boot your new kernel following the usual procedures.
|
||||
|
||||
5. Set up to configure the new SB1000 PnP card by capturing the output
|
||||
of "pnpdump" to a file and editing this file to set the correct I/O ports,
|
||||
IRQ, and DMA settings for all your PnP cards. Make sure none of the settings
|
||||
conflict with one another. Then test this configuration by running the
|
||||
"isapnp" command with your new config file as the input. Check for
|
||||
errors and fix as necessary. (As an aside, I use I/O ports 0x110 and
|
||||
0x310 and IRQ 11 for my SB1000 card and these work well for me. YMMV.)
|
||||
Then save the finished config file as /etc/isapnp.conf for proper
|
||||
configuration on subsequent reboots.
|
||||
|
||||
6. Download the original file sb1000-1.1.2.tar.gz from Franco's site or one of
|
||||
the others referenced above. As root, unpack it into a temporary directory
|
||||
and do a ``make cmconfig`` and then ``install -c cmconfig /usr/local/sbin``.
|
||||
Don't do ``make install`` because it expects to find all the utilities built
|
||||
and ready for installation, not just cmconfig.
|
||||
|
||||
7. As root, copy all the files under the ppp/ subdirectory in Franco's
|
||||
tar file into /etc/ppp, being careful not to overwrite any files that are
|
||||
already in there. Then modify ppp@gi-on to set the correct login name,
|
||||
phone number, and frequency for the cable modem. Also edit pap-secrets
|
||||
to specify your login name and password and any site-specific information
|
||||
you need.
|
||||
|
||||
8. Be sure to modify /etc/ppp/firewall to use ipchains instead of
|
||||
the older ipfwadm commands from the 2.0.x kernels. There's a neat utility to
|
||||
convert ipfwadm commands to ipchains commands:
|
||||
|
||||
http://users.dhp.com/~whisper/ipfwadm2ipchains/
|
||||
|
||||
You may also wish to modify the firewall script to implement a different
|
||||
firewalling scheme.
|
||||
|
||||
9. Start the PPP connection via the script /etc/ppp/ppp@gi-on. You must be
|
||||
root to do this. It's better to use a utility like sudo to execute
|
||||
frequently used commands like this with root permissions if possible. If you
|
||||
connect successfully the cable modem interface will come up and you'll see a
|
||||
driver message like this at the console::
|
||||
|
||||
cm0: sb1000 at (0x110,0x310), csn 1, S/N 0x2a0d16d8, IRQ 11.
|
||||
sb1000.c:v1.1.2 6/01/98 (fventuri@mediaone.net)
|
||||
|
||||
The "ifconfig" command should show two new interfaces, ppp0 and cm0.
|
||||
|
||||
The command "cmconfig cm0" will give you information about the cable modem
|
||||
interface.
|
||||
|
||||
10. Try pinging a site via ``ping -c 5 www.yahoo.com``, for example. You should
|
||||
see packets received.
|
||||
|
||||
11. If you can't get site names (like www.yahoo.com) to resolve into
|
||||
IP addresses (like 204.71.200.67), be sure your /etc/resolv.conf file
|
||||
has no syntax errors and has the right nameserver IP addresses in it.
|
||||
If this doesn't help, try something like ``ping -c 5 204.71.200.67`` to
|
||||
see if the networking is running but the DNS resolution is where the
|
||||
problem lies.
|
||||
|
||||
12. If you still have problems, go to the support web sites mentioned above
|
||||
and read the information and documentation there.
|
||||
|
||||
Common problems
|
||||
===============
|
||||
|
||||
1. Packets go out on the ppp0 interface but don't come back on the cm0
|
||||
interface. It looks like I'm connected but I can't even ping any
|
||||
numerical IP addresses. (This happens predominantly on Debian systems due
|
||||
to a default boot-time configuration script.)
|
||||
|
||||
Solution
|
||||
As root ``echo 0 > /proc/sys/net/ipv4/conf/cm0/rp_filter`` so it
|
||||
can share the same IP address as the ppp0 interface. Note that this
|
||||
command should probably be added to the /etc/ppp/cablemodem script
|
||||
*right*between* the "/sbin/ifconfig" and "/sbin/cmconfig" commands.
|
||||
You may need to do this to /proc/sys/net/ipv4/conf/ppp0/rp_filter as well.
|
||||
If you do this to /proc/sys/net/ipv4/conf/default/rp_filter on each reboot
|
||||
(in rc.local or some such) then any interfaces can share the same IP
|
||||
addresses.
|
||||
|
||||
2. I get "unresolved symbol" error messages on executing ``insmod sb1000.o``.
|
||||
|
||||
Solution
|
||||
You probably have a non-matching kernel source tree and
|
||||
/usr/include/linux and /usr/include/asm header files. Make sure you
|
||||
install the correct versions of the header files in these two directories.
|
||||
Then rebuild and reinstall the kernel.
|
||||
|
||||
3. When isapnp runs it reports an error, and my SB1000 card isn't working.
|
||||
|
||||
Solution
|
||||
There's a problem with later versions of isapnp using the "(CHECK)"
|
||||
option in the lines that allocate the two I/O addresses for the SB1000 card.
|
||||
This first popped up on RH 6.0. Delete "(CHECK)" for the SB1000 I/O addresses.
|
||||
Make sure they don't conflict with any other pieces of hardware first! Then
|
||||
rerun isapnp and go from there.
|
||||
|
||||
4. I can't execute the /etc/ppp/ppp@gi-on file.
|
||||
|
||||
Solution
|
||||
As root do ``chmod ug+x /etc/ppp/ppp@gi-on``.
|
||||
|
||||
5. The firewall script isn't working (with 2.2.x and higher kernels).
|
||||
|
||||
Solution
|
||||
Use the ipfwadm2ipchains script referenced above to convert the
|
||||
/etc/ppp/firewall script from the deprecated ipfwadm commands to ipchains.
|
||||
|
||||
6. I'm getting *tons* of firewall deny messages in the /var/kern.log,
|
||||
/var/messages, and/or /var/syslog files, and they're filling up my /var
|
||||
partition!!!
|
||||
|
||||
Solution
|
||||
First, tell your ISP that you're receiving DoS (Denial of Service)
|
||||
and/or portscanning (UDP connection attempts) attacks! Look over the deny
|
||||
messages to figure out what the attack is and where it's coming from. Next,
|
||||
edit /etc/ppp/cablemodem and make sure the ",nobroadcast" option is turned on
|
||||
to the "cmconfig" command (uncomment that line). If you're not receiving these
|
||||
denied packets on your broadcast interface (IP address xxx.yyy.zzz.255
|
||||
typically), then someone is attacking your machine in particular. Be careful
|
||||
out there....
|
||||
|
||||
7. Everything seems to work fine but my computer locks up after a while
|
||||
(and typically during a lengthy download through the cable modem)!
|
||||
|
||||
Solution
|
||||
You may need to add a short delay in the driver to 'slow down' the
|
||||
SURFboard because your PC might not be able to keep up with the transfer rate
|
||||
of the SB1000. To do this, it's probably best to download Franco's
|
||||
sb1000-1.1.2.tar.gz archive and build and install sb1000.o manually. You'll
|
||||
want to edit the 'Makefile' and look for the 'SB1000_DELAY'
|
||||
define. Uncomment those 'CFLAGS' lines (and comment out the default ones)
|
||||
and try setting the delay to something like 60 microseconds with:
|
||||
'-DSB1000_DELAY=60'. Then do ``make`` and as root ``make install`` and try
|
||||
it out. If it still doesn't work or you like playing with the driver, you may
|
||||
try other numbers. Remember though that the higher the delay, the slower the
|
||||
driver (which slows down the rest of the PC too when it is actively
|
||||
used). Thanks to Ed Daiga for this tip!
|
||||
|
||||
Credits
|
||||
=======
|
||||
|
||||
This README came from Franco Venturi's original README file which is
|
||||
still supplied with his driver .tar.gz archive. I and all other sb1000 users
|
||||
owe Franco a tremendous "Thank you!" Additional thanks goes to Carl Patten
|
||||
and Ralph Bonnell who are now managing the Linux SB1000 web site, and to
|
||||
the SB1000 users who reported and helped debug the common problems listed
|
||||
above.
|
||||
|
||||
|
||||
Clemmitt Sigler
|
||||
csigler@vt.edu
|
||||
@@ -70,7 +70,7 @@ the DPSW object that it will probe:
|
||||
Besides the configuration of the actual DPSW object, the dpaa2-switch driver
|
||||
will need the following DPAA2 objects:
|
||||
|
||||
* 1 DPMCP - A Management Command Portal object is needed for any interraction
|
||||
* 1 DPMCP - A Management Command Portal object is needed for any interaction
|
||||
with the MC firmware.
|
||||
|
||||
* 1 DPBP - A Buffer Pool is used for seeding buffers intended for the Rx path
|
||||
|
||||
@@ -1082,6 +1082,11 @@ like flow control, FEC and more.
|
||||
need to replace the cable/transceiver.
|
||||
- Error
|
||||
|
||||
* - `total_success_recovery_phy`
|
||||
- The number of total successful recovery events of any type during
|
||||
ports reset cycle.
|
||||
- Error
|
||||
|
||||
* - `rx_out_of_buffer`
|
||||
- Number of times receive queue had no software buffers allocated for the
|
||||
adapter's incoming traffic.
|
||||
|
||||
@@ -9,7 +9,6 @@ Contents:
|
||||
:maxdepth: 2
|
||||
|
||||
atm/index
|
||||
cable/index
|
||||
can/index
|
||||
cellular/index
|
||||
ethernet/index
|
||||
|
||||
@@ -24,6 +24,8 @@ Parameters
|
||||
- Permanent
|
||||
* - ``enable_remote_dev_reset``
|
||||
- Runtime
|
||||
* - ``enable_roce``
|
||||
- Permanent
|
||||
|
||||
The ``bnxt`` driver also implements the following driver-specific
|
||||
parameters.
|
||||
|
||||
@@ -69,6 +69,17 @@ Parameters
|
||||
|
||||
To verify that value has been set:
|
||||
$ devlink dev param show pci/0000:16:00.0 name tx_scheduling_layers
|
||||
* - ``msix_vec_per_pf_max``
|
||||
- driverinit
|
||||
- Set the max MSI-X that can be used by the PF, rest can be utilized for
|
||||
SRIOV. The range is from min value set in msix_vec_per_pf_min to
|
||||
2k/number of ports.
|
||||
* - ``msix_vec_per_pf_min``
|
||||
- driverinit
|
||||
- Set the min MSI-X that will be used by the PF. This value inform how many
|
||||
MSI-X will be allocated statically. The range is from 2 to value set
|
||||
in msix_vec_per_pf_max.
|
||||
|
||||
.. list-table:: Driver specific parameters implemented
|
||||
:widths: 5 5 90
|
||||
|
||||
|
||||
@@ -280,6 +280,10 @@ Description of the vnic counters:
|
||||
number of packets handled by the VNIC experiencing unexpected steering
|
||||
failure (at any point in steering flow owned by the VNIC, including the FDB
|
||||
for the eswitch owner).
|
||||
- icm_consumption
|
||||
amount of Interconnect Host Memory (ICM) consumed by the vnic in
|
||||
granularity of 4KB. ICM is host memory allocated by SW upon HCA request
|
||||
and is used for storing data structures that control HCA operation.
|
||||
|
||||
User commands examples:
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@ sfc devlink support
|
||||
===================
|
||||
|
||||
This document describes the devlink features implemented by the ``sfc``
|
||||
device driver for the ef100 device.
|
||||
device driver for the ef10 and ef100 devices.
|
||||
|
||||
Info versions
|
||||
=============
|
||||
@@ -18,6 +18,10 @@ The ``sfc`` driver reports the following versions
|
||||
* - Name
|
||||
- Type
|
||||
- Description
|
||||
* - ``fw.bundle_id``
|
||||
- stored
|
||||
- Version of the firmware "bundle" image that was last used to update
|
||||
multiple components.
|
||||
* - ``fw.mgmt.suc``
|
||||
- running
|
||||
- For boards where the management function is split between multiple
|
||||
@@ -55,3 +59,13 @@ The ``sfc`` driver reports the following versions
|
||||
* - ``fw.uefi``
|
||||
- running
|
||||
- UEFI driver version (No UNDI support).
|
||||
|
||||
Flash Update
|
||||
============
|
||||
|
||||
The ``sfc`` driver implements support for flash update using the
|
||||
``devlink-flash`` interface. It supports updating the device flash using a
|
||||
combined flash image ("bundle") that contains multiple components (on ef10,
|
||||
typically ``fw.mgmt``, ``fw.app``, ``fw.exprom`` and ``fw.uefi``).
|
||||
|
||||
The driver does not support any overwrite mask flags.
|
||||
|
||||
@@ -256,7 +256,7 @@ Testing
|
||||
=======
|
||||
|
||||
More realistic example code can be found in the kernel source under
|
||||
``tools/testing/selftests/net/ncdevmem.c``
|
||||
``tools/testing/selftests/drivers/net/hw/ncdevmem.c``
|
||||
|
||||
ncdevmem is a devmem TCP netcat. It works very similarly to netcat, but
|
||||
receives data directly into a udmabuf.
|
||||
@@ -268,8 +268,7 @@ 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
|
||||
ncdevmem -s <server IP> -c <client IP> -f <ifname> -l -p 5201 -v 7
|
||||
|
||||
On client side, use regular netcat to send TX data to ncdevmem process
|
||||
on the server::
|
||||
|
||||
@@ -1934,7 +1934,7 @@ ETHTOOL_A_RSS_INDIR attribute returns RSS indirection table where each byte
|
||||
indicates queue number.
|
||||
ETHTOOL_A_RSS_INPUT_XFRM attribute is a bitmap indicating the type of
|
||||
transformation applied to the input protocol fields before given to the RSS
|
||||
hfunc. Current supported option is symmetric-xor.
|
||||
hfunc. Current supported options are symmetric-xor and symmetric-or-xor.
|
||||
|
||||
PLCA_GET_CFG
|
||||
============
|
||||
|
||||
@@ -705,6 +705,8 @@ tcp_retries2 - INTEGER
|
||||
seconds and is a lower bound for the effective timeout.
|
||||
TCP will effectively time out at the first RTO which exceeds the
|
||||
hypothetical timeout.
|
||||
If tcp_rto_max_ms is decreased, it is recommended to also
|
||||
change tcp_retries2.
|
||||
|
||||
RFC 1122 recommends at least 100 seconds for the timeout,
|
||||
which corresponds to a value of at least 8.
|
||||
@@ -1227,8 +1229,8 @@ tcp_pingpong_thresh - INTEGER
|
||||
tcp_rto_min_us - INTEGER
|
||||
Minimal TCP retransmission timeout (in microseconds). Note that the
|
||||
rto_min route option has the highest precedence for configuring this
|
||||
setting, followed by the TCP_BPF_RTO_MIN socket option, followed by
|
||||
this tcp_rto_min_us sysctl.
|
||||
setting, followed by the TCP_BPF_RTO_MIN and TCP_RTO_MIN_US socket
|
||||
options, followed by this tcp_rto_min_us sysctl.
|
||||
|
||||
The recommended practice is to use a value less or equal to 200000
|
||||
microseconds.
|
||||
@@ -1237,6 +1239,17 @@ tcp_rto_min_us - INTEGER
|
||||
|
||||
Default: 200000
|
||||
|
||||
tcp_rto_max_ms - INTEGER
|
||||
Maximal TCP retransmission timeout (in ms).
|
||||
Note that TCP_RTO_MAX_MS socket option has higher precedence.
|
||||
|
||||
When changing tcp_rto_max_ms, it is important to understand
|
||||
that tcp_retries2 might need a change.
|
||||
|
||||
Possible Values: 1000 - 120,000
|
||||
|
||||
Default: 120,000
|
||||
|
||||
UDP variables
|
||||
=============
|
||||
|
||||
|
||||
@@ -66,6 +66,90 @@ the library exclusively, or by the in-kernel system exclusively.
|
||||
J1939 concepts
|
||||
==============
|
||||
|
||||
Data Sent to the J1939 Stack
|
||||
----------------------------
|
||||
|
||||
The data buffers sent to the J1939 stack from user space are not CAN frames
|
||||
themselves. Instead, they are payloads that the J1939 stack converts into
|
||||
proper CAN frames based on the size of the buffer and the type of transfer. The
|
||||
size of the buffer influences how the stack processes the data and determines
|
||||
the internal code path used for the transfer.
|
||||
|
||||
**Handling of Different Buffer Sizes:**
|
||||
|
||||
- **Buffers with a size of 8 bytes or less:**
|
||||
|
||||
- These are handled as simple sessions internally within the stack.
|
||||
|
||||
- The stack converts the buffer directly into a single CAN frame without
|
||||
fragmentation.
|
||||
|
||||
- This type of transfer does not require an actual client (receiver) on the
|
||||
receiving side.
|
||||
|
||||
- **Buffers up to 1785 bytes:**
|
||||
|
||||
- These are automatically handled as J1939 Transport Protocol (TP) transfers.
|
||||
|
||||
- Internally, the stack splits the buffer into multiple 8-byte CAN frames.
|
||||
|
||||
- TP transfers can be unicast or broadcast.
|
||||
|
||||
- **Broadcast TP:** Does not require a receiver on the other side and can be
|
||||
used in broadcast scenarios.
|
||||
|
||||
- **Unicast TP:** Requires an active receiver (client) on the other side to
|
||||
acknowledge the transfer.
|
||||
|
||||
- **Buffers from 1786 bytes up to 111 MiB:**
|
||||
|
||||
- These are handled as ISO 11783 Extended Transport Protocol (ETP) transfers.
|
||||
|
||||
- ETP transfers are used for larger payloads and are split into multiple CAN
|
||||
frames internally.
|
||||
|
||||
- **ETP transfers (unicast):** Require a receiver on the other side to
|
||||
process the incoming data and acknowledge each step of the transfer.
|
||||
|
||||
- ETP transfers cannot be broadcast like TP transfers, and always require a
|
||||
receiver for operation.
|
||||
|
||||
**Non-Blocking Operation with `MSG_DONTWAIT`:**
|
||||
|
||||
The J1939 stack supports non-blocking operation when used in combination with
|
||||
the `MSG_DONTWAIT` flag. In this mode, the stack attempts to take as much data
|
||||
as the available memory for the socket allows. It returns the amount of data
|
||||
that was successfully taken, and it is the responsibility of user space to
|
||||
monitor this value and handle partial transfers.
|
||||
|
||||
- If the stack cannot take the entire buffer, it returns the number of bytes
|
||||
successfully taken, and user space should handle the remainder.
|
||||
|
||||
- **Error handling:** When using `MSG_DONTWAIT`, the user must rely on the
|
||||
error queue to detect transfer errors. See the **SO_J1939_ERRQUEUE** section
|
||||
for details on how to subscribe to error notifications. Without the error
|
||||
queue, there is no other way for user space to be notified of transfer errors
|
||||
during non-blocking operations.
|
||||
|
||||
**Behavior and Requirements:**
|
||||
|
||||
- **Simple transfers (<= 8 bytes):** Do not require a receiver on the other
|
||||
side, making them easy to send without needing address claiming or
|
||||
coordination with a destination.
|
||||
|
||||
- **Unicast TP/ETP:** Requires a receiver on the other side to complete the
|
||||
transfer. The receiver must acknowledge the transfer for the session to
|
||||
proceed successfully.
|
||||
|
||||
- **Broadcast TP:** Allows sending data without a receiver, but only works for
|
||||
TP transfers. ETP cannot be broadcast and always needs a receiving client.
|
||||
|
||||
These different behaviors depend heavily on the size of the buffer provided to
|
||||
the stack, and the appropriate transport mechanism (TP or ETP) is selected
|
||||
based on the payload size. The stack automatically manages the fragmentation
|
||||
and reassembly of large payloads and ensures that the correct CAN frames are
|
||||
generated and transmitted for each session.
|
||||
|
||||
PGN
|
||||
---
|
||||
|
||||
@@ -338,6 +422,459 @@ with ``cmsg_level == SOL_J1939 && cmsg_type == SCM_J1939_DEST_ADDR``,
|
||||
}
|
||||
}
|
||||
|
||||
setsockopt(2)
|
||||
^^^^^^^^^^^^^
|
||||
|
||||
The ``setsockopt(2)`` function is used to configure various socket-level
|
||||
options for J1939 communication. The following options are supported:
|
||||
|
||||
``SO_J1939_FILTER``
|
||||
~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
The ``SO_J1939_FILTER`` option is essential when the default behavior of
|
||||
``bind(2)`` and ``connect(2)`` is insufficient for specific use cases. By
|
||||
default, ``bind(2)`` and ``connect(2)`` allow a socket to be associated with a
|
||||
single unicast or broadcast address. However, there are scenarios where finer
|
||||
control over the incoming messages is required, such as filtering by Parameter
|
||||
Group Number (PGN) rather than by addresses.
|
||||
|
||||
For example, in a system where multiple types of J1939 messages are being
|
||||
transmitted, a process might only be interested in a subset of those messages,
|
||||
such as specific PGNs, and not want to receive all messages destined for its
|
||||
address or broadcast to the bus.
|
||||
|
||||
By applying the ``SO_J1939_FILTER`` option, you can filter messages based on:
|
||||
|
||||
- **Source Address (SA)**: Filter messages coming from specific source
|
||||
addresses.
|
||||
|
||||
- **Source Name**: Filter messages coming from ECUs with specific NAME
|
||||
identifiers.
|
||||
|
||||
- **Parameter Group Number (PGN)**: Focus on receiving messages with specific
|
||||
PGNs, filtering out irrelevant ones.
|
||||
|
||||
This filtering mechanism is particularly useful when:
|
||||
|
||||
- You want to receive a subset of messages based on their PGNs, even if the
|
||||
address is the same.
|
||||
|
||||
- You need to handle both broadcast and unicast messages but only care about
|
||||
certain message types or parameters.
|
||||
|
||||
- The ``bind(2)`` and ``connect(2)`` functions only allow binding to a single
|
||||
address, which might not be sufficient if the process needs to handle multiple
|
||||
PGNs but does not want to open multiple sockets.
|
||||
|
||||
To remove existing filters, you can pass ``optval == NULL`` or ``optlen == 0``
|
||||
to ``setsockopt(2)``. This will clear all currently set filters. If you want to
|
||||
**update** the set of filters, you must pass the updated filter set to
|
||||
``setsockopt(2)``, as the new filter set will **replace** the old one entirely.
|
||||
This behavior ensures that any previous filter configuration is discarded and
|
||||
only the new set is applied.
|
||||
|
||||
Example of removing all filters:
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
setsockopt(sock, SOL_CAN_J1939, SO_J1939_FILTER, NULL, 0);
|
||||
|
||||
**Maximum number of filters:** The maximum amount of filters that can be
|
||||
applied using ``SO_J1939_FILTER`` is defined by ``J1939_FILTER_MAX``, which is
|
||||
set to 512. This means you can configure up to 512 individual filters to match
|
||||
your specific filtering needs.
|
||||
|
||||
Practical use case: **Monitoring Address Claiming**
|
||||
|
||||
One practical use case is monitoring the J1939 address claiming process by
|
||||
filtering for specific PGNs related to address claiming. This allows a process
|
||||
to monitor and handle address claims without processing unrelated messages.
|
||||
|
||||
Example:
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
struct j1939_filter filt[] = {
|
||||
{
|
||||
.pgn = J1939_PGN_ADDRESS_CLAIMED,
|
||||
.pgn_mask = J1939_PGN_PDU1_MAX,
|
||||
}, {
|
||||
.pgn = J1939_PGN_REQUEST,
|
||||
.pgn_mask = J1939_PGN_PDU1_MAX,
|
||||
}, {
|
||||
.pgn = J1939_PGN_ADDRESS_COMMANDED,
|
||||
.pgn_mask = J1939_PGN_MAX,
|
||||
},
|
||||
};
|
||||
setsockopt(sock, SOL_CAN_J1939, SO_J1939_FILTER, &filt, sizeof(filt));
|
||||
|
||||
In this example, the socket will only receive messages with the PGNs related to
|
||||
address claiming: ``J1939_PGN_ADDRESS_CLAIMED``, ``J1939_PGN_REQUEST``, and
|
||||
``J1939_PGN_ADDRESS_COMMANDED``. This is particularly useful in scenarios where
|
||||
you want to monitor and process address claims without being overwhelmed by
|
||||
other traffic on the J1939 network.
|
||||
|
||||
``SO_J1939_PROMISC``
|
||||
~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
The ``SO_J1939_PROMISC`` option enables socket-level promiscuous mode. When
|
||||
this option is enabled, the socket will receive all J1939 traffic, regardless
|
||||
of any filters set by ``bind()`` or ``connect()``. This is analogous to
|
||||
enabling promiscuous mode for an Ethernet interface, where all traffic on the
|
||||
network segment is captured.
|
||||
|
||||
However, **`SO_J1939_FILTER` has a higher priority** compared to
|
||||
``SO_J1939_PROMISC``. This means that even in promiscuous mode, you can reduce
|
||||
the number of packets received by applying specific filters with
|
||||
`SO_J1939_FILTER`. The filters will limit which packets are passed to the
|
||||
socket, allowing for more refined traffic selection while promiscuous mode is
|
||||
active.
|
||||
|
||||
The acceptable value size for this option is ``sizeof(int)``, and the value is
|
||||
only differentiated between `0` and non-zero. A value of `0` disables
|
||||
promiscuous mode, while any non-zero value enables it.
|
||||
|
||||
This combination can be useful for debugging or monitoring specific types of
|
||||
traffic while still capturing a broad set of messages.
|
||||
|
||||
Example:
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
int value = 1;
|
||||
setsockopt(sock, SOL_CAN_J1939, SO_J1939_PROMISC, &value, sizeof(value));
|
||||
|
||||
In this example, setting ``value`` to any non-zero value (e.g., `1`) enables
|
||||
promiscuous mode, allowing the socket to receive all J1939 traffic on the
|
||||
network.
|
||||
|
||||
``SO_BROADCAST``
|
||||
~~~~~~~~~~~~~~~~
|
||||
|
||||
The ``SO_BROADCAST`` option enables the sending and receiving of broadcast
|
||||
messages. By default, broadcast messages are disabled for J1939 sockets. When
|
||||
this option is enabled, the socket will be allowed to send and receive
|
||||
broadcast packets on the J1939 network.
|
||||
|
||||
Due to the nature of the CAN bus as a shared medium, all messages transmitted
|
||||
on the bus are visible to all participants. In the context of J1939,
|
||||
broadcasting refers to using a specific destination address field, where the
|
||||
destination address is set to a value that indicates the message is intended
|
||||
for all participants (usually a global address such as 0xFF). Enabling the
|
||||
broadcast option allows the socket to send and receive such broadcast messages.
|
||||
|
||||
The acceptable value size for this option is ``sizeof(int)``, and the value is
|
||||
only differentiated between `0` and non-zero. A value of `0` disables the
|
||||
ability to send and receive broadcast messages, while any non-zero value
|
||||
enables it.
|
||||
|
||||
Example:
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
int value = 1;
|
||||
setsockopt(sock, SOL_SOCKET, SO_BROADCAST, &value, sizeof(value));
|
||||
|
||||
In this example, setting ``value`` to any non-zero value (e.g., `1`) enables
|
||||
the socket to send and receive broadcast messages.
|
||||
|
||||
``SO_J1939_SEND_PRIO``
|
||||
~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
The ``SO_J1939_SEND_PRIO`` option sets the priority of outgoing J1939 messages
|
||||
for the socket. In J1939, messages can have different priorities, and lower
|
||||
numerical values indicate higher priority. This option allows the user to
|
||||
control the priority of messages sent from the socket by adjusting the priority
|
||||
bits in the CAN identifier.
|
||||
|
||||
The acceptable value **size** for this option is ``sizeof(int)``, and the value
|
||||
is expected to be in the range of 0 to 7, where `0` is the highest priority,
|
||||
and `7` is the lowest. By default, the priority is set to `6` if this option is
|
||||
not explicitly configured.
|
||||
|
||||
Note that the priority values `0` and `1` can only be set if the process has
|
||||
the `CAP_NET_ADMIN` capability. These are reserved for high-priority traffic
|
||||
and require administrative privileges.
|
||||
|
||||
Example:
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
int prio = 3; // Priority value between 0 (highest) and 7 (lowest)
|
||||
setsockopt(sock, SOL_CAN_J1939, SO_J1939_SEND_PRIO, &prio, sizeof(prio));
|
||||
|
||||
In this example, the priority is set to `3`, meaning the outgoing messages will
|
||||
be sent with a moderate priority level.
|
||||
|
||||
``SO_J1939_ERRQUEUE``
|
||||
~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
The ``SO_J1939_ERRQUEUE`` option enables the socket to receive error messages
|
||||
from the error queue, providing diagnostic information about transmission
|
||||
failures, protocol violations, or other issues that occur during J1939
|
||||
communication. Once this option is set, user space is required to handle
|
||||
``MSG_ERRQUEUE`` messages.
|
||||
|
||||
Setting ``SO_J1939_ERRQUEUE`` to ``0`` will purge any currently present error
|
||||
messages in the error queue. When enabled, error messages can be retrieved
|
||||
using the ``recvmsg(2)`` system call.
|
||||
|
||||
When subscribing to the error queue, the following error events can be
|
||||
accessed:
|
||||
|
||||
- **``J1939_EE_INFO_TX_ABORT``**: Transmission abort errors.
|
||||
- **``J1939_EE_INFO_RX_RTS``**: Reception of RTS (Request to Send) control
|
||||
frames.
|
||||
- **``J1939_EE_INFO_RX_DPO``**: Reception of data packets with Data Page Offset
|
||||
(DPO).
|
||||
- **``J1939_EE_INFO_RX_ABORT``**: Reception abort errors.
|
||||
|
||||
The error queue can be used to correlate errors with specific message transfer
|
||||
sessions using the session ID (``tskey``). The session ID is assigned via the
|
||||
``SOF_TIMESTAMPING_OPT_ID`` flag, which is set by enabling the
|
||||
``SO_TIMESTAMPING`` option.
|
||||
|
||||
If ``SO_J1939_ERRQUEUE`` is activated, the user is required to pull messages
|
||||
from the error queue, meaning that using plain ``recv(2)`` is not sufficient
|
||||
anymore. The user must use ``recvmsg(2)`` with appropriate flags to handle
|
||||
error messages. Failure to do so can result in the socket becoming blocked with
|
||||
unprocessed error messages in the queue.
|
||||
|
||||
It is **recommended** that ``SO_J1939_ERRQUEUE`` be used in combination with
|
||||
``SO_TIMESTAMPING`` in most cases. This enables proper error handling along
|
||||
with session tracking and timestamping, providing a more detailed analysis of
|
||||
message transfers and errors.
|
||||
|
||||
The acceptable value **size** for this option is ``sizeof(int)``, and the value
|
||||
is only differentiated between ``0`` and non-zero. A value of ``0`` disables
|
||||
error queue reception and purges any existing error messages, while any
|
||||
non-zero value enables it.
|
||||
|
||||
Example:
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
int enable = 1; // Enable error queue reception
|
||||
setsockopt(sock, SOL_CAN_J1939, SO_J1939_ERRQUEUE, &enable, sizeof(enable));
|
||||
|
||||
// Enable timestamping with session tracking via tskey
|
||||
int timestamping = SOF_TIMESTAMPING_OPT_ID | SOF_TIMESTAMPING_TX_ACK |
|
||||
SOF_TIMESTAMPING_TX_SCHED |
|
||||
SOF_TIMESTAMPING_RX_SOFTWARE | SOF_TIMESTAMPING_OPT_CMSG;
|
||||
setsockopt(sock, SOL_SOCKET, SO_TIMESTAMPING, ×tamping,
|
||||
sizeof(timestamping));
|
||||
|
||||
When enabled, error messages can be retrieved using ``recvmsg(2)``. By
|
||||
combining ``SO_J1939_ERRQUEUE`` with ``SO_TIMESTAMPING`` (with
|
||||
``SOF_TIMESTAMPING_OPT_ID`` and ``SOF_TIMESTAMPING_OPT_CMSG`` enabled), the
|
||||
user can track message transfers, retrieve precise timestamps, and correlate
|
||||
errors with specific sessions.
|
||||
|
||||
For more information on enabling timestamps and session tracking, refer to the
|
||||
`SO_TIMESTAMPING` section.
|
||||
|
||||
``SO_TIMESTAMPING``
|
||||
~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
The ``SO_TIMESTAMPING`` option allows the socket to receive timestamps for
|
||||
various events related to message transmissions and receptions in J1939. This
|
||||
option is often used in combination with ``SO_J1939_ERRQUEUE`` to provide
|
||||
detailed diagnostic information, session tracking, and precise timing data for
|
||||
message transfers.
|
||||
|
||||
In J1939, all payloads provided by user space, regardless of size, are
|
||||
processed by the kernel as **sessions**. This includes both single-frame
|
||||
messages (up to 8 bytes) and multi-frame protocols such as the Transport
|
||||
Protocol (TP) and Extended Transport Protocol (ETP). Even for small,
|
||||
single-frame messages, the kernel creates a session to manage the transmission
|
||||
and reception. The concept of sessions allows the kernel to manage various
|
||||
aspects of the protocol, such as reassembling multi-frame messages and tracking
|
||||
the status of transmissions.
|
||||
|
||||
When receiving extended error messages from the error queue, the error
|
||||
information is delivered through a `struct sock_extended_err`, accessible via
|
||||
the control message (``cmsg``) retrieved using the ``recvmsg(2)`` system call.
|
||||
|
||||
There are two typical origins for the extended error messages in J1939:
|
||||
|
||||
1. ``serr->ee_origin == SO_EE_ORIGIN_TIMESTAMPING``:
|
||||
|
||||
In this case, the `serr->ee_info` field will contain one of the following
|
||||
timestamp types:
|
||||
|
||||
- ``SCM_TSTAMP_SCHED``: This timestamp is valid for Extended Transport
|
||||
Protocol (ETP) transfers and simple transfers (8 bytes or less). It
|
||||
indicates when a message or set of frames has been scheduled for
|
||||
transmission.
|
||||
|
||||
- For simple transfers (8 bytes or less), it marks the point when the
|
||||
message is queued and ready to be sent onto the CAN bus.
|
||||
|
||||
- For ETP transfers, it is sent after receiving a CTS (Clear to Send)
|
||||
frame on the sender side, indicating that a new set of frames has been
|
||||
scheduled for transmission.
|
||||
|
||||
- The Transport Protocol (TP) case is currently not implemented for this
|
||||
timestamp.
|
||||
|
||||
- On the receiver side, the counterpart to this event for ETP is
|
||||
represented by the ``J1939_EE_INFO_RX_DPO`` message, which indicates the
|
||||
reception of a Data Page Offset (DPO) control frame.
|
||||
|
||||
- ``SCM_TSTAMP_ACK``: This timestamp indicates the acknowledgment of the
|
||||
message or session.
|
||||
|
||||
- For simple transfers (8 bytes or less), it marks when the message has
|
||||
been sent and an echo confirmation has been received from the CAN
|
||||
controller, indicating that the frame was transmitted onto the bus.
|
||||
|
||||
- For multi-frame transfers (TP or ETP), it signifies that the entire
|
||||
session has been acknowledged, typically after receiving the End of
|
||||
Message Acknowledgment (EOMA) packet.
|
||||
|
||||
2. ``serr->ee_origin == SO_EE_ORIGIN_LOCAL``:
|
||||
|
||||
In this case, the `serr->ee_info` field will contain one of the following
|
||||
J1939 stack-specific message types:
|
||||
|
||||
- ``J1939_EE_INFO_TX_ABORT``: This message indicates that the transmission
|
||||
of a message or session was aborted. The cause of the abort can come from
|
||||
various sources:
|
||||
|
||||
- **CAN stack failure**: The J1939 stack was unable to pass the frame to
|
||||
the CAN framework for transmission.
|
||||
|
||||
- **Echo failure**: The J1939 stack did not receive an echo confirmation
|
||||
from the CAN controller, meaning the frame may not have been successfully
|
||||
transmitted to the CAN bus.
|
||||
|
||||
- **Protocol-level issues**: For multi-frame transfers (TP/ETP), this
|
||||
could include protocol-related errors, such as an abort signaled by the
|
||||
receiver or a timeout at the protocol level, which causes the session to
|
||||
terminate prematurely.
|
||||
|
||||
- The corresponding error code is stored in ``serr->ee_data``
|
||||
(``session->err`` on kernel side), providing additional details about
|
||||
the specific reason for the abort.
|
||||
|
||||
- ``J1939_EE_INFO_RX_RTS``: This message indicates that the J1939 stack has
|
||||
received a Request to Send (RTS) control frame, signaling the start of a
|
||||
multi-frame transfer using the Transport Protocol (TP) or Extended
|
||||
Transport Protocol (ETP).
|
||||
|
||||
- It informs the receiver that the sender is ready to transmit a
|
||||
multi-frame message and includes details about the total message size
|
||||
and the number of frames to be sent.
|
||||
|
||||
- Statistics such as ``J1939_NLA_TOTAL_SIZE``, ``J1939_NLA_PGN``,
|
||||
``J1939_NLA_SRC_NAME``, and ``J1939_NLA_DEST_NAME`` are provided along
|
||||
with the ``J1939_EE_INFO_RX_RTS`` message, giving detailed information
|
||||
about the incoming transfer.
|
||||
|
||||
- ``J1939_EE_INFO_RX_DPO``: This message indicates that the J1939 stack has
|
||||
received a Data Page Offset (DPO) control frame, which is part of the
|
||||
Extended Transport Protocol (ETP).
|
||||
|
||||
- The DPO frame signals the continuation of an ETP multi-frame message by
|
||||
indicating the offset position in the data being transferred. It helps
|
||||
the receiver manage large data sets by identifying which portion of the
|
||||
message is being received.
|
||||
|
||||
- It is typically paired with a corresponding ``SCM_TSTAMP_SCHED`` event
|
||||
on the sender side, which indicates when the next set of frames is
|
||||
scheduled for transmission.
|
||||
|
||||
- This event includes statistics such as ``J1939_NLA_BYTES_ACKED``, which
|
||||
tracks the number of bytes acknowledged up to that point in the session.
|
||||
|
||||
- ``J1939_EE_INFO_RX_ABORT``: This message indicates that the reception of a
|
||||
multi-frame message (Transport Protocol or Extended Transport Protocol) has
|
||||
been aborted.
|
||||
|
||||
- The abort can be triggered by protocol-level errors such as timeouts, an
|
||||
unexpected frame, or a specific abort request from the sender.
|
||||
|
||||
- This message signals that the receiver cannot continue processing the
|
||||
transfer, and the session is terminated.
|
||||
|
||||
- The corresponding error code is stored in ``serr->ee_data``
|
||||
(``session->err`` on kernel side ), providing further details about the
|
||||
reason for the abort, such as protocol violations or timeouts.
|
||||
|
||||
- After receiving this message, the receiver discards the partially received
|
||||
frames, and the multi-frame session is considered incomplete.
|
||||
|
||||
In both cases, if ``SOF_TIMESTAMPING_OPT_ID`` is enabled, ``serr->ee_data``
|
||||
will be set to the session’s unique identifier (``session->tskey``). This
|
||||
allows user space to track message transfers by their session identifier across
|
||||
multiple frames or stages.
|
||||
|
||||
In all other cases, ``serr->ee_errno`` will be set to ``ENOMSG``, except for
|
||||
the ``J1939_EE_INFO_TX_ABORT`` and ``J1939_EE_INFO_RX_ABORT`` cases, where the
|
||||
kernel sets ``serr->ee_data`` to the error stored in ``session->err``. All
|
||||
protocol-specific errors are converted to standard kernel error values and
|
||||
stored in ``session->err``. These error values are unified across system calls
|
||||
and ``serr->ee_errno``. Some of the known error values are described in the
|
||||
`Error Codes in the J1939 Stack` section.
|
||||
|
||||
When the `J1939_EE_INFO_RX_RTS` message is provided, it will include the
|
||||
following statistics for multi-frame messages (TP and ETP):
|
||||
|
||||
- ``J1939_NLA_TOTAL_SIZE``: Total size of the message in the session.
|
||||
- ``J1939_NLA_PGN``: Parameter Group Number (PGN) identifying the message type.
|
||||
- ``J1939_NLA_SRC_NAME``: 64-bit name of the source ECU.
|
||||
- ``J1939_NLA_DEST_NAME``: 64-bit name of the destination ECU.
|
||||
- ``J1939_NLA_SRC_ADDR``: 8-bit source address of the sending ECU.
|
||||
- ``J1939_NLA_DEST_ADDR``: 8-bit destination address of the receiving ECU.
|
||||
|
||||
- For other messages (including single-frame messages), only the following
|
||||
statistic is included:
|
||||
|
||||
- ``J1939_NLA_BYTES_ACKED``: Number of bytes successfully acknowledged in the
|
||||
session.
|
||||
|
||||
The key flags for ``SO_TIMESTAMPING`` include:
|
||||
|
||||
- ``SOF_TIMESTAMPING_OPT_ID``: Enables the use of a unique session identifier
|
||||
(``tskey``) for each transfer. This identifier helps track message transfers
|
||||
and errors as distinct sessions in user space. When this option is enabled,
|
||||
``serr->ee_data`` will be set to ``session->tskey``.
|
||||
|
||||
- ``SOF_TIMESTAMPING_OPT_CMSG``: Sends timestamp information through control
|
||||
messages (``struct scm_timestamping``), allowing the application to retrieve
|
||||
timestamps alongside the data.
|
||||
|
||||
- ``SOF_TIMESTAMPING_TX_SCHED``: Provides the timestamp for when a message is
|
||||
scheduled for transmission (``SCM_TSTAMP_SCHED``).
|
||||
|
||||
- ``SOF_TIMESTAMPING_TX_ACK``: Provides the timestamp for when a message
|
||||
transmission is fully acknowledged (``SCM_TSTAMP_ACK``).
|
||||
|
||||
- ``SOF_TIMESTAMPING_RX_SOFTWARE``: Provides timestamps for reception-related
|
||||
events (e.g., ``J1939_EE_INFO_RX_RTS``, ``J1939_EE_INFO_RX_DPO``,
|
||||
``J1939_EE_INFO_RX_ABORT``).
|
||||
|
||||
These flags enable detailed monitoring of message lifecycles, including
|
||||
transmission scheduling, acknowledgments, reception timestamps, and gathering
|
||||
detailed statistics about the communication session, especially for multi-frame
|
||||
payloads like TP and ETP.
|
||||
|
||||
Example:
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
// Enable timestamping with various options, including session tracking and
|
||||
// statistics
|
||||
int sock_opt = SOF_TIMESTAMPING_OPT_CMSG |
|
||||
SOF_TIMESTAMPING_TX_ACK |
|
||||
SOF_TIMESTAMPING_TX_SCHED |
|
||||
SOF_TIMESTAMPING_OPT_ID |
|
||||
SOF_TIMESTAMPING_RX_SOFTWARE;
|
||||
|
||||
setsockopt(sock, SOL_SOCKET, SO_TIMESTAMPING, &sock_opt, sizeof(sock_opt));
|
||||
|
||||
|
||||
|
||||
Dynamic Addressing
|
||||
------------------
|
||||
|
||||
@@ -458,3 +995,141 @@ Send:
|
||||
};
|
||||
|
||||
sendto(sock, dat, sizeof(dat), 0, (const struct sockaddr *)&saddr, sizeof(saddr));
|
||||
|
||||
|
||||
Error Codes in the J1939 Stack
|
||||
------------------------------
|
||||
|
||||
This section lists all potential kernel error codes that can be exposed to user
|
||||
space when interacting with the J1939 stack. It includes both standard error
|
||||
codes and those derived from protocol-specific abort codes.
|
||||
|
||||
- ``EAGAIN``: Operation would block; retry may succeed. One common reason is
|
||||
that an active TP or ETP session exists, and an attempt was made to start a
|
||||
new overlapping TP or ETP session between the same peers.
|
||||
|
||||
- ``ENETDOWN``: Network is down. This occurs when the CAN interface is switched
|
||||
to the "down" state.
|
||||
|
||||
- ``ENOBUFS``: No buffer space available. This error occurs when the CAN
|
||||
interface's transmit (TX) queue is full, and no more messages can be queued.
|
||||
|
||||
- ``EOVERFLOW``: Value too large for defined data type. In J1939, this can
|
||||
happen if the requested data lies outside of the queued buffer. For example,
|
||||
if a CTS (Clear to Send) requests an offset not available in the kernel buffer
|
||||
because user space did not provide enough data.
|
||||
|
||||
- ``EBUSY``: Device or resource is busy. For example, this occurs if an
|
||||
identical session is already active and the stack is unable to recover from
|
||||
the condition.
|
||||
|
||||
- ``EACCES``: Permission denied. This error can occur, for example, when
|
||||
attempting to send broadcast messages, but the socket is not configured with
|
||||
``SO_BROADCAST``.
|
||||
|
||||
- ``EADDRNOTAVAIL``: Address not available. This error occurs in cases such as:
|
||||
|
||||
- When attempting to use ``getsockname(2)`` to retrieve the peer's address,
|
||||
but the socket is not connected.
|
||||
|
||||
- When trying to send data to or from a NAME, but address claiming for the
|
||||
NAME was not performed or detected by the stack.
|
||||
|
||||
- ``EBADFD``: File descriptor in bad state. This error can occur if:
|
||||
|
||||
- Attempting to send data to an unbound socket.
|
||||
|
||||
- The socket is bound but has no source name, and the source address is
|
||||
``J1939_NO_ADDR``.
|
||||
|
||||
- The ``can_ifindex`` is incorrect.
|
||||
|
||||
- ``EFAULT``: Bad address. Occurs mostly when the stack can't copy from or to a
|
||||
sockptr, when there is insufficient data from user space, or when the buffer
|
||||
provided by user space is not large enough for the requested data.
|
||||
|
||||
- ``EINTR``: A signal occurred before any data was transmitted; see ``signal(7)``.
|
||||
|
||||
- ``EINVAL``: Invalid argument passed. For example:
|
||||
|
||||
- ``msg->msg_namelen`` is less than ``J1939_MIN_NAMELEN``.
|
||||
|
||||
- ``addr->can_family`` is not equal to ``AF_CAN``.
|
||||
|
||||
- An incorrect PGN was provided.
|
||||
|
||||
- ``ENODEV``: No such device. This happens when the CAN network device cannot
|
||||
be found for the provided ``can_ifindex`` or if ``can_ifindex`` is 0.
|
||||
|
||||
- ``ENOMEM``: Out of memory. Typically related to issues with memory allocation
|
||||
in the stack.
|
||||
|
||||
- ``ENOPROTOOPT``: Protocol not available. This can occur when using
|
||||
``getsockopt(2)`` or ``setsockopt(2)`` if the requested socket option is not
|
||||
available.
|
||||
|
||||
- ``EDESTADDRREQ``: Destination address required. This error occurs:
|
||||
|
||||
- In the case of ``connect(2)``, if the ``struct sockaddr *uaddr`` is ``NULL``.
|
||||
|
||||
- In the case of ``send*(2)``, if there is an attempt to send an ETP message
|
||||
to a broadcast address.
|
||||
|
||||
- ``EDOM``: Argument out of domain. This error may happen if attempting to send
|
||||
a TP or ETP message to a PGN that is reserved for control PGNs for TP or ETP
|
||||
operations.
|
||||
|
||||
- ``EIO``: I/O error. This can occur if the amount of data provided to the
|
||||
socket for a TP or ETP session does not match the announced amount of data for
|
||||
the session.
|
||||
|
||||
- ``ENOENT``: No such file or directory. This can happen when the stack
|
||||
attempts to transfer CTS or EOMA but cannot find a matching receiving socket
|
||||
anymore.
|
||||
|
||||
- ``ENOIOCTLCMD``: No ioctls are available for the socket layer.
|
||||
|
||||
- ``EPERM``: Operation not permitted. For example, this can occur if a
|
||||
requested action requires ``CAP_NET_ADMIN`` privileges.
|
||||
|
||||
- ``ENETUNREACH``: Network unreachable. Most likely, this occurs when frames
|
||||
cannot be transmitted to the CAN bus.
|
||||
|
||||
- ``ETIME``: Timer expired. This can happen if a timeout occurs while
|
||||
attempting to send a simple message, for example, when an echo message from
|
||||
the controller is not received.
|
||||
|
||||
- ``EPROTO``: Protocol error.
|
||||
|
||||
- Used for various protocol-level errors in J1939, including:
|
||||
|
||||
- Duplicate sequence number.
|
||||
|
||||
- Unexpected EDPO or ECTS packet.
|
||||
|
||||
- Invalid PGN or offset in EDPO/ECTS.
|
||||
|
||||
- Number of EDPO packets exceeded CTS allowance.
|
||||
|
||||
- Any other protocol-level error.
|
||||
|
||||
- ``EMSGSIZE``: Message too long.
|
||||
|
||||
- ``ENOMSG``: No message available.
|
||||
|
||||
- ``EALREADY``: The ECU is already engaged in one or more connection-managed
|
||||
sessions and cannot support another.
|
||||
|
||||
- ``EHOSTUNREACH``: A timeout occurred, and the session was aborted.
|
||||
|
||||
- ``EBADMSG``: CTS (Clear to Send) messages were received during an active data
|
||||
transfer, causing an abort.
|
||||
|
||||
- ``ENOTRECOVERABLE``: The maximum retransmission request limit was reached,
|
||||
and the session cannot recover.
|
||||
|
||||
- ``ENOTCONN``: An unexpected data transfer packet was received.
|
||||
|
||||
- ``EILSEQ``: A bad sequence number was received, and the software could not
|
||||
recover.
|
||||
|
||||
|
||||
@@ -200,7 +200,7 @@ while. Example use::
|
||||
|
||||
setsockopt(kcmfd, SOL_KCM, KCM_RECV_DISABLE, &val, sizeof(val))
|
||||
|
||||
BFP programs for message delineation
|
||||
BPF programs for message delineation
|
||||
------------------------------------
|
||||
|
||||
BPF programs can be compiled using the BPF LLVM backend. For example,
|
||||
|
||||
@@ -30,6 +30,10 @@ allow_join_initial_addr_port - BOOLEAN
|
||||
|
||||
Default: 1
|
||||
|
||||
available_path_managers - STRING
|
||||
Shows the available path managers choices that are registered. More
|
||||
path managers may be available, but not loaded.
|
||||
|
||||
available_schedulers - STRING
|
||||
Shows the available schedulers choices that are registered. More packet
|
||||
schedulers may be available, but not loaded.
|
||||
@@ -72,6 +76,23 @@ enabled - BOOLEAN
|
||||
|
||||
Default: 1 (enabled)
|
||||
|
||||
path_manager - STRING
|
||||
Set the default path manager name to use for each new MPTCP
|
||||
socket. In-kernel path management will control subflow
|
||||
connections and address advertisements according to
|
||||
per-namespace values configured over the MPTCP netlink
|
||||
API. Userspace path management puts per-MPTCP-connection subflow
|
||||
connection decisions and address advertisements under control of
|
||||
a privileged userspace program, at the cost of more netlink
|
||||
traffic to propagate all of the related events and commands.
|
||||
|
||||
This is a per-namespace sysctl.
|
||||
|
||||
* "kernel" - In-kernel path manager
|
||||
* "userspace" - Userspace path manager
|
||||
|
||||
Default: "kernel"
|
||||
|
||||
pm_type - INTEGER
|
||||
Set the default path manager type to use for each new MPTCP
|
||||
socket. In-kernel path management will control subflow
|
||||
@@ -84,6 +105,8 @@ pm_type - INTEGER
|
||||
|
||||
This is a per-namespace sysctl.
|
||||
|
||||
Deprecated since v6.15, use path_manager instead.
|
||||
|
||||
* 0 - In-kernel path manager
|
||||
* 1 - Userspace path manager
|
||||
|
||||
|
||||
@@ -171,12 +171,43 @@ a channel as an IRQ/NAPI which services queues of a given type. For example,
|
||||
a configuration of 1 ``rx``, 1 ``tx`` and 1 ``combined`` channel is expected
|
||||
to utilize 3 interrupts, 2 Rx and 2 Tx queues.
|
||||
|
||||
Persistent NAPI config
|
||||
----------------------
|
||||
|
||||
Drivers often allocate and free NAPI instances dynamically. This leads to loss
|
||||
of NAPI-related user configuration each time NAPI instances are reallocated.
|
||||
The netif_napi_add_config() API prevents this loss of configuration by
|
||||
associating each NAPI instance with a persistent NAPI configuration based on
|
||||
a driver defined index value, like a queue number.
|
||||
|
||||
Using this API allows for persistent NAPI IDs (among other settings), which can
|
||||
be beneficial to userspace programs using ``SO_INCOMING_NAPI_ID``. See the
|
||||
sections below for other NAPI configuration settings.
|
||||
|
||||
Drivers should try to use netif_napi_add_config() whenever possible.
|
||||
|
||||
User API
|
||||
========
|
||||
|
||||
User interactions with NAPI depend on NAPI instance ID. The instance IDs
|
||||
are only visible to the user thru the ``SO_INCOMING_NAPI_ID`` socket option.
|
||||
It's not currently possible to query IDs used by a given device.
|
||||
|
||||
Users can query NAPI IDs for a device or device queue using netlink. This can
|
||||
be done programmatically in a user application or by using a script included in
|
||||
the kernel source tree: ``tools/net/ynl/pyynl/cli.py``.
|
||||
|
||||
For example, using the script to dump all of the queues for a device (which
|
||||
will reveal each queue's NAPI ID):
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
$ kernel-source/tools/net/ynl/pyynl/cli.py \
|
||||
--spec Documentation/netlink/specs/netdev.yaml \
|
||||
--dump queue-get \
|
||||
--json='{"ifindex": 2}'
|
||||
|
||||
See ``Documentation/netlink/specs/netdev.yaml`` for more details on
|
||||
available operations and attributes.
|
||||
|
||||
Software IRQ coalescing
|
||||
-----------------------
|
||||
|
||||
@@ -12,11 +12,11 @@ struct inet_sock icsk_inet read_mostly r
|
||||
struct request_sock_queue icsk_accept_queue
|
||||
struct inet_bind_bucket icsk_bind_hash read_mostly tcp_set_state
|
||||
struct inet_bind2_bucket icsk_bind2_hash read_mostly tcp_set_state,inet_put_port
|
||||
unsigned_long icsk_timeout read_mostly inet_csk_reset_xmit_timer,tcp_connect
|
||||
struct timer_list icsk_retransmit_timer read_mostly inet_csk_reset_xmit_timer,tcp_connect
|
||||
struct timer_list icsk_retransmit_timer read_write inet_csk_reset_xmit_timer,tcp_connect
|
||||
struct timer_list icsk_delack_timer read_mostly inet_csk_reset_xmit_timer,tcp_connect
|
||||
u32 icsk_rto read_write tcp_cwnd_validate,tcp_schedule_loss_probe,tcp_connect_init,tcp_connect,tcp_write_xmit,tcp_push_one
|
||||
u32 icsk_rto_min
|
||||
u32 icsk_rto_max read_mostly tcp_reset_xmit_timer
|
||||
u32 icsk_delack_max
|
||||
u32 icsk_pmtu_cookie read_write tcp_sync_mss,tcp_current_mss,tcp_send_syn_data,tcp_connect_init,tcp_connect
|
||||
struct tcp_congestion_ops icsk_ca_ops read_write tcp_cwnd_validate,tcp_tso_segs,tcp_ca_dst_init,tcp_connect_init,tcp_connect,tcp_write_xmit
|
||||
@@ -38,7 +38,6 @@ struct icsk_ack_u8 quick read_write w
|
||||
struct icsk_ack_u8 pingpong
|
||||
struct icsk_ack_u8 retry write_mostly read_write inet_csk_clear_xmit_timer,tcp_rearm_rto,tcp_event_new_data_sent,tcp_write_xmit,__tcp_send_ack,tcp_send_ack,
|
||||
struct icsk_ack_u8 ato read_mostly write_mostly tcp_dec_quickack_mode,tcp_event_ack_sent,__tcp_transmit_skb,__tcp_send_ack,tcp_send_ack
|
||||
struct icsk_ack_unsigned_long timeout read_write read_write inet_csk_reset_xmit_timer,tcp_connect
|
||||
struct icsk_ack_u32 lrcvtime read_write tcp_finish_connect,tcp_connect,tcp_event_data_sent,__tcp_transmit_skb
|
||||
struct icsk_ack_u16 rcv_mss write_mostly read_mostly __tcp_select_window,__tcp_cleanup_rbuf,tcp_initialize_rcv_mss,tcp_connect_init
|
||||
struct icsk_mtup_int search_high read_write tcp_mtup_init,tcp_sync_mss,tcp_connect_init,tcp_mtu_check_reprobe,tcp_write_xmit
|
||||
|
||||
@@ -167,7 +167,7 @@ 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 netns_immutable
|
||||
unsigned_long:1 fcoe_mtu
|
||||
struct list_head net_notifier_list
|
||||
struct macsec_ops* macsec_ops
|
||||
|
||||
@@ -86,6 +86,7 @@ u8 sysctl_tcp_sack
|
||||
u8 sysctl_tcp_window_scaling tcp_syn_options,tcp_parse_options
|
||||
u8 sysctl_tcp_timestamps
|
||||
u8 sysctl_tcp_early_retrans read_mostly tcp_schedule_loss_probe(tcp_write_xmit)
|
||||
u32 sysctl_tcp_rto_max_ms
|
||||
u8 sysctl_tcp_recovery tcp_fastretrans_alert
|
||||
u8 sysctl_tcp_thin_linear_timeouts tcp_retrans_timer(on_thin_streams)
|
||||
u8 sysctl_tcp_slow_start_after_idle unlikely(tcp_cwnd_validate-network-not-starved)
|
||||
|
||||
@@ -36,6 +36,7 @@ unsigned_long LINUX_MIB_TIMEWAITRECYCLED
|
||||
unsigned_long LINUX_MIB_TIMEWAITKILLED
|
||||
unsigned_long LINUX_MIB_PAWSACTIVEREJECTED
|
||||
unsigned_long LINUX_MIB_PAWSESTABREJECTED
|
||||
unsigned_long LINUX_MIB_TSECR_REJECTED
|
||||
unsigned_long LINUX_MIB_DELAYEDACKLOST
|
||||
unsigned_long LINUX_MIB_LISTENOVERFLOWS
|
||||
unsigned_long LINUX_MIB_LISTENDROPS
|
||||
|
||||
@@ -27,6 +27,7 @@ u32 dsack_dups
|
||||
u32 snd_una read_mostly read_write tcp_wnd_end,tcp_urg_mode,tcp_minshall_check,tcp_cwnd_validate(tx);tcp_ack,tcp_may_update_window,tcp_clean_rtx_queue(write),tcp_ack_tstamp(rx)
|
||||
u32 snd_sml read_write tcp_minshall_check,tcp_minshall_update
|
||||
u32 rcv_tstamp read_mostly tcp_ack
|
||||
void * tcp_clean_acked read_mostly tcp_ack
|
||||
u32 lsndtime read_write tcp_slow_start_after_idle_check,tcp_event_data_sent
|
||||
u32 last_oow_ack_time
|
||||
u32 compressed_ack_rcv_nxt
|
||||
|
||||
@@ -17,6 +17,8 @@ Release prepend support by Breno Leitao <leitao@debian.org>, Jul 7 2023
|
||||
|
||||
Userdata append support by Matthew Wood <thepacketgeek@gmail.com>, Jan 22 2024
|
||||
|
||||
Sysdata append support by Breno Leitao <leitao@debian.org>, Jan 15 2025
|
||||
|
||||
Please send bug reports to Matt Mackall <mpm@selenic.com>
|
||||
Satyam Sharma <satyam.sharma@gmail.com>, and Cong Wang <xiyou.wangcong@gmail.com>
|
||||
|
||||
@@ -45,7 +47,7 @@ following format::
|
||||
r if present, prepend kernel version (release) to the message
|
||||
src-port source for UDP packets (defaults to 6665)
|
||||
src-ip source IP to use (interface address)
|
||||
dev network interface (eth0)
|
||||
dev network interface name (eth0) or MAC address
|
||||
tgt-port port for logging agent (6666)
|
||||
tgt-ip IP address for logging agent
|
||||
tgt-macaddr ethernet MAC address for logging agent (broadcast)
|
||||
@@ -62,6 +64,10 @@ or using IPv6::
|
||||
|
||||
insmod netconsole netconsole=@/,@fd00:1:2:3::1/
|
||||
|
||||
or using a MAC address to select the egress interface::
|
||||
|
||||
linux netconsole=4444@10.0.0.1/22:33:44:55:66:77,9353@10.0.0.2/12:34:56:78:9a:bc
|
||||
|
||||
It also supports logging to multiple remote agents by specifying
|
||||
parameters for the multiple agents separated by semicolons and the
|
||||
complete string enclosed in "quotes", thusly::
|
||||
@@ -238,6 +244,102 @@ Delete `userdata` entries with `rmdir`::
|
||||
|
||||
It is recommended to not write user data values with newlines.
|
||||
|
||||
Task name auto population in userdata
|
||||
-------------------------------------
|
||||
|
||||
Inside the netconsole configfs hierarchy, there is a file called
|
||||
`taskname_enabled` under the `userdata` directory. This file is used to enable
|
||||
or disable the automatic task name population feature. This feature
|
||||
automatically populates the current task name that is scheduled in the CPU
|
||||
sneding the message.
|
||||
|
||||
To enable task name auto-population::
|
||||
|
||||
echo 1 > /sys/kernel/config/netconsole/target1/userdata/taskname_enabled
|
||||
|
||||
When this option is enabled, the netconsole messages will include an additional
|
||||
line in the userdata field with the format `taskname=<task name>`. This allows
|
||||
the receiver of the netconsole messages to easily find which application was
|
||||
currently scheduled when that message was generated, providing extra context
|
||||
for kernel messages and helping to categorize them.
|
||||
|
||||
Example::
|
||||
|
||||
echo "This is a message" > /dev/kmsg
|
||||
12,607,22085407756,-;This is a message
|
||||
taskname=echo
|
||||
|
||||
In this example, the message was generated while "echo" was the current
|
||||
scheduled process.
|
||||
|
||||
Kernel release auto population in userdata
|
||||
------------------------------------------
|
||||
|
||||
Within the netconsole configfs hierarchy, there is a file named `release_enabled`
|
||||
located in the `userdata` directory. This file controls the kernel release
|
||||
(version) auto-population feature, which appends the kernel release information
|
||||
to userdata dictionary in every message sent.
|
||||
|
||||
To enable the release auto-population::
|
||||
|
||||
echo 1 > /sys/kernel/config/netconsole/target1/userdata/release_enabled
|
||||
|
||||
Example::
|
||||
|
||||
echo "This is a message" > /dev/kmsg
|
||||
12,607,22085407756,-;This is a message
|
||||
release=6.14.0-rc6-01219-g3c027fbd941d
|
||||
|
||||
.. note::
|
||||
|
||||
This feature provides the same data as the "release prepend" feature.
|
||||
However, in this case, the release information is appended to the userdata
|
||||
dictionary rather than being included in the message header.
|
||||
|
||||
|
||||
CPU number auto population in userdata
|
||||
--------------------------------------
|
||||
|
||||
Inside the netconsole configfs hierarchy, there is a file called
|
||||
`cpu_nr` under the `userdata` directory. This file is used to enable or disable
|
||||
the automatic CPU number population feature. This feature automatically
|
||||
populates the CPU number that is sending the message.
|
||||
|
||||
To enable the CPU number auto-population::
|
||||
|
||||
echo 1 > /sys/kernel/config/netconsole/target1/userdata/cpu_nr
|
||||
|
||||
When this option is enabled, the netconsole messages will include an additional
|
||||
line in the userdata field with the format `cpu=<cpu_number>`. This allows the
|
||||
receiver of the netconsole messages to easily differentiate and demultiplex
|
||||
messages originating from different CPUs, which is particularly useful when
|
||||
dealing with parallel log output.
|
||||
|
||||
Example::
|
||||
|
||||
echo "This is a message" > /dev/kmsg
|
||||
12,607,22085407756,-;This is a message
|
||||
cpu=42
|
||||
|
||||
In this example, the message was sent by CPU 42.
|
||||
|
||||
.. note::
|
||||
|
||||
If the user has set a conflicting `cpu` key in the userdata dictionary,
|
||||
both keys will be reported, with the kernel-populated entry appearing after
|
||||
the user one. For example::
|
||||
|
||||
# User-defined CPU entry
|
||||
mkdir -p /sys/kernel/config/netconsole/target1/userdata/cpu
|
||||
echo "1" > /sys/kernel/config/netconsole/target1/userdata/cpu/value
|
||||
|
||||
Output might look like::
|
||||
|
||||
12,607,22085407756,-;This is a message
|
||||
cpu=1
|
||||
cpu=42 # kernel-populated value
|
||||
|
||||
|
||||
Extended console:
|
||||
=================
|
||||
|
||||
|
||||
@@ -210,49 +210,55 @@ packets is preferred.
|
||||
struct net_device synchronization rules
|
||||
=======================================
|
||||
ndo_open:
|
||||
Synchronization: rtnl_lock() semaphore.
|
||||
Synchronization: rtnl_lock() semaphore. In addition, netdev instance
|
||||
lock if the driver implements queue management or shaper API.
|
||||
Context: process
|
||||
|
||||
ndo_stop:
|
||||
Synchronization: rtnl_lock() semaphore.
|
||||
Synchronization: rtnl_lock() semaphore. In addition, netdev instance
|
||||
lock if the driver implements queue management or shaper API.
|
||||
Context: process
|
||||
Note: netif_running() is guaranteed false
|
||||
|
||||
ndo_do_ioctl:
|
||||
Synchronization: rtnl_lock() semaphore.
|
||||
Context: process
|
||||
|
||||
This is only called by network subsystems internally,
|
||||
not by user space calling ioctl as it was in before
|
||||
linux-5.14.
|
||||
This is only called by network subsystems internally,
|
||||
not by user space calling ioctl as it was in before
|
||||
linux-5.14.
|
||||
|
||||
ndo_siocbond:
|
||||
Synchronization: rtnl_lock() semaphore.
|
||||
Synchronization: rtnl_lock() semaphore. In addition, netdev instance
|
||||
lock if the driver implements queue management or shaper API.
|
||||
Context: process
|
||||
|
||||
Used by the bonding driver for the SIOCBOND family of
|
||||
ioctl commands.
|
||||
Used by the bonding driver for the SIOCBOND family of
|
||||
ioctl commands.
|
||||
|
||||
ndo_siocwandev:
|
||||
Synchronization: rtnl_lock() semaphore.
|
||||
Synchronization: rtnl_lock() semaphore. In addition, netdev instance
|
||||
lock if the driver implements queue management or shaper API.
|
||||
Context: process
|
||||
|
||||
Used by the drivers/net/wan framework to handle
|
||||
the SIOCWANDEV ioctl with the if_settings structure.
|
||||
|
||||
ndo_siocdevprivate:
|
||||
Synchronization: rtnl_lock() semaphore.
|
||||
Synchronization: rtnl_lock() semaphore. In addition, netdev instance
|
||||
lock if the driver implements queue management or shaper API.
|
||||
Context: process
|
||||
|
||||
This is used to implement SIOCDEVPRIVATE ioctl helpers.
|
||||
These should not be added to new drivers, so don't use.
|
||||
|
||||
ndo_eth_ioctl:
|
||||
Synchronization: rtnl_lock() semaphore.
|
||||
Synchronization: rtnl_lock() semaphore. In addition, netdev instance
|
||||
lock if the driver implements queue management or shaper API.
|
||||
Context: process
|
||||
|
||||
ndo_get_stats:
|
||||
Synchronization: rtnl_lock() semaphore, or RCU.
|
||||
Synchronization: RCU (can be called concurrently with the stats
|
||||
update path).
|
||||
Context: atomic (can't sleep under RCU)
|
||||
|
||||
ndo_start_xmit:
|
||||
@@ -284,6 +290,16 @@ ndo_set_rx_mode:
|
||||
Synchronization: netif_addr_lock spinlock.
|
||||
Context: BHs disabled
|
||||
|
||||
ndo_setup_tc:
|
||||
``TC_SETUP_BLOCK`` and ``TC_SETUP_FT`` are running under NFT locks
|
||||
(i.e. no ``rtnl_lock`` and no device instance lock). The rest of
|
||||
``tc_setup_type`` types run under netdev instance lock if the driver
|
||||
implements queue management or shaper API.
|
||||
|
||||
Most ndo callbacks not specified in the list above are running
|
||||
under ``rtnl_lock``. In addition, netdev instance lock is taken as well if
|
||||
the driver implements queue management or shaper API.
|
||||
|
||||
struct napi_struct synchronization rules
|
||||
========================================
|
||||
napi->poll:
|
||||
@@ -298,6 +314,35 @@ napi->poll:
|
||||
softirq
|
||||
will be called with interrupts disabled by netconsole.
|
||||
|
||||
struct netdev_queue_mgmt_ops synchronization rules
|
||||
==================================================
|
||||
|
||||
All queue management ndo callbacks are holding netdev instance lock.
|
||||
|
||||
RTNL and netdev instance lock
|
||||
=============================
|
||||
|
||||
Historically, all networking control operations were protected by a single
|
||||
global lock known as ``rtnl_lock``. There is an ongoing effort to replace this
|
||||
global lock with separate locks for each network namespace. Additionally,
|
||||
properties of individual netdev are increasingly protected by per-netdev locks.
|
||||
|
||||
For device drivers that implement shaping or queue management APIs, all control
|
||||
operations will be performed under the netdev instance lock. Currently, this
|
||||
instance lock is acquired within the context of ``rtnl_lock``. The drivers
|
||||
can also explicitly request instance lock to be acquired via
|
||||
``request_ops_lock``. In the future, there will be an option for individual
|
||||
drivers to opt out of using ``rtnl_lock`` and instead perform their control
|
||||
operations directly under the netdev instance lock.
|
||||
|
||||
Devices drivers are encouraged to rely on the instance lock where possible.
|
||||
|
||||
For the (mostly software) drivers that need to interact with the core stack,
|
||||
there are two sets of interfaces: ``dev_xxx`` and ``netif_xxx`` (e.g.,
|
||||
``dev_set_mtu`` and ``netif_set_mtu``). The ``dev_xxx`` functions handle
|
||||
acquiring the instance lock themselves, while the ``netif_xxx`` functions
|
||||
assume that the driver has already acquired the instance lock.
|
||||
|
||||
NETDEV_INTERNAL symbol namespace
|
||||
================================
|
||||
|
||||
|
||||
@@ -49,14 +49,21 @@ destination address) and TCP/UDP (source port, destination port) tuples
|
||||
are swapped, the computed hash is the same. This is beneficial in some
|
||||
applications that monitor TCP/IP flows (IDS, firewalls, ...etc) and need
|
||||
both directions of the flow to land on the same Rx queue (and CPU). The
|
||||
"Symmetric-XOR" is a type of RSS algorithms that achieves this hash
|
||||
symmetry by XORing the input source and destination fields of the IP
|
||||
and/or L4 protocols. This, however, results in reduced input entropy and
|
||||
could potentially be exploited. Specifically, the algorithm XORs the input
|
||||
"Symmetric-XOR" and "Symmetric-OR-XOR" are types of RSS algorithms that
|
||||
achieve this hash symmetry by XOR/ORing the input source and destination
|
||||
fields of the IP and/or L4 protocols. This, however, results in reduced
|
||||
input entropy and could potentially be exploited.
|
||||
|
||||
Specifically, the "Symmetric-XOR" algorithm XORs the input
|
||||
as follows::
|
||||
|
||||
# (SRC_IP ^ DST_IP, SRC_IP ^ DST_IP, SRC_PORT ^ DST_PORT, SRC_PORT ^ DST_PORT)
|
||||
|
||||
The "Symmetric-OR-XOR" algorithm, on the other hand, transforms the input as
|
||||
follows::
|
||||
|
||||
# (SRC_IP | DST_IP, SRC_IP ^ DST_IP, SRC_PORT | DST_PORT, SRC_PORT ^ DST_PORT)
|
||||
|
||||
The result is then fed to the underlying RSS algorithm.
|
||||
|
||||
Some advanced NICs allow steering packets to queues based on
|
||||
@@ -427,8 +434,10 @@ rps_dev_flow_table. The stack consults a CPU to hardware queue map which
|
||||
is maintained by the NIC driver. This is an auto-generated reverse map of
|
||||
the IRQ affinity table shown by /proc/interrupts. Drivers can use
|
||||
functions in the cpu_rmap (“CPU affinity reverse map”) kernel library
|
||||
to populate the map. For each CPU, the corresponding queue in the map is
|
||||
set to be one whose processing CPU is closest in cache locality.
|
||||
to populate the map. Alternatively, drivers can delegate the cpu_rmap
|
||||
management to the Kernel by calling netif_enable_cpu_rmap(). For each CPU,
|
||||
the corresponding queue in the map is set to be one whose processing CPU is
|
||||
closest in cache locality.
|
||||
|
||||
|
||||
Accelerated RFS Configuration
|
||||
|
||||
@@ -180,7 +180,7 @@ There are seven callbacks:
|
||||
struct contains two fields: offset and full_len. Offset is
|
||||
where the message starts in the skb, and full_len is the
|
||||
the length of the message. skb->len - offset may be greater
|
||||
then full_len since strparser does not trim the skb.
|
||||
than full_len since strparser does not trim the skb.
|
||||
|
||||
::
|
||||
|
||||
|
||||
@@ -137,7 +137,7 @@ would be sub-port 0 on port 1 on switch 1.
|
||||
Port Features
|
||||
^^^^^^^^^^^^^
|
||||
|
||||
dev->netns_local
|
||||
dev->netns_immutable
|
||||
|
||||
If the switchdev driver (and device) only supports offloading of the default
|
||||
network namespace (netns), the driver should set this private flag to prevent
|
||||
|
||||
@@ -140,6 +140,14 @@ SOF_TIMESTAMPING_TX_ACK:
|
||||
cumulative acknowledgment. The mechanism ignores SACK and FACK.
|
||||
This flag can be enabled via both socket options and control messages.
|
||||
|
||||
SOF_TIMESTAMPING_TX_COMPLETION:
|
||||
Request tx timestamps on packet tx completion. The completion
|
||||
timestamp is generated by the kernel when it receives packet a
|
||||
completion report from the hardware. Hardware may report multiple
|
||||
packets at once, and completion timestamps reflect the timing of the
|
||||
report and not actual tx time. This flag can be enabled via both
|
||||
socket options and control messages.
|
||||
|
||||
|
||||
1.3.2 Timestamp Reporting
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
@@ -126,7 +126,8 @@ been setup for offload, it first calls into xdo_dev_offload_ok() with
|
||||
the skb and the intended offload state to ask the driver if the offload
|
||||
will serviceable. This can check the packet information to be sure the
|
||||
offload can be supported (e.g. IPv4 or IPv6, no IPv4 options, etc) and
|
||||
return true of false to signify its support.
|
||||
return true or false to signify its support. In case driver doesn't implement
|
||||
this callback, the stack provides reasonable defaults.
|
||||
|
||||
Crypto offload mode:
|
||||
When ready to send, the driver needs to inspect the Tx packet for the
|
||||
|
||||
@@ -50,6 +50,10 @@ The flags field enables the particular offload:
|
||||
checksum. ``csum_start`` specifies byte offset of where the checksumming
|
||||
should start and ``csum_offset`` specifies byte offset where the
|
||||
device should store the computed checksum.
|
||||
- ``XDP_TXMD_FLAGS_LAUNCH_TIME``: requests the device to schedule the
|
||||
packet for transmission at a pre-determined time called launch time. The
|
||||
value of launch time is indicated by ``launch_time`` field of
|
||||
``union xsk_tx_metadata``.
|
||||
|
||||
Besides the flags above, in order to trigger the offloads, the first
|
||||
packet's ``struct xdp_desc`` descriptor should set ``XDP_TX_METADATA``
|
||||
@@ -65,6 +69,63 @@ In this case, when running in ``XDK_COPY`` mode, the TX checksum
|
||||
is calculated on the CPU. Do not enable this option in production because
|
||||
it will negatively affect performance.
|
||||
|
||||
Launch Time
|
||||
===========
|
||||
|
||||
The value of the requested launch time should be based on the device's PTP
|
||||
Hardware Clock (PHC) to ensure accuracy. AF_XDP takes a different data path
|
||||
compared to the ETF queuing discipline, which organizes packets and delays
|
||||
their transmission. Instead, AF_XDP immediately hands off the packets to
|
||||
the device driver without rearranging their order or holding them prior to
|
||||
transmission. Since the driver maintains FIFO behavior and does not perform
|
||||
packet reordering, a packet with a launch time request will block other
|
||||
packets in the same Tx Queue until it is sent. Therefore, it is recommended
|
||||
to allocate separate queue for scheduling traffic that is intended for
|
||||
future transmission.
|
||||
|
||||
In scenarios where the launch time offload feature is disabled, the device
|
||||
driver is expected to disregard the launch time request. For correct
|
||||
interpretation and meaningful operation, the launch time should never be
|
||||
set to a value larger than the farthest programmable time in the future
|
||||
(the horizon). Different devices have different hardware limitations on the
|
||||
launch time offload feature.
|
||||
|
||||
stmmac driver
|
||||
-------------
|
||||
|
||||
For stmmac, TSO and launch time (TBS) features are mutually exclusive for
|
||||
each individual Tx Queue. By default, the driver configures Tx Queue 0 to
|
||||
support TSO and the rest of the Tx Queues to support TBS. The launch time
|
||||
hardware offload feature can be enabled or disabled by using the tc-etf
|
||||
command to call the driver's ndo_setup_tc() callback.
|
||||
|
||||
The value of the launch time that is programmed in the Enhanced Normal
|
||||
Transmit Descriptors is a 32-bit value, where the most significant 8 bits
|
||||
represent the time in seconds and the remaining 24 bits represent the time
|
||||
in 256 ns increments. The programmed launch time is compared against the
|
||||
PTP time (bits[39:8]) and rolls over after 256 seconds. Therefore, the
|
||||
horizon of the launch time for dwmac4 and dwxlgmac2 is 128 seconds in the
|
||||
future.
|
||||
|
||||
igc driver
|
||||
----------
|
||||
|
||||
For igc, all four Tx Queues support the launch time feature. The launch
|
||||
time hardware offload feature can be enabled or disabled by using the
|
||||
tc-etf command to call the driver's ndo_setup_tc() callback. When entering
|
||||
TSN mode, the igc driver will reset the device and create a default Qbv
|
||||
schedule with a 1-second cycle time, with all Tx Queues open at all times.
|
||||
|
||||
The value of the launch time that is programmed in the Advanced Transmit
|
||||
Context Descriptor is a relative offset to the starting time of the Qbv
|
||||
transmission window of the queue. The Frst flag of the descriptor can be
|
||||
set to schedule the packet for the next Qbv cycle. Therefore, the horizon
|
||||
of the launch time for i225 and i226 is the ending time of the next cycle
|
||||
of the Qbv transmission window of the queue. For example, when the Qbv
|
||||
cycle time is set to 1 second, the horizon of the launch time ranges
|
||||
from 1 second to 2 seconds, depending on where the Qbv cycle is currently
|
||||
running.
|
||||
|
||||
Querying Device Capabilities
|
||||
============================
|
||||
|
||||
@@ -74,6 +135,7 @@ Refer to ``xsk-flags`` features bitmask in
|
||||
|
||||
- ``tx-timestamp``: device supports ``XDP_TXMD_FLAGS_TIMESTAMP``
|
||||
- ``tx-checksum``: device supports ``XDP_TXMD_FLAGS_CHECKSUM``
|
||||
- ``tx-launch-time-fifo``: device supports ``XDP_TXMD_FLAGS_LAUNCH_TIME``
|
||||
|
||||
See ``tools/net/ynl/samples/netdev.c`` on how to query this information.
|
||||
|
||||
|
||||
@@ -311,6 +311,14 @@ to the mailing list, e.g.::
|
||||
Posting as one thread is discouraged because it confuses patchwork
|
||||
(as of patchwork 2.2.2).
|
||||
|
||||
Co-posting selftests
|
||||
--------------------
|
||||
|
||||
Selftests should be part of the same series as the code changes.
|
||||
Specifically for fixes both code change and related test should go into
|
||||
the same tree (the tests may lack a Fixes tag, which is expected).
|
||||
Mixing code changes and test changes in a single commit is discouraged.
|
||||
|
||||
Preparing changes
|
||||
-----------------
|
||||
|
||||
|
||||
10
MAINTAINERS
10
MAINTAINERS
@@ -727,7 +727,7 @@ L: linux-mediatek@lists.infradead.org (moderated for non-subscribers)
|
||||
L: netdev@vger.kernel.org
|
||||
S: Maintained
|
||||
F: Documentation/devicetree/bindings/net/airoha,en7581-eth.yaml
|
||||
F: drivers/net/ethernet/mediatek/airoha_eth.c
|
||||
F: drivers/net/ethernet/airoha/
|
||||
|
||||
AIROHA PCIE PHY DRIVER
|
||||
M: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
@@ -8623,12 +8623,14 @@ F: Documentation/networking/devlink/etas_es58x.rst
|
||||
F: drivers/net/can/usb/etas_es58x/
|
||||
|
||||
ETHERNET BRIDGE
|
||||
M: Roopa Prabhu <roopa@nvidia.com>
|
||||
M: Nikolay Aleksandrov <razor@blackwall.org>
|
||||
M: Ido Schimmel <idosch@nvidia.com>
|
||||
L: bridge@lists.linux.dev
|
||||
L: netdev@vger.kernel.org
|
||||
S: Maintained
|
||||
W: http://www.linuxfoundation.org/en/Net:Bridge
|
||||
F: include/linux/if_bridge.h
|
||||
F: include/uapi/linux/if_bridge.h
|
||||
F: include/linux/netfilter_bridge/
|
||||
F: net/bridge/
|
||||
|
||||
@@ -11942,6 +11944,7 @@ L: platform-driver-x86@vger.kernel.org
|
||||
S: Maintained
|
||||
F: Documentation/ABI/testing/sysfs-platform-intel-pmc
|
||||
F: drivers/platform/x86/intel/pmc/
|
||||
F: include/linux/platform_data/x86/intel_pmc_ipc.h
|
||||
|
||||
INTEL PMIC GPIO DRIVERS
|
||||
M: Andy Shevchenko <andy@kernel.org>
|
||||
@@ -13979,6 +13982,7 @@ L: netdev@vger.kernel.org
|
||||
S: Maintained
|
||||
F: Documentation/networking/mctp.rst
|
||||
F: drivers/net/mctp/
|
||||
F: include/linux/usb/mctp-usb.h
|
||||
F: include/net/mctp.h
|
||||
F: include/net/mctpdevice.h
|
||||
F: include/net/netns/mctp.h
|
||||
@@ -24306,7 +24310,7 @@ W: http://vtun.sourceforge.net/tun
|
||||
F: Documentation/networking/tuntap.rst
|
||||
F: arch/um/os-Linux/drivers/
|
||||
F: drivers/net/tap.c
|
||||
F: drivers/net/tun.c
|
||||
F: drivers/net/tun*
|
||||
|
||||
TURBOCHANNEL SUBSYSTEM
|
||||
M: "Maciej W. Rozycki" <macro@orcam.me.uk>
|
||||
|
||||
@@ -1781,7 +1781,6 @@
|
||||
st,syscon = <&syscfg 0x4>;
|
||||
snps,mixed-burst;
|
||||
snps,pbl = <2>;
|
||||
snps,en-tx-lpi-clockgating;
|
||||
snps,axi-config = <&stmmac_axi_config_0>;
|
||||
snps,tso;
|
||||
access-controllers = <&etzpc 94>;
|
||||
|
||||
@@ -132,16 +132,16 @@
|
||||
#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
|
||||
|
||||
#define SCM_TS_OPT_ID 0x404C
|
||||
|
||||
#define SO_RCVPRIORITY 0x404D
|
||||
|
||||
#define SO_DEVMEM_LINEAR 0x404E
|
||||
#define SCM_DEVMEM_LINEAR SO_DEVMEM_LINEAR
|
||||
#define SO_DEVMEM_DMABUF 0x404F
|
||||
#define SCM_DEVMEM_DMABUF SO_DEVMEM_DMABUF
|
||||
#define SO_DEVMEM_DONTNEED 0x4050
|
||||
|
||||
#if !defined(__KERNEL__)
|
||||
|
||||
#if __BITS_PER_LONG == 64
|
||||
|
||||
@@ -485,7 +485,6 @@ CONFIG_VIA_VELOCITY=m
|
||||
CONFIG_PCMCIA_XIRC2PS=m
|
||||
CONFIG_FDDI=y
|
||||
CONFIG_SKFP=m
|
||||
CONFIG_NET_SB1000=m
|
||||
CONFIG_BROADCOM_PHY=m
|
||||
CONFIG_CICADA_PHY=m
|
||||
CONFIG_DAVICOM_PHY=m
|
||||
|
||||
@@ -1022,7 +1022,6 @@
|
||||
snps,force_thresh_dma_mode;
|
||||
snps,axi-config = <&stmmac_axi_setup>;
|
||||
snps,tso;
|
||||
snps,en-tx-lpi-clockgating;
|
||||
snps,txpbl = <16>;
|
||||
snps,rxpbl = <16>;
|
||||
starfive,syscon = <&aon_syscon 0xc 0x12>;
|
||||
@@ -1053,7 +1052,6 @@
|
||||
snps,force_thresh_dma_mode;
|
||||
snps,axi-config = <&stmmac_axi_setup>;
|
||||
snps,tso;
|
||||
snps,en-tx-lpi-clockgating;
|
||||
snps,txpbl = <16>;
|
||||
snps,rxpbl = <16>;
|
||||
starfive,syscon = <&sys_syscon 0x90 0x2>;
|
||||
|
||||
@@ -54,7 +54,6 @@ enum interruption_class {
|
||||
IRQIO_C70,
|
||||
IRQIO_TAP,
|
||||
IRQIO_VMR,
|
||||
IRQIO_LCS,
|
||||
IRQIO_CTC,
|
||||
IRQIO_ADM,
|
||||
IRQIO_CSC,
|
||||
|
||||
@@ -84,7 +84,6 @@ static const struct irq_class irqclass_sub_desc[] = {
|
||||
{.irq = IRQIO_C70, .name = "C70", .desc = "[I/O] 3270"},
|
||||
{.irq = IRQIO_TAP, .name = "TAP", .desc = "[I/O] Tape"},
|
||||
{.irq = IRQIO_VMR, .name = "VMR", .desc = "[I/O] Unit Record Devices"},
|
||||
{.irq = IRQIO_LCS, .name = "LCS", .desc = "[I/O] LCS"},
|
||||
{.irq = IRQIO_CTC, .name = "CTC", .desc = "[I/O] CTC"},
|
||||
{.irq = IRQIO_ADM, .name = "ADM", .desc = "[I/O] EADM Subchannel"},
|
||||
{.irq = IRQIO_CSC, .name = "CSC", .desc = "[I/O] CHSC Subchannel"},
|
||||
|
||||
@@ -120,8 +120,6 @@ static const struct acpi_device_id acpi_pnp_device_ids[] = {
|
||||
{"IBM0071"},
|
||||
/* smsc-ircc2 */
|
||||
{"SMCf010"},
|
||||
/* sb1000 */
|
||||
{"GIC1000"},
|
||||
/* parport_pc */
|
||||
{"PNP0400"}, /* Standard LPT Printer Port */
|
||||
{"PNP0401"}, /* ECP Printer Port */
|
||||
|
||||
@@ -365,9 +365,8 @@ static void bfusb_rx_complete(struct urb *urb)
|
||||
buf += 3;
|
||||
}
|
||||
|
||||
if (count < len) {
|
||||
if (count < len)
|
||||
bt_dev_err(data->hdev, "block extends over URB buffer ranges");
|
||||
}
|
||||
|
||||
if ((hdr & 0xe1) == 0xc1)
|
||||
bfusb_recv_block(data, hdr, buf, len);
|
||||
|
||||
@@ -35,6 +35,11 @@ enum {
|
||||
DSM_SET_RESET_METHOD = 3,
|
||||
};
|
||||
|
||||
#define BTINTEL_BT_DOMAIN 0x12
|
||||
#define BTINTEL_SAR_LEGACY 0
|
||||
#define BTINTEL_SAR_INC_PWR 1
|
||||
#define BTINTEL_SAR_INC_PWR_SUPPORTED 0
|
||||
|
||||
#define CMD_WRITE_BOOT_PARAMS 0xfc0e
|
||||
struct cmd_write_boot_params {
|
||||
__le32 boot_addr;
|
||||
@@ -478,6 +483,7 @@ int btintel_version_info_tlv(struct hci_dev *hdev,
|
||||
case 0x1c: /* Gale Peak (GaP) */
|
||||
case 0x1d: /* BlazarU (BzrU) */
|
||||
case 0x1e: /* BlazarI (Bzr) */
|
||||
case 0x1f: /* Scorpious Peak */
|
||||
break;
|
||||
default:
|
||||
bt_dev_err(hdev, "Unsupported Intel hardware variant (0x%x)",
|
||||
@@ -2756,6 +2762,7 @@ static int btintel_set_dsbr(struct hci_dev *hdev, struct intel_version_tlv *ver)
|
||||
/* DSBR command needs to be sent for,
|
||||
* 1. BlazarI or BlazarIW + B0 step product in IML image.
|
||||
* 2. Gale Peak2 or BlazarU in OP image.
|
||||
* 3. Scorpious Peak in IML image.
|
||||
*/
|
||||
|
||||
switch (cnvi) {
|
||||
@@ -2771,6 +2778,10 @@ static int btintel_set_dsbr(struct hci_dev *hdev, struct intel_version_tlv *ver)
|
||||
hdev->bus == HCI_USB)
|
||||
break;
|
||||
return 0;
|
||||
case BTINTEL_CNVI_SCP:
|
||||
if (ver->img_type == BTINTEL_IMG_IML)
|
||||
break;
|
||||
return 0;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
@@ -2800,6 +2811,331 @@ static int btintel_set_dsbr(struct hci_dev *hdev, struct intel_version_tlv *ver)
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_ACPI
|
||||
static acpi_status btintel_evaluate_acpi_method(struct hci_dev *hdev,
|
||||
acpi_string method,
|
||||
union acpi_object **ptr,
|
||||
u8 pkg_size)
|
||||
{
|
||||
struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
|
||||
union acpi_object *p;
|
||||
acpi_status status;
|
||||
acpi_handle handle;
|
||||
|
||||
handle = ACPI_HANDLE(GET_HCIDEV_DEV(hdev));
|
||||
if (!handle) {
|
||||
bt_dev_dbg(hdev, "ACPI-BT: No ACPI support for Bluetooth device");
|
||||
return AE_NOT_EXIST;
|
||||
}
|
||||
|
||||
status = acpi_evaluate_object(handle, method, NULL, &buffer);
|
||||
|
||||
if (ACPI_FAILURE(status)) {
|
||||
bt_dev_dbg(hdev, "ACPI-BT: ACPI Failure: %s method: %s",
|
||||
acpi_format_exception(status), method);
|
||||
return status;
|
||||
}
|
||||
|
||||
p = buffer.pointer;
|
||||
|
||||
if (p->type != ACPI_TYPE_PACKAGE || p->package.count < pkg_size) {
|
||||
bt_dev_warn(hdev, "ACPI-BT: Invalid object type: %d or package count: %d",
|
||||
p->type, p->package.count);
|
||||
kfree(buffer.pointer);
|
||||
return AE_ERROR;
|
||||
}
|
||||
|
||||
*ptr = buffer.pointer;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static union acpi_object *btintel_acpi_get_bt_pkg(union acpi_object *buffer)
|
||||
{
|
||||
union acpi_object *domain, *bt_pkg;
|
||||
int i;
|
||||
|
||||
for (i = 1; i < buffer->package.count; i++) {
|
||||
bt_pkg = &buffer->package.elements[i];
|
||||
domain = &bt_pkg->package.elements[0];
|
||||
if (domain->type == ACPI_TYPE_INTEGER &&
|
||||
domain->integer.value == BTINTEL_BT_DOMAIN)
|
||||
return bt_pkg;
|
||||
}
|
||||
return ERR_PTR(-ENOENT);
|
||||
}
|
||||
|
||||
static int btintel_send_sar_ddc(struct hci_dev *hdev, struct btintel_cp_ddc_write *data, u8 len)
|
||||
{
|
||||
struct sk_buff *skb;
|
||||
|
||||
skb = __hci_cmd_sync(hdev, 0xfc8b, len, data, HCI_CMD_TIMEOUT);
|
||||
if (IS_ERR(skb)) {
|
||||
bt_dev_warn(hdev, "Failed to send sar ddc id:0x%4.4x (%ld)",
|
||||
le16_to_cpu(data->id), PTR_ERR(skb));
|
||||
return PTR_ERR(skb);
|
||||
}
|
||||
kfree_skb(skb);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int btintel_send_edr(struct hci_dev *hdev, struct btintel_cp_ddc_write *cmd,
|
||||
int id, struct btintel_sar_inc_pwr *sar)
|
||||
{
|
||||
cmd->len = 5;
|
||||
cmd->id = cpu_to_le16(id);
|
||||
cmd->data[0] = sar->br >> 3;
|
||||
cmd->data[1] = sar->edr2 >> 3;
|
||||
cmd->data[2] = sar->edr3 >> 3;
|
||||
return btintel_send_sar_ddc(hdev, cmd, 6);
|
||||
}
|
||||
|
||||
static int btintel_send_le(struct hci_dev *hdev, struct btintel_cp_ddc_write *cmd,
|
||||
int id, struct btintel_sar_inc_pwr *sar)
|
||||
{
|
||||
cmd->len = 3;
|
||||
cmd->id = cpu_to_le16(id);
|
||||
cmd->data[0] = min3(sar->le, sar->le_lr, sar->le_2mhz) >> 3;
|
||||
return btintel_send_sar_ddc(hdev, cmd, 4);
|
||||
}
|
||||
|
||||
static int btintel_send_br(struct hci_dev *hdev, struct btintel_cp_ddc_write *cmd,
|
||||
int id, struct btintel_sar_inc_pwr *sar)
|
||||
{
|
||||
cmd->len = 3;
|
||||
cmd->id = cpu_to_le16(id);
|
||||
cmd->data[0] = sar->br >> 3;
|
||||
return btintel_send_sar_ddc(hdev, cmd, 4);
|
||||
}
|
||||
|
||||
static int btintel_send_br_mutual(struct hci_dev *hdev, struct btintel_cp_ddc_write *cmd,
|
||||
int id, struct btintel_sar_inc_pwr *sar)
|
||||
{
|
||||
cmd->len = 3;
|
||||
cmd->id = cpu_to_le16(id);
|
||||
cmd->data[0] = sar->br;
|
||||
return btintel_send_sar_ddc(hdev, cmd, 4);
|
||||
}
|
||||
|
||||
static int btintel_send_edr2(struct hci_dev *hdev, struct btintel_cp_ddc_write *cmd,
|
||||
int id, struct btintel_sar_inc_pwr *sar)
|
||||
{
|
||||
cmd->len = 3;
|
||||
cmd->id = cpu_to_le16(id);
|
||||
cmd->data[0] = sar->edr2;
|
||||
return btintel_send_sar_ddc(hdev, cmd, 4);
|
||||
}
|
||||
|
||||
static int btintel_send_edr3(struct hci_dev *hdev, struct btintel_cp_ddc_write *cmd,
|
||||
int id, struct btintel_sar_inc_pwr *sar)
|
||||
{
|
||||
cmd->len = 3;
|
||||
cmd->id = cpu_to_le16(id);
|
||||
cmd->data[0] = sar->edr3;
|
||||
return btintel_send_sar_ddc(hdev, cmd, 4);
|
||||
}
|
||||
|
||||
static int btintel_set_legacy_sar(struct hci_dev *hdev, struct btintel_sar_inc_pwr *sar)
|
||||
{
|
||||
struct btintel_cp_ddc_write *cmd;
|
||||
u8 buffer[64];
|
||||
int ret;
|
||||
|
||||
cmd = (void *)buffer;
|
||||
ret = btintel_send_br(hdev, cmd, 0x0131, sar);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = btintel_send_br(hdev, cmd, 0x0132, sar);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = btintel_send_le(hdev, cmd, 0x0133, sar);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = btintel_send_edr(hdev, cmd, 0x0137, sar);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = btintel_send_edr(hdev, cmd, 0x0138, sar);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = btintel_send_edr(hdev, cmd, 0x013b, sar);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = btintel_send_edr(hdev, cmd, 0x013c, sar);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int btintel_set_mutual_sar(struct hci_dev *hdev, struct btintel_sar_inc_pwr *sar)
|
||||
{
|
||||
struct btintel_cp_ddc_write *cmd;
|
||||
struct sk_buff *skb;
|
||||
u8 buffer[64];
|
||||
bool enable;
|
||||
int ret;
|
||||
|
||||
cmd = (void *)buffer;
|
||||
|
||||
cmd->len = 3;
|
||||
cmd->id = cpu_to_le16(0x019e);
|
||||
|
||||
if (sar->revision == BTINTEL_SAR_INC_PWR &&
|
||||
sar->inc_power_mode == BTINTEL_SAR_INC_PWR_SUPPORTED)
|
||||
cmd->data[0] = 0x01;
|
||||
else
|
||||
cmd->data[0] = 0x00;
|
||||
|
||||
ret = btintel_send_sar_ddc(hdev, cmd, 4);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (sar->revision == BTINTEL_SAR_INC_PWR &&
|
||||
sar->inc_power_mode == BTINTEL_SAR_INC_PWR_SUPPORTED) {
|
||||
cmd->len = 3;
|
||||
cmd->id = cpu_to_le16(0x019f);
|
||||
cmd->data[0] = sar->sar_2400_chain_a;
|
||||
|
||||
ret = btintel_send_sar_ddc(hdev, cmd, 4);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = btintel_send_br_mutual(hdev, cmd, 0x01a0, sar);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = btintel_send_edr2(hdev, cmd, 0x01a1, sar);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = btintel_send_edr3(hdev, cmd, 0x01a2, sar);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = btintel_send_le(hdev, cmd, 0x01a3, sar);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
enable = true;
|
||||
skb = __hci_cmd_sync(hdev, 0xfe25, 1, &enable, HCI_CMD_TIMEOUT);
|
||||
if (IS_ERR(skb)) {
|
||||
bt_dev_warn(hdev, "Failed to send Intel SAR Enable (%ld)", PTR_ERR(skb));
|
||||
return PTR_ERR(skb);
|
||||
}
|
||||
|
||||
kfree_skb(skb);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int btintel_sar_send_to_device(struct hci_dev *hdev, struct btintel_sar_inc_pwr *sar,
|
||||
struct intel_version_tlv *ver)
|
||||
{
|
||||
u16 cnvi, cnvr;
|
||||
int ret;
|
||||
|
||||
cnvi = ver->cnvi_top & 0xfff;
|
||||
cnvr = ver->cnvr_top & 0xfff;
|
||||
|
||||
if (cnvi < BTINTEL_CNVI_BLAZARI && cnvr < BTINTEL_CNVR_FMP2) {
|
||||
bt_dev_info(hdev, "Applying legacy Bluetooth SAR");
|
||||
ret = btintel_set_legacy_sar(hdev, sar);
|
||||
} else if (cnvi == BTINTEL_CNVI_GAP || cnvr == BTINTEL_CNVR_FMP2) {
|
||||
bt_dev_info(hdev, "Applying mutual Bluetooth SAR");
|
||||
ret = btintel_set_mutual_sar(hdev, sar);
|
||||
} else {
|
||||
ret = -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int btintel_acpi_set_sar(struct hci_dev *hdev, struct intel_version_tlv *ver)
|
||||
{
|
||||
union acpi_object *bt_pkg, *buffer = NULL;
|
||||
struct btintel_sar_inc_pwr sar;
|
||||
acpi_status status;
|
||||
u8 revision;
|
||||
int ret;
|
||||
|
||||
status = btintel_evaluate_acpi_method(hdev, "BRDS", &buffer, 2);
|
||||
if (ACPI_FAILURE(status))
|
||||
return -ENOENT;
|
||||
|
||||
bt_pkg = btintel_acpi_get_bt_pkg(buffer);
|
||||
|
||||
if (IS_ERR(bt_pkg)) {
|
||||
ret = PTR_ERR(bt_pkg);
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (!bt_pkg->package.count) {
|
||||
ret = -EINVAL;
|
||||
goto error;
|
||||
}
|
||||
|
||||
revision = buffer->package.elements[0].integer.value;
|
||||
|
||||
if (revision > BTINTEL_SAR_INC_PWR) {
|
||||
bt_dev_dbg(hdev, "BT_SAR: revision: 0x%2.2x not supported", revision);
|
||||
ret = -EOPNOTSUPP;
|
||||
goto error;
|
||||
}
|
||||
|
||||
memset(&sar, 0, sizeof(sar));
|
||||
|
||||
if (revision == BTINTEL_SAR_LEGACY && bt_pkg->package.count == 8) {
|
||||
sar.revision = revision;
|
||||
sar.bt_sar_bios = bt_pkg->package.elements[1].integer.value;
|
||||
sar.br = bt_pkg->package.elements[2].integer.value;
|
||||
sar.edr2 = bt_pkg->package.elements[3].integer.value;
|
||||
sar.edr3 = bt_pkg->package.elements[4].integer.value;
|
||||
sar.le = bt_pkg->package.elements[5].integer.value;
|
||||
sar.le_2mhz = bt_pkg->package.elements[6].integer.value;
|
||||
sar.le_lr = bt_pkg->package.elements[7].integer.value;
|
||||
|
||||
} else if (revision == BTINTEL_SAR_INC_PWR && bt_pkg->package.count == 10) {
|
||||
sar.revision = revision;
|
||||
sar.bt_sar_bios = bt_pkg->package.elements[1].integer.value;
|
||||
sar.inc_power_mode = bt_pkg->package.elements[2].integer.value;
|
||||
sar.sar_2400_chain_a = bt_pkg->package.elements[3].integer.value;
|
||||
sar.br = bt_pkg->package.elements[4].integer.value;
|
||||
sar.edr2 = bt_pkg->package.elements[5].integer.value;
|
||||
sar.edr3 = bt_pkg->package.elements[6].integer.value;
|
||||
sar.le = bt_pkg->package.elements[7].integer.value;
|
||||
sar.le_2mhz = bt_pkg->package.elements[8].integer.value;
|
||||
sar.le_lr = bt_pkg->package.elements[9].integer.value;
|
||||
} else {
|
||||
ret = -EINVAL;
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* Apply only if it is enabled in BIOS */
|
||||
if (sar.bt_sar_bios != 1) {
|
||||
bt_dev_dbg(hdev, "Bluetooth SAR is not enabled");
|
||||
ret = -EOPNOTSUPP;
|
||||
goto error;
|
||||
}
|
||||
|
||||
ret = btintel_sar_send_to_device(hdev, &sar, ver);
|
||||
error:
|
||||
kfree(buffer);
|
||||
return ret;
|
||||
}
|
||||
#endif /* CONFIG_ACPI */
|
||||
|
||||
static int btintel_set_specific_absorption_rate(struct hci_dev *hdev,
|
||||
struct intel_version_tlv *ver)
|
||||
{
|
||||
#ifdef CONFIG_ACPI
|
||||
return btintel_acpi_set_sar(hdev, ver);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
int btintel_bootloader_setup_tlv(struct hci_dev *hdev,
|
||||
struct intel_version_tlv *ver)
|
||||
{
|
||||
@@ -2877,6 +3213,9 @@ int btintel_bootloader_setup_tlv(struct hci_dev *hdev,
|
||||
|
||||
hci_dev_clear_flag(hdev, HCI_QUALITY_REPORT);
|
||||
|
||||
/* Send sar values to controller */
|
||||
btintel_set_specific_absorption_rate(hdev, ver);
|
||||
|
||||
/* Set PPAG feature */
|
||||
btintel_set_ppag(hdev, ver);
|
||||
|
||||
@@ -2919,6 +3258,7 @@ void btintel_set_msft_opcode(struct hci_dev *hdev, u8 hw_variant)
|
||||
case 0x1c:
|
||||
case 0x1d:
|
||||
case 0x1e:
|
||||
case 0x1f:
|
||||
hci_set_msft_opcode(hdev, 0xFC1E);
|
||||
break;
|
||||
default:
|
||||
@@ -3258,6 +3598,7 @@ static int btintel_setup_combined(struct hci_dev *hdev)
|
||||
case 0x1b:
|
||||
case 0x1d:
|
||||
case 0x1e:
|
||||
case 0x1f:
|
||||
/* Display version information of TLV type */
|
||||
btintel_version_info_tlv(hdev, &ver_tlv);
|
||||
|
||||
|
||||
@@ -56,6 +56,10 @@ struct intel_tlv {
|
||||
#define BTINTEL_CNVI_BLAZARIW 0x901
|
||||
#define BTINTEL_CNVI_GAP 0x910
|
||||
#define BTINTEL_CNVI_BLAZARU 0x930
|
||||
#define BTINTEL_CNVI_SCP 0xA00
|
||||
|
||||
/* CNVR */
|
||||
#define BTINTEL_CNVR_FMP2 0x910
|
||||
|
||||
#define BTINTEL_IMG_BOOTLOADER 0x01 /* Bootloader image */
|
||||
#define BTINTEL_IMG_IML 0x02 /* Intermediate image */
|
||||
@@ -164,6 +168,26 @@ struct hci_ppag_enable_cmd {
|
||||
#define INTEL_TLV_DEBUG_EXCEPTION 0x02
|
||||
#define INTEL_TLV_TEST_EXCEPTION 0xDE
|
||||
|
||||
struct btintel_cp_ddc_write {
|
||||
u8 len;
|
||||
__le16 id;
|
||||
u8 data[];
|
||||
} __packed;
|
||||
|
||||
/* Bluetooth SAR feature (BRDS), Revision 1 */
|
||||
struct btintel_sar_inc_pwr {
|
||||
u8 revision;
|
||||
u32 bt_sar_bios; /* Mode of SAR control to be used, 1:enabled in bios */
|
||||
u32 inc_power_mode; /* Increased power mode */
|
||||
u8 sar_2400_chain_a; /* Sar power restriction LB */
|
||||
u8 br;
|
||||
u8 edr2;
|
||||
u8 edr3;
|
||||
u8 le;
|
||||
u8 le_2mhz;
|
||||
u8 le_lr;
|
||||
};
|
||||
|
||||
#define INTEL_HW_PLATFORM(cnvx_bt) ((u8)(((cnvx_bt) & 0x0000ff00) >> 8))
|
||||
#define INTEL_HW_VARIANT(cnvx_bt) ((u8)(((cnvx_bt) & 0x003f0000) >> 16))
|
||||
#define INTEL_CNVX_TOP_TYPE(cnvx_top) ((cnvx_top) & 0x00000fff)
|
||||
|
||||
@@ -36,6 +36,7 @@
|
||||
/* Intel Bluetooth PCIe device id table */
|
||||
static const struct pci_device_id btintel_pcie_table[] = {
|
||||
{ BTINTEL_PCI_DEVICE(0xA876, PCI_ANY_ID) },
|
||||
{ BTINTEL_PCI_DEVICE(0xE476, PCI_ANY_ID) },
|
||||
{ 0 }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(pci, btintel_pcie_table);
|
||||
@@ -48,6 +49,19 @@ MODULE_DEVICE_TABLE(pci, btintel_pcie_table);
|
||||
#define BTINTEL_PCIE_HCI_EVT_PKT 0x00000004
|
||||
#define BTINTEL_PCIE_HCI_ISO_PKT 0x00000005
|
||||
|
||||
#define BTINTEL_PCIE_MAGIC_NUM 0xA5A5A5A5
|
||||
|
||||
#define BTINTEL_PCIE_BLZR_HWEXP_SIZE 1024
|
||||
#define BTINTEL_PCIE_BLZR_HWEXP_DMP_ADDR 0xB00A7C00
|
||||
|
||||
#define BTINTEL_PCIE_SCP_HWEXP_SIZE 4096
|
||||
#define BTINTEL_PCIE_SCP_HWEXP_DMP_ADDR 0xB030F800
|
||||
|
||||
#define BTINTEL_PCIE_MAGIC_NUM 0xA5A5A5A5
|
||||
|
||||
#define BTINTEL_PCIE_TRIGGER_REASON_USER_TRIGGER 0x17A2
|
||||
#define BTINTEL_PCIE_TRIGGER_REASON_FW_ASSERT 0x1E61
|
||||
|
||||
/* Alive interrupt context */
|
||||
enum {
|
||||
BTINTEL_PCIE_ROM,
|
||||
@@ -59,6 +73,83 @@ enum {
|
||||
BTINTEL_PCIE_D3
|
||||
};
|
||||
|
||||
/* Structure for dbgc fragment buffer
|
||||
* @buf_addr_lsb: LSB of the buffer's physical address
|
||||
* @buf_addr_msb: MSB of the buffer's physical address
|
||||
* @buf_size: Total size of the buffer
|
||||
*/
|
||||
struct btintel_pcie_dbgc_ctxt_buf {
|
||||
u32 buf_addr_lsb;
|
||||
u32 buf_addr_msb;
|
||||
u32 buf_size;
|
||||
};
|
||||
|
||||
/* Structure for dbgc fragment
|
||||
* @magic_num: 0XA5A5A5A5
|
||||
* @ver: For Driver-FW compatibility
|
||||
* @total_size: Total size of the payload debug info
|
||||
* @num_buf: Num of allocated debug bufs
|
||||
* @bufs: All buffer's addresses and sizes
|
||||
*/
|
||||
struct btintel_pcie_dbgc_ctxt {
|
||||
u32 magic_num;
|
||||
u32 ver;
|
||||
u32 total_size;
|
||||
u32 num_buf;
|
||||
struct btintel_pcie_dbgc_ctxt_buf bufs[BTINTEL_PCIE_DBGC_BUFFER_COUNT];
|
||||
};
|
||||
|
||||
/* This function initializes the memory for DBGC buffers and formats the
|
||||
* DBGC fragment which consists header info and DBGC buffer's LSB, MSB and
|
||||
* size as the payload
|
||||
*/
|
||||
static int btintel_pcie_setup_dbgc(struct btintel_pcie_data *data)
|
||||
{
|
||||
struct btintel_pcie_dbgc_ctxt db_frag;
|
||||
struct data_buf *buf;
|
||||
int i;
|
||||
|
||||
data->dbgc.count = BTINTEL_PCIE_DBGC_BUFFER_COUNT;
|
||||
data->dbgc.bufs = devm_kcalloc(&data->pdev->dev, data->dbgc.count,
|
||||
sizeof(*buf), GFP_KERNEL);
|
||||
if (!data->dbgc.bufs)
|
||||
return -ENOMEM;
|
||||
|
||||
data->dbgc.buf_v_addr = dmam_alloc_coherent(&data->pdev->dev,
|
||||
data->dbgc.count *
|
||||
BTINTEL_PCIE_DBGC_BUFFER_SIZE,
|
||||
&data->dbgc.buf_p_addr,
|
||||
GFP_KERNEL | __GFP_NOWARN);
|
||||
if (!data->dbgc.buf_v_addr)
|
||||
return -ENOMEM;
|
||||
|
||||
data->dbgc.frag_v_addr = dmam_alloc_coherent(&data->pdev->dev,
|
||||
sizeof(struct btintel_pcie_dbgc_ctxt),
|
||||
&data->dbgc.frag_p_addr,
|
||||
GFP_KERNEL | __GFP_NOWARN);
|
||||
if (!data->dbgc.frag_v_addr)
|
||||
return -ENOMEM;
|
||||
|
||||
data->dbgc.frag_size = sizeof(struct btintel_pcie_dbgc_ctxt);
|
||||
|
||||
db_frag.magic_num = BTINTEL_PCIE_MAGIC_NUM;
|
||||
db_frag.ver = BTINTEL_PCIE_DBGC_FRAG_VERSION;
|
||||
db_frag.total_size = BTINTEL_PCIE_DBGC_FRAG_PAYLOAD_SIZE;
|
||||
db_frag.num_buf = BTINTEL_PCIE_DBGC_FRAG_BUFFER_COUNT;
|
||||
|
||||
for (i = 0; i < data->dbgc.count; i++) {
|
||||
buf = &data->dbgc.bufs[i];
|
||||
buf->data_p_addr = data->dbgc.buf_p_addr + i * BTINTEL_PCIE_DBGC_BUFFER_SIZE;
|
||||
buf->data = data->dbgc.buf_v_addr + i * BTINTEL_PCIE_DBGC_BUFFER_SIZE;
|
||||
db_frag.bufs[i].buf_addr_lsb = lower_32_bits(buf->data_p_addr);
|
||||
db_frag.bufs[i].buf_addr_msb = upper_32_bits(buf->data_p_addr);
|
||||
db_frag.bufs[i].buf_size = BTINTEL_PCIE_DBGC_BUFFER_SIZE;
|
||||
}
|
||||
|
||||
memcpy(data->dbgc.frag_v_addr, &db_frag, sizeof(db_frag));
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline void ipc_print_ia_ring(struct hci_dev *hdev, struct ia *ia,
|
||||
u16 queue_num)
|
||||
{
|
||||
@@ -273,6 +364,271 @@ static int btintel_pcie_reset_bt(struct btintel_pcie_data *data)
|
||||
return reg == 0 ? 0 : -ENODEV;
|
||||
}
|
||||
|
||||
static void btintel_pcie_mac_init(struct btintel_pcie_data *data)
|
||||
{
|
||||
u32 reg;
|
||||
|
||||
/* Set MAC_INIT bit to start primary bootloader */
|
||||
reg = btintel_pcie_rd_reg32(data, BTINTEL_PCIE_CSR_FUNC_CTRL_REG);
|
||||
reg &= ~(BTINTEL_PCIE_CSR_FUNC_CTRL_FUNC_INIT |
|
||||
BTINTEL_PCIE_CSR_FUNC_CTRL_BUS_MASTER_DISCON |
|
||||
BTINTEL_PCIE_CSR_FUNC_CTRL_SW_RESET);
|
||||
reg |= (BTINTEL_PCIE_CSR_FUNC_CTRL_FUNC_ENA |
|
||||
BTINTEL_PCIE_CSR_FUNC_CTRL_MAC_INIT);
|
||||
btintel_pcie_wr_reg32(data, BTINTEL_PCIE_CSR_FUNC_CTRL_REG, reg);
|
||||
}
|
||||
|
||||
static int btintel_pcie_add_dmp_data(struct hci_dev *hdev, const void *data, int size)
|
||||
{
|
||||
struct sk_buff *skb;
|
||||
int err;
|
||||
|
||||
skb = alloc_skb(size, GFP_ATOMIC);
|
||||
if (!skb)
|
||||
return -ENOMEM;
|
||||
|
||||
skb_put_data(skb, data, size);
|
||||
err = hci_devcd_append(hdev, skb);
|
||||
if (err) {
|
||||
bt_dev_err(hdev, "Failed to append data in the coredump");
|
||||
return err;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int btintel_pcie_get_mac_access(struct btintel_pcie_data *data)
|
||||
{
|
||||
u32 reg;
|
||||
int retry = 15;
|
||||
|
||||
reg = btintel_pcie_rd_reg32(data, BTINTEL_PCIE_CSR_FUNC_CTRL_REG);
|
||||
|
||||
reg |= BTINTEL_PCIE_CSR_FUNC_CTRL_STOP_MAC_ACCESS_DIS;
|
||||
reg |= BTINTEL_PCIE_CSR_FUNC_CTRL_XTAL_CLK_REQ;
|
||||
if ((reg & BTINTEL_PCIE_CSR_FUNC_CTRL_MAC_ACCESS_STS) == 0)
|
||||
reg |= BTINTEL_PCIE_CSR_FUNC_CTRL_MAC_ACCESS_REQ;
|
||||
|
||||
btintel_pcie_wr_reg32(data, BTINTEL_PCIE_CSR_FUNC_CTRL_REG, reg);
|
||||
|
||||
do {
|
||||
reg = btintel_pcie_rd_reg32(data, BTINTEL_PCIE_CSR_FUNC_CTRL_REG);
|
||||
if (reg & BTINTEL_PCIE_CSR_FUNC_CTRL_MAC_ACCESS_STS)
|
||||
return 0;
|
||||
/* Need delay here for Target Access harwdware to settle down*/
|
||||
usleep_range(1000, 1200);
|
||||
|
||||
} while (--retry > 0);
|
||||
|
||||
return -ETIME;
|
||||
}
|
||||
|
||||
static void btintel_pcie_release_mac_access(struct btintel_pcie_data *data)
|
||||
{
|
||||
u32 reg;
|
||||
|
||||
reg = btintel_pcie_rd_reg32(data, BTINTEL_PCIE_CSR_FUNC_CTRL_REG);
|
||||
|
||||
if (reg & BTINTEL_PCIE_CSR_FUNC_CTRL_MAC_ACCESS_REQ)
|
||||
reg &= ~BTINTEL_PCIE_CSR_FUNC_CTRL_MAC_ACCESS_REQ;
|
||||
|
||||
if (reg & BTINTEL_PCIE_CSR_FUNC_CTRL_STOP_MAC_ACCESS_DIS)
|
||||
reg &= ~BTINTEL_PCIE_CSR_FUNC_CTRL_STOP_MAC_ACCESS_DIS;
|
||||
|
||||
if (reg & BTINTEL_PCIE_CSR_FUNC_CTRL_XTAL_CLK_REQ)
|
||||
reg &= ~BTINTEL_PCIE_CSR_FUNC_CTRL_XTAL_CLK_REQ;
|
||||
|
||||
btintel_pcie_wr_reg32(data, BTINTEL_PCIE_CSR_FUNC_CTRL_REG, reg);
|
||||
}
|
||||
|
||||
static void btintel_pcie_copy_tlv(struct sk_buff *skb, enum btintel_pcie_tlv_type type,
|
||||
void *data, int size)
|
||||
{
|
||||
struct intel_tlv *tlv;
|
||||
|
||||
tlv = skb_put(skb, sizeof(*tlv) + size);
|
||||
tlv->type = type;
|
||||
tlv->len = size;
|
||||
memcpy(tlv->val, data, tlv->len);
|
||||
}
|
||||
|
||||
static int btintel_pcie_read_dram_buffers(struct btintel_pcie_data *data)
|
||||
{
|
||||
u32 offset, prev_size, wr_ptr_status, dump_size, i;
|
||||
struct btintel_pcie_dbgc *dbgc = &data->dbgc;
|
||||
u8 buf_idx, dump_time_len, fw_build;
|
||||
struct hci_dev *hdev = data->hdev;
|
||||
struct intel_tlv *tlv;
|
||||
struct timespec64 now;
|
||||
struct sk_buff *skb;
|
||||
struct tm tm_now;
|
||||
char buf[256];
|
||||
u16 hdr_len;
|
||||
int ret;
|
||||
|
||||
wr_ptr_status = btintel_pcie_rd_dev_mem(data, BTINTEL_PCIE_DBGC_CUR_DBGBUFF_STATUS);
|
||||
offset = wr_ptr_status & BTINTEL_PCIE_DBG_OFFSET_BIT_MASK;
|
||||
|
||||
buf_idx = BTINTEL_PCIE_DBGC_DBG_BUF_IDX(wr_ptr_status);
|
||||
if (buf_idx > dbgc->count) {
|
||||
bt_dev_warn(hdev, "Buffer index is invalid");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
prev_size = buf_idx * BTINTEL_PCIE_DBGC_BUFFER_SIZE;
|
||||
if (prev_size + offset >= prev_size)
|
||||
data->dmp_hdr.write_ptr = prev_size + offset;
|
||||
else
|
||||
return -EINVAL;
|
||||
|
||||
ktime_get_real_ts64(&now);
|
||||
time64_to_tm(now.tv_sec, 0, &tm_now);
|
||||
dump_time_len = snprintf(buf, sizeof(buf), "Dump Time: %02d-%02d-%04ld %02d:%02d:%02d",
|
||||
tm_now.tm_mday, tm_now.tm_mon + 1, tm_now.tm_year + 1900,
|
||||
tm_now.tm_hour, tm_now.tm_min, tm_now.tm_sec);
|
||||
|
||||
fw_build = snprintf(buf + dump_time_len, sizeof(buf) - dump_time_len,
|
||||
"Firmware Timestamp: Year %u WW %02u buildtype %u build %u",
|
||||
2000 + (data->dmp_hdr.fw_timestamp >> 8),
|
||||
data->dmp_hdr.fw_timestamp & 0xff, data->dmp_hdr.fw_build_type,
|
||||
data->dmp_hdr.fw_build_num);
|
||||
|
||||
hdr_len = sizeof(*tlv) + sizeof(data->dmp_hdr.cnvi_bt) +
|
||||
sizeof(*tlv) + sizeof(data->dmp_hdr.write_ptr) +
|
||||
sizeof(*tlv) + sizeof(data->dmp_hdr.wrap_ctr) +
|
||||
sizeof(*tlv) + sizeof(data->dmp_hdr.trigger_reason) +
|
||||
sizeof(*tlv) + sizeof(data->dmp_hdr.fw_git_sha1) +
|
||||
sizeof(*tlv) + sizeof(data->dmp_hdr.cnvr_top) +
|
||||
sizeof(*tlv) + sizeof(data->dmp_hdr.cnvi_top) +
|
||||
sizeof(*tlv) + dump_time_len +
|
||||
sizeof(*tlv) + fw_build;
|
||||
|
||||
dump_size = hdr_len + sizeof(hdr_len);
|
||||
|
||||
skb = alloc_skb(dump_size, GFP_KERNEL);
|
||||
if (!skb)
|
||||
return -ENOMEM;
|
||||
|
||||
/* Add debug buffers data length to dump size */
|
||||
dump_size += BTINTEL_PCIE_DBGC_BUFFER_SIZE * dbgc->count;
|
||||
|
||||
ret = hci_devcd_init(hdev, dump_size);
|
||||
if (ret) {
|
||||
bt_dev_err(hdev, "Failed to init devcoredump, err %d", ret);
|
||||
kfree_skb(skb);
|
||||
return ret;
|
||||
}
|
||||
|
||||
skb_put_data(skb, &hdr_len, sizeof(hdr_len));
|
||||
|
||||
btintel_pcie_copy_tlv(skb, BTINTEL_CNVI_BT, &data->dmp_hdr.cnvi_bt,
|
||||
sizeof(data->dmp_hdr.cnvi_bt));
|
||||
|
||||
btintel_pcie_copy_tlv(skb, BTINTEL_WRITE_PTR, &data->dmp_hdr.write_ptr,
|
||||
sizeof(data->dmp_hdr.write_ptr));
|
||||
|
||||
data->dmp_hdr.wrap_ctr = btintel_pcie_rd_dev_mem(data,
|
||||
BTINTEL_PCIE_DBGC_DBGBUFF_WRAP_ARND);
|
||||
|
||||
btintel_pcie_copy_tlv(skb, BTINTEL_WRAP_CTR, &data->dmp_hdr.wrap_ctr,
|
||||
sizeof(data->dmp_hdr.wrap_ctr));
|
||||
|
||||
btintel_pcie_copy_tlv(skb, BTINTEL_TRIGGER_REASON, &data->dmp_hdr.trigger_reason,
|
||||
sizeof(data->dmp_hdr.trigger_reason));
|
||||
|
||||
btintel_pcie_copy_tlv(skb, BTINTEL_FW_SHA, &data->dmp_hdr.fw_git_sha1,
|
||||
sizeof(data->dmp_hdr.fw_git_sha1));
|
||||
|
||||
btintel_pcie_copy_tlv(skb, BTINTEL_CNVR_TOP, &data->dmp_hdr.cnvr_top,
|
||||
sizeof(data->dmp_hdr.cnvr_top));
|
||||
|
||||
btintel_pcie_copy_tlv(skb, BTINTEL_CNVI_TOP, &data->dmp_hdr.cnvi_top,
|
||||
sizeof(data->dmp_hdr.cnvi_top));
|
||||
|
||||
btintel_pcie_copy_tlv(skb, BTINTEL_DUMP_TIME, buf, dump_time_len);
|
||||
|
||||
btintel_pcie_copy_tlv(skb, BTINTEL_FW_BUILD, buf + dump_time_len, fw_build);
|
||||
|
||||
ret = hci_devcd_append(hdev, skb);
|
||||
if (ret)
|
||||
goto exit_err;
|
||||
|
||||
for (i = 0; i < dbgc->count; i++) {
|
||||
ret = btintel_pcie_add_dmp_data(hdev, dbgc->bufs[i].data,
|
||||
BTINTEL_PCIE_DBGC_BUFFER_SIZE);
|
||||
if (ret)
|
||||
break;
|
||||
}
|
||||
|
||||
exit_err:
|
||||
hci_devcd_complete(hdev);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void btintel_pcie_dump_traces(struct hci_dev *hdev)
|
||||
{
|
||||
struct btintel_pcie_data *data = hci_get_drvdata(hdev);
|
||||
int ret = 0;
|
||||
|
||||
ret = btintel_pcie_get_mac_access(data);
|
||||
if (ret) {
|
||||
bt_dev_err(hdev, "Failed to get mac access: (%d)", ret);
|
||||
return;
|
||||
}
|
||||
|
||||
ret = btintel_pcie_read_dram_buffers(data);
|
||||
|
||||
btintel_pcie_release_mac_access(data);
|
||||
|
||||
if (ret)
|
||||
bt_dev_err(hdev, "Failed to dump traces: (%d)", ret);
|
||||
}
|
||||
|
||||
static void btintel_pcie_dump_hdr(struct hci_dev *hdev, struct sk_buff *skb)
|
||||
{
|
||||
struct btintel_pcie_data *data = hci_get_drvdata(hdev);
|
||||
u16 len = skb->len;
|
||||
u16 *hdrlen_ptr;
|
||||
char buf[80];
|
||||
|
||||
hdrlen_ptr = skb_put_zero(skb, sizeof(len));
|
||||
|
||||
snprintf(buf, sizeof(buf), "Controller Name: 0x%X\n",
|
||||
INTEL_HW_VARIANT(data->dmp_hdr.cnvi_bt));
|
||||
skb_put_data(skb, buf, strlen(buf));
|
||||
|
||||
snprintf(buf, sizeof(buf), "Firmware Build Number: %u\n",
|
||||
data->dmp_hdr.fw_build_num);
|
||||
skb_put_data(skb, buf, strlen(buf));
|
||||
|
||||
snprintf(buf, sizeof(buf), "Driver: %s\n", data->dmp_hdr.driver_name);
|
||||
skb_put_data(skb, buf, strlen(buf));
|
||||
|
||||
snprintf(buf, sizeof(buf), "Vendor: Intel\n");
|
||||
skb_put_data(skb, buf, strlen(buf));
|
||||
|
||||
*hdrlen_ptr = skb->len - len;
|
||||
}
|
||||
|
||||
static void btintel_pcie_dump_notify(struct hci_dev *hdev, int state)
|
||||
{
|
||||
struct btintel_pcie_data *data = hci_get_drvdata(hdev);
|
||||
|
||||
switch (state) {
|
||||
case HCI_DEVCOREDUMP_IDLE:
|
||||
data->dmp_hdr.state = HCI_DEVCOREDUMP_IDLE;
|
||||
break;
|
||||
case HCI_DEVCOREDUMP_ACTIVE:
|
||||
data->dmp_hdr.state = HCI_DEVCOREDUMP_ACTIVE;
|
||||
break;
|
||||
case HCI_DEVCOREDUMP_TIMEOUT:
|
||||
case HCI_DEVCOREDUMP_ABORT:
|
||||
case HCI_DEVCOREDUMP_DONE:
|
||||
data->dmp_hdr.state = HCI_DEVCOREDUMP_IDLE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* This function enables BT function by setting BTINTEL_PCIE_CSR_FUNC_CTRL_MAC_INIT bit in
|
||||
* BTINTEL_PCIE_CSR_FUNC_CTRL_REG register and wait for MSI-X with
|
||||
* BTINTEL_PCIE_MSIX_HW_INT_CAUSES_GP0.
|
||||
@@ -329,20 +685,6 @@ static int btintel_pcie_enable_bt(struct btintel_pcie_data *data)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* BIT(0) - ROM, BIT(1) - IML and BIT(3) - OP
|
||||
* Sometimes during firmware image switching from ROM to IML or IML to OP image,
|
||||
* the previous image bit is not cleared by firmware when alive interrupt is
|
||||
* received. Driver needs to take care of these sticky bits when deciding the
|
||||
* current image running on controller.
|
||||
* Ex: 0x10 and 0x11 - both represents that controller is running IML
|
||||
*/
|
||||
static inline bool btintel_pcie_in_rom(struct btintel_pcie_data *data)
|
||||
{
|
||||
return data->boot_stage_cache & BTINTEL_PCIE_CSR_BOOT_STAGE_ROM &&
|
||||
!(data->boot_stage_cache & BTINTEL_PCIE_CSR_BOOT_STAGE_IML) &&
|
||||
!(data->boot_stage_cache & BTINTEL_PCIE_CSR_BOOT_STAGE_OPFW);
|
||||
}
|
||||
|
||||
static inline bool btintel_pcie_in_op(struct btintel_pcie_data *data)
|
||||
{
|
||||
return data->boot_stage_cache & BTINTEL_PCIE_CSR_BOOT_STAGE_OPFW;
|
||||
@@ -393,6 +735,27 @@ static inline char *btintel_pcie_alivectxt_state2str(u32 alive_intr_ctxt)
|
||||
}
|
||||
}
|
||||
|
||||
static int btintel_pcie_read_device_mem(struct btintel_pcie_data *data,
|
||||
void *buf, u32 dev_addr, int len)
|
||||
{
|
||||
int err;
|
||||
u32 *val = buf;
|
||||
|
||||
/* Get device mac access */
|
||||
err = btintel_pcie_get_mac_access(data);
|
||||
if (err) {
|
||||
bt_dev_err(data->hdev, "Failed to get mac access %d", err);
|
||||
return err;
|
||||
}
|
||||
|
||||
for (; len > 0; len -= 4, dev_addr += 4, val++)
|
||||
*val = btintel_pcie_rd_dev_mem(data, dev_addr);
|
||||
|
||||
btintel_pcie_release_mac_access(data);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* This function handles the MSI-X interrupt for gp0 cause (bit 0 in
|
||||
* BTINTEL_PCIE_CSR_MSIX_HW_INT_CAUSES) which is sent for boot stage and image response.
|
||||
*/
|
||||
@@ -714,6 +1077,126 @@ exit_error:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void btintel_pcie_read_hwexp(struct btintel_pcie_data *data)
|
||||
{
|
||||
int len, err, offset, pending;
|
||||
struct sk_buff *skb;
|
||||
u8 *buf, prefix[64];
|
||||
u32 addr, val;
|
||||
u16 pkt_len;
|
||||
|
||||
struct tlv {
|
||||
u8 type;
|
||||
__le16 len;
|
||||
u8 val[];
|
||||
} __packed;
|
||||
|
||||
struct tlv *tlv;
|
||||
|
||||
switch (data->dmp_hdr.cnvi_top & 0xfff) {
|
||||
case BTINTEL_CNVI_BLAZARI:
|
||||
case BTINTEL_CNVI_BLAZARIW:
|
||||
/* only from step B0 onwards */
|
||||
if (INTEL_CNVX_TOP_STEP(data->dmp_hdr.cnvi_top) != 0x01)
|
||||
return;
|
||||
len = BTINTEL_PCIE_BLZR_HWEXP_SIZE; /* exception data length */
|
||||
addr = BTINTEL_PCIE_BLZR_HWEXP_DMP_ADDR;
|
||||
break;
|
||||
case BTINTEL_CNVI_SCP:
|
||||
len = BTINTEL_PCIE_SCP_HWEXP_SIZE;
|
||||
addr = BTINTEL_PCIE_SCP_HWEXP_DMP_ADDR;
|
||||
break;
|
||||
default:
|
||||
bt_dev_err(data->hdev, "Unsupported cnvi 0x%8.8x", data->dmp_hdr.cnvi_top);
|
||||
return;
|
||||
}
|
||||
|
||||
buf = kzalloc(len, GFP_KERNEL);
|
||||
if (!buf)
|
||||
goto exit_on_error;
|
||||
|
||||
btintel_pcie_mac_init(data);
|
||||
|
||||
err = btintel_pcie_read_device_mem(data, buf, addr, len);
|
||||
if (err)
|
||||
goto exit_on_error;
|
||||
|
||||
val = get_unaligned_le32(buf);
|
||||
if (val != BTINTEL_PCIE_MAGIC_NUM) {
|
||||
bt_dev_err(data->hdev, "Invalid exception dump signature: 0x%8.8x",
|
||||
val);
|
||||
goto exit_on_error;
|
||||
}
|
||||
|
||||
snprintf(prefix, sizeof(prefix), "Bluetooth: %s: ", bt_dev_name(data->hdev));
|
||||
|
||||
offset = 4;
|
||||
do {
|
||||
pending = len - offset;
|
||||
if (pending < sizeof(*tlv))
|
||||
break;
|
||||
tlv = (struct tlv *)(buf + offset);
|
||||
|
||||
/* If type == 0, then there are no more TLVs to be parsed */
|
||||
if (!tlv->type) {
|
||||
bt_dev_dbg(data->hdev, "Invalid TLV type 0");
|
||||
break;
|
||||
}
|
||||
pkt_len = le16_to_cpu(tlv->len);
|
||||
offset += sizeof(*tlv);
|
||||
pending = len - offset;
|
||||
if (pkt_len > pending)
|
||||
break;
|
||||
|
||||
offset += pkt_len;
|
||||
|
||||
/* Only TLVs of type == 1 are HCI events, no need to process other
|
||||
* TLVs
|
||||
*/
|
||||
if (tlv->type != 1)
|
||||
continue;
|
||||
|
||||
bt_dev_dbg(data->hdev, "TLV packet length: %u", pkt_len);
|
||||
if (pkt_len > HCI_MAX_EVENT_SIZE)
|
||||
break;
|
||||
skb = bt_skb_alloc(pkt_len, GFP_KERNEL);
|
||||
if (!skb)
|
||||
goto exit_on_error;
|
||||
hci_skb_pkt_type(skb) = HCI_EVENT_PKT;
|
||||
skb_put_data(skb, tlv->val, pkt_len);
|
||||
|
||||
/* copy Intel specific pcie packet type */
|
||||
val = BTINTEL_PCIE_HCI_EVT_PKT;
|
||||
memcpy(skb_push(skb, BTINTEL_PCIE_HCI_TYPE_LEN), &val,
|
||||
BTINTEL_PCIE_HCI_TYPE_LEN);
|
||||
|
||||
print_hex_dump(KERN_DEBUG, prefix, DUMP_PREFIX_OFFSET, 16, 1,
|
||||
tlv->val, pkt_len, false);
|
||||
|
||||
btintel_pcie_recv_frame(data, skb);
|
||||
} while (offset < len);
|
||||
|
||||
exit_on_error:
|
||||
kfree(buf);
|
||||
}
|
||||
|
||||
static void btintel_pcie_msix_hw_exp_handler(struct btintel_pcie_data *data)
|
||||
{
|
||||
bt_dev_err(data->hdev, "Received hw exception interrupt");
|
||||
|
||||
if (test_and_set_bit(BTINTEL_PCIE_CORE_HALTED, &data->flags))
|
||||
return;
|
||||
|
||||
if (test_and_set_bit(BTINTEL_PCIE_HWEXP_INPROGRESS, &data->flags))
|
||||
return;
|
||||
|
||||
/* Trigger device core dump when there is HW exception */
|
||||
if (!test_and_set_bit(BTINTEL_PCIE_COREDUMP_INPROGRESS, &data->flags))
|
||||
data->dmp_hdr.trigger_reason = BTINTEL_PCIE_TRIGGER_REASON_FW_ASSERT;
|
||||
|
||||
queue_work(data->workqueue, &data->rx_work);
|
||||
}
|
||||
|
||||
static void btintel_pcie_rx_work(struct work_struct *work)
|
||||
{
|
||||
struct btintel_pcie_data *data = container_of(work,
|
||||
@@ -722,6 +1205,23 @@ static void btintel_pcie_rx_work(struct work_struct *work)
|
||||
int err;
|
||||
struct hci_dev *hdev = data->hdev;
|
||||
|
||||
if (test_bit(BTINTEL_PCIE_HWEXP_INPROGRESS, &data->flags)) {
|
||||
/* Unlike usb products, controller will not send hardware
|
||||
* exception event on exception. Instead controller writes the
|
||||
* hardware event to device memory along with optional debug
|
||||
* events, raises MSIX and halts. Driver shall read the
|
||||
* exception event from device memory and passes it stack for
|
||||
* further processing.
|
||||
*/
|
||||
btintel_pcie_read_hwexp(data);
|
||||
clear_bit(BTINTEL_PCIE_HWEXP_INPROGRESS, &data->flags);
|
||||
}
|
||||
|
||||
if (test_bit(BTINTEL_PCIE_COREDUMP_INPROGRESS, &data->flags)) {
|
||||
btintel_pcie_dump_traces(data->hdev);
|
||||
clear_bit(BTINTEL_PCIE_COREDUMP_INPROGRESS, &data->flags);
|
||||
}
|
||||
|
||||
/* Process the sk_buf in queue and send to the HCI layer */
|
||||
while ((skb = skb_dequeue(&data->rx_skb_q))) {
|
||||
err = btintel_pcie_recv_frame(data, skb);
|
||||
@@ -840,6 +1340,10 @@ static irqreturn_t btintel_pcie_irq_msix_handler(int irq, void *dev_id)
|
||||
return IRQ_NONE;
|
||||
}
|
||||
|
||||
/* This interrupt is raised when there is an hardware exception */
|
||||
if (intr_hw & BTINTEL_PCIE_MSIX_HW_INT_CAUSES_HWEXP)
|
||||
btintel_pcie_msix_hw_exp_handler(data);
|
||||
|
||||
/* This interrupt is triggered by the firmware after updating
|
||||
* boot_stage register and image_response register
|
||||
*/
|
||||
@@ -920,7 +1424,8 @@ struct btintel_pcie_causes_list {
|
||||
static struct btintel_pcie_causes_list causes_list[] = {
|
||||
{ BTINTEL_PCIE_MSIX_FH_INT_CAUSES_0, BTINTEL_PCIE_CSR_MSIX_FH_INT_MASK, 0x00 },
|
||||
{ BTINTEL_PCIE_MSIX_FH_INT_CAUSES_1, BTINTEL_PCIE_CSR_MSIX_FH_INT_MASK, 0x01 },
|
||||
{ BTINTEL_PCIE_MSIX_HW_INT_CAUSES_GP0, BTINTEL_PCIE_CSR_MSIX_HW_INT_MASK, 0x20 },
|
||||
{ BTINTEL_PCIE_MSIX_HW_INT_CAUSES_GP0, BTINTEL_PCIE_CSR_MSIX_HW_INT_MASK, 0x20 },
|
||||
{ BTINTEL_PCIE_MSIX_HW_INT_CAUSES_HWEXP, BTINTEL_PCIE_CSR_MSIX_HW_INT_MASK, 0x23 },
|
||||
};
|
||||
|
||||
/* This function configures the interrupt masks for both HW_INT_CAUSES and
|
||||
@@ -1007,6 +1512,11 @@ static void btintel_pcie_init_ci(struct btintel_pcie_data *data,
|
||||
ci->addr_urbdq1 = data->rxq.urbd1s_p_addr;
|
||||
ci->num_urbdq1 = data->rxq.count;
|
||||
ci->urbdq_db_vec = BTINTEL_PCIE_RXQ_NUM;
|
||||
|
||||
ci->dbg_output_mode = 0x01;
|
||||
ci->dbgc_addr = data->dbgc.frag_p_addr;
|
||||
ci->dbgc_size = data->dbgc.frag_size;
|
||||
ci->dbg_preset = 0x00;
|
||||
}
|
||||
|
||||
static void btintel_pcie_free_txq_bufs(struct btintel_pcie_data *data,
|
||||
@@ -1219,6 +1729,11 @@ static int btintel_pcie_alloc(struct btintel_pcie_data *data)
|
||||
/* Setup Index Array */
|
||||
btintel_pcie_setup_ia(data, p_addr, v_addr, &data->ia);
|
||||
|
||||
/* Setup data buffers for dbgc */
|
||||
err = btintel_pcie_setup_dbgc(data);
|
||||
if (err)
|
||||
goto exit_error_txq;
|
||||
|
||||
/* Setup Context Information */
|
||||
p_addr += sizeof(u16) * BTINTEL_PCIE_NUM_QUEUES * 4;
|
||||
v_addr += sizeof(u16) * BTINTEL_PCIE_NUM_QUEUES * 4;
|
||||
@@ -1392,6 +1907,7 @@ static void btintel_pcie_release_hdev(struct btintel_pcie_data *data)
|
||||
|
||||
static int btintel_pcie_setup_internal(struct hci_dev *hdev)
|
||||
{
|
||||
struct btintel_pcie_data *data = hci_get_drvdata(hdev);
|
||||
const u8 param[1] = { 0xFF };
|
||||
struct intel_version_tlv ver_tlv;
|
||||
struct sk_buff *skb;
|
||||
@@ -1449,6 +1965,7 @@ static int btintel_pcie_setup_internal(struct hci_dev *hdev)
|
||||
*/
|
||||
switch (INTEL_HW_VARIANT(ver_tlv.cnvi_bt)) {
|
||||
case 0x1e: /* BzrI */
|
||||
case 0x1f: /* ScP */
|
||||
/* Display version information of TLV type */
|
||||
btintel_version_info_tlv(hdev, &ver_tlv);
|
||||
|
||||
@@ -1474,6 +1991,23 @@ static int btintel_pcie_setup_internal(struct hci_dev *hdev)
|
||||
break;
|
||||
}
|
||||
|
||||
data->dmp_hdr.cnvi_top = ver_tlv.cnvi_top;
|
||||
data->dmp_hdr.cnvr_top = ver_tlv.cnvr_top;
|
||||
data->dmp_hdr.fw_timestamp = ver_tlv.timestamp;
|
||||
data->dmp_hdr.fw_build_type = ver_tlv.build_type;
|
||||
data->dmp_hdr.fw_build_num = ver_tlv.build_num;
|
||||
data->dmp_hdr.cnvi_bt = ver_tlv.cnvi_bt;
|
||||
|
||||
if (ver_tlv.img_type == 0x02 || ver_tlv.img_type == 0x03)
|
||||
data->dmp_hdr.fw_git_sha1 = ver_tlv.git_sha1;
|
||||
|
||||
err = hci_devcd_register(hdev, btintel_pcie_dump_traces, btintel_pcie_dump_hdr,
|
||||
btintel_pcie_dump_notify);
|
||||
if (err) {
|
||||
bt_dev_err(hdev, "Failed to register coredump (%d)", err);
|
||||
goto exit_error;
|
||||
}
|
||||
|
||||
btintel_print_fseq_info(hdev);
|
||||
exit_error:
|
||||
kfree_skb(skb);
|
||||
@@ -1538,6 +2072,7 @@ static int btintel_pcie_setup_hdev(struct btintel_pcie_data *data)
|
||||
goto exit_error;
|
||||
}
|
||||
|
||||
data->dmp_hdr.driver_name = KBUILD_MODNAME;
|
||||
return 0;
|
||||
|
||||
exit_error:
|
||||
@@ -1650,11 +2185,28 @@ static void btintel_pcie_remove(struct pci_dev *pdev)
|
||||
pci_set_drvdata(pdev, NULL);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_DEV_COREDUMP
|
||||
static void btintel_pcie_coredump(struct device *dev)
|
||||
{
|
||||
struct pci_dev *pdev = to_pci_dev(dev);
|
||||
struct btintel_pcie_data *data = pci_get_drvdata(pdev);
|
||||
|
||||
if (test_and_set_bit(BTINTEL_PCIE_COREDUMP_INPROGRESS, &data->flags))
|
||||
return;
|
||||
|
||||
data->dmp_hdr.trigger_reason = BTINTEL_PCIE_TRIGGER_REASON_USER_TRIGGER;
|
||||
queue_work(data->workqueue, &data->rx_work);
|
||||
}
|
||||
#endif
|
||||
|
||||
static struct pci_driver btintel_pcie_driver = {
|
||||
.name = KBUILD_MODNAME,
|
||||
.id_table = btintel_pcie_table,
|
||||
.probe = btintel_pcie_probe,
|
||||
.remove = btintel_pcie_remove,
|
||||
#ifdef CONFIG_DEV_COREDUMP
|
||||
.driver.coredump = btintel_pcie_coredump
|
||||
#endif
|
||||
};
|
||||
module_pci_driver(btintel_pcie_driver);
|
||||
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
#define BTINTEL_PCIE_CSR_CI_ADDR_LSB_REG (BTINTEL_PCIE_CSR_BASE + 0x118)
|
||||
#define BTINTEL_PCIE_CSR_CI_ADDR_MSB_REG (BTINTEL_PCIE_CSR_BASE + 0x11C)
|
||||
#define BTINTEL_PCIE_CSR_IMG_RESPONSE_REG (BTINTEL_PCIE_CSR_BASE + 0x12C)
|
||||
#define BTINTEL_PCIE_PRPH_DEV_ADDR_REG (BTINTEL_PCIE_CSR_BASE + 0x440)
|
||||
#define BTINTEL_PCIE_PRPH_DEV_RD_REG (BTINTEL_PCIE_CSR_BASE + 0x458)
|
||||
#define BTINTEL_PCIE_CSR_HBUS_TARG_WRPTR (BTINTEL_PCIE_CSR_BASE + 0x460)
|
||||
|
||||
/* BTINTEL_PCIE_CSR Function Control Register */
|
||||
@@ -23,6 +25,12 @@
|
||||
#define BTINTEL_PCIE_CSR_FUNC_CTRL_MAC_INIT (BIT(6))
|
||||
#define BTINTEL_PCIE_CSR_FUNC_CTRL_FUNC_INIT (BIT(7))
|
||||
#define BTINTEL_PCIE_CSR_FUNC_CTRL_MAC_ACCESS_STS (BIT(20))
|
||||
|
||||
#define BTINTEL_PCIE_CSR_FUNC_CTRL_MAC_ACCESS_REQ (BIT(21))
|
||||
/* Stop MAC Access disconnection request */
|
||||
#define BTINTEL_PCIE_CSR_FUNC_CTRL_STOP_MAC_ACCESS_DIS (BIT(22))
|
||||
#define BTINTEL_PCIE_CSR_FUNC_CTRL_XTAL_CLK_REQ (BIT(23))
|
||||
|
||||
#define BTINTEL_PCIE_CSR_FUNC_CTRL_BUS_MASTER_STS (BIT(28))
|
||||
#define BTINTEL_PCIE_CSR_FUNC_CTRL_BUS_MASTER_DISCON (BIT(29))
|
||||
#define BTINTEL_PCIE_CSR_FUNC_CTRL_SW_RESET (BIT(31))
|
||||
@@ -48,6 +56,30 @@
|
||||
#define BTINTEL_PCIE_CSR_MSIX_IVAR_BASE (BTINTEL_PCIE_CSR_MSIX_BASE + 0x0880)
|
||||
#define BTINTEL_PCIE_CSR_MSIX_IVAR(cause) (BTINTEL_PCIE_CSR_MSIX_IVAR_BASE + (cause))
|
||||
|
||||
/* IOSF Debug Register */
|
||||
#define BTINTEL_PCIE_DBGC_BASE_ADDR (0xf3800300)
|
||||
#define BTINTEL_PCIE_DBGC_CUR_DBGBUFF_STATUS (BTINTEL_PCIE_DBGC_BASE_ADDR + 0x1C)
|
||||
#define BTINTEL_PCIE_DBGC_DBGBUFF_WRAP_ARND (BTINTEL_PCIE_DBGC_BASE_ADDR + 0x2C)
|
||||
|
||||
#define BTINTEL_PCIE_DBG_IDX_BIT_MASK 0x0F
|
||||
#define BTINTEL_PCIE_DBGC_DBG_BUF_IDX(data) (((data) >> 24) & BTINTEL_PCIE_DBG_IDX_BIT_MASK)
|
||||
#define BTINTEL_PCIE_DBG_OFFSET_BIT_MASK 0xFFFFFF
|
||||
|
||||
/* The DRAM buffer count, each buffer size, and
|
||||
* fragment buffer size
|
||||
*/
|
||||
#define BTINTEL_PCIE_DBGC_BUFFER_COUNT 16
|
||||
#define BTINTEL_PCIE_DBGC_BUFFER_SIZE (256 * 1024) /* 256 KB */
|
||||
|
||||
#define BTINTEL_PCIE_DBGC_FRAG_VERSION 1
|
||||
#define BTINTEL_PCIE_DBGC_FRAG_BUFFER_COUNT BTINTEL_PCIE_DBGC_BUFFER_COUNT
|
||||
|
||||
/* Magic number(4), version(4), size of payload length(4) */
|
||||
#define BTINTEL_PCIE_DBGC_FRAG_HEADER_SIZE 12
|
||||
|
||||
/* Num of alloc Dbg buff (4) + (LSB(4), MSB(4), Size(4)) for each buffer */
|
||||
#define BTINTEL_PCIE_DBGC_FRAG_PAYLOAD_SIZE 196
|
||||
|
||||
/* Causes for the FH register interrupts */
|
||||
enum msix_fh_int_causes {
|
||||
BTINTEL_PCIE_MSIX_FH_INT_CAUSES_0 = BIT(0), /* cause 0 */
|
||||
@@ -57,6 +89,7 @@ enum msix_fh_int_causes {
|
||||
/* Causes for the HW register interrupts */
|
||||
enum msix_hw_int_causes {
|
||||
BTINTEL_PCIE_MSIX_HW_INT_CAUSES_GP0 = BIT(0), /* cause 32 */
|
||||
BTINTEL_PCIE_MSIX_HW_INT_CAUSES_HWEXP = BIT(3), /* cause 35 */
|
||||
};
|
||||
|
||||
/* PCIe device states
|
||||
@@ -69,6 +102,25 @@ enum {
|
||||
BTINTEL_PCIE_STATE_D3_HOT = 2,
|
||||
BTINTEL_PCIE_STATE_D3_COLD = 3,
|
||||
};
|
||||
|
||||
enum {
|
||||
BTINTEL_PCIE_CORE_HALTED,
|
||||
BTINTEL_PCIE_HWEXP_INPROGRESS,
|
||||
BTINTEL_PCIE_COREDUMP_INPROGRESS
|
||||
};
|
||||
|
||||
enum btintel_pcie_tlv_type {
|
||||
BTINTEL_CNVI_BT,
|
||||
BTINTEL_WRITE_PTR,
|
||||
BTINTEL_WRAP_CTR,
|
||||
BTINTEL_TRIGGER_REASON,
|
||||
BTINTEL_FW_SHA,
|
||||
BTINTEL_CNVR_TOP,
|
||||
BTINTEL_CNVI_TOP,
|
||||
BTINTEL_DUMP_TIME,
|
||||
BTINTEL_FW_BUILD,
|
||||
};
|
||||
|
||||
#define BTINTEL_PCIE_MSIX_NON_AUTO_CLEAR_CAUSE BIT(7)
|
||||
|
||||
/* Minimum and Maximum number of MSI-X Vector
|
||||
@@ -325,6 +377,37 @@ struct rxq {
|
||||
struct data_buf *bufs;
|
||||
};
|
||||
|
||||
/* Structure for DRAM Buffer
|
||||
* @count: Number of descriptors
|
||||
* @buf: Array of data_buf structure
|
||||
*/
|
||||
struct btintel_pcie_dbgc {
|
||||
u16 count;
|
||||
|
||||
void *frag_v_addr;
|
||||
dma_addr_t frag_p_addr;
|
||||
u16 frag_size;
|
||||
|
||||
dma_addr_t buf_p_addr;
|
||||
void *buf_v_addr;
|
||||
struct data_buf *bufs;
|
||||
};
|
||||
|
||||
struct btintel_pcie_dump_header {
|
||||
const char *driver_name;
|
||||
u32 cnvi_top;
|
||||
u32 cnvr_top;
|
||||
u16 fw_timestamp;
|
||||
u8 fw_build_type;
|
||||
u32 fw_build_num;
|
||||
u32 fw_git_sha1;
|
||||
u32 cnvi_bt;
|
||||
u32 write_ptr;
|
||||
u32 wrap_ctr;
|
||||
u16 trigger_reason;
|
||||
int state;
|
||||
};
|
||||
|
||||
/* struct btintel_pcie_data
|
||||
* @pdev: pci device
|
||||
* @hdev: hdev device
|
||||
@@ -405,6 +488,8 @@ struct btintel_pcie_data {
|
||||
struct txq txq;
|
||||
struct rxq rxq;
|
||||
u32 alive_intr_ctxt;
|
||||
struct btintel_pcie_dbgc dbgc;
|
||||
struct btintel_pcie_dump_header dmp_hdr;
|
||||
};
|
||||
|
||||
static inline u32 btintel_pcie_rd_reg32(struct btintel_pcie_data *data,
|
||||
@@ -444,3 +529,11 @@ static inline void btintel_pcie_clr_reg_bits(struct btintel_pcie_data *data,
|
||||
r &= ~bits;
|
||||
iowrite32(r, data->base_addr + offset);
|
||||
}
|
||||
|
||||
static inline u32 btintel_pcie_rd_dev_mem(struct btintel_pcie_data *data,
|
||||
u32 addr)
|
||||
{
|
||||
btintel_pcie_wr_reg32(data, BTINTEL_PCIE_PRPH_DEV_ADDR_REG, addr);
|
||||
return btintel_pcie_rd_reg32(data, BTINTEL_PCIE_PRPH_DEV_RD_REG);
|
||||
}
|
||||
|
||||
|
||||
@@ -1330,13 +1330,6 @@ int btmtk_usb_setup(struct hci_dev *hdev)
|
||||
break;
|
||||
case 0x7922:
|
||||
case 0x7925:
|
||||
/* Reset the device to ensure it's in the initial state before
|
||||
* downloading the firmware to ensure.
|
||||
*/
|
||||
|
||||
if (!test_bit(BTMTK_FIRMWARE_LOADED, &btmtk_data->flags))
|
||||
btmtk_usb_subsys_reset(hdev, dev_id);
|
||||
fallthrough;
|
||||
case 0x7961:
|
||||
btmtk_fw_get_filename(fw_bin_name, sizeof(fw_bin_name), dev_id,
|
||||
fw_version, fw_flavor);
|
||||
@@ -1345,12 +1338,9 @@ int btmtk_usb_setup(struct hci_dev *hdev)
|
||||
btmtk_usb_hci_wmt_sync);
|
||||
if (err < 0) {
|
||||
bt_dev_err(hdev, "Failed to set up firmware (%d)", err);
|
||||
clear_bit(BTMTK_FIRMWARE_LOADED, &btmtk_data->flags);
|
||||
return err;
|
||||
}
|
||||
|
||||
set_bit(BTMTK_FIRMWARE_LOADED, &btmtk_data->flags);
|
||||
|
||||
/* It's Device EndPoint Reset Option Register */
|
||||
err = btmtk_usb_uhw_reg_write(hdev, MTK_EP_RST_OPT,
|
||||
MTK_EP_RST_IN_OUT_OPT);
|
||||
|
||||
@@ -610,7 +610,8 @@ static void btmtksdio_txrx_work(struct work_struct *work)
|
||||
} while (int_status || time_is_before_jiffies(txrx_timeout));
|
||||
|
||||
/* Enable interrupt */
|
||||
sdio_writel(bdev->func, C_INT_EN_SET, MTK_REG_CHLPCR, NULL);
|
||||
if (bdev->func->irq_handler)
|
||||
sdio_writel(bdev->func, C_INT_EN_SET, MTK_REG_CHLPCR, NULL);
|
||||
|
||||
sdio_release_host(bdev->func);
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
/*
|
||||
* NXP Bluetooth driver
|
||||
* Copyright 2023 NXP
|
||||
* Copyright 2023-2025 NXP
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
@@ -31,6 +31,7 @@
|
||||
#define BTNXPUART_SERDEV_OPEN 4
|
||||
#define BTNXPUART_IR_IN_PROGRESS 5
|
||||
#define BTNXPUART_FW_DOWNLOAD_ABORT 6
|
||||
#define BTNXPUART_FW_DUMP_IN_PROGRESS 7
|
||||
|
||||
/* NXP HW err codes */
|
||||
#define BTNXPUART_IR_HW_ERR 0xb0
|
||||
@@ -98,14 +99,19 @@
|
||||
#define PS_STATE_AWAKE 0
|
||||
#define PS_STATE_SLEEP 1
|
||||
|
||||
/* Bluetooth vendor command : Sleep mode */
|
||||
/* NXP Vendor Commands. Refer user manual UM11628 on nxp.com */
|
||||
/* Set custom BD Address */
|
||||
#define HCI_NXP_SET_BD_ADDR 0xfc22
|
||||
/* Set Auto-Sleep mode */
|
||||
#define HCI_NXP_AUTO_SLEEP_MODE 0xfc23
|
||||
/* Bluetooth vendor command : Wakeup method */
|
||||
/* Set Wakeup method */
|
||||
#define HCI_NXP_WAKEUP_METHOD 0xfc53
|
||||
/* Bluetooth vendor command : Set operational baudrate */
|
||||
/* Set operational baudrate */
|
||||
#define HCI_NXP_SET_OPER_SPEED 0xfc09
|
||||
/* Bluetooth vendor command: Independent Reset */
|
||||
/* Independent Reset (Soft Reset) */
|
||||
#define HCI_NXP_IND_RESET 0xfcfc
|
||||
/* Bluetooth vendor command: Trigger FW dump */
|
||||
#define HCI_NXP_TRIGGER_DUMP 0xfe91
|
||||
|
||||
/* Bluetooth Power State : Vendor cmd params */
|
||||
#define BT_PS_ENABLE 0x02
|
||||
@@ -162,6 +168,12 @@ struct btnxpuart_data {
|
||||
const char *fw_name_old;
|
||||
};
|
||||
|
||||
enum bootloader_param_change {
|
||||
not_changed,
|
||||
cmd_sent,
|
||||
changed
|
||||
};
|
||||
|
||||
struct btnxpuart_dev {
|
||||
struct hci_dev *hdev;
|
||||
struct serdev_device *serdev;
|
||||
@@ -177,6 +189,7 @@ struct btnxpuart_dev {
|
||||
u32 fw_v1_sent_bytes;
|
||||
u32 fw_dnld_v3_offset;
|
||||
u32 fw_v3_offset_correction;
|
||||
u32 fw_v3_prev_sent;
|
||||
u32 fw_v1_expected_len;
|
||||
u32 boot_reg_offset;
|
||||
wait_queue_head_t fw_dnld_done_wait_q;
|
||||
@@ -185,8 +198,8 @@ struct btnxpuart_dev {
|
||||
u32 new_baudrate;
|
||||
u32 current_baudrate;
|
||||
u32 fw_init_baudrate;
|
||||
bool timeout_changed;
|
||||
bool baudrate_changed;
|
||||
enum bootloader_param_change timeout_changed;
|
||||
enum bootloader_param_change baudrate_changed;
|
||||
bool helper_downloaded;
|
||||
|
||||
struct ps_data psdata;
|
||||
@@ -204,10 +217,11 @@ struct btnxpuart_dev {
|
||||
#define NXP_NAK_V3 0x7b
|
||||
#define NXP_CRC_ERROR_V3 0x7c
|
||||
|
||||
/* Bootloader signature error codes */
|
||||
#define NXP_ACK_RX_TIMEOUT 0x0002 /* ACK not received from host */
|
||||
#define NXP_HDR_RX_TIMEOUT 0x0003 /* FW Header chunk not received */
|
||||
#define NXP_DATA_RX_TIMEOUT 0x0004 /* FW Data chunk not received */
|
||||
/* Bootloader signature error codes: Refer AN12820 from nxp.com */
|
||||
#define NXP_CRC_RX_ERROR BIT(0) /* CRC error in previous packet */
|
||||
#define NXP_ACK_RX_TIMEOUT BIT(2) /* ACK not received from host */
|
||||
#define NXP_HDR_RX_TIMEOUT BIT(3) /* FW Header chunk not received */
|
||||
#define NXP_DATA_RX_TIMEOUT BIT(4) /* FW Data chunk not received */
|
||||
|
||||
#define HDR_LEN 16
|
||||
|
||||
@@ -310,6 +324,35 @@ union nxp_v3_rx_timeout_nak_u {
|
||||
u8 buf[6];
|
||||
};
|
||||
|
||||
struct nxp_v3_crc_nak {
|
||||
u8 nak;
|
||||
u8 crc;
|
||||
} __packed;
|
||||
|
||||
union nxp_v3_crc_nak_u {
|
||||
struct nxp_v3_crc_nak pkt;
|
||||
u8 buf[2];
|
||||
};
|
||||
|
||||
/* FW dump */
|
||||
#define NXP_FW_DUMP_SIZE (1024 * 1000)
|
||||
|
||||
struct nxp_fw_dump_hdr {
|
||||
__le16 seq_num;
|
||||
__le16 reserved;
|
||||
__le16 buf_type;
|
||||
__le16 buf_len;
|
||||
};
|
||||
|
||||
union nxp_set_bd_addr_payload {
|
||||
struct {
|
||||
u8 param_id;
|
||||
u8 param_len;
|
||||
u8 param[6];
|
||||
} __packed data;
|
||||
u8 buf[8];
|
||||
};
|
||||
|
||||
static u8 crc8_table[CRC8_TABLE_SIZE];
|
||||
|
||||
/* Default configurations */
|
||||
@@ -447,8 +490,14 @@ static int ps_setup(struct hci_dev *hdev)
|
||||
return PTR_ERR(psdata->h2c_ps_gpio);
|
||||
}
|
||||
|
||||
if (!psdata->h2c_ps_gpio)
|
||||
if (device_property_read_u8(&serdev->dev, "nxp,wakein-pin", &psdata->h2c_wakeup_gpio)) {
|
||||
psdata->h2c_wakeup_gpio = 0xff; /* 0xff: use default pin/gpio */
|
||||
} else if (!psdata->h2c_ps_gpio) {
|
||||
bt_dev_warn(hdev, "nxp,wakein-pin property without device-wakeup GPIO");
|
||||
psdata->h2c_wakeup_gpio = 0xff;
|
||||
}
|
||||
|
||||
device_property_read_u8(&serdev->dev, "nxp,wakeout-pin", &psdata->c2h_wakeup_gpio);
|
||||
|
||||
psdata->hdev = hdev;
|
||||
INIT_WORK(&psdata->work, ps_work_func);
|
||||
@@ -540,9 +589,11 @@ static int send_wakeup_method_cmd(struct hci_dev *hdev, void *data)
|
||||
|
||||
pcmd.c2h_wakeupmode = psdata->c2h_wakeupmode;
|
||||
pcmd.c2h_wakeup_gpio = psdata->c2h_wakeup_gpio;
|
||||
pcmd.h2c_wakeup_gpio = 0xff;
|
||||
switch (psdata->h2c_wakeupmode) {
|
||||
case WAKEUP_METHOD_GPIO:
|
||||
pcmd.h2c_wakeupmode = BT_CTRL_WAKEUP_METHOD_GPIO;
|
||||
pcmd.h2c_wakeup_gpio = psdata->h2c_wakeup_gpio;
|
||||
break;
|
||||
case WAKEUP_METHOD_DTR:
|
||||
pcmd.h2c_wakeupmode = BT_CTRL_WAKEUP_METHOD_DSR;
|
||||
@@ -552,7 +603,6 @@ static int send_wakeup_method_cmd(struct hci_dev *hdev, void *data)
|
||||
pcmd.h2c_wakeupmode = BT_CTRL_WAKEUP_METHOD_BREAK;
|
||||
break;
|
||||
}
|
||||
pcmd.h2c_wakeup_gpio = 0xff;
|
||||
|
||||
skb = nxp_drv_send_cmd(hdev, HCI_NXP_WAKEUP_METHOD, sizeof(pcmd), &pcmd);
|
||||
if (IS_ERR(skb)) {
|
||||
@@ -586,8 +636,13 @@ static void ps_init(struct hci_dev *hdev)
|
||||
usleep_range(5000, 10000);
|
||||
|
||||
psdata->ps_state = PS_STATE_AWAKE;
|
||||
psdata->c2h_wakeupmode = BT_HOST_WAKEUP_METHOD_NONE;
|
||||
psdata->c2h_wakeup_gpio = 0xff;
|
||||
|
||||
if (psdata->c2h_wakeup_gpio) {
|
||||
psdata->c2h_wakeupmode = BT_HOST_WAKEUP_METHOD_GPIO;
|
||||
} else {
|
||||
psdata->c2h_wakeupmode = BT_HOST_WAKEUP_METHOD_NONE;
|
||||
psdata->c2h_wakeup_gpio = 0xff;
|
||||
}
|
||||
|
||||
psdata->cur_h2c_wakeupmode = WAKEUP_METHOD_INVALID;
|
||||
if (psdata->h2c_ps_gpio)
|
||||
@@ -618,11 +673,6 @@ static void ps_init(struct hci_dev *hdev)
|
||||
|
||||
psdata->cur_psmode = PS_MODE_DISABLE;
|
||||
psdata->target_ps_mode = DEFAULT_PS_MODE;
|
||||
|
||||
if (psdata->cur_h2c_wakeupmode != psdata->h2c_wakeupmode)
|
||||
hci_cmd_sync_queue(hdev, send_wakeup_method_cmd, NULL, NULL);
|
||||
if (psdata->cur_psmode != psdata->target_ps_mode)
|
||||
hci_cmd_sync_queue(hdev, send_ps_cmd, NULL, NULL);
|
||||
}
|
||||
|
||||
/* NXP Firmware Download Feature */
|
||||
@@ -637,8 +687,8 @@ static int nxp_download_firmware(struct hci_dev *hdev)
|
||||
nxpdev->boot_reg_offset = 0;
|
||||
nxpdev->fw_dnld_v3_offset = 0;
|
||||
nxpdev->fw_v3_offset_correction = 0;
|
||||
nxpdev->baudrate_changed = false;
|
||||
nxpdev->timeout_changed = false;
|
||||
nxpdev->baudrate_changed = not_changed;
|
||||
nxpdev->timeout_changed = not_changed;
|
||||
nxpdev->helper_downloaded = false;
|
||||
|
||||
serdev_device_set_baudrate(nxpdev->serdev, HCI_NXP_PRI_BAUDRATE);
|
||||
@@ -651,8 +701,10 @@ static int nxp_download_firmware(struct hci_dev *hdev)
|
||||
&nxpdev->tx_state),
|
||||
msecs_to_jiffies(60000));
|
||||
|
||||
release_firmware(nxpdev->fw);
|
||||
memset(nxpdev->fw_name, 0, sizeof(nxpdev->fw_name));
|
||||
if (nxpdev->fw && strlen(nxpdev->fw_name)) {
|
||||
release_firmware(nxpdev->fw);
|
||||
memset(nxpdev->fw_name, 0, sizeof(nxpdev->fw_name));
|
||||
}
|
||||
|
||||
if (err == 0) {
|
||||
bt_dev_err(hdev, "FW Download Timeout. offset: %d",
|
||||
@@ -767,6 +819,16 @@ static bool is_fw_downloading(struct btnxpuart_dev *nxpdev)
|
||||
return test_bit(BTNXPUART_FW_DOWNLOADING, &nxpdev->tx_state);
|
||||
}
|
||||
|
||||
static bool ind_reset_in_progress(struct btnxpuart_dev *nxpdev)
|
||||
{
|
||||
return test_bit(BTNXPUART_IR_IN_PROGRESS, &nxpdev->tx_state);
|
||||
}
|
||||
|
||||
static bool fw_dump_in_progress(struct btnxpuart_dev *nxpdev)
|
||||
{
|
||||
return test_bit(BTNXPUART_FW_DUMP_IN_PROGRESS, &nxpdev->tx_state);
|
||||
}
|
||||
|
||||
static bool process_boot_signature(struct btnxpuart_dev *nxpdev)
|
||||
{
|
||||
if (test_bit(BTNXPUART_CHECK_BOOT_SIGNATURE, &nxpdev->tx_state)) {
|
||||
@@ -860,15 +922,14 @@ static int nxp_recv_fw_req_v1(struct hci_dev *hdev, struct sk_buff *skb)
|
||||
len = __le16_to_cpu(req->len);
|
||||
|
||||
if (!nxp_data->helper_fw_name) {
|
||||
if (!nxpdev->timeout_changed) {
|
||||
nxpdev->timeout_changed = nxp_fw_change_timeout(hdev,
|
||||
len);
|
||||
if (nxpdev->timeout_changed != changed) {
|
||||
nxp_fw_change_timeout(hdev, len);
|
||||
nxpdev->timeout_changed = changed;
|
||||
goto free_skb;
|
||||
}
|
||||
if (!nxpdev->baudrate_changed) {
|
||||
nxpdev->baudrate_changed = nxp_fw_change_baudrate(hdev,
|
||||
len);
|
||||
if (nxpdev->baudrate_changed) {
|
||||
if (nxpdev->baudrate_changed != changed) {
|
||||
if (nxp_fw_change_baudrate(hdev, len)) {
|
||||
nxpdev->baudrate_changed = changed;
|
||||
serdev_device_set_baudrate(nxpdev->serdev,
|
||||
HCI_NXP_SEC_BAUDRATE);
|
||||
serdev_device_set_flow_control(nxpdev->serdev, true);
|
||||
@@ -1047,32 +1108,35 @@ static void nxp_handle_fw_download_error(struct hci_dev *hdev, struct v3_data_re
|
||||
struct btnxpuart_dev *nxpdev = hci_get_drvdata(hdev);
|
||||
__u32 offset = __le32_to_cpu(req->offset);
|
||||
__u16 err = __le16_to_cpu(req->error);
|
||||
union nxp_v3_rx_timeout_nak_u nak_tx_buf;
|
||||
|
||||
switch (err) {
|
||||
case NXP_ACK_RX_TIMEOUT:
|
||||
case NXP_HDR_RX_TIMEOUT:
|
||||
case NXP_DATA_RX_TIMEOUT:
|
||||
nak_tx_buf.pkt.nak = NXP_NAK_V3;
|
||||
nak_tx_buf.pkt.offset = __cpu_to_le32(offset);
|
||||
nak_tx_buf.pkt.crc = crc8(crc8_table, nak_tx_buf.buf,
|
||||
sizeof(nak_tx_buf) - 1, 0xff);
|
||||
serdev_device_write_buf(nxpdev->serdev, nak_tx_buf.buf,
|
||||
sizeof(nak_tx_buf));
|
||||
break;
|
||||
default:
|
||||
bt_dev_dbg(hdev, "Unknown bootloader error code: %d", err);
|
||||
break;
|
||||
union nxp_v3_rx_timeout_nak_u timeout_nak_buf;
|
||||
union nxp_v3_crc_nak_u crc_nak_buf;
|
||||
|
||||
if (err & NXP_CRC_RX_ERROR) {
|
||||
crc_nak_buf.pkt.nak = NXP_CRC_ERROR_V3;
|
||||
crc_nak_buf.pkt.crc = crc8(crc8_table, crc_nak_buf.buf,
|
||||
sizeof(crc_nak_buf) - 1, 0xff);
|
||||
serdev_device_write_buf(nxpdev->serdev, crc_nak_buf.buf,
|
||||
sizeof(crc_nak_buf));
|
||||
} else if (err & NXP_ACK_RX_TIMEOUT ||
|
||||
err & NXP_HDR_RX_TIMEOUT ||
|
||||
err & NXP_DATA_RX_TIMEOUT) {
|
||||
timeout_nak_buf.pkt.nak = NXP_NAK_V3;
|
||||
timeout_nak_buf.pkt.offset = __cpu_to_le32(offset);
|
||||
timeout_nak_buf.pkt.crc = crc8(crc8_table, timeout_nak_buf.buf,
|
||||
sizeof(timeout_nak_buf) - 1, 0xff);
|
||||
serdev_device_write_buf(nxpdev->serdev, timeout_nak_buf.buf,
|
||||
sizeof(timeout_nak_buf));
|
||||
} else {
|
||||
bt_dev_err(hdev, "Unknown bootloader error code: %d", err);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static int nxp_recv_fw_req_v3(struct hci_dev *hdev, struct sk_buff *skb)
|
||||
{
|
||||
struct btnxpuart_dev *nxpdev = hci_get_drvdata(hdev);
|
||||
struct v3_data_req *req;
|
||||
__u16 len;
|
||||
__u16 len = 0;
|
||||
__u16 err = 0;
|
||||
__u32 offset;
|
||||
|
||||
if (!process_boot_signature(nxpdev))
|
||||
@@ -1082,23 +1146,40 @@ static int nxp_recv_fw_req_v3(struct hci_dev *hdev, struct sk_buff *skb)
|
||||
if (!req || !nxpdev->fw)
|
||||
goto free_skb;
|
||||
|
||||
if (!req->error) {
|
||||
err = __le16_to_cpu(req->error);
|
||||
|
||||
if (!err) {
|
||||
nxp_send_ack(NXP_ACK_V3, hdev);
|
||||
if (nxpdev->timeout_changed == cmd_sent)
|
||||
nxpdev->timeout_changed = changed;
|
||||
if (nxpdev->baudrate_changed == cmd_sent)
|
||||
nxpdev->baudrate_changed = changed;
|
||||
} else {
|
||||
nxp_handle_fw_download_error(hdev, req);
|
||||
if (nxpdev->timeout_changed == cmd_sent &&
|
||||
err == NXP_CRC_RX_ERROR) {
|
||||
nxpdev->fw_v3_offset_correction -= nxpdev->fw_v3_prev_sent;
|
||||
nxpdev->timeout_changed = not_changed;
|
||||
}
|
||||
if (nxpdev->baudrate_changed == cmd_sent &&
|
||||
err == NXP_CRC_RX_ERROR) {
|
||||
nxpdev->fw_v3_offset_correction -= nxpdev->fw_v3_prev_sent;
|
||||
nxpdev->baudrate_changed = not_changed;
|
||||
}
|
||||
goto free_skb;
|
||||
}
|
||||
|
||||
len = __le16_to_cpu(req->len);
|
||||
|
||||
if (!nxpdev->timeout_changed) {
|
||||
nxpdev->timeout_changed = nxp_fw_change_timeout(hdev, len);
|
||||
if (nxpdev->timeout_changed != changed) {
|
||||
nxp_fw_change_timeout(hdev, len);
|
||||
nxpdev->timeout_changed = cmd_sent;
|
||||
goto free_skb;
|
||||
}
|
||||
|
||||
if (!nxpdev->baudrate_changed) {
|
||||
nxpdev->baudrate_changed = nxp_fw_change_baudrate(hdev, len);
|
||||
if (nxpdev->baudrate_changed) {
|
||||
if (nxpdev->baudrate_changed != changed) {
|
||||
if (nxp_fw_change_baudrate(hdev, len)) {
|
||||
nxpdev->baudrate_changed = cmd_sent;
|
||||
serdev_device_set_baudrate(nxpdev->serdev,
|
||||
HCI_NXP_SEC_BAUDRATE);
|
||||
serdev_device_set_flow_control(nxpdev->serdev, true);
|
||||
@@ -1130,6 +1211,7 @@ static int nxp_recv_fw_req_v3(struct hci_dev *hdev, struct sk_buff *skb)
|
||||
nxpdev->fw_dnld_v3_offset, len);
|
||||
|
||||
free_skb:
|
||||
nxpdev->fw_v3_prev_sent = len;
|
||||
kfree_skb(skb);
|
||||
return 0;
|
||||
}
|
||||
@@ -1168,7 +1250,7 @@ static int nxp_set_baudrate_cmd(struct hci_dev *hdev, void *data)
|
||||
static int nxp_check_boot_sign(struct btnxpuart_dev *nxpdev)
|
||||
{
|
||||
serdev_device_set_baudrate(nxpdev->serdev, HCI_NXP_PRI_BAUDRATE);
|
||||
if (test_bit(BTNXPUART_IR_IN_PROGRESS, &nxpdev->tx_state))
|
||||
if (ind_reset_in_progress(nxpdev))
|
||||
serdev_device_set_flow_control(nxpdev->serdev, false);
|
||||
else
|
||||
serdev_device_set_flow_control(nxpdev->serdev, true);
|
||||
@@ -1197,6 +1279,102 @@ static int nxp_set_ind_reset(struct hci_dev *hdev, void *data)
|
||||
return hci_recv_frame(hdev, skb);
|
||||
}
|
||||
|
||||
/* Firmware dump */
|
||||
static void nxp_coredump(struct hci_dev *hdev)
|
||||
{
|
||||
struct sk_buff *skb;
|
||||
u8 pcmd = 2;
|
||||
|
||||
skb = nxp_drv_send_cmd(hdev, HCI_NXP_TRIGGER_DUMP, 1, &pcmd);
|
||||
if (!IS_ERR(skb))
|
||||
kfree_skb(skb);
|
||||
}
|
||||
|
||||
static void nxp_coredump_hdr(struct hci_dev *hdev, struct sk_buff *skb)
|
||||
{
|
||||
/* Nothing to be added in FW dump header */
|
||||
}
|
||||
|
||||
static int nxp_process_fw_dump(struct hci_dev *hdev, struct sk_buff *skb)
|
||||
{
|
||||
struct hci_acl_hdr *acl_hdr = (struct hci_acl_hdr *)skb_pull_data(skb,
|
||||
sizeof(*acl_hdr));
|
||||
struct nxp_fw_dump_hdr *fw_dump_hdr = (struct nxp_fw_dump_hdr *)skb->data;
|
||||
struct btnxpuart_dev *nxpdev = hci_get_drvdata(hdev);
|
||||
__u16 seq_num = __le16_to_cpu(fw_dump_hdr->seq_num);
|
||||
__u16 buf_len = __le16_to_cpu(fw_dump_hdr->buf_len);
|
||||
int err;
|
||||
|
||||
if (seq_num == 0x0001) {
|
||||
if (test_and_set_bit(BTNXPUART_FW_DUMP_IN_PROGRESS, &nxpdev->tx_state)) {
|
||||
bt_dev_err(hdev, "FW dump already in progress");
|
||||
goto free_skb;
|
||||
}
|
||||
bt_dev_warn(hdev, "==== Start FW dump ===");
|
||||
err = hci_devcd_init(hdev, NXP_FW_DUMP_SIZE);
|
||||
if (err < 0)
|
||||
goto free_skb;
|
||||
|
||||
schedule_delayed_work(&hdev->dump.dump_timeout,
|
||||
msecs_to_jiffies(20000));
|
||||
}
|
||||
|
||||
err = hci_devcd_append(hdev, skb_clone(skb, GFP_ATOMIC));
|
||||
if (err < 0)
|
||||
goto free_skb;
|
||||
|
||||
if (buf_len == 0) {
|
||||
bt_dev_warn(hdev, "==== FW dump complete ===");
|
||||
clear_bit(BTNXPUART_FW_DUMP_IN_PROGRESS, &nxpdev->tx_state);
|
||||
hci_devcd_complete(hdev);
|
||||
nxp_set_ind_reset(hdev, NULL);
|
||||
}
|
||||
|
||||
free_skb:
|
||||
kfree_skb(skb);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int nxp_recv_acl_pkt(struct hci_dev *hdev, struct sk_buff *skb)
|
||||
{
|
||||
__u16 handle = __le16_to_cpu(hci_acl_hdr(skb)->handle);
|
||||
|
||||
/* FW dump chunks are ACL packets with conn handle 0xfff */
|
||||
if ((handle & 0x0FFF) == 0xFFF)
|
||||
return nxp_process_fw_dump(hdev, skb);
|
||||
else
|
||||
return hci_recv_frame(hdev, skb);
|
||||
}
|
||||
|
||||
static int nxp_set_bdaddr(struct hci_dev *hdev, const bdaddr_t *bdaddr)
|
||||
{
|
||||
union nxp_set_bd_addr_payload pcmd;
|
||||
int err;
|
||||
|
||||
pcmd.data.param_id = 0xfe;
|
||||
pcmd.data.param_len = 6;
|
||||
memcpy(pcmd.data.param, bdaddr, 6);
|
||||
|
||||
/* BD address can be assigned only after first reset command. */
|
||||
err = __hci_cmd_sync_status(hdev, HCI_OP_RESET, 0, NULL,
|
||||
HCI_INIT_TIMEOUT);
|
||||
if (err) {
|
||||
bt_dev_err(hdev,
|
||||
"Reset before setting local-bd-addr failed (%d)",
|
||||
err);
|
||||
return err;
|
||||
}
|
||||
|
||||
err = __hci_cmd_sync_status(hdev, HCI_NXP_SET_BD_ADDR, sizeof(pcmd),
|
||||
pcmd.buf, HCI_CMD_TIMEOUT);
|
||||
if (err) {
|
||||
bt_dev_err(hdev, "Changing device address failed (%d)", err);
|
||||
return err;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* NXP protocol */
|
||||
static int nxp_setup(struct hci_dev *hdev)
|
||||
{
|
||||
@@ -1216,11 +1394,6 @@ static int nxp_setup(struct hci_dev *hdev)
|
||||
serdev_device_set_baudrate(nxpdev->serdev, nxpdev->fw_init_baudrate);
|
||||
nxpdev->current_baudrate = nxpdev->fw_init_baudrate;
|
||||
|
||||
if (nxpdev->current_baudrate != HCI_NXP_SEC_BAUDRATE) {
|
||||
nxpdev->new_baudrate = HCI_NXP_SEC_BAUDRATE;
|
||||
hci_cmd_sync_queue(hdev, nxp_set_baudrate_cmd, NULL, NULL);
|
||||
}
|
||||
|
||||
ps_init(hdev);
|
||||
|
||||
if (test_and_clear_bit(BTNXPUART_IR_IN_PROGRESS, &nxpdev->tx_state))
|
||||
@@ -1229,6 +1402,22 @@ static int nxp_setup(struct hci_dev *hdev)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int nxp_post_init(struct hci_dev *hdev)
|
||||
{
|
||||
struct btnxpuart_dev *nxpdev = hci_get_drvdata(hdev);
|
||||
struct ps_data *psdata = &nxpdev->psdata;
|
||||
|
||||
if (nxpdev->current_baudrate != HCI_NXP_SEC_BAUDRATE) {
|
||||
nxpdev->new_baudrate = HCI_NXP_SEC_BAUDRATE;
|
||||
nxp_set_baudrate_cmd(hdev, NULL);
|
||||
}
|
||||
if (psdata->cur_h2c_wakeupmode != psdata->h2c_wakeupmode)
|
||||
send_wakeup_method_cmd(hdev, NULL);
|
||||
if (psdata->cur_psmode != psdata->target_ps_mode)
|
||||
send_ps_cmd(hdev, NULL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void nxp_hw_err(struct hci_dev *hdev, u8 code)
|
||||
{
|
||||
struct btnxpuart_dev *nxpdev = hci_get_drvdata(hdev);
|
||||
@@ -1247,25 +1436,44 @@ static int nxp_shutdown(struct hci_dev *hdev)
|
||||
{
|
||||
struct btnxpuart_dev *nxpdev = hci_get_drvdata(hdev);
|
||||
struct sk_buff *skb;
|
||||
u8 *status;
|
||||
u8 pcmd = 0;
|
||||
|
||||
if (test_bit(BTNXPUART_IR_IN_PROGRESS, &nxpdev->tx_state)) {
|
||||
if (ind_reset_in_progress(nxpdev)) {
|
||||
skb = nxp_drv_send_cmd(hdev, HCI_NXP_IND_RESET, 1, &pcmd);
|
||||
if (IS_ERR(skb))
|
||||
return PTR_ERR(skb);
|
||||
|
||||
status = skb_pull_data(skb, 1);
|
||||
if (status) {
|
||||
serdev_device_set_flow_control(nxpdev->serdev, false);
|
||||
set_bit(BTNXPUART_FW_DOWNLOADING, &nxpdev->tx_state);
|
||||
}
|
||||
kfree_skb(skb);
|
||||
serdev_device_set_flow_control(nxpdev->serdev, false);
|
||||
set_bit(BTNXPUART_FW_DOWNLOADING, &nxpdev->tx_state);
|
||||
/* HCI_NXP_IND_RESET command may not returns any response */
|
||||
if (!IS_ERR(skb))
|
||||
kfree_skb(skb);
|
||||
} else if (nxpdev->current_baudrate != nxpdev->fw_init_baudrate) {
|
||||
nxpdev->new_baudrate = nxpdev->fw_init_baudrate;
|
||||
nxp_set_baudrate_cmd(hdev, NULL);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static bool nxp_wakeup(struct hci_dev *hdev)
|
||||
{
|
||||
struct btnxpuart_dev *nxpdev = hci_get_drvdata(hdev);
|
||||
struct ps_data *psdata = &nxpdev->psdata;
|
||||
|
||||
if (psdata->c2h_wakeupmode != BT_HOST_WAKEUP_METHOD_NONE)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static void nxp_reset(struct hci_dev *hdev)
|
||||
{
|
||||
struct btnxpuart_dev *nxpdev = hci_get_drvdata(hdev);
|
||||
|
||||
if (!ind_reset_in_progress(nxpdev) && !fw_dump_in_progress(nxpdev)) {
|
||||
bt_dev_dbg(hdev, "CMD Timeout detected. Resetting.");
|
||||
nxp_set_ind_reset(hdev, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
static int btnxpuart_queue_skb(struct hci_dev *hdev, struct sk_buff *skb)
|
||||
{
|
||||
struct btnxpuart_dev *nxpdev = hci_get_drvdata(hdev);
|
||||
@@ -1286,6 +1494,9 @@ static int nxp_enqueue(struct hci_dev *hdev, struct sk_buff *skb)
|
||||
struct wakeup_cmd_payload wakeup_parm;
|
||||
__le32 baudrate_parm;
|
||||
|
||||
if (fw_dump_in_progress(nxpdev))
|
||||
return -EBUSY;
|
||||
|
||||
/* if vendor commands are received from user space (e.g. hcitool), update
|
||||
* driver flags accordingly and ask driver to re-send the command to FW.
|
||||
* In case the payload for any command does not match expected payload
|
||||
@@ -1454,7 +1665,7 @@ static int btnxpuart_flush(struct hci_dev *hdev)
|
||||
}
|
||||
|
||||
static const struct h4_recv_pkt nxp_recv_pkts[] = {
|
||||
{ H4_RECV_ACL, .recv = hci_recv_frame },
|
||||
{ H4_RECV_ACL, .recv = nxp_recv_acl_pkt },
|
||||
{ H4_RECV_SCO, .recv = hci_recv_frame },
|
||||
{ H4_RECV_EVENT, .recv = hci_recv_frame },
|
||||
{ H4_RECV_ISO, .recv = hci_recv_frame },
|
||||
@@ -1476,11 +1687,13 @@ static size_t btnxpuart_receive_buf(struct serdev_device *serdev,
|
||||
if (IS_ERR(nxpdev->rx_skb)) {
|
||||
int err = PTR_ERR(nxpdev->rx_skb);
|
||||
/* Safe to ignore out-of-sync bootloader signatures */
|
||||
if (!is_fw_downloading(nxpdev))
|
||||
if (!is_fw_downloading(nxpdev) &&
|
||||
!ind_reset_in_progress(nxpdev))
|
||||
bt_dev_err(nxpdev->hdev, "Frame reassembly failed (%d)", err);
|
||||
return count;
|
||||
}
|
||||
if (!is_fw_downloading(nxpdev))
|
||||
if (!is_fw_downloading(nxpdev) &&
|
||||
!ind_reset_in_progress(nxpdev))
|
||||
nxpdev->hdev->stat.byte_rx += count;
|
||||
return count;
|
||||
}
|
||||
@@ -1499,6 +1712,7 @@ static int nxp_serdev_probe(struct serdev_device *serdev)
|
||||
{
|
||||
struct hci_dev *hdev;
|
||||
struct btnxpuart_dev *nxpdev;
|
||||
bdaddr_t ba = {0};
|
||||
|
||||
nxpdev = devm_kzalloc(&serdev->dev, sizeof(*nxpdev), GFP_KERNEL);
|
||||
if (!nxpdev)
|
||||
@@ -1543,11 +1757,21 @@ static int nxp_serdev_probe(struct serdev_device *serdev)
|
||||
hdev->close = btnxpuart_close;
|
||||
hdev->flush = btnxpuart_flush;
|
||||
hdev->setup = nxp_setup;
|
||||
hdev->post_init = nxp_post_init;
|
||||
hdev->send = nxp_enqueue;
|
||||
hdev->hw_error = nxp_hw_err;
|
||||
hdev->shutdown = nxp_shutdown;
|
||||
hdev->wakeup = nxp_wakeup;
|
||||
hdev->reset = nxp_reset;
|
||||
hdev->set_bdaddr = nxp_set_bdaddr;
|
||||
SET_HCIDEV_DEV(hdev, &serdev->dev);
|
||||
|
||||
device_property_read_u8_array(&nxpdev->serdev->dev,
|
||||
"local-bd-address",
|
||||
(u8 *)&ba, sizeof(ba));
|
||||
if (bacmp(&ba, BDADDR_ANY))
|
||||
set_bit(HCI_QUIRK_USE_BDADDR_PROPERTY, &hdev->quirks);
|
||||
|
||||
if (hci_register_dev(hdev) < 0) {
|
||||
dev_err(&serdev->dev, "Can't register HCI device\n");
|
||||
goto probe_fail;
|
||||
@@ -1556,6 +1780,8 @@ static int nxp_serdev_probe(struct serdev_device *serdev)
|
||||
if (ps_setup(hdev))
|
||||
goto probe_fail;
|
||||
|
||||
hci_devcd_register(hdev, nxp_coredump, nxp_coredump_hdr, NULL);
|
||||
|
||||
return 0;
|
||||
|
||||
probe_fail:
|
||||
@@ -1573,16 +1799,15 @@ static void nxp_serdev_remove(struct serdev_device *serdev)
|
||||
clear_bit(BTNXPUART_FW_DOWNLOADING, &nxpdev->tx_state);
|
||||
wake_up_interruptible(&nxpdev->check_boot_sign_wait_q);
|
||||
wake_up_interruptible(&nxpdev->fw_dnld_done_wait_q);
|
||||
} else {
|
||||
/* Restore FW baudrate to fw_init_baudrate if changed.
|
||||
* This will ensure FW baudrate is in sync with
|
||||
* driver baudrate in case this driver is re-inserted.
|
||||
*/
|
||||
if (nxpdev->current_baudrate != nxpdev->fw_init_baudrate) {
|
||||
nxpdev->new_baudrate = nxpdev->fw_init_baudrate;
|
||||
nxp_set_baudrate_cmd(hdev, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
if (test_bit(HCI_RUNNING, &hdev->flags)) {
|
||||
/* Ensure shutdown callback is executed before unregistering, so
|
||||
* that baudrate is reset to initial value.
|
||||
*/
|
||||
nxp_shutdown(hdev);
|
||||
}
|
||||
|
||||
ps_cleanup(nxpdev);
|
||||
hci_unregister_dev(hdev);
|
||||
hci_free_dev(hdev);
|
||||
@@ -1608,6 +1833,17 @@ static int nxp_serdev_resume(struct device *dev)
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_DEV_COREDUMP
|
||||
static void nxp_serdev_coredump(struct device *dev)
|
||||
{
|
||||
struct btnxpuart_dev *nxpdev = dev_get_drvdata(dev);
|
||||
struct hci_dev *hdev = nxpdev->hdev;
|
||||
|
||||
if (hdev->dump.coredump)
|
||||
hdev->dump.coredump(hdev);
|
||||
}
|
||||
#endif
|
||||
|
||||
static struct btnxpuart_data w8987_data __maybe_unused = {
|
||||
.helper_fw_name = NULL,
|
||||
.fw_name = FIRMWARE_W8987,
|
||||
@@ -1638,6 +1874,9 @@ static struct serdev_device_driver nxp_serdev_driver = {
|
||||
.name = "btnxpuart",
|
||||
.of_match_table = of_match_ptr(nxpuart_of_match_table),
|
||||
.pm = &nxp_pm_ops,
|
||||
#ifdef CONFIG_DEV_COREDUMP
|
||||
.coredump = nxp_serdev_coredump,
|
||||
#endif
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
@@ -785,6 +785,7 @@ int qca_uart_setup(struct hci_dev *hdev, uint8_t baudrate,
|
||||
const char *firmware_name, const char *rampatch_name)
|
||||
{
|
||||
struct qca_fw_config config = {};
|
||||
const char *variant = "";
|
||||
int err;
|
||||
u8 rom_ver = 0;
|
||||
u32 soc_ver;
|
||||
@@ -815,6 +816,10 @@ int qca_uart_setup(struct hci_dev *hdev, uint8_t baudrate,
|
||||
snprintf(config.fwname, sizeof(config.fwname), "qca/%s", rampatch_name);
|
||||
} else {
|
||||
switch (soc_type) {
|
||||
case QCA_WCN3950:
|
||||
snprintf(config.fwname, sizeof(config.fwname),
|
||||
"qca/cmbtfw%02x.tlv", rom_ver);
|
||||
break;
|
||||
case QCA_WCN3990:
|
||||
case QCA_WCN3991:
|
||||
case QCA_WCN3998:
|
||||
@@ -880,16 +885,23 @@ int qca_uart_setup(struct hci_dev *hdev, uint8_t baudrate,
|
||||
}
|
||||
} else {
|
||||
switch (soc_type) {
|
||||
case QCA_WCN3950:
|
||||
if (le32_to_cpu(ver.soc_id) == QCA_WCN3950_SOC_ID_T)
|
||||
variant = "t";
|
||||
else if (le32_to_cpu(ver.soc_id) == QCA_WCN3950_SOC_ID_S)
|
||||
variant = "u";
|
||||
|
||||
snprintf(config.fwname, sizeof(config.fwname),
|
||||
"qca/cmnv%02x%s.bin", rom_ver, variant);
|
||||
break;
|
||||
case QCA_WCN3990:
|
||||
case QCA_WCN3991:
|
||||
case QCA_WCN3998:
|
||||
if (le32_to_cpu(ver.soc_id) == QCA_WCN3991_SOC_ID) {
|
||||
snprintf(config.fwname, sizeof(config.fwname),
|
||||
"qca/crnv%02xu.bin", rom_ver);
|
||||
} else {
|
||||
snprintf(config.fwname, sizeof(config.fwname),
|
||||
"qca/crnv%02x.bin", rom_ver);
|
||||
}
|
||||
if (le32_to_cpu(ver.soc_id) == QCA_WCN3991_SOC_ID)
|
||||
variant = "u";
|
||||
|
||||
snprintf(config.fwname, sizeof(config.fwname),
|
||||
"qca/crnv%02x%s.bin", rom_ver, variant);
|
||||
break;
|
||||
case QCA_WCN3988:
|
||||
snprintf(config.fwname, sizeof(config.fwname),
|
||||
@@ -948,6 +960,7 @@ int qca_uart_setup(struct hci_dev *hdev, uint8_t baudrate,
|
||||
* VsMsftOpCode.
|
||||
*/
|
||||
switch (soc_type) {
|
||||
case QCA_WCN3950:
|
||||
case QCA_WCN3988:
|
||||
case QCA_WCN3990:
|
||||
case QCA_WCN3991:
|
||||
|
||||
@@ -41,6 +41,9 @@
|
||||
|
||||
#define QCA_WCN3991_SOC_ID 0x40014320
|
||||
|
||||
#define QCA_WCN3950_SOC_ID_T 0x40074130
|
||||
#define QCA_WCN3950_SOC_ID_S 0x40075130
|
||||
|
||||
/* QCA chipset version can be decided by patch and SoC
|
||||
* version, combination with upper 2 bytes from SoC
|
||||
* and lower 2 bytes from patch will be used.
|
||||
@@ -145,6 +148,7 @@ enum qca_btsoc_type {
|
||||
QCA_INVALID = -1,
|
||||
QCA_AR3002,
|
||||
QCA_ROME,
|
||||
QCA_WCN3950,
|
||||
QCA_WCN3988,
|
||||
QCA_WCN3990,
|
||||
QCA_WCN3998,
|
||||
|
||||
@@ -376,10 +376,38 @@ static const struct usb_device_id quirks_table[] = {
|
||||
BTUSB_WIDEBAND_SPEECH },
|
||||
{ USB_DEVICE(0x0489, 0xe0f3), .driver_info = BTUSB_QCA_WCN6855 |
|
||||
BTUSB_WIDEBAND_SPEECH },
|
||||
{ USB_DEVICE(0x0489, 0xe100), .driver_info = BTUSB_QCA_WCN6855 |
|
||||
BTUSB_WIDEBAND_SPEECH },
|
||||
{ USB_DEVICE(0x0489, 0xe103), .driver_info = BTUSB_QCA_WCN6855 |
|
||||
BTUSB_WIDEBAND_SPEECH },
|
||||
{ USB_DEVICE(0x0489, 0xe10a), .driver_info = BTUSB_QCA_WCN6855 |
|
||||
BTUSB_WIDEBAND_SPEECH },
|
||||
{ USB_DEVICE(0x0489, 0xe10d), .driver_info = BTUSB_QCA_WCN6855 |
|
||||
BTUSB_WIDEBAND_SPEECH },
|
||||
{ USB_DEVICE(0x0489, 0xe11b), .driver_info = BTUSB_QCA_WCN6855 |
|
||||
BTUSB_WIDEBAND_SPEECH },
|
||||
{ USB_DEVICE(0x0489, 0xe11c), .driver_info = BTUSB_QCA_WCN6855 |
|
||||
BTUSB_WIDEBAND_SPEECH },
|
||||
{ USB_DEVICE(0x0489, 0xe11f), .driver_info = BTUSB_QCA_WCN6855 |
|
||||
BTUSB_WIDEBAND_SPEECH },
|
||||
{ USB_DEVICE(0x0489, 0xe141), .driver_info = BTUSB_QCA_WCN6855 |
|
||||
BTUSB_WIDEBAND_SPEECH },
|
||||
{ USB_DEVICE(0x0489, 0xe14a), .driver_info = BTUSB_QCA_WCN6855 |
|
||||
BTUSB_WIDEBAND_SPEECH },
|
||||
{ USB_DEVICE(0x0489, 0xe14b), .driver_info = BTUSB_QCA_WCN6855 |
|
||||
BTUSB_WIDEBAND_SPEECH },
|
||||
{ USB_DEVICE(0x0489, 0xe14d), .driver_info = BTUSB_QCA_WCN6855 |
|
||||
BTUSB_WIDEBAND_SPEECH },
|
||||
{ USB_DEVICE(0x13d3, 0x3623), .driver_info = BTUSB_QCA_WCN6855 |
|
||||
BTUSB_WIDEBAND_SPEECH },
|
||||
{ USB_DEVICE(0x13d3, 0x3624), .driver_info = BTUSB_QCA_WCN6855 |
|
||||
BTUSB_WIDEBAND_SPEECH },
|
||||
{ USB_DEVICE(0x2c7c, 0x0130), .driver_info = BTUSB_QCA_WCN6855 |
|
||||
BTUSB_WIDEBAND_SPEECH },
|
||||
{ USB_DEVICE(0x2c7c, 0x0131), .driver_info = BTUSB_QCA_WCN6855 |
|
||||
BTUSB_WIDEBAND_SPEECH },
|
||||
{ USB_DEVICE(0x2c7c, 0x0132), .driver_info = BTUSB_QCA_WCN6855 |
|
||||
BTUSB_WIDEBAND_SPEECH },
|
||||
|
||||
/* Broadcom BCM2035 */
|
||||
{ USB_DEVICE(0x0a5c, 0x2009), .driver_info = BTUSB_BCM92035 },
|
||||
@@ -640,6 +668,10 @@ static const struct usb_device_id quirks_table[] = {
|
||||
BTUSB_WIDEBAND_SPEECH },
|
||||
{ USB_DEVICE(0x0489, 0xe102), .driver_info = BTUSB_MEDIATEK |
|
||||
BTUSB_WIDEBAND_SPEECH },
|
||||
{ USB_DEVICE(0x0489, 0xe152), .driver_info = BTUSB_MEDIATEK |
|
||||
BTUSB_WIDEBAND_SPEECH },
|
||||
{ USB_DEVICE(0x0489, 0xe153), .driver_info = BTUSB_MEDIATEK |
|
||||
BTUSB_WIDEBAND_SPEECH },
|
||||
{ USB_DEVICE(0x04ca, 0x3804), .driver_info = BTUSB_MEDIATEK |
|
||||
BTUSB_WIDEBAND_SPEECH },
|
||||
{ USB_DEVICE(0x04ca, 0x38e4), .driver_info = BTUSB_MEDIATEK |
|
||||
@@ -2477,6 +2509,8 @@ static int btusb_setup_csr(struct hci_dev *hdev)
|
||||
set_bit(HCI_QUIRK_BROKEN_ERR_DATA_REPORTING, &hdev->quirks);
|
||||
set_bit(HCI_QUIRK_BROKEN_FILTER_CLEAR_ALL, &hdev->quirks);
|
||||
set_bit(HCI_QUIRK_NO_SUSPEND_NOTIFIER, &hdev->quirks);
|
||||
set_bit(HCI_QUIRK_BROKEN_READ_VOICE_SETTING, &hdev->quirks);
|
||||
set_bit(HCI_QUIRK_BROKEN_READ_PAGE_SCAN_TYPE, &hdev->quirks);
|
||||
|
||||
/* Clear the reset quirk since this is not an actual
|
||||
* early Bluetooth 1.1 device from CSR.
|
||||
@@ -2688,7 +2722,7 @@ static void btusb_mtk_claim_iso_intf(struct btusb_data *data)
|
||||
device_unlock(&btmtk_data->isopkt_intf->dev);
|
||||
if (err < 0) {
|
||||
btmtk_data->isopkt_intf = NULL;
|
||||
bt_dev_err(data->hdev, "Failed to claim iso interface");
|
||||
bt_dev_err(data->hdev, "Failed to claim iso interface: %d", err);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -102,7 +102,8 @@ static inline struct sk_buff *hci_uart_dequeue(struct hci_uart *hu)
|
||||
if (!skb) {
|
||||
percpu_down_read(&hu->proto_lock);
|
||||
|
||||
if (test_bit(HCI_UART_PROTO_READY, &hu->flags))
|
||||
if (test_bit(HCI_UART_PROTO_READY, &hu->flags) ||
|
||||
test_bit(HCI_UART_PROTO_INIT, &hu->flags))
|
||||
skb = hu->proto->dequeue(hu);
|
||||
|
||||
percpu_up_read(&hu->proto_lock);
|
||||
@@ -124,7 +125,8 @@ int hci_uart_tx_wakeup(struct hci_uart *hu)
|
||||
if (!percpu_down_read_trylock(&hu->proto_lock))
|
||||
return 0;
|
||||
|
||||
if (!test_bit(HCI_UART_PROTO_READY, &hu->flags))
|
||||
if (!test_bit(HCI_UART_PROTO_READY, &hu->flags) &&
|
||||
!test_bit(HCI_UART_PROTO_INIT, &hu->flags))
|
||||
goto no_schedule;
|
||||
|
||||
set_bit(HCI_UART_TX_WAKEUP, &hu->tx_state);
|
||||
@@ -278,7 +280,8 @@ static int hci_uart_send_frame(struct hci_dev *hdev, struct sk_buff *skb)
|
||||
|
||||
percpu_down_read(&hu->proto_lock);
|
||||
|
||||
if (!test_bit(HCI_UART_PROTO_READY, &hu->flags)) {
|
||||
if (!test_bit(HCI_UART_PROTO_READY, &hu->flags) &&
|
||||
!test_bit(HCI_UART_PROTO_INIT, &hu->flags)) {
|
||||
percpu_up_read(&hu->proto_lock);
|
||||
return -EUNATCH;
|
||||
}
|
||||
@@ -585,7 +588,8 @@ static void hci_uart_tty_wakeup(struct tty_struct *tty)
|
||||
if (tty != hu->tty)
|
||||
return;
|
||||
|
||||
if (test_bit(HCI_UART_PROTO_READY, &hu->flags))
|
||||
if (test_bit(HCI_UART_PROTO_READY, &hu->flags) ||
|
||||
test_bit(HCI_UART_PROTO_INIT, &hu->flags))
|
||||
hci_uart_tx_wakeup(hu);
|
||||
}
|
||||
|
||||
@@ -611,7 +615,8 @@ static void hci_uart_tty_receive(struct tty_struct *tty, const u8 *data,
|
||||
|
||||
percpu_down_read(&hu->proto_lock);
|
||||
|
||||
if (!test_bit(HCI_UART_PROTO_READY, &hu->flags)) {
|
||||
if (!test_bit(HCI_UART_PROTO_READY, &hu->flags) &&
|
||||
!test_bit(HCI_UART_PROTO_INIT, &hu->flags)) {
|
||||
percpu_up_read(&hu->proto_lock);
|
||||
return;
|
||||
}
|
||||
@@ -707,12 +712,16 @@ static int hci_uart_set_proto(struct hci_uart *hu, int id)
|
||||
|
||||
hu->proto = p;
|
||||
|
||||
set_bit(HCI_UART_PROTO_INIT, &hu->flags);
|
||||
|
||||
err = hci_uart_register_dev(hu);
|
||||
if (err) {
|
||||
return err;
|
||||
}
|
||||
|
||||
set_bit(HCI_UART_PROTO_READY, &hu->flags);
|
||||
clear_bit(HCI_UART_PROTO_INIT, &hu->flags);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -623,6 +623,7 @@ static int qca_open(struct hci_uart *hu)
|
||||
qcadev = serdev_device_get_drvdata(hu->serdev);
|
||||
|
||||
switch (qcadev->btsoc_type) {
|
||||
case QCA_WCN3950:
|
||||
case QCA_WCN3988:
|
||||
case QCA_WCN3990:
|
||||
case QCA_WCN3991:
|
||||
@@ -1366,6 +1367,7 @@ static int qca_set_baudrate(struct hci_dev *hdev, uint8_t baudrate)
|
||||
|
||||
/* Give the controller time to process the request */
|
||||
switch (qca_soc_type(hu)) {
|
||||
case QCA_WCN3950:
|
||||
case QCA_WCN3988:
|
||||
case QCA_WCN3990:
|
||||
case QCA_WCN3991:
|
||||
@@ -1452,6 +1454,7 @@ static unsigned int qca_get_speed(struct hci_uart *hu,
|
||||
static int qca_check_speeds(struct hci_uart *hu)
|
||||
{
|
||||
switch (qca_soc_type(hu)) {
|
||||
case QCA_WCN3950:
|
||||
case QCA_WCN3988:
|
||||
case QCA_WCN3990:
|
||||
case QCA_WCN3991:
|
||||
@@ -1494,6 +1497,7 @@ static int qca_set_speed(struct hci_uart *hu, enum qca_speed_type speed_type)
|
||||
* changing the baudrate of chip and host.
|
||||
*/
|
||||
switch (soc_type) {
|
||||
case QCA_WCN3950:
|
||||
case QCA_WCN3988:
|
||||
case QCA_WCN3990:
|
||||
case QCA_WCN3991:
|
||||
@@ -1528,6 +1532,7 @@ static int qca_set_speed(struct hci_uart *hu, enum qca_speed_type speed_type)
|
||||
|
||||
error:
|
||||
switch (soc_type) {
|
||||
case QCA_WCN3950:
|
||||
case QCA_WCN3988:
|
||||
case QCA_WCN3990:
|
||||
case QCA_WCN3991:
|
||||
@@ -1746,6 +1751,7 @@ static int qca_regulator_init(struct hci_uart *hu)
|
||||
}
|
||||
|
||||
switch (soc_type) {
|
||||
case QCA_WCN3950:
|
||||
case QCA_WCN3988:
|
||||
case QCA_WCN3990:
|
||||
case QCA_WCN3991:
|
||||
@@ -1776,6 +1782,7 @@ static int qca_regulator_init(struct hci_uart *hu)
|
||||
qca_set_speed(hu, QCA_INIT_SPEED);
|
||||
|
||||
switch (soc_type) {
|
||||
case QCA_WCN3950:
|
||||
case QCA_WCN3988:
|
||||
case QCA_WCN3990:
|
||||
case QCA_WCN3991:
|
||||
@@ -1807,6 +1814,7 @@ static int qca_power_on(struct hci_dev *hdev)
|
||||
return 0;
|
||||
|
||||
switch (soc_type) {
|
||||
case QCA_WCN3950:
|
||||
case QCA_WCN3988:
|
||||
case QCA_WCN3990:
|
||||
case QCA_WCN3991:
|
||||
@@ -1891,6 +1899,7 @@ static int qca_setup(struct hci_uart *hu)
|
||||
soc_name = "qca2066";
|
||||
break;
|
||||
|
||||
case QCA_WCN3950:
|
||||
case QCA_WCN3988:
|
||||
case QCA_WCN3990:
|
||||
case QCA_WCN3991:
|
||||
@@ -1925,6 +1934,7 @@ retry:
|
||||
clear_bit(QCA_SSR_TRIGGERED, &qca->flags);
|
||||
|
||||
switch (soc_type) {
|
||||
case QCA_WCN3950:
|
||||
case QCA_WCN3988:
|
||||
case QCA_WCN3990:
|
||||
case QCA_WCN3991:
|
||||
@@ -1958,6 +1968,7 @@ retry:
|
||||
}
|
||||
|
||||
switch (soc_type) {
|
||||
case QCA_WCN3950:
|
||||
case QCA_WCN3988:
|
||||
case QCA_WCN3990:
|
||||
case QCA_WCN3991:
|
||||
@@ -2046,6 +2057,17 @@ static const struct hci_uart_proto qca_proto = {
|
||||
.dequeue = qca_dequeue,
|
||||
};
|
||||
|
||||
static const struct qca_device_data qca_soc_data_wcn3950 __maybe_unused = {
|
||||
.soc_type = QCA_WCN3950,
|
||||
.vregs = (struct qca_vreg []) {
|
||||
{ "vddio", 15000 },
|
||||
{ "vddxo", 60000 },
|
||||
{ "vddrf", 155000 },
|
||||
{ "vddch0", 585000 },
|
||||
},
|
||||
.num_vregs = 4,
|
||||
};
|
||||
|
||||
static const struct qca_device_data qca_soc_data_wcn3988 __maybe_unused = {
|
||||
.soc_type = QCA_WCN3988,
|
||||
.vregs = (struct qca_vreg []) {
|
||||
@@ -2338,6 +2360,7 @@ static int qca_serdev_probe(struct serdev_device *serdev)
|
||||
qcadev->btsoc_type = QCA_ROME;
|
||||
|
||||
switch (qcadev->btsoc_type) {
|
||||
case QCA_WCN3950:
|
||||
case QCA_WCN3988:
|
||||
case QCA_WCN3990:
|
||||
case QCA_WCN3991:
|
||||
@@ -2359,6 +2382,7 @@ static int qca_serdev_probe(struct serdev_device *serdev)
|
||||
switch (qcadev->btsoc_type) {
|
||||
case QCA_WCN6855:
|
||||
case QCA_WCN7850:
|
||||
case QCA_WCN6750:
|
||||
if (!device_property_present(&serdev->dev, "enable-gpios")) {
|
||||
/*
|
||||
* Backward compatibility with old DT sources. If the
|
||||
@@ -2374,11 +2398,11 @@ static int qca_serdev_probe(struct serdev_device *serdev)
|
||||
break;
|
||||
}
|
||||
fallthrough;
|
||||
case QCA_WCN3950:
|
||||
case QCA_WCN3988:
|
||||
case QCA_WCN3990:
|
||||
case QCA_WCN3991:
|
||||
case QCA_WCN3998:
|
||||
case QCA_WCN6750:
|
||||
qcadev->bt_power->dev = &serdev->dev;
|
||||
err = qca_init_regulators(qcadev->bt_power, data->vregs,
|
||||
data->num_vregs);
|
||||
@@ -2683,6 +2707,7 @@ static const struct of_device_id qca_bluetooth_of_match[] = {
|
||||
{ .compatible = "qcom,qca6174-bt" },
|
||||
{ .compatible = "qcom,qca6390-bt", .data = &qca_soc_data_qca6390},
|
||||
{ .compatible = "qcom,qca9377-bt" },
|
||||
{ .compatible = "qcom,wcn3950-bt", .data = &qca_soc_data_wcn3950},
|
||||
{ .compatible = "qcom,wcn3988-bt", .data = &qca_soc_data_wcn3988},
|
||||
{ .compatible = "qcom,wcn3990-bt", .data = &qca_soc_data_wcn3990},
|
||||
{ .compatible = "qcom,wcn3991-bt", .data = &qca_soc_data_wcn3991},
|
||||
|
||||
@@ -90,6 +90,7 @@ struct hci_uart {
|
||||
#define HCI_UART_REGISTERED 1
|
||||
#define HCI_UART_PROTO_READY 2
|
||||
#define HCI_UART_NO_SUSPEND_NOTIFIER 3
|
||||
#define HCI_UART_PROTO_INIT 4
|
||||
|
||||
/* TX states */
|
||||
#define HCI_UART_SENDING 1
|
||||
|
||||
@@ -316,7 +316,7 @@ static inline void force_devcd_timeout(struct hci_dev *hdev,
|
||||
unsigned int timeout)
|
||||
{
|
||||
#ifdef CONFIG_DEV_COREDUMP
|
||||
hdev->dump.timeout = msecs_to_jiffies(timeout * 1000);
|
||||
hdev->dump.timeout = secs_to_jiffies(timeout);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -416,6 +416,7 @@ static int __vhci_create_device(struct vhci_data *data, __u8 opcode)
|
||||
hdev->wakeup = vhci_wakeup;
|
||||
hdev->setup = vhci_setup;
|
||||
set_bit(HCI_QUIRK_NON_PERSISTENT_SETUP, &hdev->quirks);
|
||||
set_bit(HCI_QUIRK_SYNC_FLOWCTL_SUPPORTED, &hdev->quirks);
|
||||
|
||||
/* bit 6 is for external configuration */
|
||||
if (opcode & 0x40)
|
||||
@@ -645,7 +646,7 @@ static int vhci_open(struct inode *inode, struct file *file)
|
||||
file->private_data = data;
|
||||
nonseekable_open(inode, file);
|
||||
|
||||
schedule_delayed_work(&data->open_timeout, msecs_to_jiffies(1000));
|
||||
schedule_delayed_work(&data->open_timeout, secs_to_jiffies(1));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -443,8 +443,11 @@ static void dpll_pin_prop_free(struct dpll_pin_properties *prop)
|
||||
static int dpll_pin_prop_dup(const struct dpll_pin_properties *src,
|
||||
struct dpll_pin_properties *dst)
|
||||
{
|
||||
if (WARN_ON(src->freq_supported && !src->freq_supported_num))
|
||||
return -EINVAL;
|
||||
|
||||
memcpy(dst, src, sizeof(*dst));
|
||||
if (src->freq_supported && src->freq_supported_num) {
|
||||
if (src->freq_supported) {
|
||||
size_t freq_size = src->freq_supported_num *
|
||||
sizeof(*src->freq_supported);
|
||||
dst->freq_supported = kmemdup(src->freq_supported,
|
||||
|
||||
@@ -203,6 +203,15 @@ static void of_gpio_try_fixup_polarity(const struct device_node *np,
|
||||
*/
|
||||
{ "qi,lb60", "rb-gpios", true },
|
||||
#endif
|
||||
#if IS_ENABLED(CONFIG_IEEE802154_CA8210)
|
||||
/*
|
||||
* According to the datasheet, the NRST pin 27 is an active-low
|
||||
* signal. However, the device tree schema and admittedly
|
||||
* the out-of-tree implementations have been used for a long
|
||||
* time incorrectly by describing reset GPIO as active-high.
|
||||
*/
|
||||
{ "cascoda,ca8210", "reset-gpio", false },
|
||||
#endif
|
||||
#if IS_ENABLED(CONFIG_PCI_LANTIQ)
|
||||
/*
|
||||
* According to the PCI specification, the RST# pin is an
|
||||
|
||||
@@ -498,8 +498,6 @@ static int irdma_save_msix_info(struct irdma_pci_f *rf)
|
||||
iw_qvlist->num_vectors = rf->msix_count;
|
||||
if (rf->msix_count <= num_online_cpus())
|
||||
rf->msix_shared = true;
|
||||
else if (rf->msix_count > num_online_cpus() + 1)
|
||||
rf->msix_count = num_online_cpus() + 1;
|
||||
|
||||
pmsix = rf->msix_entries;
|
||||
for (i = 0, ceq_idx = 0; i < rf->msix_count; i++, iw_qvinfo++) {
|
||||
|
||||
@@ -206,6 +206,43 @@ static void irdma_lan_unregister_qset(struct irdma_sc_vsi *vsi,
|
||||
ibdev_dbg(&iwdev->ibdev, "WS: LAN free_res for rdma qset failed.\n");
|
||||
}
|
||||
|
||||
static int irdma_init_interrupts(struct irdma_pci_f *rf, struct ice_pf *pf)
|
||||
{
|
||||
int i;
|
||||
|
||||
rf->msix_count = num_online_cpus() + IRDMA_NUM_AEQ_MSIX;
|
||||
rf->msix_entries = kcalloc(rf->msix_count, sizeof(*rf->msix_entries),
|
||||
GFP_KERNEL);
|
||||
if (!rf->msix_entries)
|
||||
return -ENOMEM;
|
||||
|
||||
for (i = 0; i < rf->msix_count; i++)
|
||||
if (ice_alloc_rdma_qvector(pf, &rf->msix_entries[i]))
|
||||
break;
|
||||
|
||||
if (i < IRDMA_MIN_MSIX) {
|
||||
for (; i > 0; i--)
|
||||
ice_free_rdma_qvector(pf, &rf->msix_entries[i]);
|
||||
|
||||
kfree(rf->msix_entries);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
rf->msix_count = i;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void irdma_deinit_interrupts(struct irdma_pci_f *rf, struct ice_pf *pf)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < rf->msix_count; i++)
|
||||
ice_free_rdma_qvector(pf, &rf->msix_entries[i]);
|
||||
|
||||
kfree(rf->msix_entries);
|
||||
}
|
||||
|
||||
static void irdma_remove(struct auxiliary_device *aux_dev)
|
||||
{
|
||||
struct iidc_auxiliary_dev *iidc_adev = container_of(aux_dev,
|
||||
@@ -216,6 +253,7 @@ static void irdma_remove(struct auxiliary_device *aux_dev)
|
||||
|
||||
irdma_ib_unregister_device(iwdev);
|
||||
ice_rdma_update_vsi_filter(pf, iwdev->vsi_num, false);
|
||||
irdma_deinit_interrupts(iwdev->rf, pf);
|
||||
|
||||
pr_debug("INIT: Gen2 PF[%d] device remove success\n", PCI_FUNC(pf->pdev->devfn));
|
||||
}
|
||||
@@ -230,9 +268,7 @@ static void irdma_fill_device_info(struct irdma_device *iwdev, struct ice_pf *pf
|
||||
rf->gen_ops.unregister_qset = irdma_lan_unregister_qset;
|
||||
rf->hw.hw_addr = pf->hw.hw_addr;
|
||||
rf->pcidev = pf->pdev;
|
||||
rf->msix_count = pf->num_rdma_msix;
|
||||
rf->pf_id = pf->hw.pf_id;
|
||||
rf->msix_entries = &pf->msix_entries[pf->rdma_base_vector];
|
||||
rf->default_vsi.vsi_idx = vsi->vsi_num;
|
||||
rf->protocol_used = pf->rdma_mode & IIDC_RDMA_PROTOCOL_ROCEV2 ?
|
||||
IRDMA_ROCE_PROTOCOL_ONLY : IRDMA_IWARP_PROTOCOL_ONLY;
|
||||
@@ -281,6 +317,10 @@ static int irdma_probe(struct auxiliary_device *aux_dev, const struct auxiliary_
|
||||
irdma_fill_device_info(iwdev, pf, vsi);
|
||||
rf = iwdev->rf;
|
||||
|
||||
err = irdma_init_interrupts(rf, pf);
|
||||
if (err)
|
||||
goto err_init_interrupts;
|
||||
|
||||
err = irdma_ctrl_init_hw(rf);
|
||||
if (err)
|
||||
goto err_ctrl_init;
|
||||
@@ -311,6 +351,8 @@ err_ibreg:
|
||||
err_rt_init:
|
||||
irdma_ctrl_deinit_hw(rf);
|
||||
err_ctrl_init:
|
||||
irdma_deinit_interrupts(rf, pf);
|
||||
err_init_interrupts:
|
||||
kfree(iwdev->rf);
|
||||
ib_dealloc_device(&iwdev->ibdev);
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user