Skip to contentSkip to conversation

net: ethernet: mtk_eth_soc: various enhancements

PATCH Superseded Daniel Golle 4 participants 32 messages Feb 7, 2023 – Feb 10, 2023

Subsystems (9)

v2 of 14 Superseded Latest is v14 →

lore
Share & tools
lore

Daniel Golle

author maintainer
#0 lore raw

v2 cover net: ethernet: mtk_eth_soc: various enhancements

This series brings a variety of fixes and enhancements for mtk_eth_soc, adds support for the MT7981 SoC and facilitates sharing the SGMII PCS code between mtk_eth_soc and mt7530.

Note that this series depends on commit 697c3892d825 ("regmap: apply reg_base and reg_downshift for single register ops") to not break mt7530 pcs register access.

Changes since v1:
* apply reverse xmas tree everywhere
* improve commit descriptions
* add dt bindings
* various small changes addressing all comments received for v1

Daniel Golle (11):
net: ethernet: mtk_eth_soc: add support for MT7981 SoC
dt-bindings: net: mediatek,net: add mt7981-eth binding
dt-bindings: arm: mediatek: add 'mediatek,pn_swap' property
net: ethernet: mtk_eth_soc: set MDIO bus clock frequency
net: ethernet: mtk_eth_soc: reset PCS state
net: ethernet: mtk_eth_soc: only write values if needed
net: ethernet: mtk_eth_soc: fix RX data corruption issue
net: ethernet: mtk_eth_soc: ppe: add support for flow accounting
net: pcs: add driver for MediaTek SGMII PCS
net: ethernet: mtk_eth_soc: switch to external PCS driver
net: dsa: mt7530: use external PCS driver

 .../arm/mediatek/mediatek,sgmiisys.txt        |   4 +
 .../devicetree/bindings/net/mediatek,net.yaml |  42 +++
 MAINTAINERS                                   |   7 +
 drivers/net/dsa/Kconfig                       |   1 +
 drivers/net/dsa/mt7530.c                      | 277 ++++-----------
 drivers/net/dsa/mt7530.h                      |  47 +--
 drivers/net/ethernet/mediatek/Kconfig         |   2 +
 drivers/net/ethernet/mediatek/mtk_eth_path.c  |  14 +-
 drivers/net/ethernet/mediatek/mtk_eth_soc.c   |  65 +++-
 drivers/net/ethernet/mediatek/mtk_eth_soc.h   | 100 ++----
 drivers/net/ethernet/mediatek/mtk_ppe.c       | 114 ++++++-
 drivers/net/ethernet/mediatek/mtk_ppe.h       |  25 +-
 .../net/ethernet/mediatek/mtk_ppe_debugfs.c   |   9 +-
 .../net/ethernet/mediatek/mtk_ppe_offload.c   |   8 +
 drivers/net/ethernet/mediatek/mtk_ppe_regs.h  |  14 +
 drivers/net/ethernet/mediatek/mtk_sgmii.c     | 192 ++---------
 drivers/net/pcs/Kconfig                       |   8 +
 drivers/net/pcs/Makefile                      |   1 +
 drivers/net/pcs/pcs-mtk-lynxi.c               | 315 ++++++++++++++++++
 include/linux/pcs/pcs-mtk-lynxi.h             |  13 +
 20 files changed, 756 insertions(+), 502 deletions(-)
 create mode 100644 drivers/net/pcs/pcs-mtk-lynxi.c
 create mode 100644 include/linux/pcs/pcs-mtk-lynxi.h

base-commit: 129af770823407ee115a56c69a04b440fd2fbe61

Signature · 1 line
2.39.1
author maintainer
#1 lore raw

PATCH v2 1/11 net: ethernet: mtk_eth_soc: add support for MT7981 SoC

The MediaTek MT7981 SoC comes with two 1G/2.5G SGMII ports, just like MT7986.

In addition MT7981 is equipped with a built-in 1000Base-T PHY which can be used with GMAC1.

As many MT7981 boards make use of inverting SGMII signal polarity, add new device-tree attribute 'mediatek,pn_swap' to support them.

---
 drivers/net/ethernet/mediatek/mtk_eth_path.c | 14 +++++++--
 drivers/net/ethernet/mediatek/mtk_eth_soc.c  | 21 +++++++++++++
 drivers/net/ethernet/mediatek/mtk_eth_soc.h  | 31 ++++++++++++++++++++
 drivers/net/ethernet/mediatek/mtk_sgmii.c    | 10 +++++++
 4 files changed, 73 insertions(+), 3 deletions(-)
drivers/net/ethernet/mediatek/mtk_eth_path.c +11 -3
index 72648535a14d..317e447f4991 100644
@@ -96,12 +96,20 @@ static int set_mux_gmac2_gmac0_to_gephy(struct mtk_eth *eth, int path)
 
 static int set_mux_u3_gmac2_to_qphy(struct mtk_eth *eth, int path)
 {
-	unsigned int val = 0;
+	unsigned int val = 0, mask = 0, reg = 0;
 	bool updated = true;
 
 	switch (path) {
 	case MTK_ETH_PATH_GMAC2_SGMII:
-		val = CO_QPHY_SEL;
+		if (MTK_HAS_CAPS(eth->soc->caps, MTK_U3_COPHY_V2)) {
+			reg = USB_PHY_SWITCH_REG;
+			val = SGMII_QPHY_SEL;
+			mask = QPHY_SEL_MASK;
+		} else {
+			reg = INFRA_MISC2;
+			val = CO_QPHY_SEL;
+			mask = val;
+		}
 		break;
 	default:
 		updated = false;
@@ -109,7 +117,7 @@ static int set_mux_u3_gmac2_to_qphy(struct mtk_eth *eth, int path)
 	}
 
 	if (updated)
-		regmap_update_bits(eth->infra, INFRA_MISC2, CO_QPHY_SEL, val);
+		regmap_update_bits(eth->infra, reg, mask, val);
 
 	dev_dbg(eth->dev, "path %s in %s updated = %d\n",
 		mtk_eth_path_name(path), __func__, updated);
drivers/net/ethernet/mediatek/mtk_eth_soc.c +21 -0
index 4570a39a430b..fc5174f83ef1 100644
@@ -4858,6 +4858,26 @@ static const struct mtk_soc_data mt7629_data = {
 	},
 };
 
+static const struct mtk_soc_data mt7981_data = {
+	.reg_map = &mt7986_reg_map,
+	.ana_rgc3 = 0x128,
+	.caps = MT7981_CAPS,
+	.hw_features = MTK_HW_FEATURES,
+	.required_clks = MT7981_CLKS_BITMAP,
+	.required_pctl = false,
+	.offload_version = 2,
+	.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),
+		.rx_irq_done_mask = MTK_RX_DONE_INT_V2,
+		.rx_dma_l4_valid = RX_DMA_L4_VALID_V2,
+		.dma_max_len = MTK_TX_DMA_BUF_LEN_V2,
+		.dma_len_offset = 8,
+	},
+};
+
 static const struct mtk_soc_data mt7986_data = {
 	.reg_map = &mt7986_reg_map,
 	.ana_rgc3 = 0x128,
@@ -4900,6 +4920,7 @@ const struct of_device_id of_mtk_match[] = {
 	{ .compatible = "mediatek,mt7622-eth", .data = &mt7622_data},
 	{ .compatible = "mediatek,mt7623-eth", .data = &mt7623_data},
 	{ .compatible = "mediatek,mt7629-eth", .data = &mt7629_data},
+	{ .compatible = "mediatek,mt7981-eth", .data = &mt7981_data},
 	{ .compatible = "mediatek,mt7986-eth", .data = &mt7986_data},
 	{ .compatible = "ralink,rt5350-eth", .data = &rt5350_data},
 	{},
drivers/net/ethernet/mediatek/mtk_eth_soc.h +31 -0
index afc9d52e79bf..7230dcb29315 100644
@@ -551,11 +551,22 @@
 #define SGMSYS_QPHY_PWR_STATE_CTRL 0xe8
 #define	SGMII_PHYA_PWD		BIT(4)
 
+/* Register to QPHY wrapper control */
+#define SGMSYS_QPHY_WRAP_CTRL	0xec
+#define SGMII_PN_SWAP_MASK	GENMASK(1, 0)
+#define SGMII_PN_SWAP_TX_RX	(BIT(0) | BIT(1))
+#define MTK_SGMII_FLAG_PN_SWAP	BIT(0)
+
 /* Infrasys subsystem config registers */
 #define INFRA_MISC2            0x70c
 #define CO_QPHY_SEL            BIT(0)
 #define GEPHY_MAC_SEL          BIT(1)
 
+/* Top misc registers */
+#define USB_PHY_SWITCH_REG	0x218
+#define QPHY_SEL_MASK		GENMASK(1, 0)
+#define SGMII_QPHY_SEL		0x2
+
 /* MT7628/88 specific stuff */
 #define MT7628_PDMA_OFFSET	0x0800
 #define MT7628_SDM_OFFSET	0x0c00
@@ -736,6 +747,17 @@ enum mtk_clks_map {
 				 BIT(MTK_CLK_SGMII2_CDR_FB) | \
 				 BIT(MTK_CLK_SGMII_CK) | \
 				 BIT(MTK_CLK_ETH2PLL) | BIT(MTK_CLK_SGMIITOP))
+#define MT7981_CLKS_BITMAP	(BIT(MTK_CLK_FE) | BIT(MTK_CLK_GP2) | BIT(MTK_CLK_GP1) | \
+				 BIT(MTK_CLK_WOCPU0) | \
+				 BIT(MTK_CLK_SGMII_TX_250M) | \
+				 BIT(MTK_CLK_SGMII_RX_250M) | \
+				 BIT(MTK_CLK_SGMII_CDR_REF) | \
+				 BIT(MTK_CLK_SGMII_CDR_FB) | \
+				 BIT(MTK_CLK_SGMII2_TX_250M) | \
+				 BIT(MTK_CLK_SGMII2_RX_250M) | \
+				 BIT(MTK_CLK_SGMII2_CDR_REF) | \
+				 BIT(MTK_CLK_SGMII2_CDR_FB) | \
+				 BIT(MTK_CLK_SGMII_CK))
 #define MT7986_CLKS_BITMAP	(BIT(MTK_CLK_FE) | BIT(MTK_CLK_GP2) | BIT(MTK_CLK_GP1) | \
 				 BIT(MTK_CLK_WOCPU1) | BIT(MTK_CLK_WOCPU0) | \
 				 BIT(MTK_CLK_SGMII_TX_250M) | \
@@ -849,6 +871,7 @@ enum mkt_eth_capabilities {
 	MTK_NETSYS_V2_BIT,
 	MTK_SOC_MT7628_BIT,
 	MTK_RSTCTRL_PPE1_BIT,
+	MTK_U3_COPHY_V2_BIT,
 
 	/* MUX BITS*/
 	MTK_ETH_MUX_GDM1_TO_GMAC1_ESW_BIT,
@@ -883,6 +906,7 @@ enum mkt_eth_capabilities {
 #define MTK_NETSYS_V2		BIT(MTK_NETSYS_V2_BIT)
 #define MTK_SOC_MT7628		BIT(MTK_SOC_MT7628_BIT)
 #define MTK_RSTCTRL_PPE1	BIT(MTK_RSTCTRL_PPE1_BIT)
+#define MTK_U3_COPHY_V2		BIT(MTK_U3_COPHY_V2_BIT)
 
 #define MTK_ETH_MUX_GDM1_TO_GMAC1_ESW		\
 	BIT(MTK_ETH_MUX_GDM1_TO_GMAC1_ESW_BIT)
@@ -955,6 +979,11 @@ enum mkt_eth_capabilities {
 		      MTK_MUX_U3_GMAC2_TO_QPHY | \
 		      MTK_MUX_GMAC12_TO_GEPHY_SGMII | MTK_QDMA)
 
+#define MT7981_CAPS  (MTK_GMAC1_SGMII | MTK_GMAC2_SGMII | MTK_GMAC2_GEPHY | \
+		      MTK_MUX_GMAC12_TO_GEPHY_SGMII | MTK_QDMA | \
+		      MTK_MUX_U3_GMAC2_TO_QPHY | MTK_U3_COPHY_V2 | \
+		      MTK_NETSYS_V2 | MTK_RSTCTRL_PPE1)
+
 #define MT7986_CAPS  (MTK_GMAC1_SGMII | MTK_GMAC2_SGMII | \
 		      MTK_MUX_GMAC12_TO_GEPHY_SGMII | MTK_QDMA | \
 		      MTK_NETSYS_V2 | MTK_RSTCTRL_PPE1)
@@ -1068,12 +1097,14 @@ struct mtk_soc_data {
  * @ana_rgc3:          The offset refers to register ANA_RGC3 related to regmap
  * @interface:         Currently configured interface mode
  * @pcs:               Phylink PCS structure
+ * @flags:             Flags indicating hardware properties
  */
 struct mtk_pcs {
 	struct regmap	*regmap;
 	u32             ana_rgc3;
 	phy_interface_t	interface;
 	struct phylink_pcs pcs;
+	u32		flags;
 };
 
 /* struct mtk_sgmii -  This is the structure holding sgmii regmap and its
drivers/net/ethernet/mediatek/mtk_sgmii.c +10 -0
index bb00de1003ac..0071352c93ba 100644
@@ -88,6 +88,11 @@ static int mtk_pcs_config(struct phylink_pcs *pcs, unsigned int mode,
 		regmap_update_bits(mpcs->regmap, SGMSYS_QPHY_PWR_STATE_CTRL,
 				   SGMII_PHYA_PWD, SGMII_PHYA_PWD);
 
+		if (mpcs->flags & MTK_SGMII_FLAG_PN_SWAP)
+			regmap_update_bits(mpcs->regmap, SGMSYS_QPHY_WRAP_CTRL,
+					   SGMII_PN_SWAP_MASK,
+					   SGMII_PN_SWAP_TX_RX);
+
 		if (interface == PHY_INTERFACE_MODE_2500BASEX)
 			rgc3 = RG_PHY_SPEED_3_125G;
 		else
@@ -182,6 +187,11 @@ int mtk_sgmii_init(struct mtk_sgmii *ss, struct device_node *r, u32 ana_rgc3)
 
 		ss->pcs[i].ana_rgc3 = ana_rgc3;
 		ss->pcs[i].regmap = syscon_node_to_regmap(np);
+
+		ss->pcs[i].flags = 0;
+		if (of_property_read_bool(np, "mediatek,pn_swap"))
+			ss->pcs[i].flags |= MTK_SGMII_FLAG_PN_SWAP;
+
 		of_node_put(np);
 		if (IS_ERR(ss->pcs[i].regmap))
 			return PTR_ERR(ss->pcs[i].regmap);
Signature · 1 line
2.39.1
author maintainer
#2 lore raw

PATCH v2 2/11 dt-bindings: net: mediatek,net: add mt7981-eth binding

In reply to Daniel Golle

Introduce DT bindings for the MT7981 SoC to mediatek,net.yaml.

---
 .../devicetree/bindings/net/mediatek,net.yaml | 42 +++++++++++++++++++
 1 file changed, 42 insertions(+)
Documentation/devicetree/bindings/net/mediatek,net.yaml +42 -0
index 7ef696204c5a..d17e2eb46118 100644
@@ -21,6 +21,7 @@ properties:
       - mediatek,mt7623-eth
       - mediatek,mt7622-eth
       - mediatek,mt7629-eth
+      - mediatek,mt7981-eth
       - mediatek,mt7986-eth
       - ralink,rt5350-eth
 
@@ -206,6 +207,47 @@ allOf:
 
         mediatek,wed: false
 
+  - if:
+      properties:
+        compatible:
+          contains:
+            const: mediatek,mt7981-eth
+    then:
+      properties:
+        interrupts:
+          minItems: 4
+
+        clocks:
+          minItems: 15
+          maxItems: 15
+
+        clock-names:
+          items:
+            - const: fe
+            - const: gp2
+            - const: gp1
+            - const: wocpu0
+            - const: sgmii_ck
+            - const: sgmii_tx250m
+            - const: sgmii_rx250m
+            - const: sgmii_cdr_ref
+            - const: sgmii_cdr_fb
+            - const: sgmii2_tx250m
+            - const: sgmii2_rx250m
+            - const: sgmii2_cdr_ref
+            - const: sgmii2_cdr_fb
+            - const: netsys0
+            - const: netsys1
+
+        mediatek,sgmiisys:
+          minItems: 2
+          maxItems: 2
+
+        mediatek,wed-pcie:
+          $ref: /schemas/types.yaml#/definitions/phandle
+          description:
+            Phandle to the mediatek wed-pcie controller.
+
   - if:
       properties:
         compatible:
Signature · 1 line
2.39.1
#3 lore raw

Re: [PATCH v2 02/11] dt-bindings: net: mediatek,net: add mt7981-eth binding

Quoted 3 lines · Daniel Golle

Introduce DT bindings for the MT7981 SoC to mediatek,net.yaml.

Please use scripts/get_maintainers.pl to get a list of necessary people and lists to CC. It might happen, that command when run on an older kernel, gives you outdated entries. Therefore please be sure you base your patches on recent Linux kernel.

Since this skipped also lists, there are no automated checks running on it, thus no point to review it.

Resend with proper address list, please.

Quoted 50 lines
---
 .../devicetree/bindings/net/mediatek,net.yaml | 42 +++++++++++++++++++
 1 file changed, 42 insertions(+)
Documentation/devicetree/bindings/net/mediatek,net.yaml +31 -0
index 7ef696204c5a..d17e2eb46118 100644
@@ -21,6 +21,7 @@ properties:
       - mediatek,mt7623-eth
       - mediatek,mt7622-eth
       - mediatek,mt7629-eth
+      - mediatek,mt7981-eth
       - mediatek,mt7986-eth
       - ralink,rt5350-eth
 
@@ -206,6 +207,47 @@ allOf:
 
         mediatek,wed: false
 
+  - if:
+      properties:
+        compatible:
+          contains:
+            const: mediatek,mt7981-eth
+    then:
+      properties:
+        interrupts:
+          minItems: 4
+
+        clocks:
+          minItems: 15
+          maxItems: 15
+
+        clock-names:
+          items:
+            - const: fe
+            - const: gp2
+            - const: gp1
+            - const: wocpu0
+            - const: sgmii_ck
+            - const: sgmii_tx250m
+            - const: sgmii_rx250m
+            - const: sgmii_cdr_ref
+            - const: sgmii_cdr_fb
+            - const: sgmii2_tx250m
+            - const: sgmii2_rx250m
+            - const: sgmii2_cdr_ref
+            - const: sgmii2_cdr_fb
+            - const: netsys0

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

Quoted 10 lines
Documentation/devicetree/bindings/net/mediatek,net.yaml +10 -0
+            - const: netsys1
+
+        mediatek,sgmiisys:
+          minItems: 2
+          maxItems: 2
+
+        mediatek,wed-pcie:
+          $ref: /schemas/types.yaml#/definitions/phandle
+          description:
+            Phandle to the mediatek wed-pcie controller.

Do not define properties in each variant.

Best regards,
Krzysztof

author maintainer
#4 lore raw

PATCH v2 3/11 dt-bindings: arm: mediatek: add 'mediatek,pn_swap' property

In reply to Daniel Golle

Add documentation for the newly introduced 'mediatek,pn_swap' property to mediatek,sgmiisys.txt.

---
 .../devicetree/bindings/arm/mediatek/mediatek,sgmiisys.txt    | 4 ++++
 1 file changed, 4 insertions(+)
Documentation/devicetree/bindings/arm/mediatek/mediatek,sgmiisys.txt +4 -0
index d2c24c277514..b38dd0fde21d 100644
@@ -14,6 +14,10 @@ Required Properties:
 	- "mediatek,mt7986-sgmiisys_1", "syscon"
 - #clock-cells: Must be 1
 
+Optional Properties:
+
+- mediatek,pn_swap: Invert polarity of the SGMII data lanes.
+
 The SGMIISYS controller uses the common clk binding from
 Documentation/devicetree/bindings/clock/clock-bindings.txt
 The available clocks are defined in dt-bindings/clock/mt*-clk.h.
Signature · 1 line
2.39.1
#5 lore raw

Re: [PATCH v2 03/11] dt-bindings: arm: mediatek: add 'mediatek,pn_swap' property

Quoted 3 lines · Daniel Golle

Add documentation for the newly introduced 'mediatek,pn_swap' property to mediatek,sgmiisys.txt.

Please use scripts/get_maintainers.pl to get a list of necessary people and lists to CC. It might happen, that command when run on an older kernel, gives you outdated entries. Therefore please be sure you base your patches on recent Linux kernel.

Quoted 10 lines
---
 .../devicetree/bindings/arm/mediatek/mediatek,sgmiisys.txt    | 4 ++++
 1 file changed, 4 insertions(+)
Documentation/devicetree/bindings/arm/mediatek/mediatek,sgmiisys.txt +0 -0
index d2c24c277514..b38dd0fde21d 100644

Documentation/devicetree/bindings/arm/mediatek/mediatek,sgmiisys.txt Required Properties: · line 19

Quoted 6 lines
Documentation/devicetree/bindings/arm/mediatek/mediatek,sgmiisys.txt +3 -0
@@ -14,6 +14,10 @@ Required Properties:
 	- "mediatek,mt7986-sgmiisys_1", "syscon"
 - #clock-cells: Must be 1
 
+Optional Properties:
+
+- mediatek,pn_swap: Invert polarity of the SGMII data lanes.

No:
1. No new properties for TXT bindings,
2. Underscore is not allowed.
3. Does not look like property of this node. This is a clock controller or system controller, not SGMII/phy etc.

Best regards,
Krzysztof

author maintainer
#6 lore raw

Re: [PATCH v2 03/11] dt-bindings: arm: mediatek: add 'mediatek,pn_swap' property

Hi Krzysztof,

Quoted 23 lines · Krzysztof Kozlowski
Quoted 3 lines · Daniel Golle

Add documentation for the newly introduced 'mediatek,pn_swap' property to mediatek,sgmiisys.txt.

Please use scripts/get_maintainers.pl to get a list of necessary people and lists to CC. It might happen, that command when run on an older kernel, gives you outdated entries. Therefore please be sure you base your patches on recent Linux kernel.

Quoted 13 lines
---
 .../devicetree/bindings/arm/mediatek/mediatek,sgmiisys.txt    | 4 ++++
 1 file changed, 4 insertions(+)
Documentation/devicetree/bindings/arm/mediatek/mediatek,sgmiisys.txt +0 -0
index d2c24c277514..b38dd0fde21d 100644
@@ -14,6 +14,10 @@ Required Properties:
 	- "mediatek,mt7986-sgmiisys_1", "syscon"
 - #clock-cells: Must be 1
 
Quoted 6 lines

Documentation/devicetree/bindings/arm/mediatek/mediatek,sgmiisys.txt Required Properties: · line 19

Quoted 3 lines
Documentation/devicetree/bindings/arm/mediatek/mediatek,sgmiisys.txt +3 -0
+Optional Properties:
+
+- mediatek,pn_swap: Invert polarity of the SGMII data lanes.

No:
1. No new properties for TXT bindings,

So I'll have to convert the bindings to YAML, right?

Quoted 1 line

2. Underscore is not allowed.

Ack, will change the name of the property.

Quoted 2 lines

3. Does not look like property of this node. This is a clock controller or system controller, not SGMII/phy etc.

The register range referred to by this node *does* represent also an SGMII phy. These sgmiisys nodes also carry the 'syscon' compatible, and are referenced in the node of the Ethernet core, and then used by drivers/net/ethernet/mediatek/mtk_sgmii.c using syscon_node_to_regmap. (This is the current situation already, and not related to the patchset now adding only a new property to support hardware which needs that)

So: Should I introduce a new binding for the same compatible strings related to the SGMII PHY features? Or is it fine in this case to add this property to the existing binding?

Thank you in advance for your advise!

Daniel

#7 lore raw

Re: [PATCH v2 03/11] dt-bindings: arm: mediatek: add 'mediatek,pn_swap' property

Quoted 26 lines · Daniel Golle

Hi Krzysztof,

Quoted 23 lines · Krzysztof Kozlowski
Quoted 3 lines · Daniel Golle

Add documentation for the newly introduced 'mediatek,pn_swap' property to mediatek,sgmiisys.txt.

Please use scripts/get_maintainers.pl to get a list of necessary people and lists to CC. It might happen, that command when run on an older kernel, gives you outdated entries. Therefore please be sure you base your patches on recent Linux kernel.

Quoted 13 lines
---
 .../devicetree/bindings/arm/mediatek/mediatek,sgmiisys.txt    | 4 ++++
 1 file changed, 4 insertions(+)
Documentation/devicetree/bindings/arm/mediatek/mediatek,sgmiisys.txt +0 -0
index d2c24c277514..b38dd0fde21d 100644
@@ -14,6 +14,10 @@ Required Properties:
 	- "mediatek,mt7986-sgmiisys_1", "syscon"
 - #clock-cells: Must be 1
 
Quoted 8 lines
Quoted 6 lines

Documentation/devicetree/bindings/arm/mediatek/mediatek,sgmiisys.txt Required Properties: · line 19

Quoted 3 lines
Documentation/devicetree/bindings/arm/mediatek/mediatek,sgmiisys.txt +3 -0
+Optional Properties:
+
+- mediatek,pn_swap: Invert polarity of the SGMII data lanes.

No:
1. No new properties for TXT bindings,

So I'll have to convert the bindings to YAML, right?

Yes, please.

Quoted 8 lines
Quoted 2 lines

2. Underscore is not allowed.

Ack, will change the name of the property.

Quoted 2 lines

3. Does not look like property of this node. This is a clock controller or system controller, not SGMII/phy etc.

Quoted 6 lines

The register range referred to by this node *does* represent also an SGMII phy. These sgmiisys nodes also carry the 'syscon' compatible, and are referenced in the node of the Ethernet core, and then used by drivers/net/ethernet/mediatek/mtk_sgmii.c using syscon_node_to_regmap. (This is the current situation already, and not related to the patchset now adding only a new property to support hardware which needs that)

Just because a register is located in syscon block, does not mean that SGMII configuration is a property of this device.

Quoted 4 lines

So: Should I introduce a new binding for the same compatible strings related to the SGMII PHY features? Or is it fine in this case to add this property to the existing binding?

The user of syscon should configure it. I don't think you need new binding. You just have to update the user of this syscon.

Best regards,
Krzysztof

author maintainer
#8 lore raw

Re: [PATCH v2 03/11] dt-bindings: arm: mediatek: add 'mediatek,pn_swap' property

Quoted 12 lines · Krzysztof Kozlowski
Quoted 10 lines · Daniel Golle

...

Quoted 2 lines

3. Does not look like property of this node. This is a clock controller or system controller, not SGMII/phy etc.

The register range referred to by this node *does* represent also an SGMII phy. These sgmiisys nodes also carry the 'syscon' compatible, and are referenced in the node of the Ethernet core, and then used by drivers/net/ethernet/mediatek/mtk_sgmii.c using syscon_node_to_regmap. (This is the current situation already, and not related to the patchset now adding only a new property to support hardware which needs that)

Quoted 2 lines

Just because a register is located in syscon block, does not mean that SGMII configuration is a property of this device.

It's not just one register, the whole SGMII PCS is located in those mediatek,sgmiisys syscon nodes.

Quoted 8 lines
Quoted 5 lines

So: Should I introduce a new binding for the same compatible strings related to the SGMII PHY features? Or is it fine in this case to add this property to the existing binding?

The user of syscon should configure it. I don't think you need new binding. You just have to update the user of this syscon.

Excuse my confusion, but it's still not entirely clear to me. So in this case I should add the description of the added propterty of the individual SGMII units (there can be more than one) to Documentation/devicetree/bindings/net/mediatek,net.yaml eventhough the properties are in the sgmiisys syscon nodes?

If so I will have to figure out how to describe properties of other nodes in the binding of the node referencing them. Are there any good examples for that?

Or should the property itself be moved into yet another array of booleans which should be added in the node describing the ethernet controller and referencing these sgmiisys syscons using phandles?

#9 lore raw

Re: [PATCH v2 03/11] dt-bindings: arm: mediatek: add 'mediatek,pn_swap' property

Quoted 13 lines · Daniel Golle
Quoted 12 lines · Krzysztof Kozlowski
Quoted 10 lines · Daniel Golle

...

Quoted 2 lines

3. Does not look like property of this node. This is a clock controller or system controller, not SGMII/phy etc.

The register range referred to by this node *does* represent also an SGMII phy. These sgmiisys nodes also carry the 'syscon' compatible, and are referenced in the node of the Ethernet core, and then used by drivers/net/ethernet/mediatek/mtk_sgmii.c using syscon_node_to_regmap. (This is the current situation already, and not related to the patchset now adding only a new property to support hardware which needs that)

Quoted 5 lines
Quoted 2 lines

Just because a register is located in syscon block, does not mean that SGMII configuration is a property of this device.

It's not just one register, the whole SGMII PCS is located in those mediatek,sgmiisys syscon nodes.

Then maybe this should be a PCS PHY device instead of adding properties unrelated to clock/system controller? I don't know, currently this binding says it is a provider of clocks...

Quoted 7 lines
Quoted 7 lines
Quoted 6 lines

So: Should I introduce a new binding for the same compatible strings related to the SGMII PHY features? Or is it fine in this case to add this property to the existing binding?

Quoted 8 lines
Quoted 2 lines

The user of syscon should configure it. I don't think you need new binding. You just have to update the user of this syscon.

Excuse my confusion, but it's still not entirely clear to me. So in this case I should add the description of the added propterty of the individual SGMII units (there can be more than one) to Documentation/devicetree/bindings/net/mediatek,net.yaml eventhough the properties are in the sgmiisys syscon nodes?

I guess the property should be in the node representing the SGMII. You add it now to the clock (or system) controller, so it does not look right. It's not a property of a clock controller.

Now which node should have this property depends on your devices - which I have no clue about, I read what is in the bindings.

Quoted 4 lines

If so I will have to figure out how to describe properties of other nodes in the binding of the node referencing them. Are there any good examples for that?

phys and pcs'es?

Quoted 4 lines

Or should the property itself be moved into yet another array of booleans which should be added in the node describing the ethernet controller and referencing these sgmiisys syscons using phandles?

Best regards,
Krzysztof

author maintainer
#10 lore raw

Re: [PATCH v2 03/11] dt-bindings: arm: mediatek: add 'mediatek,pn_swap' property

Hi Krzysztof,

thank you for taking the time to review and explain.

Quoted 17 lines · Krzysztof Kozlowski
Quoted 16 lines · Daniel Golle
Quoted 14 lines · Krzysztof Kozlowski
Quoted 10 lines · Daniel Golle

...

Quoted 2 lines

3. Does not look like property of this node. This is a clock controller or system controller, not SGMII/phy etc.

The register range referred to by this node *does* represent also an SGMII phy. These sgmiisys nodes also carry the 'syscon' compatible, and are referenced in the node of the Ethernet core, and then used by drivers/net/ethernet/mediatek/mtk_sgmii.c using syscon_node_to_regmap. (This is the current situation already, and not related to the patchset now adding only a new property to support hardware which needs that)

Just because a register is located in syscon block, does not mean that SGMII configuration is a property of this device.

Quoted 6 lines
Quoted 2 lines

It's not just one register, the whole SGMII PCS is located in those mediatek,sgmiisys syscon nodes.

Then maybe this should be a PCS PHY device instead of adding properties unrelated to clock/system controller? I don't know, currently this binding says it is a provider of clocks...

As in reality it is really a clock provider and also SGMII PCS at the same time, maybe we should just update the description of the binding to match that:

Documentation/devicetree/bindings/arm/mediatek/mediatek,sgmiisys.txt +1 -0
index d2c24c2775141..db6f75df200ba 100644
@@ -2,6 +2,7 @@ MediaTek SGMIISYS controller
 ============================
 
 The MediaTek SGMIISYS controller provides various clocks to the system.
+It also represents the SGMII PCS used by the Ethernet core.
 
 Required Properties:
 

See

https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/drivers/net/ethernet/mediatek/mtk_sgmii.c#n179

https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/arch/arm64/boot/dts/mediatek/mt7986a.dtsi#n409

Quoted 17 lines
Quoted 8 lines
Quoted 8 lines
Quoted 7 lines

So: Should I introduce a new binding for the same compatible strings related to the SGMII PHY features? Or is it fine in this case to add this property to the existing binding?

Quoted 8 lines
Quoted 2 lines

The user of syscon should configure it. I don't think you need new binding. You just have to update the user of this syscon.

Excuse my confusion, but it's still not entirely clear to me. So in this case I should add the description of the added propterty of the individual SGMII units (there can be more than one) to Documentation/devicetree/bindings/net/mediatek,net.yaml eventhough the properties are in the sgmiisys syscon nodes?

Quoted 3 lines

I guess the property should be in the node representing the SGMII. You add it now to the clock (or system) controller, so it does not look right. It's not a property of a clock controller.

Well maybe this node needs to be split then into one node representing only the clock controller and another node representing the SGMII PCS? I'm not sure if this is even possible, some registers in this range represent clocks, other registers are accessed using regmap API in mtk_sgmii.c.

And (see the rest of this series) the exact same SGMII PCS can also be found in MT7531 switch IC which has it's own (a bit odd) way to access 32-bit registers over MDIO, also in this case it is simply not easily possible to represent the SGMII PCS in device tree.

Quoted 3 lines

Now which node should have this property depends on your devices - which I have no clue about, I read what is in the bindings.

There isn't any other node exclusively representing the SGMII PCS. I guess the only other option would be to move the property to the Ethernet controller node, which imho complicates things as it is really a property of an individual SGMII PHY (of which there can be more than one).

Quoted 7 lines
Quoted 5 lines

If so I will have to figure out how to describe properties of other nodes in the binding of the node referencing them. Are there any good examples for that?

phys and pcs'es?

Hm, none of the current PCS (or PHY) drivers are represented by a syscon node... (and maybe that's the mistake in first place?)

Quoted 9 lines
Quoted 5 lines

Or should the property itself be moved into yet another array of booleans which should be added in the node describing the ethernet controller and referencing these sgmiisys syscons using phandles?

Best regards,
Krzysztof

#11 lore raw

Re: [PATCH v2 03/11] dt-bindings: arm: mediatek: add 'mediatek,pn_swap' property

Quoted 46 lines · Daniel Golle

Hi Krzysztof,

thank you for taking the time to review and explain.

Quoted 17 lines · Krzysztof Kozlowski
Quoted 16 lines · Daniel Golle
Quoted 14 lines · Krzysztof Kozlowski
Quoted 10 lines · Daniel Golle

...

Quoted 2 lines

3. Does not look like property of this node. This is a clock controller or system controller, not SGMII/phy etc.

The register range referred to by this node *does* represent also an SGMII phy. These sgmiisys nodes also carry the 'syscon' compatible, and are referenced in the node of the Ethernet core, and then used by drivers/net/ethernet/mediatek/mtk_sgmii.c using syscon_node_to_regmap. (This is the current situation already, and not related to the patchset now adding only a new property to support hardware which needs that)

Just because a register is located in syscon block, does not mean that SGMII configuration is a property of this device.

Quoted 6 lines
Quoted 2 lines

It's not just one register, the whole SGMII PCS is located in those mediatek,sgmiisys syscon nodes.

Then maybe this should be a PCS PHY device instead of adding properties unrelated to clock/system controller? I don't know, currently this binding says it is a provider of clocks...

As in reality it is really a clock provider and also SGMII PCS at the same time, maybe we should just update the description of the binding to match that:

Documentation/devicetree/bindings/arm/mediatek/mediatek,sgmiisys.txt +1 -0
index d2c24c2775141..db6f75df200ba 100644
@@ -2,6 +2,7 @@ MediaTek SGMIISYS controller
 ============================
 
 The MediaTek SGMIISYS controller provides various clocks to the system.
+It also represents the SGMII PCS used by the Ethernet core.
 
 Required Properties:
 
Quoted 5 lines

See

https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/drivers/net/ethernet/mediatek/mtk_sgmii.c#n179

https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/arch/arm64/boot/dts/mediatek/mt7986a.dtsi#n409

But it is not used as phy or PCS. It is used as syscon. If it was a phy or PCS, then the property probably belonged here, but bindings and Linux implementation were created in different way, so it is not a phy or PCS, just a syscon.

Quoted 17 lines
Quoted 13 lines
Quoted 4 lines
Quoted 4 lines
Quoted 3 lines

So: Should I introduce a new binding for the same compatible strings related to the SGMII PHY features? Or is it fine in this case to add this property to the existing binding?

Quoted 8 lines
Quoted 2 lines

The user of syscon should configure it. I don't think you need new binding. You just have to update the user of this syscon.

Excuse my confusion, but it's still not entirely clear to me. So in this case I should add the description of the added propterty of the individual SGMII units (there can be more than one) to Documentation/devicetree/bindings/net/mediatek,net.yaml eventhough the properties are in the sgmiisys syscon nodes?

Quoted 3 lines

I guess the property should be in the node representing the SGMII. You add it now to the clock (or system) controller, so it does not look right. It's not a property of a clock controller.

Quoted 5 lines

Well maybe this node needs to be split then into one node representing only the clock controller and another node representing the SGMII PCS? I'm not sure if this is even possible, some registers in this range represent clocks, other registers are accessed using regmap API in mtk_sgmii.c.

This can be the same node, but it must be used like PCS. syscon phandle for getting regmap is something entirely else.

Quoted 18 lines

And (see the rest of this series) the exact same SGMII PCS can also be found in MT7531 switch IC which has it's own (a bit odd) way to access 32-bit registers over MDIO, also in this case it is simply not easily possible to represent the SGMII PCS in device tree.

Quoted 3 lines

Now which node should have this property depends on your devices - which I have no clue about, I read what is in the bindings.

There isn't any other node exclusively representing the SGMII PCS. I guess the only other option would be to move the property to the Ethernet controller node, which imho complicates things as it is really a property of an individual SGMII PHY (of which there can be more than one).

Quoted 2 lines
Quoted 2 lines
Quoted 8 lines
Quoted 5 lines
Quoted 3 lines

If so I will have to figure out how to describe properties of other nodes in the binding of the node referencing them. Are there any good examples for that?

phys and pcs'es?

Hm, none of the current PCS (or PHY) drivers are represented by a syscon node... (and maybe that's the mistake in first place?)

Yes.

Best regards,
Krzysztof

#12 lore raw

Re: [PATCH v2 03/11] dt-bindings: arm: mediatek: add 'mediatek,pn_swap' property

Quoted 5 lines · Krzysztof Kozlowski
Quoted 2 lines · Daniel Golle

Hm, none of the current PCS (or PHY) drivers are represented by a syscon node... (and maybe that's the mistake in first place?)

Yes.

Nos, it isn't.

Signature · 2 lines
RMK's Patch system: https://www.armlinux.org.uk/developer/patches/
FTTP is here! 40Mbps down 10Mbps up. Decent connectivity at last!
#13 lore raw

Re: [PATCH v2 03/11] dt-bindings: arm: mediatek: add 'mediatek,pn_swap' property

Quoted 8 lines · Russell King (Oracle)
Quoted 5 lines · Krzysztof Kozlowski
Quoted 2 lines · Daniel Golle

Hm, none of the current PCS (or PHY) drivers are represented by a syscon node... (and maybe that's the mistake in first place?)

Yes.

Nos, it isn't.

To expand on this - I have no idea why you consider it a mistake that apparently all PCS aren't represented by a syscon node.

PCS is a sub-block in an ethernet system, just the same as a MAC is a sub-block. PCS can appear in several locations of an ethernet system, but are generally found either side of a serial ethernet link such as 1000base-X, SGMII, USXGMII, 10Gbase-R etc.

So, one can find PCS within an ethernet PHY - and there may be one facing the MAC connection, and there will be another facing the media. We generally do not need to separate these PCS from the PHY itself because we view the PHY as one whole device.

The optional PCS on the MAC side of the link is something that we need to know about, because this has to be configured to talk to the PHY, or to configure and obtain negotiation results from in the case of fibre links.

PCS on the MAC side are not a system level device, they are very much a specific piece of ethernet hardware in the same way that the MAC is, and we don't represent the MAC as a syscon node. There is no reason to do so with PCS.

These PCS on the MAC side tend to be accessed via direct MMIO accesses, or over a MDIO bus.

There's other blocks in the IEEE 802.3 ethernet layering, such as the PMA/PMD module (which for the MAC side we tend to model with the drivers/phy layer) - but again, these also appear in ethernet PHYs in order to produce the electrical signals for e.g. twisted pair ethernet.

So, to effectively state that you consider that PCS should always be represented as a syscon node is rather naieve, and really as a DT reviewer you should not be making such decisions, but soliciting opinions from those who know this subject area in detail _whether_ they are some kind of system controller before making such a decision.

Signature · 2 lines
RMK's Patch system: https://www.armlinux.org.uk/developer/patches/
FTTP is here! 40Mbps down 10Mbps up. Decent connectivity at last!
#14 lore raw

Re: [PATCH v2 03/11] dt-bindings: arm: mediatek: add 'mediatek,pn_swap' property

Quoted 42 lines · Russell King (Oracle)
Quoted 8 lines · Russell King (Oracle)
Quoted 5 lines · Krzysztof Kozlowski
Quoted 2 lines · Daniel Golle

Hm, none of the current PCS (or PHY) drivers are represented by a syscon node... (and maybe that's the mistake in first place?)

Yes.

Nos, it isn't.

To expand on this - I have no idea why you consider it a mistake that apparently all PCS aren't represented by a syscon node.

PCS is a sub-block in an ethernet system, just the same as a MAC is a sub-block. PCS can appear in several locations of an ethernet system, but are generally found either side of a serial ethernet link such as 1000base-X, SGMII, USXGMII, 10Gbase-R etc.

So, one can find PCS within an ethernet PHY - and there may be one facing the MAC connection, and there will be another facing the media. We generally do not need to separate these PCS from the PHY itself because we view the PHY as one whole device.

The optional PCS on the MAC side of the link is something that we need to know about, because this has to be configured to talk to the PHY, or to configure and obtain negotiation results from in the case of fibre links.

PCS on the MAC side are not a system level device, they are very much a specific piece of ethernet hardware in the same way that the MAC is, and we don't represent the MAC as a syscon node. There is no reason to do so with PCS.

These PCS on the MAC side tend to be accessed via direct MMIO accesses, or over a MDIO bus.

There's other blocks in the IEEE 802.3 ethernet layering, such as the PMA/PMD module (which for the MAC side we tend to model with the drivers/phy layer) - but again, these also appear in ethernet PHYs in order to produce the electrical signals for e.g. twisted pair ethernet.

Quoted 6 lines

So, to effectively state that you consider that PCS should always be represented as a syscon node is rather naieve, and really as a DT reviewer you should not be making such decisions, but soliciting opinions from those who know this subject area in detail _whether_ they are some kind of system controller before making such a decision.

Daniel switched to private emails, so unfortunately our talk is not visible here, nevertheless thanks for the feedback. Much appreciated!

Best regards,
Krzysztof

#15 lore raw

Re: [PATCH v2 03/11] dt-bindings: arm: mediatek: add 'mediatek,pn_swap' property

In reply to Krzysztof Kozlowski
Quoted 8 lines · Krzysztof Kozlowski

Documentation/devicetree/bindings/arm/mediatek/mediatek,sgmiisys.txt Required Properties: · line 19

Quoted 3 lines · Daniel Golle
Documentation/devicetree/bindings/arm/mediatek/mediatek,sgmiisys.txt +3 -0
+Optional Properties:
+
+- mediatek,pn_swap: Invert polarity of the SGMII data lanes.

No:
3. Does not look like property of this node. This is a clock controller or system controller, not SGMII/phy etc.

Wrong. Totally wrong.

SGMII data lines consist of a "positive" and a "negative" signal. Clearly, this PHY supports swapping the sense of those.

This CLEARLY has nothing to do with a clock controller. It's also not system-controller related either.

Signature · 2 lines
RMK's Patch system: https://www.armlinux.org.uk/developer/patches/
FTTP is here! 40Mbps down 10Mbps up. Decent connectivity at last!
author maintainer
#16 lore raw

PATCH v2 4/11 net: ethernet: mtk_eth_soc: set MDIO bus clock frequency

In reply to Daniel Golle

Set MDIO bus clock frequency and allow setting a custom maximum frquency from device tree.

---
 drivers/net/ethernet/mediatek/mtk_eth_soc.c | 21 +++++++++++++++++++++
 drivers/net/ethernet/mediatek/mtk_eth_soc.h |  7 +++++++
 2 files changed, 28 insertions(+)
drivers/net/ethernet/mediatek/mtk_eth_soc.c +21 -0
index fc5174f83ef1..4ee582e39c12 100644
@@ -789,8 +789,10 @@ static const struct phylink_mac_ops mtk_phylink_ops = {
 
 static int mtk_mdio_init(struct mtk_eth *eth)
 {
+	unsigned int max_clk = 2500000, divider;
 	struct device_node *mii_np;
 	int ret;
+	u32 val;
 
 	mii_np = of_get_child_by_name(eth->dev->of_node, "mdio-bus");
 	if (!mii_np) {
@@ -818,6 +820,25 @@ static int mtk_mdio_init(struct mtk_eth *eth)
 	eth->mii_bus->parent = eth->dev;
 
 	snprintf(eth->mii_bus->id, MII_BUS_ID_SIZE, "%pOFn", mii_np);
+
+	if (!of_property_read_u32(mii_np, "clock-frequency", &val)) {
+		if (val > MDC_MAX_FREQ || val < MDC_MAX_FREQ / MDC_MAX_DIVIDER) {
+			dev_err(eth->dev, "MDIO clock frequency out of range");
+			ret = -EINVAL;
+			goto err_put_node;
+		}
+		max_clk = val;
+	}
+	divider = min_t(unsigned int, DIV_ROUND_UP(MDC_MAX_FREQ, max_clk), 63);
+
+	/* Configure MDC Divider */
+	val = mtk_r32(eth, MTK_PPSC);
+	val &= ~PPSC_MDC_CFG;
+	val |= FIELD_PREP(PPSC_MDC_CFG, divider) | PPSC_MDC_TURBO;
+	mtk_w32(eth, val, MTK_PPSC);
+
+	dev_dbg(eth->dev, "MDC is running on %d Hz\n", MDC_MAX_FREQ / divider);
+
 	ret = of_mdiobus_register(eth->mii_bus, mii_np);
 
 err_put_node:
drivers/net/ethernet/mediatek/mtk_eth_soc.h +7 -0
index 7230dcb29315..7014c02ba2d4 100644
@@ -363,6 +363,13 @@
 #define RX_DMA_VTAG_V2		BIT(0)
 #define RX_DMA_L4_VALID_V2	BIT(2)
 
+/* PHY Polling and SMI Master Control registers */
+#define MTK_PPSC		0x10000
+#define PPSC_MDC_CFG		GENMASK(29, 24)
+#define PPSC_MDC_TURBO		BIT(20)
+#define MDC_MAX_FREQ		25000000
+#define MDC_MAX_DIVIDER		63
+
 /* PHY Indirect Access Control registers */
 #define MTK_PHY_IAC		0x10004
 #define PHY_IAC_ACCESS		BIT(31)
Signature · 1 line
2.39.1
author maintainer
#18 lore raw

PATCH v2 5/11 net: ethernet: mtk_eth_soc: reset PCS state

In reply to Daniel Golle

Reset PCS state when changing interface mode.

---
 drivers/net/ethernet/mediatek/mtk_eth_soc.h | 4 ++++
 drivers/net/ethernet/mediatek/mtk_sgmii.c   | 4 ++++
 2 files changed, 8 insertions(+)
drivers/net/ethernet/mediatek/mtk_eth_soc.h +4 -0
index 7014c02ba2d4..142def8629c8 100644
@@ -548,6 +548,10 @@
 #define SGMII_SEND_AN_ERROR_EN		BIT(11)
 #define SGMII_IF_MODE_MASK		GENMASK(5, 1)
 
+/* Register to reset SGMII design */
+#define SGMII_RESERVED_0	0x34
+#define SGMII_SW_RESET		BIT(0)
+
 /* Register to set SGMII speed, ANA RG_ Control Signals III*/
 #define SGMSYS_ANA_RG_CS3	0x2028
 #define RG_PHY_SPEED_MASK	(BIT(2) | BIT(3))
drivers/net/ethernet/mediatek/mtk_sgmii.c +4 -0
index 0071352c93ba..d8184448cd5a 100644
@@ -88,6 +88,10 @@ static int mtk_pcs_config(struct phylink_pcs *pcs, unsigned int mode,
 		regmap_update_bits(mpcs->regmap, SGMSYS_QPHY_PWR_STATE_CTRL,
 				   SGMII_PHYA_PWD, SGMII_PHYA_PWD);
 
+		/* Reset SGMII PCS state */
+		regmap_update_bits(mpcs->regmap, SGMII_RESERVED_0,
+				   SGMII_SW_RESET, SGMII_SW_RESET);
+
 		if (mpcs->flags & MTK_SGMII_FLAG_PN_SWAP)
 			regmap_update_bits(mpcs->regmap, SGMSYS_QPHY_WRAP_CTRL,
 					   SGMII_PN_SWAP_MASK,
Signature · 1 line
2.39.1
author maintainer
#20 lore raw

PATCH v2 6/11 net: ethernet: mtk_eth_soc: only write values if needed

In reply to Daniel Golle

Only restart auto-negotiation and write link timer if actually necessary.

---
 drivers/net/ethernet/mediatek/mtk_sgmii.c | 24 +++++++++++------------
 1 file changed, 12 insertions(+), 12 deletions(-)
drivers/net/ethernet/mediatek/mtk_sgmii.c +12 -12
index d8184448cd5a..9c58006d1c33 100644
@@ -38,20 +38,16 @@ static int mtk_pcs_config(struct phylink_pcs *pcs, unsigned int mode,
 			  const unsigned long *advertising,
 			  bool permit_pause_to_mac)
 {
+	bool mode_changed = false, changed, use_an;
 	struct mtk_pcs *mpcs = pcs_to_mtk_pcs(pcs);
 	unsigned int rgc3, sgm_mode, bmcr;
 	int advertise, link_timer;
-	bool changed, use_an;
 
 	advertise = phylink_mii_c22_pcs_encode_advertisement(interface,
 							     advertising);
 	if (advertise < 0)
 		return advertise;
 
-	link_timer = phylink_get_link_timer_ns(interface);
-	if (link_timer < 0)
-		return link_timer;
-
 	/* Clearing IF_MODE_BIT0 switches the PCS to BASE-X mode, and
 	 * we assume that fixes it's speed at bitrate = line rate (in
 	 * other words, 1000Mbps or 2500Mbps).
@@ -77,8 +73,7 @@ static int mtk_pcs_config(struct phylink_pcs *pcs, unsigned int mode,
 	}
 
 	if (use_an) {
-		/* FIXME: Do we need to set AN_RESTART here? */
-		bmcr = SGMII_AN_RESTART | SGMII_AN_ENABLE;
+		bmcr = SGMII_AN_ENABLE;
 	} else {
 		bmcr = 0;
 	}
@@ -106,16 +101,21 @@ static int mtk_pcs_config(struct phylink_pcs *pcs, unsigned int mode,
 		regmap_update_bits(mpcs->regmap, mpcs->ana_rgc3,
 				   RG_PHY_SPEED_3_125G, rgc3);
 
+		/* Setup the link timer and QPHY power up inside SGMIISYS */
+		link_timer = phylink_get_link_timer_ns(interface);
+		if (link_timer < 0)
+			return link_timer;
+
+		regmap_write(mpcs->regmap, SGMSYS_PCS_LINK_TIMER, link_timer / 2 / 8);
+
 		mpcs->interface = interface;
+		mode_changed = true;
 	}
 
 	/* Update the advertisement, noting whether it has changed */
 	regmap_update_bits_check(mpcs->regmap, SGMSYS_PCS_ADVERTISE,
 				 SGMII_ADVERTISE, advertise, &changed);
 
-	/* Setup the link timer and QPHY power up inside SGMIISYS */
-	regmap_write(mpcs->regmap, SGMSYS_PCS_LINK_TIMER, link_timer / 2 / 8);
-
 	/* Update the sgmsys mode register */
 	regmap_update_bits(mpcs->regmap, SGMSYS_SGMII_MODE,
 			   SGMII_REMOTE_FAULT_DIS | SGMII_SPEED_DUPLEX_AN |
@@ -123,7 +123,7 @@ static int mtk_pcs_config(struct phylink_pcs *pcs, unsigned int mode,
 
 	/* Update the BMCR */
 	regmap_update_bits(mpcs->regmap, SGMSYS_PCS_CONTROL_1,
-			   SGMII_AN_RESTART | SGMII_AN_ENABLE, bmcr);
+			   SGMII_AN_ENABLE, bmcr);
 
 	/* Release PHYA power down state
 	 * Only removing bit SGMII_PHYA_PWD isn't enough.
@@ -137,7 +137,7 @@ static int mtk_pcs_config(struct phylink_pcs *pcs, unsigned int mode,
 	usleep_range(50, 100);
 	regmap_write(mpcs->regmap, SGMSYS_QPHY_PWR_STATE_CTRL, 0);
 
-	return changed;
+	return changed || mode_changed;
 }
 
 static void mtk_pcs_restart_an(struct phylink_pcs *pcs)
Signature · 1 line
2.39.1
#21 lore raw

Re: [PATCH v2 06/11] net: ethernet: mtk_eth_soc: only write values if needed

drivers/net/ethernet/mediatek/mtk_sgmii.c static int mtk_pcs_config(struct phylink_pcs *pcs, unsigned int mode, · line 107

Quoted 8 lines · Daniel Golle
drivers/net/ethernet/mediatek/mtk_sgmii.c +4 -0
@@ -106,16 +101,21 @@ static int mtk_pcs_config(struct phylink_pcs *pcs, unsigned int mode,
 		regmap_update_bits(mpcs->regmap, mpcs->ana_rgc3,
 				   RG_PHY_SPEED_3_125G, rgc3);
 
+		/* Setup the link timer and QPHY power up inside SGMIISYS */
+		link_timer = phylink_get_link_timer_ns(interface);
+		if (link_timer < 0)
+			return link_timer;

I know I asked for this to be placed inside this if(), but I'd prefer it if it were before any register state was touched, so if it returns an error then no register state is affected by the pcs_config() call.

IIRC, we don't touch any state before the if(), so it should be a matter of placing it as one of the first things in the if() block.

Thanks!

Signature · 2 lines
RMK's Patch system: https://www.armlinux.org.uk/developer/patches/
FTTP is here! 40Mbps down 10Mbps up. Decent connectivity at last!
author maintainer
#22 lore raw

PATCH v2 7/11 net: ethernet: mtk_eth_soc: fix RX data corruption issue

In reply to Daniel Golle

Also set bit 12 when setting up MAC MCR, as MediaTek SDK did the same change stating:
"If without this patch, kernel might receive invalid packets that are corrupted by GMAC."[1]
Unfortunately the meaning of bit 12 is not documented in datasheets or vendor code.

[1]: https://git01.mediatek.com/plugins/gitiles/openwrt/feeds/mtk-openwrt-feeds/+/d8a2975939a12686c4a95c40db21efdc3f821f63

---
 drivers/net/ethernet/mediatek/mtk_eth_soc.c | 2 +-
 drivers/net/ethernet/mediatek/mtk_eth_soc.h | 1 +
 2 files changed, 2 insertions(+), 1 deletion(-)
drivers/net/ethernet/mediatek/mtk_eth_soc.c +1 -1
index 4ee582e39c12..aabbf0337589 100644
@@ -615,7 +615,7 @@ static int mtk_mac_finish(struct phylink_config *config, unsigned int mode,
 	/* Setup gmac */
 	mcr_cur = mtk_r32(mac->hw, MTK_MAC_MCR(mac->id));
 	mcr_new = mcr_cur;
-	mcr_new |= MAC_MCR_IPG_CFG | MAC_MCR_FORCE_MODE |
+	mcr_new |= MAC_MCR_IPG_CFG | MAC_MCR_BIT_12 | MAC_MCR_FORCE_MODE |
 		   MAC_MCR_BACKOFF_EN | MAC_MCR_BACKPR_EN | MAC_MCR_FORCE_LINK;
 
 	/* Only update control register when needed! */
drivers/net/ethernet/mediatek/mtk_eth_soc.h +1 -0
index 142def8629c8..084d07c96c04 100644
@@ -404,6 +404,7 @@
 #define MAC_MCR_FORCE_MODE	BIT(15)
 #define MAC_MCR_TX_EN		BIT(14)
 #define MAC_MCR_RX_EN		BIT(13)
+#define MAC_MCR_BIT_12		BIT(12)
 #define MAC_MCR_BACKOFF_EN	BIT(9)
 #define MAC_MCR_BACKPR_EN	BIT(8)
 #define MAC_MCR_FORCE_RX_FC	BIT(5)
Signature · 1 line
2.39.1
author maintainer
#23 lore raw

PATCH v2 8/11 net: ethernet: mtk_eth_soc: ppe: add support for flow accounting

In reply to Daniel Golle

The PPE units found in MT7622 and newer support packet and byte accounting of hw-offloaded flows. Add support for reading those counters as found in MediaTek's SDK[1].

[1]: https://git01.mediatek.com/plugins/gitiles/openwrt/feeds/mtk-openwrt-feeds/+/bc6a6a375c800dc2b80e1a325a2c732d1737df92

---
 drivers/net/ethernet/mediatek/mtk_eth_soc.c   |   8 +-
 drivers/net/ethernet/mediatek/mtk_eth_soc.h   |   1 +
 drivers/net/ethernet/mediatek/mtk_ppe.c       | 114 +++++++++++++++++-
 drivers/net/ethernet/mediatek/mtk_ppe.h       |  25 +++-
 .../net/ethernet/mediatek/mtk_ppe_debugfs.c   |   9 +-
 .../net/ethernet/mediatek/mtk_ppe_offload.c   |   8 ++
 drivers/net/ethernet/mediatek/mtk_ppe_regs.h  |  14 +++
 7 files changed, 170 insertions(+), 9 deletions(-)
drivers/net/ethernet/mediatek/mtk_eth_soc.c +6 -2
index aabbf0337589..97df77c7999e 100644
@@ -4709,8 +4709,8 @@ static int mtk_probe(struct platform_device *pdev)
 		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);
+			eth->ppe[i] = mtk_ppe_init(eth, eth->base + ppe_addr, i);
+
 			if (!eth->ppe[i]) {
 				err = -ENOMEM;
 				goto err_deinit_ppe;
@@ -4832,6 +4832,7 @@ static const struct mtk_soc_data mt7622_data = {
 	.required_pctl = false,
 	.offload_version = 2,
 	.hash_offset = 2,
+	.has_accounting = true,
 	.foe_entry_size = sizeof(struct mtk_foe_entry) - 16,
 	.txrx = {
 		.txd_size = sizeof(struct mtk_tx_dma),
@@ -4869,6 +4870,7 @@ static const struct mtk_soc_data mt7629_data = {
 	.hw_features = MTK_HW_FEATURES,
 	.required_clks = MT7629_CLKS_BITMAP,
 	.required_pctl = false,
+	.has_accounting = true,
 	.txrx = {
 		.txd_size = sizeof(struct mtk_tx_dma),
 		.rxd_size = sizeof(struct mtk_rx_dma),
@@ -4889,6 +4891,7 @@ static const struct mtk_soc_data mt7981_data = {
 	.offload_version = 2,
 	.hash_offset = 4,
 	.foe_entry_size = sizeof(struct mtk_foe_entry),
+	.has_accounting = true,
 	.txrx = {
 		.txd_size = sizeof(struct mtk_tx_dma_v2),
 		.rxd_size = sizeof(struct mtk_rx_dma_v2),
@@ -4909,6 +4912,7 @@ static const struct mtk_soc_data mt7986_data = {
 	.offload_version = 2,
 	.hash_offset = 4,
 	.foe_entry_size = sizeof(struct mtk_foe_entry),
+	.has_accounting = true,
 	.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 +1 -0
index 084d07c96c04..c2e0fd773cc2 100644
@@ -1087,6 +1087,7 @@ struct mtk_soc_data {
 	u8		hash_offset;
 	u16		foe_entry_size;
 	netdev_features_t hw_features;
+	bool		has_accounting;
 	struct {
 		u32	txd_size;
 		u32	rxd_size;
drivers/net/ethernet/mediatek/mtk_ppe.c +111 -3

159 lines not on this page · raw message

drivers/net/ethernet/mediatek/mtk_ppe.h +23 -2
index 5e8bc48252b1..e1aab2e8e262 100644
@@ -57,6 +57,7 @@ enum {
 #define MTK_FOE_IB2_MULTICAST		BIT(8)
 
 #define MTK_FOE_IB2_WDMA_QID2		GENMASK(13, 12)
+#define MTK_FOE_IB2_MIB_CNT		BIT(15)
 #define MTK_FOE_IB2_WDMA_DEVIDX		BIT(16)
 #define MTK_FOE_IB2_WDMA_WINFO		BIT(17)
 
@@ -285,16 +286,34 @@ struct mtk_flow_entry {
 	unsigned long cookie;
 };
 
+struct mtk_mib_entry {
+	u32	byt_cnt_l;
+	u16	byt_cnt_h;
+	u32	pkt_cnt_l;
+	u8	pkt_cnt_h;
+	u8	_rsv0;
+	u32	_rsv1;
+} __packed;
+
+struct mtk_foe_accounting {
+	u64	bytes;
+	u64	packets;
+};
+
 struct mtk_ppe {
 	struct mtk_eth *eth;
 	struct device *dev;
 	void __iomem *base;
 	int version;
 	char dirname[5];
+	bool accounting;
 
 	void *foe_table;
 	dma_addr_t foe_phys;
 
+	struct mtk_mib_entry *mib_table;
+	dma_addr_t mib_phys;
+
 	u16 foe_check_time[MTK_PPE_ENTRIES];
 	struct hlist_head *foe_flow;
 
@@ -303,8 +322,8 @@ struct mtk_ppe {
 	void *acct_table;
 };
 
-struct mtk_ppe *mtk_ppe_init(struct mtk_eth *eth, void __iomem *base,
-			     int version, int index);
+struct mtk_ppe *mtk_ppe_init(struct mtk_eth *eth, void __iomem *base, int index);
+
 void mtk_ppe_deinit(struct mtk_eth *eth);
 void mtk_ppe_start(struct mtk_ppe *ppe);
 int mtk_ppe_stop(struct mtk_ppe *ppe);
@@ -359,5 +378,7 @@ 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 index);
+struct mtk_foe_accounting *mtk_foe_entry_get_mib(struct mtk_ppe *ppe, u32 index,
+						 struct mtk_foe_accounting *diff);
 
 #endif
drivers/net/ethernet/mediatek/mtk_ppe_debugfs.c +7 -2
index 391b071bcff3..53cf87e9acbb 100644
@@ -82,6 +82,7 @@ mtk_ppe_debugfs_foe_show(struct seq_file *m, void *private, bool bind)
 		struct mtk_foe_entry *entry = mtk_foe_get_entry(ppe, i);
 		struct mtk_foe_mac_info *l2;
 		struct mtk_flow_addr_info ai = {};
+		struct mtk_foe_accounting *acct;
 		unsigned char h_source[ETH_ALEN];
 		unsigned char h_dest[ETH_ALEN];
 		int type, state;
@@ -95,6 +96,8 @@ mtk_ppe_debugfs_foe_show(struct seq_file *m, void *private, bool bind)
 		if (bind && state != MTK_FOE_STATE_BIND)
 			continue;
 
+		acct = mtk_foe_entry_get_mib(ppe, i, NULL);
+
 		type = FIELD_GET(MTK_FOE_IB1_PACKET_TYPE, entry->ib1);
 		seq_printf(m, "%05x %s %7s", i,
 			   mtk_foe_entry_state_str(state),
@@ -153,9 +156,11 @@ mtk_ppe_debugfs_foe_show(struct seq_file *m, void *private, bool bind)
 		*((__be16 *)&h_dest[4]) = htons(l2->dest_mac_lo);
 
 		seq_printf(m, " eth=%pM->%pM etype=%04x"
-			      " vlan=%d,%d ib1=%08x ib2=%08x\n",
+			      " vlan=%d,%d ib1=%08x ib2=%08x"
+			      " packets=%llu bytes=%llu\n",
 			   h_source, h_dest, ntohs(l2->etype),
-			   l2->vlan1, l2->vlan2, entry->ib1, ib2);
+			   l2->vlan1, l2->vlan2, entry->ib1, ib2,
+			   acct ? acct->packets : 0, acct ? acct->bytes : 0);
 	}
 
 	return 0;
drivers/net/ethernet/mediatek/mtk_ppe_offload.c +8 -0
index 81afd5ee3fbf..f02ccffb1e79 100644
@@ -497,6 +497,7 @@ static int
 mtk_flow_offload_stats(struct mtk_eth *eth, struct flow_cls_offload *f)
 {
 	struct mtk_flow_entry *entry;
+	struct mtk_foe_accounting diff;
 	u32 idle;
 
 	entry = rhashtable_lookup(&eth->flow_table, &f->cookie,
@@ -507,6 +508,13 @@ mtk_flow_offload_stats(struct mtk_eth *eth, struct flow_cls_offload *f)
 	idle = mtk_foe_entry_idle_time(eth->ppe[entry->ppe_index], entry);
 	f->stats.lastused = jiffies - idle * HZ;
 
+	if (entry->hash != 0xFFFF &&
+	    mtk_foe_entry_get_mib(eth->ppe[entry->ppe_index], entry->hash,
+				  &diff)) {
+		f->stats.pkts += diff.packets;
+		f->stats.bytes += diff.bytes;
+	}
+
 	return 0;
 }
 
drivers/net/ethernet/mediatek/mtk_ppe_regs.h +14 -0
index 0fdb983b0a88..a2e61b3eb006 100644
@@ -149,6 +149,20 @@ enum {
 
 #define MTK_PPE_MIB_TB_BASE			0x338
 
+#define MTK_PPE_MIB_SER_CR			0x33C
+#define MTK_PPE_MIB_SER_CR_ST			BIT(16)
+#define MTK_PPE_MIB_SER_CR_ADDR			GENMASK(13, 0)
+
+#define MTK_PPE_MIB_SER_R0			0x340
+#define MTK_PPE_MIB_SER_R0_BYTE_CNT_LOW		GENMASK(31, 0)
+
+#define MTK_PPE_MIB_SER_R1			0x344
+#define MTK_PPE_MIB_SER_R1_PKT_CNT_LOW		GENMASK(31, 16)
+#define MTK_PPE_MIB_SER_R1_BYTE_CNT_HIGH	GENMASK(15, 0)
+
+#define MTK_PPE_MIB_SER_R2			0x348
+#define MTK_PPE_MIB_SER_R2_PKT_CNT_HIGH		GENMASK(23, 0)
+
 #define MTK_PPE_MIB_CACHE_CTL			0x350
 #define MTK_PPE_MIB_CACHE_CTL_EN		BIT(0)
 #define MTK_PPE_MIB_CACHE_CTL_FLUSH		BIT(2)
Signature · 1 line
2.39.1
author maintainer
#24 lore raw

PATCH v2 9/11 net: pcs: add driver for MediaTek SGMII PCS

In reply to Daniel Golle

The SGMII core found in several MediaTek SoCs is identical to what can also be found in MediaTek's MT7531 Ethernet switch IC.
As this has not always been clear, both drivers developed different implementations to deal with the PCS.

Add a dedicated driver, mostly by copying the code now found in the Ethernet driver. The now redundant code will be removed by a follow-up commit.

---
 MAINTAINERS                       |   7 +
 drivers/net/pcs/Kconfig           |   8 +
 drivers/net/pcs/Makefile          |   1 +
 drivers/net/pcs/pcs-mtk-lynxi.c   | 315 ++++++++++++++++++++++++++++++
 include/linux/pcs/pcs-mtk-lynxi.h |  13 ++
 5 files changed, 344 insertions(+)
 create mode 100644 drivers/net/pcs/pcs-mtk-lynxi.c
 create mode 100644 include/linux/pcs/pcs-mtk-lynxi.h
MAINTAINERS +7 -0
index f76ca2808474..41f4de91a434 100644
@@ -12998,6 +12998,13 @@ L:	[email protected]
 S:	Maintained
 F:	drivers/net/ethernet/mediatek/
 
+MEDIATEK ETHERNET PCS DRIVER
+M:	Daniel Golle <[email protected]>
+L:	[email protected]
+S:	Maintained
+F:	drivers/net/pcs/pcs-mtk-lynxi.c
+F:	include/linux/pcs/pcs-mtk-lynxi.h
+
 MEDIATEK I2C CONTROLLER DRIVER
 M:	Qii Wang <[email protected]>
 L:	[email protected]
drivers/net/pcs/Kconfig +8 -0
index 6e7e6c346a3e..9b792b61c768 100644
@@ -18,6 +18,14 @@ config PCS_LYNX
 	  This module provides helpers to phylink for managing the Lynx PCS
 	  which is part of the Layerscape and QorIQ Ethernet SERDES.
 
+config PCS_MTK_LYNXI
+	tristate
+	select PHYLINK
+	select REGMAP
+	help
+	  This module provides helpers to phylink for managing the LynxI PCS
+	  which is part of MediaTek's SoC and Ethernet switch ICs.
+
 config PCS_RZN1_MIIC
 	tristate "Renesas RZ/N1 MII converter"
 	depends on OF && (ARCH_RZN1 || COMPILE_TEST)
drivers/net/pcs/Makefile +1 -0
index 4c780d8f2e98..9b9afd6b1c22 100644
@@ -5,5 +5,6 @@ pcs_xpcs-$(CONFIG_PCS_XPCS)	:= pcs-xpcs.o pcs-xpcs-nxp.o
 
 obj-$(CONFIG_PCS_XPCS)		+= pcs_xpcs.o
 obj-$(CONFIG_PCS_LYNX)		+= pcs-lynx.o
+obj-$(CONFIG_PCS_MTK_LYNXI)	+= pcs-mtk-lynxi.o
 obj-$(CONFIG_PCS_RZN1_MIIC)	+= pcs-rzn1-miic.o
 obj-$(CONFIG_PCS_ALTERA_TSE)	+= pcs-altera-tse.o
drivers/net/pcs/pcs-mtk-lynxi.c new file +315 -0

315 lines not on this page · raw message

include/linux/pcs/pcs-mtk-lynxi.h new file +13 -0
new file mode 100644
index 000000000000..be3b4ab32f4a
@@ -0,0 +1,13 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef __LINUX_PCS_MTK_LYNXI_H
+#define __LINUX_PCS_MTK_LYNXI_H
+
+#include <linux/phylink.h>
+#include <linux/regmap.h>
+
+#define MTK_SGMII_FLAG_PN_SWAP BIT(0)
+struct phylink_pcs *mtk_pcs_lynxi_create(struct device *dev,
+					 struct regmap *regmap,
+					 u32 ana_rgc3, u32 flags);
+void mtk_pcs_lynxi_destroy(struct phylink_pcs *pcs);
+#endif
Signature · 1 line
2.39.1
#25 lore raw

Re: [PATCH v2 09/11] net: pcs: add driver for MediaTek SGMII PCS

drivers/net/pcs/Kconfig config PCS_LYNX · line 23

Quoted 3 lines · Daniel Golle
drivers/net/pcs/Kconfig +3 -0
+config PCS_MTK_LYNXI
+	tristate
+	select PHYLINK

Does this need to select PHYLINK? If the user of this doesn't already select phylink, then phylink_create() won't be called and thus trying to use PCS_MTK_LYNXI becomes impossible. I know PCS_XPCS does, none of the others do though.

Quoted 38 lines
drivers/net/pcs/Kconfig +5 -0
+	select REGMAP
+	help
+	  This module provides helpers to phylink for managing the LynxI PCS
+	  which is part of MediaTek's SoC and Ethernet switch ICs.
+
 config PCS_RZN1_MIIC
 	tristate "Renesas RZ/N1 MII converter"
 	depends on OF && (ARCH_RZN1 || COMPILE_TEST)
drivers/net/pcs/Makefile +1 -0
index 4c780d8f2e98..9b9afd6b1c22 100644
@@ -5,5 +5,6 @@ pcs_xpcs-$(CONFIG_PCS_XPCS)	:= pcs-xpcs.o pcs-xpcs-nxp.o
 
 obj-$(CONFIG_PCS_XPCS)		+= pcs_xpcs.o
 obj-$(CONFIG_PCS_LYNX)		+= pcs-lynx.o
+obj-$(CONFIG_PCS_MTK_LYNXI)	+= pcs-mtk-lynxi.o
 obj-$(CONFIG_PCS_RZN1_MIIC)	+= pcs-rzn1-miic.o
 obj-$(CONFIG_PCS_ALTERA_TSE)	+= pcs-altera-tse.o
drivers/net/pcs/pcs-mtk-lynxi.c new file +13 -0
new file mode 100644
index 000000000000..0100def53d45
@@ -0,0 +1,315 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (c) 2018-2019 MediaTek Inc.
+/* A library for MediaTek SGMII circuit
+ *
+ * Author: Sean Wang <[email protected]>
+ * Author: Daniel Golle <[email protected]>
+ *
+ */
+#include <linux/mdio.h>
+#include <linux/phylink.h>
+#include <linux/pcs/pcs-mtk-lynxi.h>
+#include <linux/of.h>
+#include <linux/phylink.h>

drivers/net/pcs/pcs-mtk-lynxi.c line 23

Quoted 10 lines
drivers/net/pcs/pcs-mtk-lynxi.c new file +10 -0
+#include <linux/regmap.h>
+
+/* SGMII subsystem config registers */
+/* BMCR (low 16) BMSR (high 16) */
+#define SGMSYS_PCS_CONTROL_1		0x0
+#define SGMII_BMCR			GENMASK(15, 0)
+#define SGMII_BMSR			GENMASK(31, 16)
+#define SGMII_AN_RESTART		BIT(9)
+#define SGMII_ISOLATE			BIT(10)
+#define SGMII_AN_ENABLE			BIT(12)

Not really a review comment but a question: would it be sensible to define these as:

#define SGMII_AN_RESTART BMCR_ANRESTART

etc, since they follow the IEEE802.3 clause 22 register layout?

drivers/net/pcs/pcs-mtk-lynxi.c line 26

Quoted 3 lines
drivers/net/pcs/pcs-mtk-lynxi.c new file +3 -0
+#define SGMII_LINK_STATYS		BIT(18)
+#define SGMII_AN_ABILITY		BIT(19)
+#define SGMII_AN_COMPLETE		BIT(21)

These also correspond to BMSR bits (<<16).

drivers/net/pcs/pcs-mtk-lynxi.c line 28

Quoted 2 lines
drivers/net/pcs/pcs-mtk-lynxi.c new file +2 -0
+#define SGMII_PCS_FAULT			BIT(23)
+#define SGMII_AN_EXPANSION_CLR		BIT(30)

This define doesn't seem to be used.

Quoted 5 lines
drivers/net/pcs/pcs-mtk-lynxi.c new file +5 -0
+
+#define SGMSYS_PCS_DEVICE_ID		0x4
+#define SGMII_LYNXI_DEV_ID		0x4d544950
+
+#define SGMSYS_PCS_ADVERTISE		0x8

drivers/net/pcs/pcs-mtk-lynxi.c line 43

Quoted 10 lines
drivers/net/pcs/pcs-mtk-lynxi.c new file +10 -0
+#define SGMII_ADVERTISE			GENMASK(15, 0)
+#define SGMII_LPA			GENMASK(31, 16)
+
+#define SGMSYS_PCS_SCRATCH		0x14
+#define SGMII_DEV_VERSION		GENMASK(31, 16)
+
+/* Register to programmable link timer, the unit in 2 * 8ns */
+#define SGMSYS_PCS_LINK_TIMER		0x18
+#define SGMII_LINK_TIMER_MASK		GENMASK(19, 0)
+#define SGMII_LINK_TIMER_DEFAULT	(0x186a0 & SGMII_LINK_TIMER_MASK)

We no longer make use of SGMII_LINK_TIMER_DEFAULT, so this can be removed.

Quoted 5 lines
drivers/net/pcs/pcs-mtk-lynxi.c new file +5 -0
+
+/* Register to control remote fault */
+#define SGMSYS_SGMII_MODE		0x20
+#define SGMII_IF_MODE_SGMII		BIT(0)
+#define SGMII_SPEED_DUPLEX_AN		BIT(1)

drivers/net/pcs/pcs-mtk-lynxi.c line 57

Quoted 10 lines
drivers/net/pcs/pcs-mtk-lynxi.c new file +9 -0
+#define SGMII_SPEED_MASK		GENMASK(3, 2)
+#define SGMII_SPEED_10			FIELD_PREP(SGMII_SPEED_MASK, 0)
+#define SGMII_SPEED_100			FIELD_PREP(SGMII_SPEED_MASK, 1)
+#define SGMII_SPEED_1000		FIELD_PREP(SGMII_SPEED_MASK, 2)
+#define SGMII_DUPLEX_HALF		BIT(4)
+#define SGMII_REMOTE_FAULT_DIS		BIT(8)
 
+#define SGMII_CODE_SYNC_SET_VAL		BIT(9)
+#define SGMII_CODE_SYNC_SET_EN		BIT(10)
+#define SGMII_SEND_AN_ERROR_EN		BIT(11)

These three don't appear to be used.

drivers/net/pcs/pcs-mtk-lynxi.c line 64

Quoted 7 lines
drivers/net/pcs/pcs-mtk-lynxi.c new file +7 -0
+
+/* Register to reset SGMII design */
+#define SGMII_RESERVED_0		0x34
+#define SGMII_SW_RESET			BIT(0)
+
+/* Register to set SGMII speed, ANA RG_ Control Signals III */
+#define SGMSYS_ANA_RG_CS3		0x2028

SGMSYS_ANA_RG_CS3 isn't used here, although its register bits below are.

Quoted 4 lines
drivers/net/pcs/pcs-mtk-lynxi.c new file +4 -0
+#define RG_PHY_SPEED_MASK		(BIT(2) | BIT(3))
+#define RG_PHY_SPEED_1_25G		0x0
+#define RG_PHY_SPEED_3_125G		BIT(2)
+

...

drivers/net/pcs/pcs-mtk-lynxi.c line 90

Quoted 3 lines
drivers/net/pcs/pcs-mtk-lynxi.c new file +3 -0
+struct mtk_pcs_lynxi {
+	struct regmap		*regmap;
+	struct device		*dev;

I can only find one place that this is written to in this patch, it seems its otherwise never used. Do we need it?

Other than that, I don't see anything else to comment on that hasn't been mentioned in previous patches. Thanks!

Signature · 2 lines
RMK's Patch system: https://www.armlinux.org.uk/developer/patches/
FTTP is here! 40Mbps down 10Mbps up. Decent connectivity at last!
author maintainer
#26 lore raw

PATCH v2 10/11 net: ethernet: mtk_eth_soc: switch to external PCS driver

In reply to Daniel Golle

Now that we got a PCS driver, use it and remove the now redundant PCS code and it's header macros from the Ethernet driver.

---
 drivers/net/ethernet/mediatek/Kconfig       |   2 +
 drivers/net/ethernet/mediatek/mtk_eth_soc.c |  13 +-
 drivers/net/ethernet/mediatek/mtk_eth_soc.h |  80 +-------
 drivers/net/ethernet/mediatek/mtk_sgmii.c   | 202 +++-----------------
 4 files changed, 38 insertions(+), 259 deletions(-)
drivers/net/ethernet/mediatek/Kconfig +2 -0
index 97374fb3ee79..da0db417ab69 100644
@@ -19,6 +19,8 @@ config NET_MEDIATEK_SOC
 	select DIMLIB
 	select PAGE_POOL
 	select PAGE_POOL_STATS
+	select PCS_MTK_LYNXI
+	select REGMAP_MMIO
 	help
 	  This driver supports the gigabit ethernet MACs in the
 	  MediaTek SoC family.
drivers/net/ethernet/mediatek/mtk_eth_soc.c +10 -3
index 97df77c7999e..54e85f54d7fc 100644
@@ -4077,6 +4077,7 @@ static int mtk_unreg_dev(struct mtk_eth *eth)
 
 static int mtk_cleanup(struct mtk_eth *eth)
 {
+	mtk_sgmii_destroy(eth->sgmii);
 	mtk_unreg_dev(eth);
 	mtk_free_dev(eth);
 	cancel_work_sync(&eth->pending_work);
@@ -4580,6 +4581,7 @@ static int mtk_probe(struct platform_device *pdev)
 		if (!eth->sgmii)
 			return -ENOMEM;
 
+		eth->sgmii->dev = eth->dev;
 		err = mtk_sgmii_init(eth->sgmii, pdev->dev.of_node,
 				     eth->soc->ana_rgc3);
 
@@ -4592,14 +4594,17 @@ static int mtk_probe(struct platform_device *pdev)
 							    "mediatek,pctl");
 		if (IS_ERR(eth->pctl)) {
 			dev_err(&pdev->dev, "no pctl regmap found\n");
-			return PTR_ERR(eth->pctl);
+			err = PTR_ERR(eth->pctl);
+			goto err_destroy_sgmii;
 		}
 	}
 
 	if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) {
 		res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-		if (!res)
-			return -EINVAL;
+		if (!res) {
+			err = -EINVAL;
+			goto err_destroy_sgmii;
+		}
 	}
 
 	if (eth->soc->offload_version) {
@@ -4749,6 +4754,8 @@ static int mtk_probe(struct platform_device *pdev)
 
 	return 0;
 
+err_destroy_sgmii:
+	mtk_sgmii_destroy(eth->sgmii);
 err_deinit_ppe:
 	mtk_ppe_deinit(eth);
 	mtk_mdio_cleanup(eth);
drivers/net/ethernet/mediatek/mtk_eth_soc.h +3 -77

103 lines not on this page · raw message

drivers/net/ethernet/mediatek/mtk_sgmii.c +23 -179

230 lines not on this page · raw message

Signature · 1 line
2.39.1
author maintainer
#27 lore raw

Re: [PATCH v2 10/11] net: ethernet: mtk_eth_soc: switch to external PCS driver

Quoted 361 lines · Daniel Golle

Now that we got a PCS driver, use it and remove the now redundant PCS code and it's header macros from the Ethernet driver.

---
 drivers/net/ethernet/mediatek/Kconfig       |   2 +
 drivers/net/ethernet/mediatek/mtk_eth_soc.c |  13 +-
 drivers/net/ethernet/mediatek/mtk_eth_soc.h |  80 +-------
 drivers/net/ethernet/mediatek/mtk_sgmii.c   | 202 +++-----------------
 4 files changed, 38 insertions(+), 259 deletions(-)
drivers/net/ethernet/mediatek/Kconfig +2 -0
index 97374fb3ee79..da0db417ab69 100644
@@ -19,6 +19,8 @@ config NET_MEDIATEK_SOC
 	select DIMLIB
 	select PAGE_POOL
 	select PAGE_POOL_STATS
+	select PCS_MTK_LYNXI
+	select REGMAP_MMIO
 	help
 	  This driver supports the gigabit ethernet MACs in the
 	  MediaTek SoC family.
drivers/net/ethernet/mediatek/mtk_eth_soc.c +10 -3
index 97df77c7999e..54e85f54d7fc 100644
@@ -4077,6 +4077,7 @@ static int mtk_unreg_dev(struct mtk_eth *eth)
 
 static int mtk_cleanup(struct mtk_eth *eth)
 {
+	mtk_sgmii_destroy(eth->sgmii);
 	mtk_unreg_dev(eth);
 	mtk_free_dev(eth);
 	cancel_work_sync(&eth->pending_work);
@@ -4580,6 +4581,7 @@ static int mtk_probe(struct platform_device *pdev)
 		if (!eth->sgmii)
 			return -ENOMEM;
 
+		eth->sgmii->dev = eth->dev;
 		err = mtk_sgmii_init(eth->sgmii, pdev->dev.of_node,
 				     eth->soc->ana_rgc3);
 
@@ -4592,14 +4594,17 @@ static int mtk_probe(struct platform_device *pdev)
 							    "mediatek,pctl");
 		if (IS_ERR(eth->pctl)) {
 			dev_err(&pdev->dev, "no pctl regmap found\n");
-			return PTR_ERR(eth->pctl);
+			err = PTR_ERR(eth->pctl);
+			goto err_destroy_sgmii;
 		}
 	}
 
 	if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) {
 		res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-		if (!res)
-			return -EINVAL;
+		if (!res) {
+			err = -EINVAL;
+			goto err_destroy_sgmii;
+		}
 	}
 
 	if (eth->soc->offload_version) {
@@ -4749,6 +4754,8 @@ static int mtk_probe(struct platform_device *pdev)
 
 	return 0;
 
+err_destroy_sgmii:
+	mtk_sgmii_destroy(eth->sgmii);
 err_deinit_ppe:
 	mtk_ppe_deinit(eth);
 	mtk_mdio_cleanup(eth);
drivers/net/ethernet/mediatek/mtk_eth_soc.h +3 -77
index c2e0fd773cc2..a72748d80bba 100644
@@ -510,65 +510,6 @@
 #define ETHSYS_DMA_AG_MAP_QDMA	BIT(1)
 #define ETHSYS_DMA_AG_MAP_PPE	BIT(2)
 
-/* SGMII subsystem config registers */
-/* BMCR (low 16) BMSR (high 16) */
-#define SGMSYS_PCS_CONTROL_1	0x0
-#define SGMII_BMCR		GENMASK(15, 0)
-#define SGMII_BMSR		GENMASK(31, 16)
-#define SGMII_AN_RESTART	BIT(9)
-#define SGMII_ISOLATE		BIT(10)
-#define SGMII_AN_ENABLE		BIT(12)
-#define SGMII_LINK_STATYS	BIT(18)
-#define SGMII_AN_ABILITY	BIT(19)
-#define SGMII_AN_COMPLETE	BIT(21)
-#define SGMII_PCS_FAULT		BIT(23)
-#define SGMII_AN_EXPANSION_CLR	BIT(30)
-
-#define SGMSYS_PCS_ADVERTISE	0x8
-#define SGMII_ADVERTISE		GENMASK(15, 0)
-#define SGMII_LPA		GENMASK(31, 16)
-
-/* Register to programmable link timer, the unit in 2 * 8ns */
-#define SGMSYS_PCS_LINK_TIMER	0x18
-#define SGMII_LINK_TIMER_MASK	GENMASK(19, 0)
-#define SGMII_LINK_TIMER_DEFAULT	(0x186a0 & SGMII_LINK_TIMER_MASK)
-
-/* Register to control remote fault */
-#define SGMSYS_SGMII_MODE		0x20
-#define SGMII_IF_MODE_SGMII		BIT(0)
-#define SGMII_SPEED_DUPLEX_AN		BIT(1)
-#define SGMII_SPEED_MASK		GENMASK(3, 2)
-#define SGMII_SPEED_10			FIELD_PREP(SGMII_SPEED_MASK, 0)
-#define SGMII_SPEED_100			FIELD_PREP(SGMII_SPEED_MASK, 1)
-#define SGMII_SPEED_1000		FIELD_PREP(SGMII_SPEED_MASK, 2)
-#define SGMII_DUPLEX_HALF		BIT(4)
-#define SGMII_IF_MODE_BIT5		BIT(5)
-#define SGMII_REMOTE_FAULT_DIS		BIT(8)
-#define SGMII_CODE_SYNC_SET_VAL		BIT(9)
-#define SGMII_CODE_SYNC_SET_EN		BIT(10)
-#define SGMII_SEND_AN_ERROR_EN		BIT(11)
-#define SGMII_IF_MODE_MASK		GENMASK(5, 1)
-
-/* Register to reset SGMII design */
-#define SGMII_RESERVED_0	0x34
-#define SGMII_SW_RESET		BIT(0)
-
-/* Register to set SGMII speed, ANA RG_ Control Signals III*/
-#define SGMSYS_ANA_RG_CS3	0x2028
-#define RG_PHY_SPEED_MASK	(BIT(2) | BIT(3))
-#define RG_PHY_SPEED_1_25G	0x0
-#define RG_PHY_SPEED_3_125G	BIT(2)
-
-/* Register to power up QPHY */
-#define SGMSYS_QPHY_PWR_STATE_CTRL 0xe8
-#define	SGMII_PHYA_PWD		BIT(4)
-
-/* Register to QPHY wrapper control */
-#define SGMSYS_QPHY_WRAP_CTRL	0xec
-#define SGMII_PN_SWAP_MASK	GENMASK(1, 0)
-#define SGMII_PN_SWAP_TX_RX	(BIT(0) | BIT(1))
-#define MTK_SGMII_FLAG_PN_SWAP	BIT(0)
-
 /* Infrasys subsystem config registers */
 #define INFRA_MISC2            0x70c
 #define CO_QPHY_SEL            BIT(0)
@@ -1103,29 +1044,13 @@ struct mtk_soc_data {
 /* currently no SoC has more than 2 macs */
 #define MTK_MAX_DEVS			2
 
-/* struct mtk_pcs -    This structure holds each sgmii regmap and associated
- *                     data
- * @regmap:            The register map pointing at the range used to setup
- *                     SGMII modes
- * @ana_rgc3:          The offset refers to register ANA_RGC3 related to regmap
- * @interface:         Currently configured interface mode
- * @pcs:               Phylink PCS structure
- * @flags:             Flags indicating hardware properties
- */
-struct mtk_pcs {
-	struct regmap	*regmap;
-	u32             ana_rgc3;
-	phy_interface_t	interface;
-	struct phylink_pcs pcs;
-	u32		flags;
-};
-
 /* struct mtk_sgmii -  This is the structure holding sgmii regmap and its
  *                     characteristics
  * @pcs                Array of individual PCS structures
  */
 struct mtk_sgmii {
-	struct mtk_pcs	pcs[MTK_MAX_DEVS];
+	struct phylink_pcs *pcs[MTK_MAX_DEVS];
+	struct device *dev;
 };
 
 /* struct mtk_eth -	This is the main datasructure for holding the state
@@ -1353,6 +1278,7 @@ u32 mtk_r32(struct mtk_eth *eth, unsigned reg);
 struct phylink_pcs *mtk_sgmii_select_pcs(struct mtk_sgmii *ss, int id);
 int mtk_sgmii_init(struct mtk_sgmii *ss, struct device_node *np,
 		   u32 ana_rgc3);
+void mtk_sgmii_destroy(struct mtk_sgmii *ss);
 
 int mtk_gmac_sgmii_path_setup(struct mtk_eth *eth, int mac_id);
 int mtk_gmac_gephy_path_setup(struct mtk_eth *eth, int mac_id);
drivers/net/ethernet/mediatek/mtk_sgmii.c +1 -164
index 9c58006d1c33..d4b428e23cfc 100644
@@ -10,199 +10,35 @@
 #include <linux/mfd/syscon.h>
 #include <linux/of.h>
 #include <linux/phylink.h>
+#include <linux/pcs/pcs-mtk-lynxi.h>
 #include <linux/regmap.h>
 
 #include "mtk_eth_soc.h"
 
-static struct mtk_pcs *pcs_to_mtk_pcs(struct phylink_pcs *pcs)
-{
-	return container_of(pcs, struct mtk_pcs, pcs);
-}
-
-static void mtk_pcs_get_state(struct phylink_pcs *pcs,
-			      struct phylink_link_state *state)
-{
-	struct mtk_pcs *mpcs = pcs_to_mtk_pcs(pcs);
-	unsigned int bm, adv;
-
-	/* Read the BMSR and LPA */
-	regmap_read(mpcs->regmap, SGMSYS_PCS_CONTROL_1, &bm);
-	regmap_read(mpcs->regmap, SGMSYS_PCS_ADVERTISE, &adv);
-
-	phylink_mii_c22_pcs_decode_state(state, FIELD_GET(SGMII_BMSR, bm),
-					 FIELD_GET(SGMII_LPA, adv));
-}
-
-static int mtk_pcs_config(struct phylink_pcs *pcs, unsigned int mode,
-			  phy_interface_t interface,
-			  const unsigned long *advertising,
-			  bool permit_pause_to_mac)
-{
-	bool mode_changed = false, changed, use_an;
-	struct mtk_pcs *mpcs = pcs_to_mtk_pcs(pcs);
-	unsigned int rgc3, sgm_mode, bmcr;
-	int advertise, link_timer;
-
-	advertise = phylink_mii_c22_pcs_encode_advertisement(interface,
-							     advertising);
-	if (advertise < 0)
-		return advertise;
-
-	/* Clearing IF_MODE_BIT0 switches the PCS to BASE-X mode, and
-	 * we assume that fixes it's speed at bitrate = line rate (in
-	 * other words, 1000Mbps or 2500Mbps).
-	 */
-	if (interface == PHY_INTERFACE_MODE_SGMII) {
-		sgm_mode = SGMII_IF_MODE_SGMII;
-		if (phylink_autoneg_inband(mode)) {
-			sgm_mode |= SGMII_REMOTE_FAULT_DIS |
-				    SGMII_SPEED_DUPLEX_AN;
-			use_an = true;
-		} else {
-			use_an = false;
-		}
-	} else if (phylink_autoneg_inband(mode)) {
-		/* 1000base-X or 2500base-X autoneg */
-		sgm_mode = SGMII_REMOTE_FAULT_DIS;
-		use_an = linkmode_test_bit(ETHTOOL_LINK_MODE_Autoneg_BIT,
-					   advertising);
-	} else {
-		/* 1000base-X or 2500base-X without autoneg */
-		sgm_mode = 0;
-		use_an = false;
-	}
-
-	if (use_an) {
-		bmcr = SGMII_AN_ENABLE;
-	} else {
-		bmcr = 0;
-	}
-
-	if (mpcs->interface != interface) {
-		/* PHYA power down */
-		regmap_update_bits(mpcs->regmap, SGMSYS_QPHY_PWR_STATE_CTRL,
-				   SGMII_PHYA_PWD, SGMII_PHYA_PWD);
-
-		/* Reset SGMII PCS state */
-		regmap_update_bits(mpcs->regmap, SGMII_RESERVED_0,
-				   SGMII_SW_RESET, SGMII_SW_RESET);
-
-		if (mpcs->flags & MTK_SGMII_FLAG_PN_SWAP)
-			regmap_update_bits(mpcs->regmap, SGMSYS_QPHY_WRAP_CTRL,
-					   SGMII_PN_SWAP_MASK,
-					   SGMII_PN_SWAP_TX_RX);
-
-		if (interface == PHY_INTERFACE_MODE_2500BASEX)
-			rgc3 = RG_PHY_SPEED_3_125G;
-		else
-			rgc3 = 0;
-
-		/* Configure the underlying interface speed */
-		regmap_update_bits(mpcs->regmap, mpcs->ana_rgc3,
-				   RG_PHY_SPEED_3_125G, rgc3);
-
-		/* Setup the link timer and QPHY power up inside SGMIISYS */
-		link_timer = phylink_get_link_timer_ns(interface);
-		if (link_timer < 0)
-			return link_timer;
-
-		regmap_write(mpcs->regmap, SGMSYS_PCS_LINK_TIMER, link_timer / 2 / 8);
-
-		mpcs->interface = interface;
-		mode_changed = true;
-	}
-
-	/* Update the advertisement, noting whether it has changed */
-	regmap_update_bits_check(mpcs->regmap, SGMSYS_PCS_ADVERTISE,
-				 SGMII_ADVERTISE, advertise, &changed);
-
-	/* Update the sgmsys mode register */
-	regmap_update_bits(mpcs->regmap, SGMSYS_SGMII_MODE,
-			   SGMII_REMOTE_FAULT_DIS | SGMII_SPEED_DUPLEX_AN |
-			   SGMII_IF_MODE_SGMII, sgm_mode);
-
-	/* Update the BMCR */
-	regmap_update_bits(mpcs->regmap, SGMSYS_PCS_CONTROL_1,
-			   SGMII_AN_ENABLE, bmcr);
-
-	/* Release PHYA power down state
-	 * Only removing bit SGMII_PHYA_PWD isn't enough.
-	 * There are cases when the SGMII_PHYA_PWD register contains 0x9 which
-	 * prevents SGMII from working. The SGMII still shows link but no traffic
-	 * can flow. Writing 0x0 to the PHYA_PWD register fix the issue. 0x0 was
-	 * taken from a good working state of the SGMII interface.
-	 * Unknown how much the QPHY needs but it is racy without a sleep.
-	 * Tested on mt7622 & mt7986.
-	 */
-	usleep_range(50, 100);
-	regmap_write(mpcs->regmap, SGMSYS_QPHY_PWR_STATE_CTRL, 0);
-
-	return changed || mode_changed;
-}
-
-static void mtk_pcs_restart_an(struct phylink_pcs *pcs)
-{
-	struct mtk_pcs *mpcs = pcs_to_mtk_pcs(pcs);
-
-	regmap_update_bits(mpcs->regmap, SGMSYS_PCS_CONTROL_1,
-			   SGMII_AN_RESTART, SGMII_AN_RESTART);
-}
-
-static void mtk_pcs_link_up(struct phylink_pcs *pcs, unsigned int mode,
-			    phy_interface_t interface, int speed, int duplex)
-{
-	struct mtk_pcs *mpcs = pcs_to_mtk_pcs(pcs);
-	unsigned int sgm_mode;
-
-	if (!phylink_autoneg_inband(mode)) {
-		/* Force the speed and duplex setting */
-		if (speed == SPEED_10)
-			sgm_mode = SGMII_SPEED_10;
-		else if (speed == SPEED_100)
-			sgm_mode = SGMII_SPEED_100;
-		else
-			sgm_mode = SGMII_SPEED_1000;
-
-		if (duplex != DUPLEX_FULL)
-			sgm_mode |= SGMII_DUPLEX_HALF;
-
-		regmap_update_bits(mpcs->regmap, SGMSYS_SGMII_MODE,
-				   SGMII_DUPLEX_HALF | SGMII_SPEED_MASK,
-				   sgm_mode);
-	}
-}
-
-static const struct phylink_pcs_ops mtk_pcs_ops = {
-	.pcs_get_state = mtk_pcs_get_state,
-	.pcs_config = mtk_pcs_config,
-	.pcs_an_restart = mtk_pcs_restart_an,
-	.pcs_link_up = mtk_pcs_link_up,
-};

drivers/net/ethernet/mediatek/mtk_sgmii.c line 25

Quoted 10 lines
drivers/net/ethernet/mediatek/mtk_sgmii.c +3 -2
-
 int mtk_sgmii_init(struct mtk_sgmii *ss, struct device_node *r, u32 ana_rgc3)
 {
 	struct device_node *np;
+	struct regmap *regmap;
+	u32 flags;
 	int i;
 
-	for (i = 0; i < MTK_MAX_DEVS; i++) {
+	for (i = 0; id < MTK_MAX_DEVS; i++) {

This change was unintentional and will break the build. I've fixed it for my test builds, but forgot to commit it before sending out the series. Please discard for now.

Quoted 53 lines
drivers/net/ethernet/mediatek/mtk_sgmii.c +19 -13
 		np = of_parse_phandle(r, "mediatek,sgmiisys", i);
 		if (!np)
 			break;
 
-		ss->pcs[i].ana_rgc3 = ana_rgc3;
-		ss->pcs[i].regmap = syscon_node_to_regmap(np);
-
-		ss->pcs[i].flags = 0;
+		regmap = syscon_node_to_regmap(np);
+		flags = 0;
 		if (of_property_read_bool(np, "mediatek,pn_swap"))
-			ss->pcs[i].flags |= MTK_SGMII_FLAG_PN_SWAP;
+			flags |= MTK_SGMII_FLAG_PN_SWAP;
 
 		of_node_put(np);
-		if (IS_ERR(ss->pcs[i].regmap))
-			return PTR_ERR(ss->pcs[i].regmap);
 
-		ss->pcs[i].pcs.ops = &mtk_pcs_ops;
-		ss->pcs[i].pcs.poll = true;
-		ss->pcs[i].interface = PHY_INTERFACE_MODE_NA;
+		if (IS_ERR(regmap))
+			return PTR_ERR(regmap);
+
+		ss->pcs[i] = mtk_pcs_lynxi_create(ss->dev, regmap, ana_rgc3,
+						  flags);
 	}
 
 	return 0;
@@ -210,8 +46,16 @@ int mtk_sgmii_init(struct mtk_sgmii *ss, struct device_node *r, u32 ana_rgc3)
 
 struct phylink_pcs *mtk_sgmii_select_pcs(struct mtk_sgmii *ss, int id)
 {
-	if (!ss->pcs[id].regmap)
-		return NULL;
+	return ss->pcs[id];
+}
+
+void mtk_sgmii_destroy(struct mtk_sgmii *ss)
+{
+	int i;
+
+	if (!ss)
+		return;
 
-	return &ss->pcs[id].pcs;
+	for (i = 0; i < MTK_MAX_DEVS; i++)
+		mtk_pcs_lynxi_destroy(ss->pcs[i]);
 }
Signature · 1 line
2.39.1
author maintainer
#28 lore raw

PATCH v2 11/11 net: dsa: mt7530: use external PCS driver

In reply to Daniel Golle

Implement regmap access wrappers, for now only to be used by the pcs-mtk driver.
Make use of external PCS driver and drop the reduntant implementation in mt7530.c.
As a nice side effect the SGMII registers can now also more easily be inspected for debugging via /sys/kernel/debug/regmap.

---
 drivers/net/dsa/Kconfig  |   1 +
 drivers/net/dsa/mt7530.c | 277 ++++++++++-----------------------------
 drivers/net/dsa/mt7530.h |  47 +------
 3 files changed, 71 insertions(+), 254 deletions(-)
drivers/net/dsa/Kconfig +1 -0
index f6f3b43dfb06..6b45fa8b6907 100644
@@ -38,6 +38,7 @@ config NET_DSA_MT7530
 	tristate "MediaTek MT7530 and MT7531 Ethernet switch support"
 	select NET_DSA_TAG_MTK
 	select MEDIATEK_GE_PHY
+	select PCS_MTK_LYNXI
 	help
 	  This enables support for the MediaTek MT7530 and MT7531 Ethernet
 	  switch chips. Multi-chip module MT7530 in MT7621AT, MT7621DAT,
drivers/net/dsa/mt7530.c +66 -211

360 lines not on this page · raw message

drivers/net/dsa/mt7530.h +4 -43

64 lines not on this page · raw message

Signature · 1 line
2.39.1
#29 lore raw

Re: [PATCH v2 11/11] net: dsa: mt7530: use external PCS driver

drivers/net/dsa/mt7530.c mt753x_phylink_mac_select_pcs(struct dsa_switch *ds, int port, · line 2619

Quoted 11 lines · Daniel Golle
drivers/net/dsa/mt7530.c +2 -2
@@ -2728,11 +2612,11 @@ mt753x_phylink_mac_select_pcs(struct dsa_switch *ds, int port,
 
 	switch (interface) {
 	case PHY_INTERFACE_MODE_TRGMII:
+		return &priv->pcs[port].pcs;
 	case PHY_INTERFACE_MODE_SGMII:
 	case PHY_INTERFACE_MODE_1000BASEX:
 	case PHY_INTERFACE_MODE_2500BASEX:
-		return &priv->pcs[port].pcs;
-
+		return priv->ports[port].sgmii_pcs;

My only concern here is that we also use the PCS when in TRGMII mode in this driver, but the mtk pcs code from mtk_eth_soc doesn't handle TRGMII (and getting the link timer will fail for this mode, causing the pcs_config() method to fail.)

Thus, this driver will stop working in TRGMII mode.

Signature · 2 lines
RMK's Patch system: https://www.armlinux.org.uk/developer/patches/
FTTP is here! 40Mbps down 10Mbps up. Decent connectivity at last!
author maintainer
#30 lore raw

Re: [PATCH v2 11/11] net: dsa: mt7530: use external PCS driver

Quoted 6 lines · Russell King (Oracle)

drivers/net/dsa/mt7530.c mt753x_phylink_mac_select_pcs(struct dsa_switch *ds, int port, · line 2615

Quoted 5 lines · Daniel Golle
drivers/net/dsa/mt7530.c +1 -0
@@ -2728,11 +2612,11 @@ mt753x_phylink_mac_select_pcs(struct dsa_switch *ds, int port,
 
 	switch (interface) {
 	case PHY_INTERFACE_MODE_TRGMII:
+		return &priv->pcs[port].pcs;
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Quoted 6 lines

drivers/net/dsa/mt7530.c mt753x_phylink_mac_select_pcs(struct dsa_switch *ds, int port, · line 2619

Quoted 6 lines
drivers/net/dsa/mt7530.c +1 -2
 	case PHY_INTERFACE_MODE_SGMII:
 	case PHY_INTERFACE_MODE_1000BASEX:
 	case PHY_INTERFACE_MODE_2500BASEX:
-		return &priv->pcs[port].pcs;
-
+		return priv->ports[port].sgmii_pcs;
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Quoted 7 lines

My only concern here is that we also use the PCS when in TRGMII mode in this driver, but the mtk pcs code from mtk_eth_soc doesn't handle TRGMII (and getting the link timer will fail for this mode, causing the pcs_config() method to fail.)

Thus, this driver will stop working in TRGMII mode.

But in TRGMII mode we return &priv->pcs[port].pcs which is not the PCS code from mtk_eth_soc now moved to the new pcs-mtk-lynxi driver, but rather the old existing codepath from mt7530.c.

The new PCS driver only replaces mt7531_sgmii_pcs_* functions, which were all nearly identical with what is now in pcs-mtk-lynxi.c.

Or do I miss something here?

author maintainer
#31 lore raw

Re: [PATCH v2 11/11] net: dsa: mt7530: use external PCS driver

In reply to Russell King (Oracle)
Quoted 18 lines · Russell King (Oracle)

drivers/net/dsa/mt7530.c mt753x_phylink_mac_select_pcs(struct dsa_switch *ds, int port, · line 2619

Quoted 11 lines · Daniel Golle
drivers/net/dsa/mt7530.c +2 -2
@@ -2728,11 +2612,11 @@ mt753x_phylink_mac_select_pcs(struct dsa_switch *ds, int port,
 
 	switch (interface) {
 	case PHY_INTERFACE_MODE_TRGMII:
+		return &priv->pcs[port].pcs;
 	case PHY_INTERFACE_MODE_SGMII:
 	case PHY_INTERFACE_MODE_1000BASEX:
 	case PHY_INTERFACE_MODE_2500BASEX:
-		return &priv->pcs[port].pcs;
-
+		return priv->ports[port].sgmii_pcs;

My only concern here is that we also use the PCS when in TRGMII mode in this driver, but the mtk pcs code from mtk_eth_soc doesn't handle TRGMII (and getting the link timer will fail for this mode, causing the pcs_config() method to fail.)

Quoted 1 line

Thus, this driver will stop working in TRGMII mode.

I've just built and tested this on MT7623 BPi-R2 board with MT7530 connnected to SoC via TRGMII and observed that it all works fine.

However, on this platform we could safe some bytes by still allowing mt7530.c to be built without pcs-mtk-lynxi which isn't used on MT7623 by either the ethernet or the switch driver.

To me this is not a priority, and doing that would involve adding some ifdef'ery which isn't really nice. However, if anyone has a strong opinion in favor of allowing mt7530.c (or even mtk_eth_soc) to be built without pcs-mtk-lynxi, let me know and I will make the necessary changes.