Commit a47ab26b authored by David S. Miller's avatar David S. Miller

Merge branch 'net-ethernet-ti-add-networking-support-for-k3-am65x-j721e-soc'

Grygorii Strashko says:

====================
net: ethernet: ti: add networking support for k3 am65x/j721e soc

This v6 series adds basic networking support support TI K3 AM654x/J721E SoC which
have integrated Gigabit Ethernet MAC (Media Access Controller) into device MCU
domain and named MCU_CPSW0 (CPSW2G NUSS).

Formally TRMs refer CPSW2G NUSS as two-port Gigabit Ethernet Switch subsystem
with port 0 being the CPPI DMA host port and port 1 being the external Ethernet
port, but for 1 external port device it's just Port 0 <-> ALE <-> Port 1 and it's
rather device with HW filtering capabilities then actually switching device.
It's expected to have similar devices, but with more external ports.

The new Host port 0 Communications Port Programming Interface (CPPI5) is
operating by TI AM654x/J721E NAVSS Unified DMA Peripheral Root Complex (UDMA-P)
controller [1].

The CPSW2G contains below modules for which existing code is re-used:
 - MAC SL: cpsw_sl.c
 - Address Lookup Engine (ALE): cpsw_ale.c, basically compatible with K2 66AK2E/G
 - Management Data Input/Output interface (MDIO): davinci_mdio.c, fully
   compatible with TI AM3/4/5 devices

Basic features supported by CPSW2G NUSS driver:
 - VLAN support, 802.1Q compliant, Auto add port VLAN for untagged frames on
   ingress, Auto VLAN removal on egress and auto pad to minimum frame size.
 - multicast filtering
 - promisc mode
 - TX multiq support in Round Robin or Fixed priority modes
 - RX checksum offload for non-fragmented IPv4/IPv6 TCP/UDP packets
 - TX checksum offload support for IPv4/IPv6 TCP/UDP packets (J721E only).

Features under development:
 - Support for IEEE 1588 Clock Synchronization. The CPSW2G NUSS includes new
   version of Common Platform Time Sync (CPTS)
 - tc-mqprio: priority level Quality Of Service (QOS) support (802.1p)
 - tc-cbs: Support for Audio/Video Bridging (P802.1Qav/D6.0) HW shapers
 - tc-taprio: IEEE 802.1Qbv/D2.2 Enhancements for Scheduled Traffic
 - frame preemption: IEEE P902.3br/D2.0 Interspersing Express Traffic, 802.1Qbu
 - extended ALE features: classifier/policers, auto-aging

Patches 1-6 are intended for netdev, Patches 7-11 are intended for K3 Platform
tree and provided here for testing purposes.

Changes in v6:
 - fixed comments from Rob Herring <robh@kernel.org> and added his Reviewed-by.
 - added Tested-by: Peter Ujfalusi <peter.ujfalusi@ti.com>

Changes in v5:
 - renamed files k3-udma-desc-pool.*  k3-udma-desc-pool to k3-cppi-desc-pool.*,
   and API to k3_cppi_desc_pool_* as requested by Peter Ujfalusi <peter.ujfalusi@ti.com>
 - fixed copy-paste err in am65_cpsw_nuss_ndo_slave_set_rx_mode() which blocked
   recieving of mcast frames.
 - added Tested-by: Murali Karicheri <m-karicheri2@ti.com>

Changes in v4:
 - fixed minor comments from Jakub Kicinski <kuba@kernel.org>
 - dependencies resolved: required phy-rmii-sel changes [2] queued for merge
   except one [3] which is included in this series with Kishon's ask.

Changes in v3:
 - add ARM64 defconfig changes for testing purposes
 - fixed DT yaml definition
 - fixed comments from Jakub Kicinski <kuba@kernel.org>

Changes in v2:
 - fixed DT yaml definition
 - fixed comments from David Miller

v5: https://patchwork.ozlabs.org/cover/1258295/
v4: https://patchwork.ozlabs.org/cover/1256092/
v3: https://patchwork.ozlabs.org/cover/1254568/
v2: https://patchwork.ozlabs.org/cover/1250674/
v1: https://lwn.net/Articles/813087/

TRMs:
 AM654: http://www.ti.com/lit/ug/spruid7e/spruid7e.pdf
 J721E: http://www.ti.com/lit/ug/spruil1a/spruil1a.pdf

Preliminary documentation can be found at:
 http://software-dl.ti.com/processor-sdk-linux/esd/docs/latest/linux/Foundational_Components/Kernel/Kernel_Drivers/Network/K3_CPSW2g.html

[1] https://lwn.net/Articles/808030/
[2] https://lkml.org/lkml/2020/2/22/100
[3] https://lkml.org/lkml/2020/3/3/724
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 5bb7357f cae21a48
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/net/ti,k3-am654-cpsw-nuss.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: The TI AM654x/J721E SoC Gigabit Ethernet MAC (Media Access Controller) Device Tree Bindings
maintainers:
- Grygorii Strashko <grygorii.strashko@ti.com>
- Sekhar Nori <nsekhar@ti.com>
description:
The TI AM654x/J721E SoC Gigabit Ethernet MAC (CPSW2G NUSS) has two ports
(one external) and provides Ethernet packet communication for the device.
CPSW2G NUSS features - the Reduced Gigabit Media Independent Interface (RGMII),
Reduced Media Independent Interface (RMII), the Management Data
Input/Output (MDIO) interface for physical layer device (PHY) management,
new version of Common Platform Time Sync (CPTS), updated Address Lookup
Engine (ALE).
One external Ethernet port (port 1) with selectable RGMII/RMII interfaces and
an internal Communications Port Programming Interface (CPPI5) (Host port 0).
Host Port 0 CPPI Packet Streaming Interface interface supports 8 TX channels
and one RX channels and operating by TI AM654x/J721E NAVSS Unified DMA
Peripheral Root Complex (UDMA-P) controller.
The CPSW2G NUSS is integrated into device MCU domain named MCU_CPSW0.
Additional features
priority level Quality Of Service (QOS) support (802.1p)
Support for Audio/Video Bridging (P802.1Qav/D6.0)
Support for IEEE 1588 Clock Synchronization (2008 Annex D, Annex E and Annex F)
Flow Control (802.3x) Support
Time Sensitive Network Support
IEEE P902.3br/D2.0 Interspersing Express Traffic
IEEE 802.1Qbv/D2.2 Enhancements for Scheduled Traffic
Configurable number of addresses plus VLANs
Configurable number of classifier/policers
VLAN support, 802.1Q compliant, Auto add port VLAN for untagged frames on
ingress, Auto VLAN removal on egress and auto pad to minimum frame size.
RX/TX csum offload
Specifications can be found at
http://www.ti.com/lit/ug/spruid7e/spruid7e.pdf
http://www.ti.com/lit/ug/spruil1a/spruil1a.pdf
properties:
"#address-cells": true
"#size-cells": true
compatible:
oneOf:
- const: ti,am654-cpsw-nuss
- const: ti,j721e-cpsw-nuss
reg:
maxItems: 1
description:
The physical base address and size of full the CPSW2G NUSS IO range
reg-names:
items:
- const: cpsw_nuss
ranges: true
dma-coherent: true
clocks:
description: CPSW2G NUSS functional clock
clock-names:
items:
- const: fck
power-domains:
maxItems: 1
dmas:
maxItems: 9
dma-names:
items:
- const: tx0
- const: tx1
- const: tx2
- const: tx3
- const: tx4
- const: tx5
- const: tx6
- const: tx7
- const: rx
ethernet-ports:
type: object
properties:
'#address-cells':
const: 1
'#size-cells':
const: 0
patternProperties:
port@1:
type: object
description: CPSW2G NUSS external ports
allOf:
- $ref: ethernet-controller.yaml#
properties:
reg:
items:
- const: 1
description: CPSW port number
phys:
maxItems: 1
description: phandle on phy-gmii-sel PHY
label:
description: label associated with this port
ti,mac-only:
$ref: /schemas/types.yaml#definitions/flag
description:
Specifies the port works in mac-only mode.
ti,syscon-efuse:
$ref: /schemas/types.yaml#definitions/phandle-array
description:
Phandle to the system control device node which provides access
to efuse IO range with MAC addresses
required:
- reg
- phys
additionalProperties: false
patternProperties:
"^mdio@[0-9a-f]+$":
type: object
allOf:
- $ref: "ti,davinci-mdio.yaml#"
description:
CPSW MDIO bus.
required:
- compatible
- reg
- reg-names
- ranges
- clocks
- clock-names
- power-domains
- dmas
- dma-names
- '#address-cells'
- '#size-cells'
additionalProperties: false
examples:
- |
#include <dt-bindings/pinctrl/k3.h>
#include <dt-bindings/soc/ti,sci_pm_domain.h>
#include <dt-bindings/net/ti-dp83867.h>
mcu_cpsw: ethernet@46000000 {
compatible = "ti,am654-cpsw-nuss";
#address-cells = <2>;
#size-cells = <2>;
reg = <0x0 0x46000000 0x0 0x200000>;
reg-names = "cpsw_nuss";
ranges = <0x0 0x0 0x46000000 0x0 0x200000>;
dma-coherent;
clocks = <&k3_clks 5 10>;
clock-names = "fck";
power-domains = <&k3_pds 5 TI_SCI_PD_EXCLUSIVE>;
pinctrl-names = "default";
pinctrl-0 = <&mcu_cpsw_pins_default &mcu_mdio_pins_default>;
dmas = <&mcu_udmap 0xf000>,
<&mcu_udmap 0xf001>,
<&mcu_udmap 0xf002>,
<&mcu_udmap 0xf003>,
<&mcu_udmap 0xf004>,
<&mcu_udmap 0xf005>,
<&mcu_udmap 0xf006>,
<&mcu_udmap 0xf007>,
<&mcu_udmap 0x7000>;
dma-names = "tx0", "tx1", "tx2", "tx3", "tx4", "tx5", "tx6", "tx7",
"rx";
ethernet-ports {
#address-cells = <1>;
#size-cells = <0>;
cpsw_port1: port@1 {
reg = <1>;
ti,mac-only;
label = "port1";
ti,syscon-efuse = <&mcu_conf 0x200>;
phys = <&phy_gmii_sel 1>;
phy-mode = "rgmii-rxid";
phy-handle = <&phy0>;
};
};
davinci_mdio: mdio@f00 {
compatible = "ti,cpsw-mdio","ti,davinci_mdio";
reg = <0x0 0xf00 0x0 0x100>;
#address-cells = <1>;
#size-cells = <0>;
clocks = <&k3_clks 5 10>;
clock-names = "fck";
bus_freq = <1000000>;
phy0: ethernet-phy@0 {
reg = <0>;
ti,rx-internal-delay = <DP83867_RGMIIDCTL_2_00_NS>;
ti,fifo-depth = <DP83867_PHYCR_FIFO_DEPTH_4_B_NIB>;
};
};
};
......@@ -187,4 +187,53 @@ ospi1: spi@47050000 {
#size-cells = <0>;
};
};
mcu_cpsw: ethernet@46000000 {
compatible = "ti,am654-cpsw-nuss";
#address-cells = <2>;
#size-cells = <2>;
reg = <0x0 0x46000000 0x0 0x200000>;
reg-names = "cpsw_nuss";
ranges = <0x0 0x0 0x0 0x46000000 0x0 0x200000>;
dma-coherent;
clocks = <&k3_clks 5 10>;
clock-names = "fck";
power-domains = <&k3_pds 5 TI_SCI_PD_EXCLUSIVE>;
dmas = <&mcu_udmap 0xf000>,
<&mcu_udmap 0xf001>,
<&mcu_udmap 0xf002>,
<&mcu_udmap 0xf003>,
<&mcu_udmap 0xf004>,
<&mcu_udmap 0xf005>,
<&mcu_udmap 0xf006>,
<&mcu_udmap 0xf007>,
<&mcu_udmap 0x7000>;
dma-names = "tx0", "tx1", "tx2", "tx3",
"tx4", "tx5", "tx6", "tx7",
"rx";
ethernet-ports {
#address-cells = <1>;
#size-cells = <0>;
cpsw_port1: port@1 {
reg = <1>;
ti,mac-only;
label = "port1";
ti,syscon-efuse = <&mcu_conf 0x200>;
phys = <&phy_gmii_sel 1>;
};
};
davinci_mdio: mdio@f00 {
compatible = "ti,cpsw-mdio","ti,davinci_mdio";
reg = <0x0 0xf00 0x0 0x100>;
#address-cells = <1>;
#size-cells = <0>;
clocks = <&k3_clks 5 10>;
clock-names = "fck";
bus_freq = <1000000>;
};
};
};
......@@ -30,6 +30,7 @@ aliases {
i2c3 = &main_i2c1;
i2c4 = &main_i2c2;
i2c5 = &main_i2c3;
ethernet0 = &cpsw_port1;
};
chosen { };
......
......@@ -7,6 +7,7 @@
#include "k3-am654.dtsi"
#include <dt-bindings/input/input.h>
#include <dt-bindings/net/ti-dp83867.h>
/ {
compatible = "ti,am654-evm", "ti,am654";
......@@ -95,7 +96,30 @@ AM65X_WKUP_IOPAD(0x002c, PIN_OUTPUT, 0) /* (R4) MCU_OSPI0_CSn0 */
wkup_pca554_default: wkup_pca554_default {
pinctrl-single,pins = <
AM65X_WKUP_IOPAD(0x0034, PIN_INPUT, 7) /* (T1) MCU_OSPI1_CLK.WKUP_GPIO0_25 */
>;
};
mcu_cpsw_pins_default: mcu_cpsw_pins_default {
pinctrl-single,pins = <
AM65X_WKUP_IOPAD(0x0058, PIN_OUTPUT, 0) /* (N4) MCU_RGMII1_TX_CTL */
AM65X_WKUP_IOPAD(0x005c, PIN_INPUT, 0) /* (N5) MCU_RGMII1_RX_CTL */
AM65X_WKUP_IOPAD(0x0060, PIN_OUTPUT, 0) /* (M2) MCU_RGMII1_TD3 */
AM65X_WKUP_IOPAD(0x0064, PIN_OUTPUT, 0) /* (M3) MCU_RGMII1_TD2 */
AM65X_WKUP_IOPAD(0x0068, PIN_OUTPUT, 0) /* (M4) MCU_RGMII1_TD1 */
AM65X_WKUP_IOPAD(0x006c, PIN_OUTPUT, 0) /* (M5) MCU_RGMII1_TD0 */
AM65X_WKUP_IOPAD(0x0078, PIN_INPUT, 0) /* (L2) MCU_RGMII1_RD3 */
AM65X_WKUP_IOPAD(0x007c, PIN_INPUT, 0) /* (L5) MCU_RGMII1_RD2 */
AM65X_WKUP_IOPAD(0x0080, PIN_INPUT, 0) /* (M6) MCU_RGMII1_RD1 */
AM65X_WKUP_IOPAD(0x0084, PIN_INPUT, 0) /* (L6) MCU_RGMII1_RD0 */
AM65X_WKUP_IOPAD(0x0070, PIN_INPUT, 0) /* (N1) MCU_RGMII1_TXC */
AM65X_WKUP_IOPAD(0x0074, PIN_INPUT, 0) /* (M1) MCU_RGMII1_RXC */
>;
};
mcu_mdio_pins_default: mcu_mdio1_pins_default {
pinctrl-single,pins = <
AM65X_WKUP_IOPAD(0x008c, PIN_OUTPUT, 0) /* (L1) MCU_MDIO0_MDC */
AM65X_WKUP_IOPAD(0x0088, PIN_INPUT, 0) /* (L4) MCU_MDIO0_MDIO */
>;
};
};
......@@ -419,3 +443,21 @@ csi2_phy0: endpoint {
data-lanes = <1 2>;
};
};
&mcu_cpsw {
pinctrl-names = "default";
pinctrl-0 = <&mcu_cpsw_pins_default &mcu_mdio_pins_default>;
};
&davinci_mdio {
phy0: ethernet-phy@0 {
reg = <0>;
ti,rx-internal-delay = <DP83867_RGMIIDCTL_2_00_NS>;
ti,fifo-depth = <DP83867_PHYCR_FIFO_DEPTH_4_B_NIB>;
};
};
&cpsw_port1 {
phy-mode = "rgmii-rxid";
phy-handle = <&phy0>;
};
......@@ -8,6 +8,7 @@
#include "k3-j721e-som-p0.dtsi"
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/input/input.h>
#include <dt-bindings/net/ti-dp83867.h>
/ {
chosen {
......@@ -128,6 +129,30 @@ J721E_WKUP_IOPAD(0x3c, PIN_INPUT, 0) /* (B23) MCU_OSPI1_DQS */
J721E_WKUP_IOPAD(0x38, PIN_INPUT, 0) /* (A23) MCU_OSPI1_LBCLKO */
>;
};
mcu_cpsw_pins_default: mcu_cpsw_pins_default {
pinctrl-single,pins = <
J721E_WKUP_IOPAD(0x0058, PIN_OUTPUT, 0) /* MCU_RGMII1_TX_CTL */
J721E_WKUP_IOPAD(0x005c, PIN_INPUT, 0) /* MCU_RGMII1_RX_CTL */
J721E_WKUP_IOPAD(0x0060, PIN_OUTPUT, 0) /* MCU_RGMII1_TD3 */
J721E_WKUP_IOPAD(0x0064, PIN_OUTPUT, 0) /* MCU_RGMII1_TD2 */
J721E_WKUP_IOPAD(0x0068, PIN_OUTPUT, 0) /* MCU_RGMII1_TD1 */
J721E_WKUP_IOPAD(0x006c, PIN_OUTPUT, 0) /* MCU_RGMII1_TD0 */
J721E_WKUP_IOPAD(0x0078, PIN_INPUT, 0) /* MCU_RGMII1_RD3 */
J721E_WKUP_IOPAD(0x007c, PIN_INPUT, 0) /* MCU_RGMII1_RD2 */
J721E_WKUP_IOPAD(0x0080, PIN_INPUT, 0) /* MCU_RGMII1_RD1 */
J721E_WKUP_IOPAD(0x0084, PIN_INPUT, 0) /* MCU_RGMII1_RD0 */
J721E_WKUP_IOPAD(0x0070, PIN_INPUT, 0) /* MCU_RGMII1_TXC */
J721E_WKUP_IOPAD(0x0074, PIN_INPUT, 0) /* MCU_RGMII1_RXC */
>;
};
mcu_mdio_pins_default: mcu_mdio1_pins_default {
pinctrl-single,pins = <
J721E_WKUP_IOPAD(0x008c, PIN_OUTPUT, 0) /* MCU_MDIO0_MDC */
J721E_WKUP_IOPAD(0x0088, PIN_INPUT, 0) /* MCU_MDIO0_MDIO */
>;
};
};
&wkup_uart0 {
......@@ -429,3 +454,21 @@ exp5: gpio@20 {
#gpio-cells = <2>;
};
};
&mcu_cpsw {
pinctrl-names = "default";
pinctrl-0 = <&mcu_cpsw_pins_default &mcu_mdio_pins_default>;
};
&davinci_mdio {
phy0: ethernet-phy@0 {
reg = <0>;
ti,rx-internal-delay = <DP83867_RGMIIDCTL_2_00_NS>;
ti,fifo-depth = <DP83867_PHYCR_FIFO_DEPTH_4_B_NIB>;
};
};
&cpsw_port1 {
phy-mode = "rgmii-rxid";
phy-handle = <&phy0>;
};
......@@ -270,4 +270,53 @@ mcu_udmap: dma-controller@285c0000 {
ti,sci-rm-range-rflow = <0x00>; /* GP RFLOW */
};
};
mcu_cpsw: ethernet@46000000 {
compatible = "ti,j721e-cpsw-nuss";
#address-cells = <2>;
#size-cells = <2>;
reg = <0x0 0x46000000 0x0 0x200000>;
reg-names = "cpsw_nuss";
ranges = <0x0 0x0 0x0 0x46000000 0x0 0x200000>;
dma-coherent;
clocks = <&k3_clks 18 22>;
clock-names = "fck";
power-domains = <&k3_pds 18 TI_SCI_PD_EXCLUSIVE>;
dmas = <&mcu_udmap 0xf000>,
<&mcu_udmap 0xf001>,
<&mcu_udmap 0xf002>,
<&mcu_udmap 0xf003>,
<&mcu_udmap 0xf004>,
<&mcu_udmap 0xf005>,
<&mcu_udmap 0xf006>,
<&mcu_udmap 0xf007>,
<&mcu_udmap 0x7000>;
dma-names = "tx0", "tx1", "tx2", "tx3",
"tx4", "tx5", "tx6", "tx7",
"rx";
ethernet-ports {
#address-cells = <1>;
#size-cells = <0>;
cpsw_port1: port@1 {
reg = <1>;
ti,mac-only;
label = "port1";
ti,syscon-efuse = <&mcu_conf 0x200>;
phys = <&phy_gmii_sel 1>;
};
};
davinci_mdio: mdio@f00 {
compatible = "ti,cpsw-mdio","ti,davinci_mdio";
reg = <0x0 0xf00 0x0 0x100>;
#address-cells = <1>;
#size-cells = <0>;
clocks = <&k3_clks 18 22>;
clock-names = "fck";
bus_freq = <1000000>;
};
};
};
......@@ -30,6 +30,7 @@ aliases {
serial9 = &main_uart7;
serial10 = &main_uart8;
serial11 = &main_uart9;
ethernet0 = &cpsw_port1;
};
chosen { };
......
......@@ -283,6 +283,7 @@ CONFIG_SMSC911X=y
CONFIG_SNI_AVE=y
CONFIG_SNI_NETSEC=y
CONFIG_STMMAC_ETH=m
CONFIG_TI_K3_AM65_CPSW_NUSS=y
CONFIG_MDIO_BUS_MUX_MMIOREG=y
CONFIG_MARVELL_PHY=m
CONFIG_MARVELL_10G_PHY=m
......@@ -698,6 +699,8 @@ CONFIG_QCOM_HIDMA_MGMT=y
CONFIG_QCOM_HIDMA=y
CONFIG_RCAR_DMAC=y
CONFIG_RENESAS_USB_DMAC=m
CONFIG_TI_K3_UDMA=y
CONFIG_TI_K3_UDMA_GLUE_LAYER=y
CONFIG_VFIO=y
CONFIG_VFIO_PCI=y
CONFIG_VIRTIO_PCI=y
......
......@@ -6,7 +6,7 @@
config NET_VENDOR_TI
bool "Texas Instruments (TI) devices"
default y
depends on PCI || EISA || AR7 || ARCH_DAVINCI || ARCH_OMAP2PLUS || ARCH_KEYSTONE
depends on PCI || EISA || AR7 || ARCH_DAVINCI || ARCH_OMAP2PLUS || ARCH_KEYSTONE || ARCH_K3
---help---
If you have a network (Ethernet) card belonging to this class, say Y.
......@@ -31,7 +31,7 @@ config TI_DAVINCI_EMAC
config TI_DAVINCI_MDIO
tristate "TI DaVinci MDIO Support"
depends on ARCH_DAVINCI || ARCH_OMAP2PLUS || ARCH_KEYSTONE || COMPILE_TEST
depends on ARCH_DAVINCI || ARCH_OMAP2PLUS || ARCH_KEYSTONE || ARCH_K3 || COMPILE_TEST
select PHYLIB
---help---
This driver supports TI's DaVinci MDIO module.
......@@ -53,6 +53,7 @@ config TI_CPSW
select MFD_SYSCON
select PAGE_POOL
select REGMAP
imply PHY_TI_GMII_SEL
---help---
This driver supports TI's CPSW Ethernet Switch.
......@@ -94,6 +95,21 @@ config TI_CPTS_MOD
imply PTP_1588_CLOCK
default m
config TI_K3_AM65_CPSW_NUSS
tristate "TI K3 AM654x/J721E CPSW Ethernet driver"
depends on ARCH_K3 && OF && TI_K3_UDMA_GLUE_LAYER
select TI_DAVINCI_MDIO
imply PHY_TI_GMII_SEL
help
This driver supports TI K3 AM654/J721E CPSW2G Ethernet SubSystem.
The two-port Gigabit Ethernet MAC (MCU_CPSW0) subsystem provides
Ethernet packet communication for the device: One Ethernet port
(port 1) with selectable RGMII and RMII interfaces and an internal
Communications Port Programming Interface (CPPI) port (port 0).
To compile this driver as a module, choose M here: the module
will be called ti-am65-cpsw-nuss.
config TI_KEYSTONE_NETCP
tristate "TI Keystone NETCP Core Support"
select TI_DAVINCI_MDIO
......
......@@ -23,3 +23,6 @@ obj-$(CONFIG_TI_KEYSTONE_NETCP) += keystone_netcp.o
keystone_netcp-y := netcp_core.o cpsw_ale.o
obj-$(CONFIG_TI_KEYSTONE_NETCP_ETHSS) += keystone_netcp_ethss.o
keystone_netcp_ethss-y := netcp_ethss.o netcp_sgmii.o netcp_xgbepcsr.o cpsw_ale.o
obj-$(CONFIG_TI_K3_AM65_CPSW_NUSS) += ti-am65-cpsw-nuss.o
ti-am65-cpsw-nuss-y := am65-cpsw-nuss.o cpsw_sl.o am65-cpsw-ethtool.o cpsw_ale.o k3-cppi-desc-pool.o
This diff is collapsed.
This diff is collapsed.
/* SPDX-License-Identifier: GPL-2.0 */
/* Copyright (C) 2020 Texas Instruments Incorporated - http://www.ti.com/
*
*/
#ifndef AM65_CPSW_NUSS_H_
#define AM65_CPSW_NUSS_H_
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/netdevice.h>
#define HOST_PORT_NUM 0
#define AM65_CPSW_MAX_TX_QUEUES 8
#define AM65_CPSW_MAX_RX_QUEUES 1
#define AM65_CPSW_MAX_RX_FLOWS 1
struct am65_cpsw_slave_data {
bool mac_only;
struct cpsw_sl *mac_sl;
struct device_node *phy_node;
struct phy_device *phy;
phy_interface_t phy_if;
struct phy *ifphy;
bool rx_pause;
bool tx_pause;
u8 mac_addr[ETH_ALEN];
};
struct am65_cpsw_port {
struct am65_cpsw_common *common;
struct net_device *ndev;
const char *name;
u32 port_id;
void __iomem *port_base;
void __iomem *stat_base;
bool disabled;
struct am65_cpsw_slave_data slave;
};
struct am65_cpsw_host {
struct am65_cpsw_common *common;
void __iomem *port_base;
void __iomem *stat_base;
};
struct am65_cpsw_tx_chn {
struct napi_struct napi_tx;
struct am65_cpsw_common *common;
struct k3_cppi_desc_pool *desc_pool;
struct k3_udma_glue_tx_channel *tx_chn;
int irq;
u32 id;
u32 descs_num;
char tx_chn_name[128];
};
struct am65_cpsw_rx_chn {
struct device *dev;
struct k3_cppi_desc_pool *desc_pool;
struct k3_udma_glue_rx_channel *rx_chn;
u32 descs_num;
int irq;
};
#define AM65_CPSW_QUIRK_I2027_NO_TX_CSUM BIT(0)
struct am65_cpsw_pdata {
u32 quirks;
};
struct am65_cpsw_common {
struct device *dev;
const struct am65_cpsw_pdata *pdata;
void __iomem *ss_base;
void __iomem *cpsw_base;
u32 port_num;
struct am65_cpsw_host host;
struct am65_cpsw_port *ports;
u32 disabled_ports_mask;
int usage_count; /* number of opened ports */
struct cpsw_ale *ale;
int tx_ch_num;
u32 rx_flow_id_base;
struct am65_cpsw_tx_chn tx_chns[AM65_CPSW_MAX_TX_QUEUES];
struct completion tdown_complete;
atomic_t tdown_cnt;
struct am65_cpsw_rx_chn rx_chns;
struct napi_struct napi_rx;
u32 nuss_ver;
u32 cpsw_ver;
bool pf_p0_rx_ptype_rrobin;
};
struct am65_cpsw_ndev_stats {
u64 tx_packets;
u64 tx_bytes;
u64 rx_packets;
u64 rx_bytes;
struct u64_stats_sync syncp;
};
struct am65_cpsw_ndev_priv {
u32 msg_enable;
struct am65_cpsw_port *port;
struct am65_cpsw_ndev_stats __percpu *stats;
};
#define am65_ndev_to_priv(ndev) \
((struct am65_cpsw_ndev_priv *)netdev_priv(ndev))
#define am65_ndev_to_port(ndev) (am65_ndev_to_priv(ndev)->port)
#define am65_ndev_to_common(ndev) (am65_ndev_to_port(ndev)->common)
#define am65_ndev_to_slave(ndev) (&am65_ndev_to_port(ndev)->slave)
#define am65_common_get_host(common) (&(common)->host)
#define am65_common_get_port(common, id) (&(common)->ports[(id) - 1])
#define am65_cpsw_napi_to_common(pnapi) \
container_of(pnapi, struct am65_cpsw_common, napi_rx)
#define am65_cpsw_napi_to_tx_chn(pnapi) \
container_of(pnapi, struct am65_cpsw_tx_chn, napi_tx)
#define AM65_CPSW_DRV_NAME "am65-cpsw-nuss"
#define AM65_CPSW_IS_CPSW2G(common) ((common)->port_num == 1)
extern const struct ethtool_ops am65_cpsw_ethtool_ops_slave;
void am65_cpsw_nuss_adjust_link(struct net_device *ndev);
void am65_cpsw_nuss_set_p0_ptype(struct am65_cpsw_common *common);
void am65_cpsw_nuss_remove_tx_chns(struct am65_cpsw_common *common);
int am65_cpsw_nuss_update_tx_chns(struct am65_cpsw_common *common, int num_tx);
#endif /* AM65_CPSW_NUSS_H_ */
......@@ -44,6 +44,8 @@
#define ALE_UNKNOWNVLAN_FORCE_UNTAG_EGRESS 0x9C
#define ALE_VLAN_MASK_MUX(reg) (0xc0 + (0x4 * (reg)))
#define AM65_CPSW_ALE_THREAD_DEF_REG 0x134
#define ALE_TABLE_WRITE BIT(31)
#define ALE_TYPE_FREE 0
......@@ -122,6 +124,8 @@ DEFINE_ALE_FIELD(mcast, 40, 1)
DEFINE_ALE_FIELD(vlan_unreg_mcast_idx, 20, 3)
DEFINE_ALE_FIELD(vlan_reg_mcast_idx, 44, 3)
#define NU_VLAN_UNREG_MCAST_IDX 1
/* The MAC address field in the ALE entry cannot be macroized as above */
static inline void cpsw_ale_get_addr(u32 *ale_entry, u8 *addr)
{
......@@ -455,6 +459,8 @@ int cpsw_ale_add_vlan(struct cpsw_ale *ale, u16 vid, int port_mask, int untag,
cpsw_ale_set_vlan_unreg_mcast(ale_entry, unreg_mcast,
ale->vlan_field_bits);
} else {
cpsw_ale_set_vlan_unreg_mcast_idx(ale_entry,
NU_VLAN_UNREG_MCAST_IDX);
cpsw_ale_set_vlan_mcast(ale, ale_entry, reg_mcast, unreg_mcast);
}
cpsw_ale_set_vlan_member_list(ale_entry, port_mask,
......@@ -775,6 +781,22 @@ static struct ale_control_info ale_controls[ALE_NUM_CONTROLS] = {
.port_shift = 0,
.bits = 1,
},
[ALE_PORT_MACONLY] = {
.name = "mac_only_port_mode",
.offset = ALE_PORTCTL,
.port_offset = 4,
.shift = 11,
.port_shift = 0,
.bits = 1,
},
[ALE_PORT_MACONLY_CAF] = {
.name = "mac_only_port_caf",
.offset = ALE_PORTCTL,
.port_offset = 4,
.shift = 13,
.port_shift = 0,
.bits = 1,
},
[ALE_PORT_MCAST_LIMIT] = {
.name = "mcast_limit",
.offset = ALE_PORTCTL,
......@@ -823,6 +845,22 @@ static struct ale_control_info ale_controls[ALE_NUM_CONTROLS] = {
.port_shift = 0,
.bits = 6,
},
[ALE_DEFAULT_THREAD_ID] = {
.name = "default_thread_id",
.offset = AM65_CPSW_ALE_THREAD_DEF_REG,
.port_offset = 0,
.shift = 0,
.port_shift = 0,
.bits = 6,
},
[ALE_DEFAULT_THREAD_ENABLE] = {
.name = "default_thread_id_enable",
.offset = AM65_CPSW_ALE_THREAD_DEF_REG,
.port_offset = 0,
.shift = 15,
.port_shift = 0,
.bits = 1,
},
};
int cpsw_ale_control_set(struct cpsw_ale *ale, int port, int control,
......
......@@ -62,8 +62,12 @@ enum cpsw_ale_control {
ALE_PORT_UNKNOWN_MCAST_FLOOD,
ALE_PORT_UNKNOWN_REG_MCAST_FLOOD,
ALE_PORT_UNTAGGED_EGRESS,
ALE_PORT_MACONLY,
ALE_PORT_MACONLY_CAF,
ALE_PORT_BCAST_LIMIT,
ALE_PORT_MCAST_LIMIT,
ALE_DEFAULT_THREAD_ID,
ALE_DEFAULT_THREAD_ENABLE,
ALE_NUM_CONTROLS,
};
......
// SPDX-License-Identifier: GPL-2.0
/* TI K3 CPPI5 descriptors pool API
*
* Copyright (C) 2020 Texas Instruments Incorporated - http://www.ti.com
*/
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
#include <linux/device.h>
#include <linux/dma-mapping.h>
#include <linux/err.h>
#include <linux/genalloc.h>
#include <linux/kernel.h>
#include "k3-cppi-desc-pool.h"
struct k3_cppi_desc_pool {
struct device *dev;
dma_addr_t dma_addr;
void *cpumem; /* dma_alloc map */
size_t desc_size;
size_t mem_size;
size_t num_desc;
struct gen_pool *gen_pool;
};
void k3_cppi_desc_pool_destroy(struct k3_cppi_desc_pool *pool)
{
if (!pool)
return;
WARN(gen_pool_size(pool->gen_pool) != gen_pool_avail(pool->gen_pool),
"k3_knav_desc_pool size %zu != avail %zu",
gen_pool_size(pool->gen_pool),
gen_pool_avail(pool->gen_pool));
if (pool->cpumem)
dma_free_coherent(pool->dev, pool->mem_size, pool->cpumem,
pool->dma_addr);
gen_pool_destroy(pool->gen_pool); /* frees pool->name */
}
struct k3_cppi_desc_pool *
k3_cppi_desc_pool_create_name(struct device *dev, size_t size,
size_t desc_size,
const char *name)
{
struct k3_cppi_desc_pool *pool;
const char *pool_name = NULL;
int ret = -ENOMEM;
pool = devm_kzalloc(dev, sizeof(*pool), GFP_KERNEL);
if (!pool)
return ERR_PTR(ret);
pool->dev = dev;
pool->desc_size = roundup_pow_of_two(desc_size);
pool->num_desc = size;
pool->mem_size = pool->num_desc * pool->desc_size;
pool_name = kstrdup_const(name ? name : dev_name(pool->dev),
GFP_KERNEL);
if (!pool_name)
return ERR_PTR(-ENOMEM);
pool->gen_pool = gen_pool_create(ilog2(pool->desc_size), -1);
if (IS_ERR(pool->gen_pool)) {
ret = PTR_ERR(pool->gen_pool);
dev_err(pool->dev, "pool create failed %d\n", ret);
kfree_const(pool_name);
goto gen_pool_create_fail;
}
pool->gen_pool->name = pool_name;
pool->cpumem = dma_alloc_coherent(pool->dev, pool->mem_size,
&pool->dma_addr, GFP_KERNEL);
if (!pool->cpumem)
goto dma_alloc_fail;
ret = gen_pool_add_virt(pool->gen_pool, (unsigned long)pool->cpumem,
(phys_addr_t)pool->dma_addr, pool->mem_size,
-1);
if (ret < 0) {
dev_err(pool->dev, "pool add failed %d\n", ret);
goto gen_pool_add_virt_fail;
}
return pool;
gen_pool_add_virt_fail:
dma_free_coherent(pool->dev, pool->mem_size, pool->cpumem,
pool->dma_addr);
dma_alloc_fail:
gen_pool_destroy(pool->gen_pool); /* frees pool->name */
gen_pool_create_fail:
devm_kfree(pool->dev, pool);
return ERR_PTR(ret);
}
dma_addr_t k3_cppi_desc_pool_virt2dma(struct k3_cppi_desc_pool *pool,
void *addr)
{
return addr ? pool->dma_addr + (addr - pool->cpumem) : 0;
}
void *k3_cppi_desc_pool_dma2virt(struct k3_cppi_desc_pool *pool, dma_addr_t dma)
{
return dma ? pool->cpumem + (dma - pool->dma_addr) : NULL;
}
void *k3_cppi_desc_pool_alloc(struct k3_cppi_desc_pool *pool)
{
return (void *)gen_pool_alloc(pool->gen_pool, pool->desc_size);
}
void k3_cppi_desc_pool_free(struct k3_cppi_desc_pool *pool, void *addr)
{
gen_pool_free(pool->gen_pool, (unsigned long)addr, pool->desc_size);
}
size_t k3_cppi_desc_pool_avail(struct k3_cppi_desc_pool *pool)
{
return gen_pool_avail(pool->gen_pool) / pool->desc_size;
}
/* SPDX-License-Identifier: GPL-2.0 */
/* TI K3 CPPI5 descriptors pool
*
* Copyright (C) 2020 Texas Instruments Incorporated - http://www.ti.com
*/
#ifndef K3_CPPI_DESC_POOL_H_
#define K3_CPPI_DESC_POOL_H_
#include <linux/device.h>
#include <linux/types.h>
struct k3_cppi_desc_pool;
void k3_cppi_desc_pool_destroy(struct k3_cppi_desc_pool *pool);
struct k3_cppi_desc_pool *
k3_cppi_desc_pool_create_name(struct device *dev, size_t size,
size_t desc_size,
const char *name);
#define k3_cppi_desc_pool_create(dev, size, desc_size) \
k3_cppi_desc_pool_create_name(dev, size, desc_size, NULL)
dma_addr_t
k3_cppi_desc_pool_virt2dma(struct k3_cppi_desc_pool *pool, void *addr);
void *
k3_cppi_desc_pool_dma2virt(struct k3_cppi_desc_pool *pool, dma_addr_t dma);
void *k3_cppi_desc_pool_alloc(struct k3_cppi_desc_pool *pool);
void k3_cppi_desc_pool_free(struct k3_cppi_desc_pool *pool, void *addr);
size_t k3_cppi_desc_pool_avail(struct k3_cppi_desc_pool *pool);
#endif /* K3_CPPI_DESC_POOL_H_ */
......@@ -106,11 +106,8 @@ config TWL4030_USB
config PHY_TI_GMII_SEL
tristate
default y if TI_CPSW=y || TI_CPSW_SWITCHDEV=y
depends on TI_CPSW || TI_CPSW_SWITCHDEV || COMPILE_TEST
select GENERIC_PHY
select REGMAP
default m
help
This driver supports configuring of the TI CPSW Port mode depending on
the Ethernet PHY connected to the CPSW Port.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment