Skip to contentSkip to conversation

Add WED support for MT7986 chipset

PATCH Superseded Lorenzo Bianconi 4 participants 20 messages Sep 8, 2022 – Sep 13, 2022

Subsystems (5)

v1 of 3 Superseded Latest is v3 →

lore
Share & tools
lore

Lorenzo Bianconi

author maintainer
#0 lore raw

cover 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).

Lorenzo Bianconi (12):
arm64: dts: mediatek: mt7986: add support for Wireless Ethernet
Dispatch
dt-bindings: net: mediatek: add WED binding for MT7986 eth driver
net: ethernet: mtk_eth_soc: move gdma_to_ppe and ppe_base definitions
in mtk register map
net: ethernet: mtk_eth_soc: move ppe table hash offset to mtk_soc_data
structure
net: ethernet: mtk_eth_soc: add the capability to run multiple ppe
net: ethernet: mtk_eth_soc: move wdma_base definitions in mtk register
map
net: ethernet: mtk_eth_soc: add foe_entry_size to mtk_eth_soc
net: ethernet: mtk_eth_soc: add foe info in mtk_soc_data structure
net: ethernet: mtk_eth_wed: add mtk_wed_configure_irq and

    mtk_wed_dma_{enable/disable}
  net: ethernet: mtk_eth_wed: add wed support for mt7986 chipset
  net: ethernet: mtk_eth_wed: add axi bus support
  net: ethernet: mtk_eth_soc: introduce flow offloading support for
    mt7986
 .../devicetree/bindings/net/mediatek,net.yaml |   9 +
 arch/arm64/boot/dts/mediatek/mt7986a.dtsi     |  20 +
 drivers/net/ethernet/mediatek/mtk_eth_soc.c   | 184 ++++++-
 drivers/net/ethernet/mediatek/mtk_eth_soc.h   |  45 +-
 drivers/net/ethernet/mediatek/mtk_ppe.c       | 271 ++++++----
 drivers/net/ethernet/mediatek/mtk_ppe.h       |  54 +-
 .../net/ethernet/mediatek/mtk_ppe_debugfs.c   |  10 +-
 .../net/ethernet/mediatek/mtk_ppe_offload.c   |  62 ++-
 drivers/net/ethernet/mediatek/mtk_ppe_regs.h  |   8 +
 drivers/net/ethernet/mediatek/mtk_wed.c       | 473 ++++++++++++++----
 drivers/net/ethernet/mediatek/mtk_wed.h       |   8 +-
 .../net/ethernet/mediatek/mtk_wed_debugfs.c   |   3 +
 drivers/net/ethernet/mediatek/mtk_wed_regs.h  |  85 +++-
 include/linux/soc/mediatek/mtk_wed.h          |  15 +
 14 files changed, 955 insertions(+), 292 deletions(-)
Signature · 1 line
2.37.3
author maintainer
#1 lore raw

PATCH 1/12 arm64: dts: mediatek: mt7986: add support for Wireless Ethernet Dispatch

Introduce wed0 and wed1 nodes in order to enable offloading forwarding between ethernet and wireless devices on the mt7986 chipset.

---
 arch/arm64/boot/dts/mediatek/mt7986a.dtsi | 20 ++++++++++++++++++++
 1 file changed, 20 insertions(+)
arch/arm64/boot/dts/mediatek/mt7986a.dtsi +20 -0
index e3a407d03551..419d056b8369 100644
@@ -222,6 +222,25 @@ ethsys: syscon@15000000 {
 			 #reset-cells = <1>;
 		};
 
+		wed_pcie: wed_pcie@10003000 {
+			compatible = "mediatek,wed";
+			reg = <0 0x10003000 0 0x10>;
+		};
+
+		wed0: wed@15010000 {
+			compatible = "mediatek,wed", "syscon";
+			reg = <0 0x15010000 0 0x1000>;
+			interrupt-parent = <&gic>;
+			interrupts = <GIC_SPI 205 IRQ_TYPE_LEVEL_HIGH>;
+		};
+
+		wed1: wed@15011000 {
+			compatible = "mediatek,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 +275,7 @@ eth: ethernet@15100000 {
 						 <&apmixedsys CLK_APMIXED_SGMPLL>;
 			mediatek,ethsys = <&ethsys>;
 			mediatek,sgmiisys = <&sgmiisys0>, <&sgmiisys1>;
+			mediatek,wed = <&wed0>, <&wed1>;
 			#reset-cells = <1>;
 			#address-cells = <1>;
 			#size-cells = <0>;
Signature · 1 line
2.37.3
maintainer
#2 lore raw

Re: [PATCH net-next 01/12] arm64: dts: mediatek: mt7986: add support for Wireless Ethernet Dispatch

Quoted 15 lines · Lorenzo Bianconi

Introduce wed0 and wed1 nodes in order to enable offloading forwarding between ethernet and wireless devices on the mt7986 chipset.

---
 arch/arm64/boot/dts/mediatek/mt7986a.dtsi | 20 ++++++++++++++++++++
 1 file changed, 20 insertions(+)
arch/arm64/boot/dts/mediatek/mt7986a.dtsi +0 -0
index e3a407d03551..419d056b8369 100644

arch/arm64/boot/dts/mediatek/mt7986a.dtsi ethsys: syscon@15000000 { · line 226

Quoted 5 lines
arch/arm64/boot/dts/mediatek/mt7986a.dtsi +2 -0
@@ -222,6 +222,25 @@ ethsys: syscon@15000000 {
 			 #reset-cells = <1>;
 		};
 
+		wed_pcie: wed_pcie@10003000 {
+			compatible = "mediatek,wed";

This is undocumented. It needs a binding.

arch/arm64/boot/dts/mediatek/mt7986a.dtsi ethsys: syscon@15000000 { · line 231

Quoted 5 lines
arch/arm64/boot/dts/mediatek/mt7986a.dtsi +5 -0
+			reg = <0 0x10003000 0 0x10>;
+		};
+
+		wed0: wed@15010000 {
+			compatible = "mediatek,wed", "syscon";

Some are syscon's and some are not?

Quoted 27 lines
arch/arm64/boot/dts/mediatek/mt7986a.dtsi +13 -0
+			reg = <0 0x15010000 0 0x1000>;
+			interrupt-parent = <&gic>;
+			interrupts = <GIC_SPI 205 IRQ_TYPE_LEVEL_HIGH>;
+		};
+
+		wed1: wed@15011000 {
+			compatible = "mediatek,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 +275,7 @@ eth: ethernet@15100000 {
 						 <&apmixedsys CLK_APMIXED_SGMPLL>;
 			mediatek,ethsys = <&ethsys>;
 			mediatek,sgmiisys = <&sgmiisys0>, <&sgmiisys1>;
+			mediatek,wed = <&wed0>, <&wed1>;
 			#reset-cells = <1>;
 			#address-cells = <1>;
 			#size-cells = <0>;
Signature · 1 line
2.37.3
author maintainer
#3 lore raw

Re: [PATCH net-next 01/12] arm64: dts: mediatek: mt7986: add support for Wireless Ethernet Dispatch

Quoted 19 lines · Rob Herring
Quoted 18 lines · Lorenzo Bianconi

Introduce wed0 and wed1 nodes in order to enable offloading forwarding between ethernet and wireless devices on the mt7986 chipset.

---
 arch/arm64/boot/dts/mediatek/mt7986a.dtsi | 20 ++++++++++++++++++++
 1 file changed, 20 insertions(+)
arch/arm64/boot/dts/mediatek/mt7986a.dtsi +0 -0
index e3a407d03551..419d056b8369 100644
@@ -222,6 +222,25 @@ ethsys: syscon@15000000 {
 			 #reset-cells = <1>;
 		};
 
Quoted 4 lines

arch/arm64/boot/dts/mediatek/mt7986a.dtsi ethsys: syscon@15000000 { · line 226

Quoted 2 lines
arch/arm64/boot/dts/mediatek/mt7986a.dtsi +2 -0
+		wed_pcie: wed_pcie@10003000 {
+			compatible = "mediatek,wed";

This is undocumented. It needs a binding.

ack I will fix it in v2.

Quoted 8 lines

arch/arm64/boot/dts/mediatek/mt7986a.dtsi ethsys: syscon@15000000 { · line 231

Quoted 6 lines
arch/arm64/boot/dts/mediatek/mt7986a.dtsi +5 -0
+			reg = <0 0x10003000 0 0x10>;
+		};
+
+		wed0: wed@15010000 {
+			compatible = "mediatek,wed", "syscon";

Some are syscon's and some are not?

ack I will fix it in v2.

Regards,
Lorenzo

Quoted 28 lines
Quoted 28 lines
arch/arm64/boot/dts/mediatek/mt7986a.dtsi +13 -0
+			reg = <0 0x15010000 0 0x1000>;
+			interrupt-parent = <&gic>;
+			interrupts = <GIC_SPI 205 IRQ_TYPE_LEVEL_HIGH>;
+		};
+
+		wed1: wed@15011000 {
+			compatible = "mediatek,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 +275,7 @@ eth: ethernet@15100000 {
 						 <&apmixedsys CLK_APMIXED_SGMPLL>;
 			mediatek,ethsys = <&ethsys>;
 			mediatek,sgmiisys = <&sgmiisys0>, <&sgmiisys1>;
+			mediatek,wed = <&wed0>, <&wed1>;
 			#reset-cells = <1>;
 			#address-cells = <1>;
 			#size-cells = <0>;
Signature · 1 line
2.37.3
author maintainer
#4 lore raw

PATCH 2/12 dt-bindings: net: mediatek: add WED binding for MT7986 eth driver

In reply to Lorenzo Bianconi

Document the binding for the Wireless Ethernet Dispatch core on the MT7986 ethernet driver

---
 Documentation/devicetree/bindings/net/mediatek,net.yaml | 9 +++++++++
 1 file changed, 9 insertions(+)
Documentation/devicetree/bindings/net/mediatek,net.yaml +9 -0
index f5564ecddb62..0116f100ef19 100644
@@ -238,6 +238,15 @@ allOf:
           minItems: 2
           maxItems: 2
 
+        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.
+
 patternProperties:
   "^mac@[0-1]$":
     type: object
Signature · 1 line
2.37.3
maintainer
#5 lore raw

Re: [PATCH net-next 02/12] dt-bindings: net: mediatek: add WED binding for MT7986 eth driver

Quoted 14 lines · Lorenzo Bianconi

Document the binding for the Wireless Ethernet Dispatch core on the MT7986 ethernet driver

---
 Documentation/devicetree/bindings/net/mediatek,net.yaml | 9 +++++++++
 1 file changed, 9 insertions(+)
Documentation/devicetree/bindings/net/mediatek,net.yaml +0 -0
index f5564ecddb62..0116f100ef19 100644
@@ -238,6 +238,15 @@ allOf:
           minItems: 2

Documentation/devicetree/bindings/net/mediatek,net.yaml allOf: · line 248

Quoted 10 lines
Documentation/devicetree/bindings/net/mediatek,net.yaml +8 -0
           maxItems: 2
 
+        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.

There's already a definition of this in the binding. Move it to the main section and put 'mediatek,wed: false' in if/then schemas for variants that don't have it.

Rob

author maintainer
#6 lore raw

Re: [PATCH net-next 02/12] dt-bindings: net: mediatek: add WED binding for MT7986 eth driver

Quoted 17 lines · Lorenzo Bianconi
Quoted 16 lines

Document the binding for the Wireless Ethernet Dispatch core on the MT7986 ethernet driver

---
 Documentation/devicetree/bindings/net/mediatek,net.yaml | 9 +++++++++
 1 file changed, 9 insertions(+)
Documentation/devicetree/bindings/net/mediatek,net.yaml +0 -0
index f5564ecddb62..0116f100ef19 100644
@@ -238,6 +238,15 @@ allOf:
           minItems: 2
           maxItems: 2
 
Quoted 12 lines

Documentation/devicetree/bindings/net/mediatek,net.yaml allOf: · line 248

Quoted 8 lines
Documentation/devicetree/bindings/net/mediatek,net.yaml +8 -0
+        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.

There's already a definition of this in the binding. Move it to the main section and put 'mediatek,wed: false' in if/then schemas for variants that don't have it.

ack, I will fix it in v2.

Regards,
Lorenzo

Quoted 2 lines

Rob

author maintainer
#7 lore raw

PATCH 3/12 net: ethernet: mtk_eth_soc: move gdma_to_ppe and ppe_base definitions in mtk register map

In reply to Lorenzo Bianconi

This is a preliminary patch to introduce mt7986 hw packet engine.

---
 drivers/net/ethernet/mediatek/mtk_eth_soc.c | 15 +++++++++++----
 drivers/net/ethernet/mediatek/mtk_eth_soc.h |  3 ++-
 drivers/net/ethernet/mediatek/mtk_ppe.h     |  2 --
 3 files changed, 13 insertions(+), 7 deletions(-)
drivers/net/ethernet/mediatek/mtk_eth_soc.c +11 -4
index c19c67a480ae..b2b92fe2a96a 100644
@@ -73,6 +73,8 @@ static const struct mtk_reg_map mtk_reg_map = {
 		.fq_blen	= 0x1b2c,
 	},
 	.gdm1_cnt		= 0x2400,
+	.gdma_to_ppe		= 0x4444,
+	.ppe_base		= 0x0c00,
 };
 
 static const struct mtk_reg_map mt7628_reg_map = {
@@ -126,6 +128,8 @@ static const struct mtk_reg_map mt7986_reg_map = {
 		.fq_blen	= 0x472c,
 	},
 	.gdm1_cnt		= 0x1c00,
+	.gdma_to_ppe		= 0x3333,
+	.ppe_base		= 0x2000,
 };
 
 /* strings used by ethtool */
@@ -2978,21 +2982,22 @@ 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)) {
+		const struct mtk_soc_data *soc = eth->soc;
 		u32 gdm_config = MTK_GDMA_TO_PDMA;
 
 		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;
+		if (soc->offload_version && mtk_ppe_start(eth->ppe) == 0)
+			gdm_config = soc->reg_map->gdma_to_ppe;
 
 		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
@@ -4098,7 +4103,9 @@ 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);
+		u32 ppe_addr = eth->soc->reg_map->ppe_base;
+
+		eth->ppe = mtk_ppe_init(eth, eth->base + ppe_addr, 2);
 		if (!eth->ppe) {
 			err = -ENOMEM;
 			goto err_free_dev;
drivers/net/ethernet/mediatek/mtk_eth_soc.h +2 -1
index ecf85e9ed824..2617cbecdfca 100644
@@ -105,7 +105,6 @@
 #define MTK_GDMA_TCS_EN		BIT(21)
 #define MTK_GDMA_UCS_EN		BIT(20)
 #define MTK_GDMA_TO_PDMA	0x0
-#define MTK_GDMA_TO_PPE		0x4444
 #define MTK_GDMA_DROP_ALL       0x7777
 
 /* Unicast Filter MAC Address Register - Low */
@@ -955,6 +954,8 @@ struct mtk_reg_map {
 		u32	fq_blen;	/* fq free page buffer length */
 	} qdma;
 	u32	gdm1_cnt;
+	u32	gdma_to_ppe;
+	u32	ppe_base;
 };
 
 /* struct mtk_eth_data -	This is the structure holding all differences
drivers/net/ethernet/mediatek/mtk_ppe.h +0 -2
index 8f786c47b61a..bb079e3c0417 100644
@@ -8,8 +8,6 @@
 #include <linux/bitfield.h>
 #include <linux/rhashtable.h>
 
-#define MTK_ETH_PPE_BASE		0xc00
-
 #define MTK_PPE_ENTRIES_SHIFT		3
 #define MTK_PPE_ENTRIES			(1024 << MTK_PPE_ENTRIES_SHIFT)
 #define MTK_PPE_HASH_MASK		(MTK_PPE_ENTRIES - 1)
Signature · 1 line
2.37.3
author maintainer
#8 lore raw

PATCH 4/12 net: ethernet: mtk_eth_soc: move ppe table hash offset to mtk_soc_data structure

In reply to Lorenzo Bianconi

This is a preliminary patch to introduce mt7986 hw packet engine.

---
 drivers/net/ethernet/mediatek/mtk_eth_soc.c |  4 ++++
 drivers/net/ethernet/mediatek/mtk_eth_soc.h |  2 ++
 drivers/net/ethernet/mediatek/mtk_ppe.c     | 24 +++++++++++++++------
 drivers/net/ethernet/mediatek/mtk_ppe.h     |  2 +-
 4 files changed, 25 insertions(+), 7 deletions(-)
drivers/net/ethernet/mediatek/mtk_eth_soc.c +4 -0
index b2b92fe2a96a..d09717d4f3be 100644
@@ -4201,6 +4201,7 @@ static const struct mtk_soc_data mt7621_data = {
 	.required_clks = MT7621_CLKS_BITMAP,
 	.required_pctl = false,
 	.offload_version = 2,
+	.hash_offset = 2,
 	.txrx = {
 		.txd_size = sizeof(struct mtk_tx_dma),
 		.rxd_size = sizeof(struct mtk_rx_dma),
@@ -4219,6 +4220,7 @@ static const struct mtk_soc_data mt7622_data = {
 	.required_clks = MT7622_CLKS_BITMAP,
 	.required_pctl = false,
 	.offload_version = 2,
+	.hash_offset = 2,
 	.txrx = {
 		.txd_size = sizeof(struct mtk_tx_dma),
 		.rxd_size = sizeof(struct mtk_rx_dma),
@@ -4236,6 +4238,7 @@ static const struct mtk_soc_data mt7623_data = {
 	.required_clks = MT7623_CLKS_BITMAP,
 	.required_pctl = true,
 	.offload_version = 2,
+	.hash_offset = 2,
 	.txrx = {
 		.txd_size = sizeof(struct mtk_tx_dma),
 		.rxd_size = sizeof(struct mtk_rx_dma),
@@ -4269,6 +4272,7 @@ static const struct mtk_soc_data mt7986_data = {
 	.caps = MT7986_CAPS,
 	.required_clks = MT7986_CLKS_BITMAP,
 	.required_pctl = false,
+	.hash_offset = 4,
 	.txrx = {
 		.txd_size = sizeof(struct mtk_tx_dma_v2),
 		.rxd_size = sizeof(struct mtk_rx_dma_v2),
drivers/net/ethernet/mediatek/mtk_eth_soc.h +2 -0
index 2617cbecdfca..6c5e144cb9f0 100644
@@ -969,6 +969,7 @@ struct mtk_reg_map {
  *				the target SoC
  * @required_pctl		A bool value to show whether the SoC requires
  *				the extra setup for those pins used by GMAC.
+ * @hash_offset			Flow table hash offset.
  * @txd_size			Tx DMA descriptor size.
  * @rxd_size			Rx DMA descriptor size.
  * @rx_irq_done_mask		Rx irq done register mask.
@@ -983,6 +984,7 @@ struct mtk_soc_data {
 	u32		required_clks;
 	bool		required_pctl;
 	u8		offload_version;
+	u8		hash_offset;
 	netdev_features_t hw_features;
 	struct {
 		u32	txd_size;
drivers/net/ethernet/mediatek/mtk_ppe.c +18 -6
index cfe804bc8d20..1cc7d8338722 100644
@@ -88,7 +88,7 @@ static void mtk_ppe_cache_enable(struct mtk_ppe *ppe, bool enable)
 		enable * MTK_PPE_CACHE_CTL_EN);
 }
 
-static u32 mtk_ppe_hash_entry(struct mtk_foe_entry *e)
+static u32 mtk_ppe_hash_entry(struct mtk_eth *eth, struct mtk_foe_entry *e)
 {
 	u32 hv1, hv2, hv3;
 	u32 hash;
@@ -122,7 +122,7 @@ static u32 mtk_ppe_hash_entry(struct mtk_foe_entry *e)
 	hash = (hash >> 24) | ((hash & 0xffffff) << 8);
 	hash ^= hv1 ^ hv2 ^ hv3;
 	hash ^= hash >> 16;
-	hash <<= 1;
+	hash <<= (ffs(eth->soc->hash_offset) - 1);
 	hash &= MTK_PPE_ENTRIES - 1;
 
 	return hash;
@@ -540,15 +540,16 @@ mtk_foe_entry_commit_l2(struct mtk_ppe *ppe, struct mtk_flow_entry *entry)
 int mtk_foe_entry_commit(struct mtk_ppe *ppe, struct mtk_flow_entry *entry)
 {
 	int type = FIELD_GET(MTK_FOE_IB1_PACKET_TYPE, entry->data.ib1);
+	const struct mtk_soc_data *soc = ppe->eth->soc;
 	u32 hash;
 
 	if (type == MTK_PPE_PKT_TYPE_BRIDGE)
 		return mtk_foe_entry_commit_l2(ppe, entry);
 
-	hash = mtk_ppe_hash_entry(&entry->data);
+	hash = mtk_ppe_hash_entry(ppe->eth, &entry->data);
 	entry->hash = 0xffff;
 	spin_lock_bh(&ppe_lock);
-	hlist_add_head(&entry->list, &ppe->foe_flow[hash / 2]);
+	hlist_add_head(&entry->list, &ppe->foe_flow[hash / soc->hash_offset]);
 	spin_unlock_bh(&ppe_lock);
 
 	return 0;
@@ -558,6 +559,7 @@ static void
 mtk_foe_entry_commit_subflow(struct mtk_ppe *ppe, struct mtk_flow_entry *entry,
 			     u16 hash)
 {
+	const struct mtk_soc_data *soc = ppe->eth->soc;
 	struct mtk_flow_entry *flow_info;
 	struct mtk_foe_entry foe, *hwe;
 	struct mtk_foe_mac_info *l2;
@@ -572,7 +574,8 @@ mtk_foe_entry_commit_subflow(struct mtk_ppe *ppe, struct mtk_flow_entry *entry,
 	flow_info->l2_data.base_flow = entry;
 	flow_info->type = MTK_FLOW_TYPE_L2_SUBFLOW;
 	flow_info->hash = hash;
-	hlist_add_head(&flow_info->list, &ppe->foe_flow[hash / 2]);
+	hlist_add_head(&flow_info->list,
+		       &ppe->foe_flow[hash / soc->hash_offset]);
 	hlist_add_head(&flow_info->l2_data.list, &entry->l2_flows);
 
 	hwe = &ppe->foe_table[hash];
@@ -596,7 +599,8 @@ mtk_foe_entry_commit_subflow(struct mtk_ppe *ppe, struct mtk_flow_entry *entry,
 
 void __mtk_ppe_check_skb(struct mtk_ppe *ppe, struct sk_buff *skb, u16 hash)
 {
-	struct hlist_head *head = &ppe->foe_flow[hash / 2];
+	const struct mtk_soc_data *soc = ppe->eth->soc;
+	struct hlist_head *head = &ppe->foe_flow[hash / soc->hash_offset];
 	struct mtk_foe_entry *hwe = &ppe->foe_table[hash];
 	struct mtk_flow_entry *entry;
 	struct mtk_foe_bridge key = {};
@@ -680,9 +684,11 @@ int mtk_foe_entry_idle_time(struct mtk_ppe *ppe, struct mtk_flow_entry *entry)
 struct mtk_ppe *mtk_ppe_init(struct mtk_eth *eth, void __iomem *base,
 		 int version)
 {
+	const struct mtk_soc_data *soc = eth->soc;
 	struct device *dev = eth->dev;
 	struct mtk_foe_entry *foe;
 	struct mtk_ppe *ppe;
+	u32 foe_flow_size;
 
 	ppe = devm_kzalloc(dev, sizeof(*ppe), GFP_KERNEL);
 	if (!ppe)
@@ -705,6 +711,12 @@ struct mtk_ppe *mtk_ppe_init(struct mtk_eth *eth, void __iomem *base,
 
 	ppe->foe_table = foe;
 
+	foe_flow_size = (MTK_PPE_ENTRIES / soc->hash_offset) *
+			sizeof(*ppe->foe_flow);
+	ppe->foe_flow = devm_kzalloc(dev, foe_flow_size, GFP_KERNEL);
+	if (!ppe->foe_flow)
+		return NULL;
+
 	mtk_ppe_debugfs_init(ppe);
 
 	return ppe;
drivers/net/ethernet/mediatek/mtk_ppe.h +1 -1
index bb079e3c0417..22efed6599c2 100644
@@ -270,7 +270,7 @@ struct mtk_ppe {
 	dma_addr_t foe_phys;
 
 	u16 foe_check_time[MTK_PPE_ENTRIES];
-	struct hlist_head foe_flow[MTK_PPE_ENTRIES / 2];
+	struct hlist_head *foe_flow;
 
 	struct rhashtable l2_flows;
 
Signature · 1 line
2.37.3
author maintainer
#9 lore raw

PATCH 5/12 net: ethernet: mtk_eth_soc: add the capability to run multiple ppe

In reply to Lorenzo Bianconi

mt7986 chipset support multiple packet engines for wlan <-> eth packet forwarding.

---
 drivers/net/ethernet/mediatek/mtk_eth_soc.c   | 35 ++++++++++++-------
 drivers/net/ethernet/mediatek/mtk_eth_soc.h   |  2 +-
 drivers/net/ethernet/mediatek/mtk_ppe.c       | 14 +++++---
 drivers/net/ethernet/mediatek/mtk_ppe.h       |  9 +++--
 .../net/ethernet/mediatek/mtk_ppe_debugfs.c   |  8 ++---
 .../net/ethernet/mediatek/mtk_ppe_offload.c   | 13 +++----
 6 files changed, 48 insertions(+), 33 deletions(-)
drivers/net/ethernet/mediatek/mtk_eth_soc.c +23 -12
index d09717d4f3be..bbafe5598b14 100644
@@ -1919,7 +1919,7 @@ static int mtk_poll_rx(struct napi_struct *napi, int budget,
 
 		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)) {
@@ -2983,15 +2983,18 @@ 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)) {
 		const struct mtk_soc_data *soc = eth->soc;
-		u32 gdm_config = MTK_GDMA_TO_PDMA;
+		u32 gdm_config;
+		int i;
 
 		err = mtk_start_dma(eth);
 		if (err)
 			return err;
 
-		if (soc->offload_version && mtk_ppe_start(eth->ppe) == 0)
-			gdm_config = soc->reg_map->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);
@@ -3035,6 +3038,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);
 
@@ -3062,8 +3066,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;
 }
@@ -4103,12 +4107,19 @@ static int mtk_probe(struct platform_device *pdev)
 	}
 
 	if (eth->soc->offload_version) {
-		u32 ppe_addr = eth->soc->reg_map->ppe_base;
-
-		eth->ppe = mtk_ppe_init(eth, eth->base + ppe_addr, 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);
drivers/net/ethernet/mediatek/mtk_eth_soc.h +1 -1
index 6c5e144cb9f0..54448795159d 100644
@@ -1114,7 +1114,7 @@ struct mtk_eth {
 
 	int				ip_align;
 
-	struct mtk_ppe			*ppe;
+	struct mtk_ppe			*ppe[2];
 	struct rhashtable		flow_table;
 
 	struct bpf_prog			__rcu *prog;
drivers/net/ethernet/mediatek/mtk_ppe.c +9 -5
index 1cc7d8338722..687d365b601a 100644
@@ -682,7 +682,7 @@ int mtk_foe_entry_idle_time(struct mtk_ppe *ppe, struct mtk_flow_entry *entry)
 }
 
 struct mtk_ppe *mtk_ppe_init(struct mtk_eth *eth, void __iomem *base,
-		 int version)
+			     int version, int index)
 {
 	const struct mtk_soc_data *soc = eth->soc;
 	struct device *dev = eth->dev;
@@ -717,7 +717,7 @@ struct mtk_ppe *mtk_ppe_init(struct mtk_eth *eth, void __iomem *base,
 	if (!ppe->foe_flow)
 		return NULL;
 
-	mtk_ppe_debugfs_init(ppe);
+	mtk_ppe_debugfs_init(ppe, index);
 
 	return ppe;
 }
@@ -738,10 +738,13 @@ static void mtk_ppe_init_foe_table(struct mtk_ppe *ppe)
 			ppe->foe_table[i + skip[k]].ib1 |= MTK_FOE_IB1_STATIC;
 }
 
-int mtk_ppe_start(struct mtk_ppe *ppe)
+void mtk_ppe_start(struct mtk_ppe *ppe)
 {
 	u32 val;
 
+	if (!ppe)
+		return;
+
 	mtk_ppe_init_foe_table(ppe);
 	ppe_w32(ppe, MTK_PPE_TB_BASE, ppe->foe_phys);
 
@@ -809,8 +812,6 @@ int mtk_ppe_start(struct mtk_ppe *ppe)
 	ppe_w32(ppe, MTK_PPE_GLO_CFG, val);
 
 	ppe_w32(ppe, MTK_PPE_DEFAULT_CPU_PORT, 0);
-
-	return 0;
 }
 
 int mtk_ppe_stop(struct mtk_ppe *ppe)
@@ -818,6 +819,9 @@ int mtk_ppe_stop(struct mtk_ppe *ppe)
 	u32 val;
 	int i;
 
+	if (!ppe)
+		return 0;
+
 	for (i = 0; i < MTK_PPE_ENTRIES; i++)
 		ppe->foe_table[i].ib1 = FIELD_PREP(MTK_FOE_IB1_STATE,
 						   MTK_FOE_STATE_INVALID);
drivers/net/ethernet/mediatek/mtk_ppe.h +6 -3
index 22efed6599c2..4c31d854e986 100644
@@ -247,6 +247,7 @@ struct mtk_flow_entry {
 	};
 	u8 type;
 	s8 wed_index;
+	u8 ppe_index;
 	u16 hash;
 	union {
 		struct mtk_foe_entry data;
@@ -265,6 +266,7 @@ struct mtk_ppe {
 	struct device *dev;
 	void __iomem *base;
 	int version;
+	char dirname[5];
 
 	struct mtk_foe_entry *foe_table;
 	dma_addr_t foe_phys;
@@ -277,8 +279,9 @@ struct mtk_ppe {
 	void *acct_table;
 };
 
-struct mtk_ppe *mtk_ppe_init(struct mtk_eth *eth, void __iomem *base, int version);
-int mtk_ppe_start(struct mtk_ppe *ppe);
+struct mtk_ppe *mtk_ppe_init(struct mtk_eth *eth, void __iomem *base,
+			     int version, int index);
+void mtk_ppe_start(struct mtk_ppe *ppe);
 int mtk_ppe_stop(struct mtk_ppe *ppe);
 
 void __mtk_ppe_check_skb(struct mtk_ppe *ppe, struct sk_buff *skb, u16 hash);
@@ -320,6 +323,6 @@ int mtk_foe_entry_set_wdma(struct mtk_foe_entry *entry, int wdma_idx, int txq,
 int mtk_foe_entry_commit(struct mtk_ppe *ppe, struct mtk_flow_entry *entry);
 void mtk_foe_entry_clear(struct mtk_ppe *ppe, struct mtk_flow_entry *entry);
 int mtk_foe_entry_idle_time(struct mtk_ppe *ppe, struct mtk_flow_entry *entry);
-int mtk_ppe_debugfs_init(struct mtk_ppe *ppe);
+int mtk_ppe_debugfs_init(struct mtk_ppe *ppe, int index);
 
 #endif
drivers/net/ethernet/mediatek/mtk_ppe_debugfs.c +4 -4
index eb0b598f14e4..0868226ccc27 100644
@@ -187,7 +187,7 @@ mtk_ppe_debugfs_foe_open_bind(struct inode *inode, struct file *file)
 			   inode->i_private);
 }
 
-int mtk_ppe_debugfs_init(struct mtk_ppe *ppe)
+int mtk_ppe_debugfs_init(struct mtk_ppe *ppe, int index)
 {
 	static const struct file_operations fops_all = {
 		.open = mtk_ppe_debugfs_foe_open_all,
@@ -195,17 +195,17 @@ int mtk_ppe_debugfs_init(struct mtk_ppe *ppe)
 		.llseek = seq_lseek,
 		.release = single_release,
 	};
-
 	static const struct file_operations fops_bind = {
 		.open = mtk_ppe_debugfs_foe_open_bind,
 		.read = seq_read,
 		.llseek = seq_lseek,
 		.release = single_release,
 	};
-
 	struct dentry *root;
 
-	root = debugfs_create_dir("mtk_ppe", NULL);
+	snprintf(ppe->dirname, sizeof(ppe->dirname), "ppe%d", index);
+
+	root = debugfs_create_dir(ppe->dirname, NULL);
 	debugfs_create_file("entries", S_IRUGO, root, ppe, &fops_all);
 	debugfs_create_file("bind", S_IRUGO, root, ppe, &fops_bind);
 
drivers/net/ethernet/mediatek/mtk_ppe_offload.c +5 -8
index 25dc3c3aa31d..0324e7750065 100644
@@ -434,7 +434,7 @@ mtk_flow_offload_replace(struct mtk_eth *eth, struct flow_cls_offload *f)
 	memcpy(&entry->data, &foe, sizeof(entry->data));
 	entry->wed_index = wed_index;
 
-	err = mtk_foe_entry_commit(eth->ppe, entry);
+	err = mtk_foe_entry_commit(eth->ppe[entry->ppe_index], entry);
 	if (err < 0)
 		goto free;
 
@@ -446,7 +446,7 @@ mtk_flow_offload_replace(struct mtk_eth *eth, struct flow_cls_offload *f)
 	return 0;
 
 clear:
-	mtk_foe_entry_clear(eth->ppe, entry);
+	mtk_foe_entry_clear(eth->ppe[entry->ppe_index], entry);
 free:
 	kfree(entry);
 	if (wed_index >= 0)
@@ -464,7 +464,7 @@ mtk_flow_offload_destroy(struct mtk_eth *eth, struct flow_cls_offload *f)
 	if (!entry)
 		return -ENOENT;
 
-	mtk_foe_entry_clear(eth->ppe, entry);
+	mtk_foe_entry_clear(eth->ppe[entry->ppe_index], entry);
 	rhashtable_remove_fast(&eth->flow_table, &entry->node,
 			       mtk_flow_ht_params);
 	if (entry->wed_index >= 0)
@@ -485,7 +485,7 @@ mtk_flow_offload_stats(struct mtk_eth *eth, struct flow_cls_offload *f)
 	if (!entry)
 		return -ENOENT;
 
-	idle = mtk_foe_entry_idle_time(eth->ppe, entry);
+	idle = mtk_foe_entry_idle_time(eth->ppe[entry->ppe_index], entry);
 	f->stats.lastused = jiffies - idle * HZ;
 
 	return 0;
@@ -537,7 +537,7 @@ mtk_eth_setup_tc_block(struct net_device *dev, struct flow_block_offload *f)
 	struct flow_block_cb *block_cb;
 	flow_setup_cb_t *cb;
 
-	if (!eth->ppe || !eth->ppe->foe_table)
+	if (!eth->soc->offload_version)
 		return -EOPNOTSUPP;
 
 	if (f->binder_type != FLOW_BLOCK_BINDER_TYPE_CLSACT_INGRESS)
@@ -589,8 +589,5 @@ int mtk_eth_setup_tc(struct net_device *dev, enum tc_setup_type type,
 
 int mtk_eth_offload_init(struct mtk_eth *eth)
 {
-	if (!eth->ppe || !eth->ppe->foe_table)
-		return 0;
-
 	return rhashtable_init(&eth->flow_table, &mtk_flow_ht_params);
 }
Signature · 1 line
2.37.3
author maintainer
#10 lore raw

PATCH 6/12 net: ethernet: mtk_eth_soc: move wdma_base definitions in mtk register map

In reply to Lorenzo Bianconi

This is a preliminary patch to introduce mt7986 wed support.

---
 drivers/net/ethernet/mediatek/mtk_eth_soc.c | 16 ++++++++++------
 drivers/net/ethernet/mediatek/mtk_eth_soc.h |  4 +---
 2 files changed, 11 insertions(+), 9 deletions(-)
drivers/net/ethernet/mediatek/mtk_eth_soc.c +10 -6
index bbafe5598b14..f289b994e7d5 100644
@@ -75,6 +75,10 @@ static const struct mtk_reg_map mtk_reg_map = {
 	.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 = {
@@ -130,6 +134,10 @@ static const struct mtk_reg_map mt7986_reg_map = {
 	.gdm1_cnt		= 0x1c00,
 	.gdma_to_ppe		= 0x3333,
 	.ppe_base		= 0x2000,
+	.wdma_base = {
+		[0]		= 0x4800,
+		[1]		= 0x4c00,
+	},
 };
 
 /* strings used by ethtool */
@@ -4019,16 +4027,12 @@ 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))
+		if (!np || i >= ARRAY_SIZE(eth->soc->reg_map->wdma_base))
 			break;
 
-		wdma = eth->base + wdma_regs[i];
+		wdma = eth->base + eth->soc->reg_map->wdma_base[i];
 		mtk_wed_add_hw(np, eth, wdma, i);
 	}
 
drivers/net/ethernet/mediatek/mtk_eth_soc.h +1 -3
index 54448795159d..39a0361ca989 100644
@@ -268,9 +268,6 @@
 #define TX_DMA_FPORT_MASK_V2	0xf
 #define TX_DMA_SWC_V2		BIT(30)
 
-#define MTK_WDMA0_BASE		0x2800
-#define MTK_WDMA1_BASE		0x2c00
-
 /* QDMA descriptor txd4 */
 #define TX_DMA_CHKSUM		(0x7 << 29)
 #define TX_DMA_TSO		BIT(28)
@@ -956,6 +953,7 @@ struct mtk_reg_map {
 	u32	gdm1_cnt;
 	u32	gdma_to_ppe;
 	u32	ppe_base;
+	u32	wdma_base[2];
 };
 
 /* struct mtk_eth_data -	This is the structure holding all differences
Signature · 1 line
2.37.3
author maintainer
#11 lore raw

PATCH 7/12 net: ethernet: mtk_eth_soc: add foe_entry_size to mtk_eth_soc

In reply to Lorenzo Bianconi

Introduce foe_entry_size to mtk_eth_soc data structure since mt7986 relies on a bigger mtk_foe_entry data structure.

---
 drivers/net/ethernet/mediatek/mtk_eth_soc.c   |  3 +
 drivers/net/ethernet/mediatek/mtk_eth_soc.h   | 10 ++++
 drivers/net/ethernet/mediatek/mtk_ppe.c       | 55 +++++++++++--------
 drivers/net/ethernet/mediatek/mtk_ppe.h       |  2 +-
 .../net/ethernet/mediatek/mtk_ppe_debugfs.c   |  2 +-
 5 files changed, 48 insertions(+), 24 deletions(-)
drivers/net/ethernet/mediatek/mtk_eth_soc.c +3 -0
index f289b994e7d5..b4bccd42a22c 100644
@@ -4217,6 +4217,7 @@ static const struct mtk_soc_data mt7621_data = {
 	.required_pctl = false,
 	.offload_version = 2,
 	.hash_offset = 2,
+	.foe_entry_size = sizeof(struct mtk_foe_entry),
 	.txrx = {
 		.txd_size = sizeof(struct mtk_tx_dma),
 		.rxd_size = sizeof(struct mtk_rx_dma),
@@ -4236,6 +4237,7 @@ static const struct mtk_soc_data mt7622_data = {
 	.required_pctl = false,
 	.offload_version = 2,
 	.hash_offset = 2,
+	.foe_entry_size = sizeof(struct mtk_foe_entry),
 	.txrx = {
 		.txd_size = sizeof(struct mtk_tx_dma),
 		.rxd_size = sizeof(struct mtk_rx_dma),
@@ -4254,6 +4256,7 @@ static const struct mtk_soc_data mt7623_data = {
 	.required_pctl = true,
 	.offload_version = 2,
 	.hash_offset = 2,
+	.foe_entry_size = sizeof(struct mtk_foe_entry),
 	.txrx = {
 		.txd_size = sizeof(struct mtk_tx_dma),
 		.rxd_size = sizeof(struct mtk_rx_dma),
drivers/net/ethernet/mediatek/mtk_eth_soc.h +10 -0
index 39a0361ca989..08236e054616 100644
@@ -968,6 +968,7 @@ struct mtk_reg_map {
  * @required_pctl		A bool value to show whether the SoC requires
  *				the extra setup for those pins used by GMAC.
  * @hash_offset			Flow table hash offset.
+ * @foe_entry_size		Foe table entry size.
  * @txd_size			Tx DMA descriptor size.
  * @rxd_size			Rx DMA descriptor size.
  * @rx_irq_done_mask		Rx irq done register mask.
@@ -983,6 +984,7 @@ struct mtk_soc_data {
 	bool		required_pctl;
 	u8		offload_version;
 	u8		hash_offset;
+	u16		foe_entry_size;
 	netdev_features_t hw_features;
 	struct {
 		u32	txd_size;
@@ -1143,6 +1145,14 @@ struct mtk_mac {
 /* the struct describing the SoC. these are declared in the soc_xyz.c files */
 extern const struct of_device_id of_mtk_match[];
 
+static inline struct mtk_foe_entry *
+mtk_foe_get_entry(struct mtk_ppe *ppe, u16 hash)
+{
+	const struct mtk_soc_data *soc = ppe->eth->soc;
+
+	return ppe->foe_table + hash * soc->foe_entry_size;
+}
+
 /* read the hardware status register */
 void mtk_stats_update_mac(struct mtk_mac *mac);
 
drivers/net/ethernet/mediatek/mtk_ppe.c +33 -22

135 lines not on this page · raw message

drivers/net/ethernet/mediatek/mtk_ppe.h +1 -1
index 4c31d854e986..6d4c91acd1a5 100644
@@ -268,7 +268,7 @@ struct mtk_ppe {
 	int version;
 	char dirname[5];
 
-	struct mtk_foe_entry *foe_table;
+	void *foe_table;
 	dma_addr_t foe_phys;
 
 	u16 foe_check_time[MTK_PPE_ENTRIES];
drivers/net/ethernet/mediatek/mtk_ppe_debugfs.c +1 -1
index 0868226ccc27..ec49829ab32d 100644
@@ -79,7 +79,7 @@ mtk_ppe_debugfs_foe_show(struct seq_file *m, void *private, bool bind)
 	int i;
 
 	for (i = 0; i < MTK_PPE_ENTRIES; i++) {
-		struct mtk_foe_entry *entry = &ppe->foe_table[i];
+		struct mtk_foe_entry *entry = mtk_foe_get_entry(ppe, i);
 		struct mtk_foe_mac_info *l2;
 		struct mtk_flow_addr_info ai = {};
 		unsigned char h_source[ETH_ALEN];
Signature · 1 line
2.37.3
author maintainer
#12 lore raw

PATCH 8/12 net: ethernet: mtk_eth_soc: add foe info in mtk_soc_data structure

In reply to Lorenzo Bianconi

Introduce foe struct in mtk_soc_data as a container for foe table chip related definitions.
This is a preliminary patch to enable mt7986 wed support.

---
 drivers/net/ethernet/mediatek/mtk_eth_soc.c   |  70 +++++++-
 drivers/net/ethernet/mediatek/mtk_eth_soc.h   |  27 ++-
 drivers/net/ethernet/mediatek/mtk_ppe.c       | 161 ++++++++++--------
 drivers/net/ethernet/mediatek/mtk_ppe.h       |  29 ++--
 .../net/ethernet/mediatek/mtk_ppe_offload.c   |  34 ++--
 5 files changed, 208 insertions(+), 113 deletions(-)
drivers/net/ethernet/mediatek/mtk_eth_soc.c +63 -7
index b4bccd42a22c..8aa0a61b35fc 100644
@@ -4216,8 +4216,6 @@ 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),
 	.txrx = {
 		.txd_size = sizeof(struct mtk_tx_dma),
 		.rxd_size = sizeof(struct mtk_rx_dma),
@@ -4226,6 +4224,26 @@ static const struct mtk_soc_data mt7621_data = {
 		.dma_max_len = MTK_TX_DMA_BUF_LEN,
 		.dma_len_offset = 16,
 	},
+	.foe = {
+		.entry_size = sizeof(struct mtk_foe_entry),
+		.hash_offset = 2,
+		.ib1 = {
+			.bind_ppoe = BIT(19),
+			.bind_vlan_tag = BIT(20),
+			.bind_cache = BIT(22),
+			.bind_ttl = BIT(24),
+			.bind_ts = GENMASK(14, 0),
+			.bind_vlan_layer = GENMASK(18, 16),
+			.pkt_type = GENMASK(27, 25),
+		},
+		.ib2 = {
+			.multicast = BIT(8),
+			.wdma_winfo = BIT(17),
+			.port_ag = GENMASK(23, 18),
+			.port_mg = GENMASK(17, 12),
+			.dst_port = GENMASK(7, 5),
+		},
+	},
 };
 
 static const struct mtk_soc_data mt7622_data = {
@@ -4236,8 +4254,6 @@ 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),
 	.txrx = {
 		.txd_size = sizeof(struct mtk_tx_dma),
 		.rxd_size = sizeof(struct mtk_rx_dma),
@@ -4246,6 +4262,26 @@ static const struct mtk_soc_data mt7622_data = {
 		.dma_max_len = MTK_TX_DMA_BUF_LEN,
 		.dma_len_offset = 16,
 	},
+	.foe = {
+		.entry_size = sizeof(struct mtk_foe_entry),
+		.hash_offset = 2,
+		.ib1 = {
+			.bind_ppoe = BIT(19),
+			.bind_vlan_tag = BIT(20),
+			.bind_cache = BIT(22),
+			.bind_ttl = BIT(24),
+			.bind_ts = GENMASK(14, 0),
+			.bind_vlan_layer = GENMASK(18, 16),
+			.pkt_type = GENMASK(27, 25),
+		},
+		.ib2 = {
+			.multicast = BIT(8),
+			.wdma_winfo = BIT(17),
+			.port_ag = GENMASK(23, 18),
+			.port_mg = GENMASK(17, 12),
+			.dst_port = GENMASK(7, 5),
+		},
+	},
 };
 
 static const struct mtk_soc_data mt7623_data = {
@@ -4255,8 +4291,6 @@ 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),
 	.txrx = {
 		.txd_size = sizeof(struct mtk_tx_dma),
 		.rxd_size = sizeof(struct mtk_rx_dma),
@@ -4265,6 +4299,26 @@ static const struct mtk_soc_data mt7623_data = {
 		.dma_max_len = MTK_TX_DMA_BUF_LEN,
 		.dma_len_offset = 16,
 	},
+	.foe = {
+		.entry_size = sizeof(struct mtk_foe_entry),
+		.hash_offset = 2,
+		.ib1 = {
+			.bind_ppoe = BIT(19),
+			.bind_vlan_tag = BIT(20),
+			.bind_cache = BIT(22),
+			.bind_ttl = BIT(24),
+			.bind_ts = GENMASK(14, 0),
+			.bind_vlan_layer = GENMASK(18, 16),
+			.pkt_type = GENMASK(27, 25),
+		},
+		.ib2 = {
+			.multicast = BIT(8),
+			.wdma_winfo = BIT(17),
+			.port_ag = GENMASK(23, 18),
+			.port_mg = GENMASK(17, 12),
+			.dst_port = GENMASK(7, 5),
+		},
+	},
 };
 
 static const struct mtk_soc_data mt7629_data = {
@@ -4290,7 +4344,6 @@ static const struct mtk_soc_data mt7986_data = {
 	.caps = MT7986_CAPS,
 	.required_clks = MT7986_CLKS_BITMAP,
 	.required_pctl = false,
-	.hash_offset = 4,
 	.txrx = {
 		.txd_size = sizeof(struct mtk_tx_dma_v2),
 		.rxd_size = sizeof(struct mtk_rx_dma_v2),
@@ -4299,6 +4352,9 @@ static const struct mtk_soc_data mt7986_data = {
 		.dma_max_len = MTK_TX_DMA_BUF_LEN_V2,
 		.dma_len_offset = 8,
 	},
+	.foe = {
+		.hash_offset = 4,
+	},
 };
 
 static const struct mtk_soc_data rt5350_data = {
drivers/net/ethernet/mediatek/mtk_eth_soc.h +22 -5
index 08236e054616..6d0b080c2048 100644
@@ -967,14 +967,13 @@ struct mtk_reg_map {
  *				the target SoC
  * @required_pctl		A bool value to show whether the SoC requires
  *				the extra setup for those pins used by GMAC.
- * @hash_offset			Flow table hash offset.
- * @foe_entry_size		Foe table entry size.
  * @txd_size			Tx DMA descriptor size.
  * @rxd_size			Rx DMA descriptor size.
  * @rx_irq_done_mask		Rx irq done register mask.
  * @rx_dma_l4_valid		Rx DMA valid register mask.
  * @dma_max_len			Max DMA tx/rx buffer length.
  * @dma_len_offset		Tx/Rx DMA length field offset.
+ * @foe				Foe table chip info.
  */
 struct mtk_soc_data {
 	const struct mtk_reg_map *reg_map;
@@ -983,8 +982,6 @@ struct mtk_soc_data {
 	u32		required_clks;
 	bool		required_pctl;
 	u8		offload_version;
-	u8		hash_offset;
-	u16		foe_entry_size;
 	netdev_features_t hw_features;
 	struct {
 		u32	txd_size;
@@ -994,6 +991,26 @@ struct mtk_soc_data {
 		u32	dma_max_len;
 		u32	dma_len_offset;
 	} txrx;
+	struct {
+		u16	entry_size;
+		u8	hash_offset;
+		struct {
+			u32 bind_ppoe;
+			u32 bind_vlan_tag;
+			u32 bind_cache;
+			u32 bind_ttl;
+			u32 bind_ts;
+			u32 bind_vlan_layer;
+			u32 pkt_type;
+		} ib1;
+		struct {
+			u32 wdma_winfo;
+			u32 port_ag;
+			u32 port_mg;
+			u16 multicast;
+			u16 dst_port;
+		} ib2;
+	} foe;
 };
 
 /* currently no SoC has more than 2 macs */
@@ -1150,7 +1167,7 @@ mtk_foe_get_entry(struct mtk_ppe *ppe, u16 hash)
 {
 	const struct mtk_soc_data *soc = ppe->eth->soc;
 
-	return ppe->foe_table + hash * soc->foe_entry_size;
+	return ppe->foe_table + hash * soc->foe.entry_size;
 }
 
 /* read the hardware status register */
drivers/net/ethernet/mediatek/mtk_ppe.c +87 -74

388 lines not on this page · raw message

drivers/net/ethernet/mediatek/mtk_ppe.h +19 -10
index 6d4c91acd1a5..a364f45edf38 100644
@@ -61,6 +61,8 @@ enum {
 #define MTK_FOE_VLAN2_WINFO_WCID	GENMASK(13, 6)
 #define MTK_FOE_VLAN2_WINFO_RING	GENMASK(15, 14)
 
+#define MTK_FIELD_PREP(mask, val)	(((typeof(mask))(val) << __bf_shf(mask)) & (mask))
+#define MTK_FIELD_GET(mask, val)	((typeof(mask))(((val) & (mask)) >> __bf_shf(mask)))
 enum {
 	MTK_FOE_STATE_INVALID,
 	MTK_FOE_STATE_UNBIND,
@@ -306,20 +308,27 @@ mtk_ppe_check_skb(struct mtk_ppe *ppe, struct sk_buff *skb, u16 hash)
 	__mtk_ppe_check_skb(ppe, skb, hash);
 }
 
-int mtk_foe_entry_prepare(struct mtk_foe_entry *entry, int type, int l4proto,
-			  u8 pse_port, u8 *src_mac, u8 *dest_mac);
-int mtk_foe_entry_set_pse_port(struct mtk_foe_entry *entry, u8 port);
-int mtk_foe_entry_set_ipv4_tuple(struct mtk_foe_entry *entry, bool orig,
+int mtk_foe_entry_prepare(struct mtk_eth *eth, struct mtk_foe_entry *entry,
+			  int type, int l4proto, u8 pse_port, u8 *src_mac,
+			  u8 *dest_mac);
+int mtk_foe_entry_set_pse_port(struct mtk_eth *eth,
+			       struct mtk_foe_entry *entry, u8 port);
+int mtk_foe_entry_set_ipv4_tuple(struct mtk_eth *eth,
+				 struct mtk_foe_entry *entry, bool orig,
 				 __be32 src_addr, __be16 src_port,
 				 __be32 dest_addr, __be16 dest_port);
-int mtk_foe_entry_set_ipv6_tuple(struct mtk_foe_entry *entry,
+int mtk_foe_entry_set_ipv6_tuple(struct mtk_eth *eth,
+				 struct mtk_foe_entry *entry,
 				 __be32 *src_addr, __be16 src_port,
 				 __be32 *dest_addr, __be16 dest_port);
-int mtk_foe_entry_set_dsa(struct mtk_foe_entry *entry, int port);
-int mtk_foe_entry_set_vlan(struct mtk_foe_entry *entry, int vid);
-int mtk_foe_entry_set_pppoe(struct mtk_foe_entry *entry, int sid);
-int mtk_foe_entry_set_wdma(struct mtk_foe_entry *entry, int wdma_idx, int txq,
-			   int bss, int wcid);
+int mtk_foe_entry_set_dsa(struct mtk_eth *eth, struct mtk_foe_entry *entry,
+			  int port);
+int mtk_foe_entry_set_vlan(struct mtk_eth *eth, struct mtk_foe_entry *entry,
+			   int vid);
+int mtk_foe_entry_set_pppoe(struct mtk_eth *eth, struct mtk_foe_entry *entry,
+			    int sid);
+int mtk_foe_entry_set_wdma(struct mtk_eth *eth, struct mtk_foe_entry *entry,
+			   int wdma_idx, int txq, int bss, int wcid);
 int mtk_foe_entry_commit(struct mtk_ppe *ppe, struct mtk_flow_entry *entry);
 void mtk_foe_entry_clear(struct mtk_ppe *ppe, struct mtk_flow_entry *entry);
 int mtk_foe_entry_idle_time(struct mtk_ppe *ppe, struct mtk_flow_entry *entry);
drivers/net/ethernet/mediatek/mtk_ppe_offload.c +17 -17
index 0324e7750065..56c49ac712b9 100644
@@ -52,18 +52,19 @@ static const struct rhashtable_params mtk_flow_ht_params = {
 };
 
 static int
-mtk_flow_set_ipv4_addr(struct mtk_foe_entry *foe, struct mtk_flow_data *data,
-		       bool egress)
+mtk_flow_set_ipv4_addr(struct mtk_eth *eth, struct mtk_foe_entry *foe,
+		       struct mtk_flow_data *data, bool egress)
 {
-	return mtk_foe_entry_set_ipv4_tuple(foe, egress,
+	return mtk_foe_entry_set_ipv4_tuple(eth, foe, egress,
 					    data->v4.src_addr, data->src_port,
 					    data->v4.dst_addr, data->dst_port);
 }
 
 static int
-mtk_flow_set_ipv6_addr(struct mtk_foe_entry *foe, struct mtk_flow_data *data)
+mtk_flow_set_ipv6_addr(struct mtk_eth *eth, struct mtk_foe_entry *foe,
+		       struct mtk_flow_data *data)
 {
-	return mtk_foe_entry_set_ipv6_tuple(foe,
+	return mtk_foe_entry_set_ipv6_tuple(eth, foe,
 					    data->v6.src_addr.s6_addr32, data->src_port,
 					    data->v6.dst_addr.s6_addr32, data->dst_port);
 }
@@ -190,8 +191,8 @@ mtk_flow_set_output_device(struct mtk_eth *eth, struct mtk_foe_entry *foe,
 	int pse_port, dsa_port;
 
 	if (mtk_flow_get_wdma_info(dev, dest_mac, &info) == 0) {
-		mtk_foe_entry_set_wdma(foe, info.wdma_idx, info.queue, info.bss,
-				       info.wcid);
+		mtk_foe_entry_set_wdma(eth, foe, info.wdma_idx, info.queue,
+				       info.bss, info.wcid);
 		pse_port = 3;
 		*wed_index = info.wdma_idx;
 		goto out;
@@ -199,7 +200,7 @@ mtk_flow_set_output_device(struct mtk_eth *eth, struct mtk_foe_entry *foe,
 
 	dsa_port = mtk_flow_get_dsa_port(&dev);
 	if (dsa_port >= 0)
-		mtk_foe_entry_set_dsa(foe, dsa_port);
+		mtk_foe_entry_set_dsa(eth, foe, dsa_port);
 
 	if (dev == eth->netdev[0])
 		pse_port = 1;
@@ -209,7 +210,7 @@ mtk_flow_set_output_device(struct mtk_eth *eth, struct mtk_foe_entry *foe,
 		return -EOPNOTSUPP;
 
 out:
-	mtk_foe_entry_set_pse_port(foe, pse_port);
+	mtk_foe_entry_set_pse_port(eth, foe, pse_port);
 
 	return 0;
 }
@@ -333,9 +334,8 @@ mtk_flow_offload_replace(struct mtk_eth *eth, struct flow_cls_offload *f)
 	    !is_valid_ether_addr(data.eth.h_dest))
 		return -EINVAL;
 
-	err = mtk_foe_entry_prepare(&foe, offload_type, l4proto, 0,
-				    data.eth.h_source,
-				    data.eth.h_dest);
+	err = mtk_foe_entry_prepare(eth, &foe, offload_type, l4proto, 0,
+				    data.eth.h_source, data.eth.h_dest);
 	if (err)
 		return err;
 
@@ -360,7 +360,7 @@ mtk_flow_offload_replace(struct mtk_eth *eth, struct flow_cls_offload *f)
 		data.v4.src_addr = addrs.key->src;
 		data.v4.dst_addr = addrs.key->dst;
 
-		mtk_flow_set_ipv4_addr(&foe, &data, false);
+		mtk_flow_set_ipv4_addr(eth, &foe, &data, false);
 	}
 
 	if (addr_type == FLOW_DISSECTOR_KEY_IPV6_ADDRS) {
@@ -371,7 +371,7 @@ mtk_flow_offload_replace(struct mtk_eth *eth, struct flow_cls_offload *f)
 		data.v6.src_addr = addrs.key->src;
 		data.v6.dst_addr = addrs.key->dst;
 
-		mtk_flow_set_ipv6_addr(&foe, &data);
+		mtk_flow_set_ipv6_addr(eth, &foe, &data);
 	}
 
 	flow_action_for_each(i, act, &rule->action) {
@@ -401,7 +401,7 @@ mtk_flow_offload_replace(struct mtk_eth *eth, struct flow_cls_offload *f)
 	}
 
 	if (addr_type == FLOW_DISSECTOR_KEY_IPV4_ADDRS) {
-		err = mtk_flow_set_ipv4_addr(&foe, &data, true);
+		err = mtk_flow_set_ipv4_addr(eth, &foe, &data, true);
 		if (err)
 			return err;
 	}
@@ -413,10 +413,10 @@ mtk_flow_offload_replace(struct mtk_eth *eth, struct flow_cls_offload *f)
 		if (data.vlan.proto != htons(ETH_P_8021Q))
 			return -EOPNOTSUPP;
 
-		mtk_foe_entry_set_vlan(&foe, data.vlan.id);
+		mtk_foe_entry_set_vlan(eth, &foe, data.vlan.id);
 	}
 	if (data.pppoe.num == 1)
-		mtk_foe_entry_set_pppoe(&foe, data.pppoe.sid);
+		mtk_foe_entry_set_pppoe(eth, &foe, data.pppoe.sid);
 
 	err = mtk_flow_set_output_device(eth, &foe, odev, data.eth.h_dest,
 					 &wed_index);
Signature · 1 line
2.37.3
#13 lore raw

Re: [PATCH net-next 08/12] net: ethernet: mtk_eth_soc: add foe info in mtk_soc_data structure

Quoted 19 lines · Lorenzo Bianconi

Introduce foe struct in mtk_soc_data as a container for foe table chip related definitions.
This is a preliminary patch to enable mt7986 wed support.

---
 drivers/net/ethernet/mediatek/mtk_eth_soc.c   |  70 +++++++-
 drivers/net/ethernet/mediatek/mtk_eth_soc.h   |  27 ++-
 drivers/net/ethernet/mediatek/mtk_ppe.c       | 161 ++++++++++--------
 drivers/net/ethernet/mediatek/mtk_ppe.h       |  29 ++--
 .../net/ethernet/mediatek/mtk_ppe_offload.c   |  34 ++--
 5 files changed, 208 insertions(+), 113 deletions(-)

[...]

drivers/net/ethernet/mediatek/mtk_ppe.h +0 -0
index 6d4c91acd1a5..a364f45edf38 100644

drivers/net/ethernet/mediatek/mtk_ppe.h enum { · line 65

Quoted 5 lines
drivers/net/ethernet/mediatek/mtk_ppe.h +2 -0
@@ -61,6 +61,8 @@ enum {
 #define MTK_FOE_VLAN2_WINFO_WCID	GENMASK(13, 6)
 #define MTK_FOE_VLAN2_WINFO_RING	GENMASK(15, 14)
 
+#define MTK_FIELD_PREP(mask, val)	(((typeof(mask))(val) << __bf_shf(mask)) & (mask))
+#define MTK_FIELD_GET(mask, val)	((typeof(mask))(((val) & (mask)) >> __bf_shf(mask)))

This seems to trigger a compiler bug on ARMv7 (e.g. MT7623) builds:

LD .tmp_vmlinux.kallsyms1
arm-openwrt-linux-muslgnueabi-ld: drivers/net/ethernet/mediatek/mtk_ppe.o: in function `mtk_flow_entry_match':
/usr/src/lede/build_dir/target-arm_cortex-a7+neon-vfpv4_musl_eabi/linux-mediatek_mt7623/linux-5.15.67/drivers/net/ethernet/mediatek/mtk_ppe.c:406: undefined reference to `__ffsdi2'
arm-openwrt-linux-muslgnueabi-ld: drivers/net/ethernet/mediatek/mtk_ppe.o: in function `__mtk_foe_entry_commit':
/usr/src/lede/build_dir/target-arm_cortex-a7+neon-vfpv4_musl_eabi/linux-mediatek_mt7623/linux-5.15.67/drivers/net/ethernet/mediatek/mtk_ppe.c:533: undefined reference to `__ffsdi2'
arm-openwrt-linux-muslgnueabi-ld: drivers/net/ethernet/mediatek/mtk_ppe.o: in function `mtk_foe_entry_l2':
/usr/src/lede/build_dir/target-arm_cortex-a7+neon-vfpv4_musl_eabi/linux-mediatek_mt7623/linux-5.15.67/drivers/net/ethernet/mediatek/mtk_ppe.c:134: undefined reference to `__ffsdi2'
arm-openwrt-linux-muslgnueabi-ld: drivers/net/ethernet/mediatek/mtk_ppe.o: in function `mtk_foe_entry_commit_subflow':
/usr/src/lede/build_dir/target-arm_cortex-a7+neon-vfpv4_musl_eabi/linux-mediatek_mt7623/linux-5.15.67/drivers/net/ethernet/mediatek/mtk_ppe.c:611: undefined reference to `__ffsdi2'
arm-openwrt-linux-muslgnueabi-ld: drivers/net/ethernet/mediatek/mtk_ppe.o: in function `mtk_foe_entry_ib2':
/usr/src/lede/build_dir/target-arm_cortex-a7+neon-vfpv4_musl_eabi/linux-mediatek_mt7623/linux-5.15.67/drivers/net/ethernet/mediatek/mtk_ppe.c:148: undefined reference to `__ffsdi2'
arm-openwrt-linux-muslgnueabi-ld: drivers/net/ethernet/mediatek/mtk_ppe.o:/usr/src/lede/build_dir/target-arm_cortex-a7+neon-vfpv4_musl_eabi/linux-mediatek_mt7623/linux-5.15.67/drivers/net/ethernet/mediatek/mtk_ppe.c:169: more undefined references to `__ffsdi2' follow

Quoted 3 lines
drivers/net/ethernet/mediatek/mtk_ppe.h +0 -0
 enum {
 	MTK_FOE_STATE_INVALID,
 	MTK_FOE_STATE_UNBIND,
author maintainer
#14 lore raw

Re: [PATCH net-next 08/12] net: ethernet: mtk_eth_soc: add foe info in mtk_soc_data structure

Quoted 28 lines · Lorenzo Bianconi
Quoted 19 lines

Introduce foe struct in mtk_soc_data as a container for foe table chip related definitions.
This is a preliminary patch to enable mt7986 wed support.

---
 drivers/net/ethernet/mediatek/mtk_eth_soc.c   |  70 +++++++-
 drivers/net/ethernet/mediatek/mtk_eth_soc.h   |  27 ++-
 drivers/net/ethernet/mediatek/mtk_ppe.c       | 161 ++++++++++--------
 drivers/net/ethernet/mediatek/mtk_ppe.h       |  29 ++--
 .../net/ethernet/mediatek/mtk_ppe_offload.c   |  34 ++--
 5 files changed, 208 insertions(+), 113 deletions(-)

[...]

drivers/net/ethernet/mediatek/mtk_ppe.h +0 -0
index 6d4c91acd1a5..a364f45edf38 100644

drivers/net/ethernet/mediatek/mtk_ppe.h enum { · line 65

Quoted 5 lines
drivers/net/ethernet/mediatek/mtk_ppe.h +2 -0
@@ -61,6 +61,8 @@ enum {
 #define MTK_FOE_VLAN2_WINFO_WCID	GENMASK(13, 6)
 #define MTK_FOE_VLAN2_WINFO_RING	GENMASK(15, 14)
 
+#define MTK_FIELD_PREP(mask, val)	(((typeof(mask))(val) << __bf_shf(mask)) & (mask))
+#define MTK_FIELD_GET(mask, val)	((typeof(mask))(((val) & (mask)) >> __bf_shf(mask)))

This seems to trigger a compiler bug on ARMv7 (e.g. MT7623) builds:

Quoted 12 lines

LD .tmp_vmlinux.kallsyms1
arm-openwrt-linux-muslgnueabi-ld: drivers/net/ethernet/mediatek/mtk_ppe.o: in function `mtk_flow_entry_match':
/usr/src/lede/build_dir/target-arm_cortex-a7+neon-vfpv4_musl_eabi/linux-mediatek_mt7623/linux-5.15.67/drivers/net/ethernet/mediatek/mtk_ppe.c:406: undefined reference to `__ffsdi2'
arm-openwrt-linux-muslgnueabi-ld: drivers/net/ethernet/mediatek/mtk_ppe.o: in function `__mtk_foe_entry_commit':
/usr/src/lede/build_dir/target-arm_cortex-a7+neon-vfpv4_musl_eabi/linux-mediatek_mt7623/linux-5.15.67/drivers/net/ethernet/mediatek/mtk_ppe.c:533: undefined reference to `__ffsdi2'
arm-openwrt-linux-muslgnueabi-ld: drivers/net/ethernet/mediatek/mtk_ppe.o: in function `mtk_foe_entry_l2':
/usr/src/lede/build_dir/target-arm_cortex-a7+neon-vfpv4_musl_eabi/linux-mediatek_mt7623/linux-5.15.67/drivers/net/ethernet/mediatek/mtk_ppe.c:134: undefined reference to `__ffsdi2'
arm-openwrt-linux-muslgnueabi-ld: drivers/net/ethernet/mediatek/mtk_ppe.o: in function `mtk_foe_entry_commit_subflow':
/usr/src/lede/build_dir/target-arm_cortex-a7+neon-vfpv4_musl_eabi/linux-mediatek_mt7623/linux-5.15.67/drivers/net/ethernet/mediatek/mtk_ppe.c:611: undefined reference to `__ffsdi2'
arm-openwrt-linux-muslgnueabi-ld: drivers/net/ethernet/mediatek/mtk_ppe.o: in function `mtk_foe_entry_ib2':
/usr/src/lede/build_dir/target-arm_cortex-a7+neon-vfpv4_musl_eabi/linux-mediatek_mt7623/linux-5.15.67/drivers/net/ethernet/mediatek/mtk_ppe.c:148: undefined reference to `__ffsdi2'
arm-openwrt-linux-muslgnueabi-ld: drivers/net/ethernet/mediatek/mtk_ppe.o:/usr/src/lede/build_dir/target-arm_cortex-a7+neon-vfpv4_musl_eabi/linux-mediatek_mt7623/linux-5.15.67/drivers/net/ethernet/mediatek/mtk_ppe.c:169: more undefined references to `__ffsdi2' follow

Hi Daniel,

ack, I will fix it in v2.

Regards,
Lorenzo

Quoted 5 lines
Quoted 5 lines
drivers/net/ethernet/mediatek/mtk_ppe.h +0 -0
 enum {
 	MTK_FOE_STATE_INVALID,
 	MTK_FOE_STATE_UNBIND,
#15 lore raw

Re: [PATCH net-next 08/12] net: ethernet: mtk_eth_soc: add foe info in mtk_soc_data structure

In reply to Lorenzo Bianconi
I love your patch! Yet something to improve:

Hi Lorenzo,

I love your patch! Yet something to improve:

[auto build test ERROR on net-next/master]

url:    https://github.com/intel-lab-lkp/linux/commits/Lorenzo-Bianconi/Add-WED-support-for-MT7986-chipset/20220909-033910
base:   https://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next.git 9f8f1933dce555d3c246f447f54fca8de8889da9
config: arm-randconfig-r005-20220911 (https://download.01.org/0day-ci/archive/20220913/[email protected]/config)
compiler: arm-linux-gnueabi-gcc (GCC) 12.1.0

reproduce (this is a W=1 build):
wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross chmod +x ~/bin/make.cross
# https://github.com/intel-lab-lkp/linux/commit/8500175ee61539b6c5cb7acb854ce592e78cf639
git remote add linux-review https://github.com/intel-lab-lkp/linux
git fetch --no-tags linux-review Lorenzo-Bianconi/Add-WED-support-for-MT7986-chipset/20220909-033910 git checkout 8500175ee61539b6c5cb7acb854ce592e78cf639
# save the config file
mkdir build_dir && cp config build_dir/.config
COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-12.1.0 make.cross W=1 O=build_dir ARCH=arm SHELL=/bin/bash

If you fix the issue, kindly add following tag where applicable

All errors (new ones prefixed by >>, old ones prefixed by <<):

>> ERROR: modpost: "__ffsdi2" [drivers/net/ethernet/mediatek/mtk_eth.ko] undefined!
Signature · 2 lines
0-DAY CI Kernel Test Service
https://01.org/lkp
author maintainer
#16 lore raw

PATCH 9/12 net: ethernet: mtk_eth_wed: add mtk_wed_configure_irq and mtk_wed_dma_{enable/disable}

In reply to Lorenzo Bianconi

Introduce mtk_wed_configure_irq, mtk_wed_dma_enable and mtk_wed_dma_disable utility routines.
This is a preliminary patch to introduce mt7986 wed support.

---
 drivers/net/ethernet/mediatek/mtk_wed.c      | 87 +++++++++++++-------
 drivers/net/ethernet/mediatek/mtk_wed_regs.h |  6 +-
 2 files changed, 64 insertions(+), 29 deletions(-)
drivers/net/ethernet/mediatek/mtk_wed.c +59 -28
index 29be2fcafea3..d1ef5b563ddf 100644
@@ -237,9 +237,30 @@ mtk_wed_set_ext_int(struct mtk_wed_device *dev, bool en)
 }
 
 static void
-mtk_wed_stop(struct mtk_wed_device *dev)
+mtk_wed_dma_disable(struct mtk_wed_device *dev)
 {
+	wed_clr(dev, MTK_WED_WPDMA_GLO_CFG,
+		MTK_WED_WPDMA_GLO_CFG_TX_DRV_EN |
+		MTK_WED_WPDMA_GLO_CFG_RX_DRV_EN);
+
+	wed_clr(dev, MTK_WED_WDMA_GLO_CFG, MTK_WED_WDMA_GLO_CFG_RX_DRV_EN);
+
+	wed_clr(dev, MTK_WED_GLO_CFG,
+		MTK_WED_GLO_CFG_TX_DMA_EN |
+		MTK_WED_GLO_CFG_RX_DMA_EN);
+
 	regmap_write(dev->hw->mirror, dev->hw->index * 4, 0);
+	wdma_m32(dev, MTK_WDMA_GLO_CFG,
+		 MTK_WDMA_GLO_CFG_TX_DMA_EN |
+		 MTK_WDMA_GLO_CFG_RX_INFO1_PRERES |
+		 MTK_WDMA_GLO_CFG_RX_INFO2_PRERES |
+		 MTK_WDMA_GLO_CFG_RX_INFO3_PRERES, 0);
+}
+
+static void
+mtk_wed_stop(struct mtk_wed_device *dev)
+{
+	mtk_wed_dma_disable(dev);
 	mtk_wed_set_ext_int(dev, false);
 
 	wed_clr(dev, MTK_WED_CTRL,
@@ -252,15 +273,6 @@ mtk_wed_stop(struct mtk_wed_device *dev)
 	wdma_w32(dev, MTK_WDMA_INT_MASK, 0);
 	wdma_w32(dev, MTK_WDMA_INT_GRP2, 0);
 	wed_w32(dev, MTK_WED_WPDMA_INT_MASK, 0);
-
-	wed_clr(dev, MTK_WED_GLO_CFG,
-		MTK_WED_GLO_CFG_TX_DMA_EN |
-		MTK_WED_GLO_CFG_RX_DMA_EN);
-	wed_clr(dev, MTK_WED_WPDMA_GLO_CFG,
-		MTK_WED_WPDMA_GLO_CFG_TX_DRV_EN |
-		MTK_WED_WPDMA_GLO_CFG_RX_DRV_EN);
-	wed_clr(dev, MTK_WED_WDMA_GLO_CFG,
-		MTK_WED_WDMA_GLO_CFG_RX_DRV_EN);
 }
 
 static void
@@ -313,7 +325,10 @@ mtk_wed_hw_init_early(struct mtk_wed_device *dev)
 	      MTK_WED_WDMA_GLO_CFG_IDLE_DMAD_SUPPLY;
 	wed_m32(dev, MTK_WED_WDMA_GLO_CFG, mask, set);
 
-	wdma_set(dev, MTK_WDMA_GLO_CFG, MTK_WDMA_GLO_CFG_RX_INFO_PRERES);
+	wdma_set(dev, MTK_WDMA_GLO_CFG,
+		 MTK_WDMA_GLO_CFG_RX_INFO1_PRERES |
+		 MTK_WDMA_GLO_CFG_RX_INFO2_PRERES |
+		 MTK_WDMA_GLO_CFG_RX_INFO3_PRERES);
 
 	offset = dev->hw->index ? 0x04000400 : 0;
 	wed_w32(dev, MTK_WED_WDMA_OFFSET0, 0x2a042a20 + offset);
@@ -520,43 +535,38 @@ mtk_wed_wdma_ring_setup(struct mtk_wed_device *dev, int idx, int size)
 }
 
 static void
-mtk_wed_start(struct mtk_wed_device *dev, u32 irq_mask)
+mtk_wed_configure_irq(struct mtk_wed_device *dev, u32 irq_mask)
 {
-	u32 wdma_mask;
-	u32 val;
-	int i;
-
-	for (i = 0; i < ARRAY_SIZE(dev->tx_wdma); i++)
-		if (!dev->tx_wdma[i].desc)
-			mtk_wed_wdma_ring_setup(dev, i, 16);
-
-	wdma_mask = FIELD_PREP(MTK_WDMA_INT_MASK_RX_DONE, GENMASK(1, 0));
-
-	mtk_wed_hw_init(dev);
+	u32 wdma_mask = FIELD_PREP(MTK_WDMA_INT_MASK_RX_DONE, GENMASK(1, 0));
 
+	/* wed control cr set */
 	wed_set(dev, MTK_WED_CTRL,
 		MTK_WED_CTRL_WDMA_INT_AGENT_EN |
 		MTK_WED_CTRL_WPDMA_INT_AGENT_EN |
 		MTK_WED_CTRL_WED_TX_BM_EN |
 		MTK_WED_CTRL_WED_TX_FREE_AGENT_EN);
 
-	wed_w32(dev, MTK_WED_PCIE_INT_TRIGGER, MTK_WED_PCIE_INT_TRIGGER_STATUS);
+	wed_w32(dev, MTK_WED_PCIE_INT_TRIGGER,
+		MTK_WED_PCIE_INT_TRIGGER_STATUS);
 
 	wed_w32(dev, MTK_WED_WPDMA_INT_TRIGGER,
 		MTK_WED_WPDMA_INT_TRIGGER_RX_DONE |
 		MTK_WED_WPDMA_INT_TRIGGER_TX_DONE);
 
-	wed_set(dev, MTK_WED_WPDMA_INT_CTRL,
-		MTK_WED_WPDMA_INT_CTRL_SUBRT_ADV);
-
+	/* initail wdma interrupt agent */
 	wed_w32(dev, MTK_WED_WDMA_INT_TRIGGER, wdma_mask);
 	wed_clr(dev, MTK_WED_WDMA_INT_CTRL, wdma_mask);
 
 	wdma_w32(dev, MTK_WDMA_INT_MASK, wdma_mask);
 	wdma_w32(dev, MTK_WDMA_INT_GRP2, wdma_mask);
-
 	wed_w32(dev, MTK_WED_WPDMA_INT_MASK, irq_mask);
 	wed_w32(dev, MTK_WED_INT_MASK, irq_mask);
+}
+
+static void
+mtk_wed_dma_enable(struct mtk_wed_device *dev)
+{
+	wed_set(dev, MTK_WED_WPDMA_INT_CTRL, MTK_WED_WPDMA_INT_CTRL_SUBRT_ADV);
 
 	wed_set(dev, MTK_WED_GLO_CFG,
 		MTK_WED_GLO_CFG_TX_DMA_EN |
@@ -567,6 +577,26 @@ mtk_wed_start(struct mtk_wed_device *dev, u32 irq_mask)
 	wed_set(dev, MTK_WED_WDMA_GLO_CFG,
 		MTK_WED_WDMA_GLO_CFG_RX_DRV_EN);
 
+	wdma_set(dev, MTK_WDMA_GLO_CFG,
+		 MTK_WDMA_GLO_CFG_TX_DMA_EN |
+		 MTK_WDMA_GLO_CFG_RX_INFO1_PRERES |
+		 MTK_WDMA_GLO_CFG_RX_INFO2_PRERES |
+		 MTK_WDMA_GLO_CFG_RX_INFO3_PRERES);
+}
+
+static void
+mtk_wed_start(struct mtk_wed_device *dev, u32 irq_mask)
+{
+	u32 val;
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(dev->tx_wdma); i++)
+		if (!dev->tx_wdma[i].desc)
+			mtk_wed_wdma_ring_setup(dev, i, 16);
+
+	mtk_wed_hw_init(dev);
+	mtk_wed_configure_irq(dev, irq_mask);
+
 	mtk_wed_set_ext_int(dev, true);
 	val = dev->wlan.wpdma_phys |
 	      MTK_PCIE_MIRROR_MAP_EN |
@@ -577,6 +607,7 @@ mtk_wed_start(struct mtk_wed_device *dev, u32 irq_mask)
 	val |= BIT(0);
 	regmap_write(dev->hw->mirror, dev->hw->index * 4, val);
 
+	mtk_wed_dma_enable(dev);
 	dev->running = true;
 }
 
drivers/net/ethernet/mediatek/mtk_wed_regs.h +5 -1
index 0a0465ea58b4..eec22daebd30 100644
@@ -224,7 +224,11 @@ struct mtk_wdma_desc {
 #define MTK_WDMA_RING_RX(_n)				(0x100 + (_n) * 0x10)
 
 #define MTK_WDMA_GLO_CFG				0x204
-#define MTK_WDMA_GLO_CFG_RX_INFO_PRERES			GENMASK(28, 26)
+#define MTK_WDMA_GLO_CFG_TX_DMA_EN			BIT(0)
+#define MTK_WDMA_GLO_CFG_RX_DMA_EN			BIT(2)
+#define MTK_WDMA_GLO_CFG_RX_INFO3_PRERES		BIT(26)
+#define MTK_WDMA_GLO_CFG_RX_INFO2_PRERES		BIT(27)
+#define MTK_WDMA_GLO_CFG_RX_INFO1_PRERES		BIT(28)
 
 #define MTK_WDMA_RESET_IDX				0x208
 #define MTK_WDMA_RESET_IDX_TX				GENMASK(3, 0)
Signature · 1 line
2.37.3
author maintainer
#17 lore raw

PATCH 10/12 net: ethernet: mtk_eth_wed: add wed support for mt7986 chipset

In reply to Lorenzo Bianconi

Introduce Wireless Etherne Dispatcher support on transmission side for mt7986 chipset

---
 drivers/net/ethernet/mediatek/mtk_eth_soc.c   |  48 ++-
 drivers/net/ethernet/mediatek/mtk_eth_soc.h   |   7 +
 drivers/net/ethernet/mediatek/mtk_wed.c       | 362 ++++++++++++++----
 drivers/net/ethernet/mediatek/mtk_wed.h       |   8 +-
 .../net/ethernet/mediatek/mtk_wed_debugfs.c   |   3 +
 drivers/net/ethernet/mediatek/mtk_wed_regs.h  |  77 +++-
 include/linux/soc/mediatek/mtk_wed.h          |   8 +
 7 files changed, 418 insertions(+), 95 deletions(-)
drivers/net/ethernet/mediatek/mtk_eth_soc.c +39 -9
index 8aa0a61b35fc..7dae650c4586 100644
@@ -3944,6 +3944,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;
@@ -4024,16 +4025,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);
-		void __iomem *wdma;
-
-		if (!np || i >= ARRAY_SIZE(eth->soc->reg_map->wdma_base))
-			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 + eth->soc->reg_map->wdma_base[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++) {
@@ -4282,6 +4298,13 @@ static const struct mtk_soc_data mt7622_data = {
 			.dst_port = GENMASK(7, 5),
 		},
 	},
+	.wed = {
+		.desc_ctrl_len1 = GENMASK(14, 0),
+		.desc_ctrl_last_seg1 = BIT(15),
+		.tx_bm_tkid_addr = 0x088,
+		.tx_bm_dyn_thr_lo = GENMASK(6, 0),
+		.tx_bm_dyn_thr_hi = GENMASK(22, 16),
+	},
 };
 
 static const struct mtk_soc_data mt7623_data = {
@@ -4355,6 +4378,13 @@ static const struct mtk_soc_data mt7986_data = {
 	.foe = {
 		.hash_offset = 4,
 	},
+	.wed = {
+		.desc_ctrl_len1 = GENMASK(13, 0),
+		.desc_ctrl_last_seg1 = BIT(14),
+		.tx_bm_tkid_addr = 0x0c8,
+		.tx_bm_dyn_thr_lo = GENMASK(8, 0),
+		.tx_bm_dyn_thr_hi = GENMASK(24, 16),
+	},
 };
 
 static const struct mtk_soc_data rt5350_data = {
drivers/net/ethernet/mediatek/mtk_eth_soc.h +7 -0
index 6d0b080c2048..e40ad480513d 100644
@@ -1011,6 +1011,13 @@ struct mtk_soc_data {
 			u16 dst_port;
 		} ib2;
 	} foe;
+	struct {
+		u32 desc_ctrl_len1;
+		u32 desc_ctrl_last_seg1;
+		u32 tx_bm_tkid_addr;
+		u32 tx_bm_dyn_thr_lo;
+		u32 tx_bm_dyn_thr_hi;
+	} wed;
 };
 
 /* currently no SoC has more than 2 macs */
drivers/net/ethernet/mediatek/mtk_wed.c +281 -81

593 lines not on this page · raw message

drivers/net/ethernet/mediatek/mtk_wed.h +6 -2
index 981ec613f4b0..ae420ca01a48 100644
@@ -18,11 +18,13 @@ struct mtk_wed_hw {
 	struct regmap *hifsys;
 	struct device *dev;
 	void __iomem *wdma;
+	phys_addr_t wdma_phy;
 	struct regmap *mirror;
 	struct dentry *debugfs_dir;
 	struct mtk_wed_device *wed_dev;
 	u32 debugfs_reg;
 	u32 num_flows;
+	u8 version;
 	char dirname[5];
 	int irq;
 	int index;
@@ -101,14 +103,16 @@ wpdma_txfree_w32(struct mtk_wed_device *dev, u32 reg, u32 val)
 }
 
 void mtk_wed_add_hw(struct device_node *np, struct mtk_eth *eth,
-		    void __iomem *wdma, int index);
+		    void __iomem *wdma, phys_addr_t wdma_phy,
+		    int index);
 void mtk_wed_exit(void);
 int mtk_wed_flow_add(int index);
 void mtk_wed_flow_remove(int index);
 #else
 static inline void
 mtk_wed_add_hw(struct device_node *np, struct mtk_eth *eth,
-	       void __iomem *wdma, int index)
+	       void __iomem *wdma, phys_addr_t wdma_phy,
+	       int index)
 {
 }
 static inline void
drivers/net/ethernet/mediatek/mtk_wed_debugfs.c +3 -0
index a81d3fd1a439..f420f187e837 100644
@@ -116,6 +116,9 @@ wed_txinfo_show(struct seq_file *s, void *data)
 		DUMP_WDMA(WDMA_GLO_CFG),
 		DUMP_WDMA_RING(WDMA_RING_RX(0)),
 		DUMP_WDMA_RING(WDMA_RING_RX(1)),
+
+		DUMP_STR("TX FREE"),
+		DUMP_WED(WED_RX_MIB(0)),
 	};
 	struct mtk_wed_hw *hw = s->private;
 	struct mtk_wed_device *dev = hw->wed_dev;
drivers/net/ethernet/mediatek/mtk_wed_regs.h +74 -3

155 lines not on this page · raw message

include/linux/soc/mediatek/mtk_wed.h +8 -0
index 7e00cca06709..592221a7149b 100644
@@ -14,6 +14,7 @@ struct mtk_wdma_desc;
 struct mtk_wed_ring {
 	struct mtk_wdma_desc *desc;
 	dma_addr_t desc_phys;
+	u32 desc_size;
 	int size;
 
 	u32 reg_base;
@@ -45,10 +46,17 @@ struct mtk_wed_device {
 		struct pci_dev *pci_dev;
 
 		u32 wpdma_phys;
+		u32 wpdma_int;
+		u32 wpdma_mask;
+		u32 wpdma_tx;
+		u32 wpdma_txfree;
 
 		u16 token_start;
 		unsigned int nbuf;
 
+		u8 tx_tbit[MTK_WED_TX_QUEUES];
+		u8 txfree_tbit;
+
 		u32 (*init_buf)(void *ptr, dma_addr_t phys, int token_id);
 		int (*offload_enable)(struct mtk_wed_device *wed);
 		void (*offload_disable)(struct mtk_wed_device *wed);
Signature · 1 line
2.37.3
author maintainer
#18 lore raw

PATCH 11/12 net: ethernet: mtk_eth_wed: add axi bus support

In reply to Lorenzo Bianconi

Other than pcie bus, introduce support for axi bus to mtk wed driver. Axi bus is used to connect mt7986-wmac soc chip available on mt7986 device.

---
 drivers/net/ethernet/mediatek/mtk_wed.c      | 112 +++++++++++++------
 drivers/net/ethernet/mediatek/mtk_wed_regs.h |   2 +
 include/linux/soc/mediatek/mtk_wed.h         |   7 ++
 3 files changed, 84 insertions(+), 37 deletions(-)
drivers/net/ethernet/mediatek/mtk_wed.c +75 -37
index 3ec891f05fa7..48c638c49355 100644
@@ -85,11 +85,31 @@ static struct mtk_wed_hw *
 mtk_wed_assign(struct mtk_wed_device *dev)
 {
 	struct mtk_wed_hw *hw;
+	int i;
+
+	if (dev->wlan.bus_type == MTK_WED_BUS_PCIE) {
+		hw = hw_list[pci_domain_nr(dev->wlan.pci_dev->bus)];
+		if (!hw)
+			return NULL;
+
+		if (!hw->wed_dev)
+			goto out;
+
+		if (hw->version == 1)
+			return NULL;
+
+		/* MT7986 WED devices do not have any pcie slot restrictions */
+	}
+	/* MT7986 PCIE or AXI */
+	for (i = 0; i < ARRAY_SIZE(hw_list); i++) {
+		hw = hw_list[i];
+		if (hw && !hw->wed_dev)
+			goto out;
+	}
 
-	hw = hw_list[pci_domain_nr(dev->wlan.pci_dev->bus)];
-	if (!hw || hw->wed_dev)
-		return NULL;
+	return NULL;
 
+out:
 	hw->wed_dev = dev;
 	return hw;
 }
@@ -321,7 +341,6 @@ mtk_wed_stop(struct mtk_wed_device *dev)
 static void
 mtk_wed_detach(struct mtk_wed_device *dev)
 {
-	struct device_node *wlan_node = dev->wlan.pci_dev->dev.of_node;
 	struct mtk_wed_hw *hw = dev->hw;
 
 	mutex_lock(&hw_lock);
@@ -336,9 +355,14 @@ mtk_wed_detach(struct mtk_wed_device *dev)
 	mtk_wed_free_buffer(dev);
 	mtk_wed_free_tx_rings(dev);
 
-	if (of_dma_is_coherent(wlan_node) && hw->hifsys)
-		regmap_update_bits(hw->hifsys, HIFSYS_DMA_AG_MAP,
-				   BIT(hw->index), BIT(hw->index));
+	if (dev->wlan.bus_type == MTK_WED_BUS_PCIE) {
+		struct device_node *wlan_node;
+
+		wlan_node = dev->wlan.pci_dev->dev.of_node;
+		if (of_dma_is_coherent(wlan_node) && hw->hifsys)
+			regmap_update_bits(hw->hifsys, HIFSYS_DMA_AG_MAP,
+					   BIT(hw->index), BIT(hw->index));
+	}
 
 	if (!hw_list[!hw->index]->wed_dev &&
 	    hw->eth->dma_dev != hw->eth->dev)
@@ -355,42 +379,55 @@ mtk_wed_detach(struct mtk_wed_device *dev)
 static void
 mtk_wed_bus_init(struct mtk_wed_device *dev)
 {
-	struct device_node *node;
-	void __iomem *base_addr;
-	u32 val;
-
-	node = of_parse_phandle(dev->hw->node, "mediatek,wed_pcie", 0);
-	if (!node)
-		return;
+	switch (dev->wlan.bus_type) {
+	case MTK_WED_BUS_PCIE: {
+		struct device_node *node;
+		void __iomem *base_addr;
+		u32 val;
+
+		node = of_parse_phandle(dev->hw->node, "mediatek,wed_pcie", 0);
+		if (!node)
+			break;
 
-	base_addr = of_iomap(node, 0);
-	val = BIT(0) | readl(base_addr);
-	writel(val, base_addr);
+		base_addr = of_iomap(node, 0);
+		val = BIT(0) | readl(base_addr);
+		writel(val, base_addr);
 
-	wed_w32(dev, MTK_WED_PCIE_INT_CTRL,
-		FIELD_PREP(MTK_WED_PCIE_INT_CTRL_POLL_EN, 2));
+		wed_w32(dev, MTK_WED_PCIE_INT_CTRL,
+			FIELD_PREP(MTK_WED_PCIE_INT_CTRL_POLL_EN, 2));
 
-	/* pcie interrupt control: pola/source selection */
-	wed_set(dev, MTK_WED_PCIE_INT_CTRL,
-		MTK_WED_PCIE_INT_CTRL_MSK_EN_POLA |
-		FIELD_PREP(MTK_WED_PCIE_INT_CTRL_SRC_SEL, 1));
-	wed_r32(dev, MTK_WED_PCIE_INT_CTRL);
+		/* pcie interrupt control: pola/source selection */
+		wed_set(dev, MTK_WED_PCIE_INT_CTRL,
+			MTK_WED_PCIE_INT_CTRL_MSK_EN_POLA |
+			FIELD_PREP(MTK_WED_PCIE_INT_CTRL_SRC_SEL, 1));
+		wed_r32(dev, MTK_WED_PCIE_INT_CTRL);
 
-	val = wed_r32(dev, MTK_WED_PCIE_CFG_INTM);
-	val = wed_r32(dev, MTK_WED_PCIE_CFG_BASE);
-	wed_w32(dev, MTK_WED_PCIE_CFG_INTM, PCIE_BASE_ADDR0 | 0x180);
-	wed_w32(dev, MTK_WED_PCIE_CFG_BASE, PCIE_BASE_ADDR0 | 0x184);
+		val = wed_r32(dev, MTK_WED_PCIE_CFG_INTM);
+		val = wed_r32(dev, MTK_WED_PCIE_CFG_BASE);
+		wed_w32(dev, MTK_WED_PCIE_CFG_INTM, PCIE_BASE_ADDR0 | 0x180);
+		wed_w32(dev, MTK_WED_PCIE_CFG_BASE, PCIE_BASE_ADDR0 | 0x184);
 
-	val = wed_r32(dev, MTK_WED_PCIE_CFG_INTM);
-	val = wed_r32(dev, MTK_WED_PCIE_CFG_BASE);
+		val = wed_r32(dev, MTK_WED_PCIE_CFG_INTM);
+		val = wed_r32(dev, MTK_WED_PCIE_CFG_BASE);
 
-	/* pcie interrupt status trigger register */
-	wed_w32(dev, MTK_WED_PCIE_INT_TRIGGER, BIT(24));
-	wed_r32(dev, MTK_WED_PCIE_INT_TRIGGER);
+		/* pcie interrupt status trigger register */
+		wed_w32(dev, MTK_WED_PCIE_INT_TRIGGER, BIT(24));
+		wed_r32(dev, MTK_WED_PCIE_INT_TRIGGER);
 
-	/* pola setting */
-	val = wed_r32(dev, MTK_WED_PCIE_INT_CTRL);
-	wed_set(dev, MTK_WED_PCIE_INT_CTRL, MTK_WED_PCIE_INT_CTRL_MSK_EN_POLA);
+		/* pola setting */
+		val = wed_r32(dev, MTK_WED_PCIE_INT_CTRL);
+		wed_set(dev, MTK_WED_PCIE_INT_CTRL,
+			MTK_WED_PCIE_INT_CTRL_MSK_EN_POLA);
+		break;
+	}
+	case MTK_WED_BUS_AXI:
+		wed_set(dev, MTK_WED_WPDMA_INT_CTRL,
+			MTK_WED_WPDMA_INT_CTRL_SIG_SRC |
+			FIELD_PREP(MTK_WED_WPDMA_INT_CTRL_SRC_SEL, 0));
+		break;
+	default:
+		break;
+	}
 }
 
 static void
@@ -800,7 +837,8 @@ mtk_wed_attach(struct mtk_wed_device *dev)
 	RCU_LOCKDEP_WARN(!rcu_read_lock_held(),
 			 "mtk_wed_attach without holding the RCU read lock");
 
-	if (pci_domain_nr(dev->wlan.pci_dev->bus) > 1 ||
+	if ((dev->wlan.bus_type == MTK_WED_BUS_PCIE &&
+	     pci_domain_nr(dev->wlan.pci_dev->bus) > 1) ||
 	    !try_module_get(THIS_MODULE))
 		ret = -ENODEV;
 
drivers/net/ethernet/mediatek/mtk_wed_regs.h +2 -0
index ecd925fbd451..1e2aafc10f4c 100644
@@ -194,6 +194,8 @@ struct mtk_wdma_desc {
 
 #define MTK_WED_WPDMA_INT_CTRL				0x520
 #define MTK_WED_WPDMA_INT_CTRL_SUBRT_ADV		BIT(21)
+#define MTK_WED_WPDMA_INT_CTRL_SIG_SRC			BIT(22)
+#define MTK_WED_WPDMA_INT_CTRL_SRC_SEL			GENMASK(17, 16)
 
 #define MTK_WED_WPDMA_INT_MASK				0x524
 
include/linux/soc/mediatek/mtk_wed.h +7 -0
index 592221a7149b..f2ae5bd140a1 100644
@@ -11,6 +11,11 @@
 struct mtk_wed_hw;
 struct mtk_wdma_desc;
 
+enum mtk_wed_bus_tye {
+	MTK_WED_BUS_PCIE,
+	MTK_WED_BUS_AXI,
+};
+
 struct mtk_wed_ring {
 	struct mtk_wdma_desc *desc;
 	dma_addr_t desc_phys;
@@ -45,6 +50,8 @@ struct mtk_wed_device {
 	struct {
 		struct pci_dev *pci_dev;
 
+		enum mtk_wed_bus_tye bus_type;
+
 		u32 wpdma_phys;
 		u32 wpdma_int;
 		u32 wpdma_mask;
Signature · 1 line
2.37.3
author maintainer
#19 lore raw

PATCH 12/12 net: ethernet: mtk_eth_soc: introduce flow offloading support for mt7986

In reply to Lorenzo Bianconi

Introduce hw flow offload support for mt7986 chipset. PPE is not enabled yet in mt7986 since mt76 support is not available yet.

---
 drivers/net/ethernet/mediatek/mtk_eth_soc.c   | 27 +++++++++--
 drivers/net/ethernet/mediatek/mtk_ppe.c       | 45 ++++++++++++++-----
 drivers/net/ethernet/mediatek/mtk_ppe.h       | 10 ++++-
 .../net/ethernet/mediatek/mtk_ppe_offload.c   | 15 ++++++-
 drivers/net/ethernet/mediatek/mtk_ppe_regs.h  |  8 ++++
 5 files changed, 87 insertions(+), 18 deletions(-)
drivers/net/ethernet/mediatek/mtk_eth_soc.c +23 -4
index 7dae650c4586..cc790f12c9cc 100644
@@ -1906,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),
@@ -1925,7 +1927,6 @@ 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[0], skb, hash);
 
@@ -4241,7 +4242,7 @@ static const struct mtk_soc_data mt7621_data = {
 		.dma_len_offset = 16,
 	},
 	.foe = {
-		.entry_size = sizeof(struct mtk_foe_entry),
+		.entry_size = sizeof(struct mtk_foe_entry) - 16,
 		.hash_offset = 2,
 		.ib1 = {
 			.bind_ppoe = BIT(19),
@@ -4279,7 +4280,7 @@ static const struct mtk_soc_data mt7622_data = {
 		.dma_len_offset = 16,
 	},
 	.foe = {
-		.entry_size = sizeof(struct mtk_foe_entry),
+		.entry_size = sizeof(struct mtk_foe_entry) - 16,
 		.hash_offset = 2,
 		.ib1 = {
 			.bind_ppoe = BIT(19),
@@ -4323,7 +4324,7 @@ static const struct mtk_soc_data mt7623_data = {
 		.dma_len_offset = 16,
 	},
 	.foe = {
-		.entry_size = sizeof(struct mtk_foe_entry),
+		.entry_size = sizeof(struct mtk_foe_entry) - 16,
 		.hash_offset = 2,
 		.ib1 = {
 			.bind_ppoe = BIT(19),
@@ -4365,6 +4366,7 @@ 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,
 	.txrx = {
@@ -4376,7 +4378,24 @@ static const struct mtk_soc_data mt7986_data = {
 		.dma_len_offset = 8,
 	},
 	.foe = {
+		.entry_size = sizeof(struct mtk_foe_entry),
 		.hash_offset = 4,
+		.ib1 = {
+			.bind_ppoe = BIT(17),
+			.bind_vlan_tag = BIT(18),
+			.bind_cache = BIT(20),
+			.bind_ttl = BIT(22),
+			.bind_ts = GENMASK(7, 0),
+			.bind_vlan_layer = GENMASK(16, 14),
+			.pkt_type = GENMASK(27, 23),
+		},
+		.ib2 = {
+			.multicast = BIT(13),
+			.wdma_winfo = BIT(19),
+			.port_ag = GENMASK(23, 20),
+			.port_mg = BIT(7),
+			.dst_port = GENMASK(12, 9),
+		},
 	},
 	.wed = {
 		.desc_ctrl_len1 = GENMASK(13, 0),
drivers/net/ethernet/mediatek/mtk_ppe.c +33 -12

81 lines not on this page · raw message

drivers/net/ethernet/mediatek/mtk_ppe.h +9 -1
index a364f45edf38..1f584fd0632d 100644
@@ -53,6 +53,7 @@ enum {
 
 #define MTK_FOE_IB2_PORT_MG		GENMASK(17, 12)
 
+#define MTK_FOE_IB2_RX_IDX		GENMASK(18, 17)
 #define MTK_FOE_IB2_PORT_AG		GENMASK(23, 18)
 
 #define MTK_FOE_IB2_DSCP		GENMASK(31, 24)
@@ -61,8 +62,12 @@ enum {
 #define MTK_FOE_VLAN2_WINFO_WCID	GENMASK(13, 6)
 #define MTK_FOE_VLAN2_WINFO_RING	GENMASK(15, 14)
 
+#define MTK_FOE_WINFO_BSS		GENMASK(5, 0)
+#define MTK_FOE_WINFO_WCID		GENMASK(15, 6)
+
 #define MTK_FIELD_PREP(mask, val)	(((typeof(mask))(val) << __bf_shf(mask)) & (mask))
 #define MTK_FIELD_GET(mask, val)	((typeof(mask))(((val) & (mask)) >> __bf_shf(mask)))
+
 enum {
 	MTK_FOE_STATE_INVALID,
 	MTK_FOE_STATE_UNBIND,
@@ -83,6 +88,9 @@ struct mtk_foe_mac_info {
 
 	u16 pppoe_id;
 	u16 src_mac_lo;
+
+	u16 minfo;
+	u16 winfo;
 };
 
 /* software-only entry type */
@@ -200,7 +208,7 @@ struct mtk_foe_entry {
 		struct mtk_foe_ipv4_dslite dslite;
 		struct mtk_foe_ipv6 ipv6;
 		struct mtk_foe_ipv6_6rd ipv6_6rd;
-		u32 data[19];
+		u32 data[23];
 	};
 };
 
drivers/net/ethernet/mediatek/mtk_ppe_offload.c +14 -1
index 56c49ac712b9..c63eeee0ceba 100644
@@ -193,7 +193,20 @@ mtk_flow_set_output_device(struct mtk_eth *eth, struct mtk_foe_entry *foe,
 	if (mtk_flow_get_wdma_info(dev, dest_mac, &info) == 0) {
 		mtk_foe_entry_set_wdma(eth, foe, info.wdma_idx, info.queue,
 				       info.bss, info.wcid);
-		pse_port = 3;
+		if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) {
+			switch (info.wdma_idx) {
+			case 0:
+				pse_port = 8;
+				break;
+			case 1:
+				pse_port = 9;
+				break;
+			default:
+				return -EINVAL;
+			}
+		} else {
+			pse_port = 3;
+		}
 		*wed_index = info.wdma_idx;
 		goto out;
 	}
drivers/net/ethernet/mediatek/mtk_ppe_regs.h +8 -0
index 0c45ea0900f1..59596d823d8b 100644
@@ -21,6 +21,9 @@
 #define MTK_PPE_GLO_CFG_BUSY			BIT(31)
 
 #define MTK_PPE_FLOW_CFG			0x204
+#define MTK_PPE_MD_TOAP_BYP_CRSN0		BIT(1)
+#define MTK_PPE_MD_TOAP_BYP_CRSN1		BIT(2)
+#define MTK_PPE_MD_TOAP_BYP_CRSN2		BIT(3)
 #define MTK_PPE_FLOW_CFG_IP4_TCP_FRAG		BIT(6)
 #define MTK_PPE_FLOW_CFG_IP4_UDP_FRAG		BIT(7)
 #define MTK_PPE_FLOW_CFG_IP6_3T_ROUTE		BIT(8)
@@ -54,6 +57,7 @@
 #define MTK_PPE_TB_CFG_HASH_MODE		GENMASK(15, 14)
 #define MTK_PPE_TB_CFG_SCAN_MODE		GENMASK(17, 16)
 #define MTK_PPE_TB_CFG_HASH_DEBUG		GENMASK(19, 18)
+#define MTK_PPE_TB_CFG_INFO_SEL			BIT(20)
 
 enum {
 	MTK_PPE_SCAN_MODE_DISABLED,
@@ -112,6 +116,8 @@ enum {
 #define MTK_PPE_DEFAULT_CPU_PORT		0x248
 #define MTK_PPE_DEFAULT_CPU_PORT_MASK(_n)	(GENMASK(2, 0) << ((_n) * 4))
 
+#define MTK_PPE_DEFAULT_CPU_PORT1		0x24c
+
 #define MTK_PPE_MTU_DROP			0x308
 
 #define MTK_PPE_VLAN_MTU0			0x30c
@@ -141,4 +147,6 @@ enum {
 #define MTK_PPE_MIB_CACHE_CTL_EN		BIT(0)
 #define MTK_PPE_MIB_CACHE_CTL_FLUSH		BIT(2)
 
+#define MTK_PPE_SBW_CTRL			0x374
+
 #endif
Signature · 1 line
2.37.3