Commit 377c17c6 authored by Paolo Abeni's avatar Paolo Abeni
Browse files

Merge branch 'add-wed-support-for-mt7986-chipset'

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: default avatarPaolo Abeni <pabeni@redhat.com>
parents 3cae32b4 03a3180e
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -20,6 +20,7 @@ properties:
    items:
      - enum:
          - mediatek,mt7622-wed
          - mediatek,mt7986-wed
      - const: syscon

  reg:
+43 −0
Original line number Diff line number Diff line
# 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>;
      };
    };
+18 −9
Original line number Diff line number Diff line
@@ -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:
@@ -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:
@@ -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:
@@ -202,6 +204,8 @@ allOf:
          minItems: 2
          maxItems: 2

        mediatek,wed: false

  - if:
      properties:
        compatible:
@@ -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
+24 −0
Original line number Diff line number Diff line
@@ -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>;
@@ -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>;
+73 −25
Original line number Diff line number Diff line
@@ -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 = {
@@ -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 */
@@ -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),
@@ -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)) {
@@ -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
@@ -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);

@@ -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;
}
@@ -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;
@@ -4007,20 +4026,31 @@ static int mtk_probe(struct platform_device *pdev)
		}
	}

	if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) {
		res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
		if (!res)
			return -EINVAL;
	}

	if (eth->soc->offload_version) {
		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;
			struct device_node *np;
			phys_addr_t wdma_phy;
			u32 wdma_base;

		if (!np || i >= ARRAY_SIZE(wdma_regs))
			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 = eth->base + wdma_regs[i];
		mtk_wed_add_hw(np, eth, wdma, i);
			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++) {
@@ -4098,11 +4128,20 @@ 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) {
		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);
		if (err)
@@ -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),
@@ -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),
@@ -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),
@@ -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),
Loading