Skip to content

Commit

Permalink
Merge branch 'add-wed-support-for-mt7986-chipset'
Browse files Browse the repository at this point in the history
Lorenzo Bianconi says:

====================
Add WED support for MT7986 chipset

Similar to MT7622, introduce Wireless Ethernet Dispatch (WED) support
for MT7986 chipset in order to offload to the hw packet engine traffic
received from LAN/WAN device to WLAN nic (MT7915E).
====================

Link: https://lore.kernel.org/r/cover.1663668203.git.lorenzo@kernel.org
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
  • Loading branch information
Paolo Abeni committed Sep 22, 2022
2 parents 3cae32b + 03a3180 commit 377c17c
Show file tree
Hide file tree
Showing 16 changed files with 1,020 additions and 313 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ properties:
items:
- enum:
- mediatek,mt7622-wed
- mediatek,mt7986-wed
- const: syscon

reg:
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
%YAML 1.2
---
$id: "http://devicetree.org/schemas/arm/mediatek/mediatek,mt7986-wed-pcie.yaml#"
$schema: "http://devicetree.org/meta-schemas/core.yaml#"

title: MediaTek PCIE WED Controller for MT7986

maintainers:
- Lorenzo Bianconi <lorenzo@kernel.org>
- Felix Fietkau <nbd@nbd.name>

description:
The mediatek WED PCIE provides a configuration interface for PCIE
controller on MT7986 soc.

properties:
compatible:
items:
- enum:
- mediatek,mt7986-wed-pcie
- const: syscon

reg:
maxItems: 1

required:
- compatible
- reg

additionalProperties: false

examples:
- |
soc {
#address-cells = <2>;
#size-cells = <2>;
wed_pcie: wed-pcie@10003000 {
compatible = "mediatek,mt7986-wed-pcie",
"syscon";
reg = <0 0x10003000 0 0x10>;
};
};
27 changes: 18 additions & 9 deletions Documentation/devicetree/bindings/net/mediatek,net.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,15 @@ properties:
A list of phandle to the syscon node that handles the SGMII setup which is required for
those SoCs equipped with SGMII.

mediatek,wed:
$ref: /schemas/types.yaml#/definitions/phandle-array
minItems: 2
maxItems: 2
items:
maxItems: 1
description:
List of phandles to wireless ethernet dispatch nodes.

dma-coherent: true

mdio-bus:
Expand Down Expand Up @@ -112,6 +121,8 @@ allOf:
Phandle to the syscon node that handles the ports slew rate and
driver current.

mediatek,wed: false

- if:
properties:
compatible:
Expand Down Expand Up @@ -144,15 +155,6 @@ allOf:
minItems: 1
maxItems: 1

mediatek,wed:
$ref: /schemas/types.yaml#/definitions/phandle-array
minItems: 2
maxItems: 2
items:
maxItems: 1
description:
List of phandles to wireless ethernet dispatch nodes.

mediatek,pcie-mirror:
$ref: /schemas/types.yaml#/definitions/phandle
description:
Expand Down Expand Up @@ -202,6 +204,8 @@ allOf:
minItems: 2
maxItems: 2

mediatek,wed: false

- if:
properties:
compatible:
Expand Down Expand Up @@ -238,6 +242,11 @@ allOf:
minItems: 2
maxItems: 2

mediatek,wed-pcie:
$ref: /schemas/types.yaml#/definitions/phandle
description:
Phandle to the mediatek wed-pcie controller.

patternProperties:
"^mac@[0-1]$":
type: object
Expand Down
24 changes: 24 additions & 0 deletions arch/arm64/boot/dts/mediatek/mt7986a.dtsi
Original file line number Diff line number Diff line change
Expand Up @@ -222,6 +222,28 @@
#reset-cells = <1>;
};

wed_pcie: wed-pcie@10003000 {
compatible = "mediatek,mt7986-wed-pcie",
"syscon";
reg = <0 0x10003000 0 0x10>;
};

wed0: wed@15010000 {
compatible = "mediatek,mt7986-wed",
"syscon";
reg = <0 0x15010000 0 0x1000>;
interrupt-parent = <&gic>;
interrupts = <GIC_SPI 205 IRQ_TYPE_LEVEL_HIGH>;
};

wed1: wed@15011000 {
compatible = "mediatek,mt7986-wed",
"syscon";
reg = <0 0x15011000 0 0x1000>;
interrupt-parent = <&gic>;
interrupts = <GIC_SPI 206 IRQ_TYPE_LEVEL_HIGH>;
};

eth: ethernet@15100000 {
compatible = "mediatek,mt7986-eth";
reg = <0 0x15100000 0 0x80000>;
Expand Down Expand Up @@ -256,6 +278,8 @@
<&apmixedsys CLK_APMIXED_SGMPLL>;
mediatek,ethsys = <&ethsys>;
mediatek,sgmiisys = <&sgmiisys0>, <&sgmiisys1>;
mediatek,wed-pcie = <&wed_pcie>;
mediatek,wed = <&wed0>, <&wed1>;
#reset-cells = <1>;
#address-cells = <1>;
#size-cells = <0>;
Expand Down
98 changes: 73 additions & 25 deletions drivers/net/ethernet/mediatek/mtk_eth_soc.c
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,12 @@ static const struct mtk_reg_map mtk_reg_map = {
.fq_blen = 0x1b2c,
},
.gdm1_cnt = 0x2400,
.gdma_to_ppe = 0x4444,
.ppe_base = 0x0c00,
.wdma_base = {
[0] = 0x2800,
[1] = 0x2c00,
},
};

static const struct mtk_reg_map mt7628_reg_map = {
Expand Down Expand Up @@ -126,6 +132,12 @@ static const struct mtk_reg_map mt7986_reg_map = {
.fq_blen = 0x472c,
},
.gdm1_cnt = 0x1c00,
.gdma_to_ppe = 0x3333,
.ppe_base = 0x2000,
.wdma_base = {
[0] = 0x4800,
[1] = 0x4c00,
},
};

/* strings used by ethtool */
Expand Down Expand Up @@ -1894,12 +1906,14 @@ static int mtk_poll_rx(struct napi_struct *napi, int budget,
bytes += skb->len;

if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) {
reason = FIELD_GET(MTK_RXD5_PPE_CPU_REASON, trxd.rxd5);
hash = trxd.rxd5 & MTK_RXD5_FOE_ENTRY;
if (hash != MTK_RXD5_FOE_ENTRY)
skb_set_hash(skb, jhash_1word(hash, 0),
PKT_HASH_TYPE_L4);
rxdcsum = &trxd.rxd3;
} else {
reason = FIELD_GET(MTK_RXD4_PPE_CPU_REASON, trxd.rxd4);
hash = trxd.rxd4 & MTK_RXD4_FOE_ENTRY;
if (hash != MTK_RXD4_FOE_ENTRY)
skb_set_hash(skb, jhash_1word(hash, 0),
Expand All @@ -1913,9 +1927,8 @@ static int mtk_poll_rx(struct napi_struct *napi, int budget,
skb_checksum_none_assert(skb);
skb->protocol = eth_type_trans(skb, netdev);

reason = FIELD_GET(MTK_RXD4_PPE_CPU_REASON, trxd.rxd4);
if (reason == MTK_PPE_CPU_REASON_HIT_UNBIND_RATE_REACHED)
mtk_ppe_check_skb(eth->ppe, skb, hash);
mtk_ppe_check_skb(eth->ppe[0], skb, hash);

if (netdev->features & NETIF_F_HW_VLAN_CTAG_RX) {
if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) {
Expand Down Expand Up @@ -2978,21 +2991,25 @@ static int mtk_open(struct net_device *dev)

/* we run 2 netdevs on the same dma ring so we only bring it up once */
if (!refcount_read(&eth->dma_refcnt)) {
u32 gdm_config = MTK_GDMA_TO_PDMA;
const struct mtk_soc_data *soc = eth->soc;
u32 gdm_config;
int i;

err = mtk_start_dma(eth);
if (err)
return err;

if (eth->soc->offload_version && mtk_ppe_start(eth->ppe) == 0)
gdm_config = MTK_GDMA_TO_PPE;
for (i = 0; i < ARRAY_SIZE(eth->ppe); i++)
mtk_ppe_start(eth->ppe[i]);

gdm_config = soc->offload_version ? soc->reg_map->gdma_to_ppe
: MTK_GDMA_TO_PDMA;
mtk_gdm_config(eth, gdm_config);

napi_enable(&eth->tx_napi);
napi_enable(&eth->rx_napi);
mtk_tx_irq_enable(eth, MTK_TX_DONE_INT);
mtk_rx_irq_enable(eth, eth->soc->txrx.rx_irq_done_mask);
mtk_rx_irq_enable(eth, soc->txrx.rx_irq_done_mask);
refcount_set(&eth->dma_refcnt, 1);
}
else
Expand Down Expand Up @@ -3030,6 +3047,7 @@ static int mtk_stop(struct net_device *dev)
{
struct mtk_mac *mac = netdev_priv(dev);
struct mtk_eth *eth = mac->hw;
int i;

phylink_stop(mac->phylink);

Expand Down Expand Up @@ -3057,8 +3075,8 @@ static int mtk_stop(struct net_device *dev)

mtk_dma_free(eth);

if (eth->soc->offload_version)
mtk_ppe_stop(eth->ppe);
for (i = 0; i < ARRAY_SIZE(eth->ppe); i++)
mtk_ppe_stop(eth->ppe[i]);

return 0;
}
Expand Down Expand Up @@ -3927,6 +3945,7 @@ void mtk_eth_set_dma_device(struct mtk_eth *eth, struct device *dma_dev)

static int mtk_probe(struct platform_device *pdev)
{
struct resource *res = NULL;
struct device_node *mac_np;
struct mtk_eth *eth;
int err, i;
Expand Down Expand Up @@ -4007,20 +4026,31 @@ static int mtk_probe(struct platform_device *pdev)
}
}

for (i = 0;; i++) {
struct device_node *np = of_parse_phandle(pdev->dev.of_node,
"mediatek,wed", i);
static const u32 wdma_regs[] = {
MTK_WDMA0_BASE,
MTK_WDMA1_BASE
};
void __iomem *wdma;

if (!np || i >= ARRAY_SIZE(wdma_regs))
break;
if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) {
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!res)
return -EINVAL;
}

wdma = eth->base + wdma_regs[i];
mtk_wed_add_hw(np, eth, wdma, i);
if (eth->soc->offload_version) {
for (i = 0;; i++) {
struct device_node *np;
phys_addr_t wdma_phy;
u32 wdma_base;

if (i >= ARRAY_SIZE(eth->soc->reg_map->wdma_base))
break;

np = of_parse_phandle(pdev->dev.of_node,
"mediatek,wed", i);
if (!np)
break;

wdma_base = eth->soc->reg_map->wdma_base[i];
wdma_phy = res ? res->start + wdma_base : 0;
mtk_wed_add_hw(np, eth, eth->base + wdma_base,
wdma_phy, i);
}
}

for (i = 0; i < 3; i++) {
Expand Down Expand Up @@ -4098,10 +4128,19 @@ static int mtk_probe(struct platform_device *pdev)
}

if (eth->soc->offload_version) {
eth->ppe = mtk_ppe_init(eth, eth->base + MTK_ETH_PPE_BASE, 2);
if (!eth->ppe) {
err = -ENOMEM;
goto err_free_dev;
u32 num_ppe;

num_ppe = MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2) ? 2 : 1;
num_ppe = min_t(u32, ARRAY_SIZE(eth->ppe), num_ppe);
for (i = 0; i < num_ppe; i++) {
u32 ppe_addr = eth->soc->reg_map->ppe_base + i * 0x400;

eth->ppe[i] = mtk_ppe_init(eth, eth->base + ppe_addr,
eth->soc->offload_version, i);
if (!eth->ppe[i]) {
err = -ENOMEM;
goto err_free_dev;
}
}

err = mtk_eth_offload_init(eth);
Expand Down Expand Up @@ -4194,6 +4233,8 @@ static const struct mtk_soc_data mt7621_data = {
.required_clks = MT7621_CLKS_BITMAP,
.required_pctl = false,
.offload_version = 2,
.hash_offset = 2,
.foe_entry_size = sizeof(struct mtk_foe_entry) - 16,
.txrx = {
.txd_size = sizeof(struct mtk_tx_dma),
.rxd_size = sizeof(struct mtk_rx_dma),
Expand All @@ -4212,6 +4253,8 @@ static const struct mtk_soc_data mt7622_data = {
.required_clks = MT7622_CLKS_BITMAP,
.required_pctl = false,
.offload_version = 2,
.hash_offset = 2,
.foe_entry_size = sizeof(struct mtk_foe_entry) - 16,
.txrx = {
.txd_size = sizeof(struct mtk_tx_dma),
.rxd_size = sizeof(struct mtk_rx_dma),
Expand All @@ -4229,6 +4272,8 @@ static const struct mtk_soc_data mt7623_data = {
.required_clks = MT7623_CLKS_BITMAP,
.required_pctl = true,
.offload_version = 2,
.hash_offset = 2,
.foe_entry_size = sizeof(struct mtk_foe_entry) - 16,
.txrx = {
.txd_size = sizeof(struct mtk_tx_dma),
.rxd_size = sizeof(struct mtk_rx_dma),
Expand Down Expand Up @@ -4260,8 +4305,11 @@ static const struct mtk_soc_data mt7986_data = {
.reg_map = &mt7986_reg_map,
.ana_rgc3 = 0x128,
.caps = MT7986_CAPS,
.hw_features = MTK_HW_FEATURES,
.required_clks = MT7986_CLKS_BITMAP,
.required_pctl = false,
.hash_offset = 4,
.foe_entry_size = sizeof(struct mtk_foe_entry),
.txrx = {
.txd_size = sizeof(struct mtk_tx_dma_v2),
.rxd_size = sizeof(struct mtk_rx_dma_v2),
Expand Down
Loading

0 comments on commit 377c17c

Please sign in to comment.