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