Thread (4 messages) 4 messages, 3 authors, 2020-07-01

Re: [PATCH RFC net-next] net: mtk_eth_soc: use resolved link config for PCS PHY

From: René van Dorst <hidden>
Date: 2020-06-30 22:15:11
Also in: linux-arm-kernel, linux-mediatek

Hi Russel and Sean,

Quoting Russell King - ARM Linux admin [off-list ref]:
On Tue, Jun 30, 2020 at 11:15:42AM +0100, Russell King wrote:
quoted
The SGMII PCS PHY needs to be updated with the link configuration in
the mac_link_up() call rather than in mac_config().  However,
mtk_sgmii_setup_mode_force() programs the SGMII block during
mac_config() when using 802.3z interface modes with the link
configuration.

Split that functionality from mtk_sgmii_setup_mode_force(), moving it
to a new mtk_sgmii_link_up() function, and call it from mac_link_up().

This does not look correct to me: 802.3z modes operate at a fixed
speed.  The contents of mtk_sgmii_link_up() look more appropriate for
SGMII mode, but the original code definitely did not call
mtk_sgmii_setup_mode_force() for SGMII mode but only 802.3z mode.

Signed-off-by: Russell King <redacted>
---
René, can you assist with this patch please - I really think there are
problems with the existing code.  You call mtk_sgmii_setup_mode_force()
in a block which is conditionalised as:

	if (state->interface == PHY_INTERFACE_MODE_SGMII ||
	    phy_interface_mode_is_8023z(state->interface)) {
...
		if (state->interface != PHY_INTERFACE_MODE_SGMII)
			err = mtk_sgmii_setup_mode_force(eth->sgmii, sid,
							 state);

Hence, mtk_sgmii_setup_mode_force() is only called for 1000BASE-X and
2500BASE-X, which do not support anything but their native speeds.
Yet, mtk_sgmii_setup_mode_force() tries to program the SGMII for 10M
and 100M.

Note that this patch is more about moving uses of state->{speed,duplex}
into mac_link_up(), rather than fixing this problem, but I don't think
the addition in mtk_mac_link_up(), nor mtk_sgmii_link_up() is of any
use.
My Coccinelle script just found this use of state->{speed,duplex} still
remaining:

                        if (MTK_HAS_CAPS(mac->hw->soc->caps,
                                         MTK_TRGMII_MT7621_CLK)) {
...
                        } else {
                                if (state->interface !=
                                    PHY_INTERFACE_MODE_TRGMII)
                                        mtk_gmac0_rgmii_adjust(mac->hw,
                                                               state->speed);

which also needs to be eliminated.  Can that also be moved to
mtk_mac_link_up()?
I know, you have pointed that out before. But I don't know how to fix
mtk_gmac0_rgmii_adjust(). This function changes the PLL of the MAC.  
But without
documentation I am not sure what all the bits are used for.

Begin April I had a conversation with Sean about this. I also  
explained what the
issue was. AFAIK he was going to take care of this issue.

Sean did you had time to resolve this issue?

Greats,

René
Thanks.
quoted
Thanks.

 drivers/net/ethernet/mediatek/mtk_eth_soc.c |  9 ++++-
 drivers/net/ethernet/mediatek/mtk_eth_soc.h |  3 +-
 drivers/net/ethernet/mediatek/mtk_sgmii.c   | 37 +++++++++++++++------
 3 files changed, 36 insertions(+), 13 deletions(-)
diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.c  
b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
index 20db302d31ce..ef9ec3b6a5c8 100644
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
@@ -326,7 +326,7 @@ static void mtk_mac_config(struct  
phylink_config *config, unsigned int mode,
 		/* Setup SGMIISYS with the determined property */
 		if (state->interface != PHY_INTERFACE_MODE_SGMII)
 			err = mtk_sgmii_setup_mode_force(eth->sgmii, sid,
-							 state);
+							 state->interface);
 		else if (phylink_autoneg_inband(mode))
 			err = mtk_sgmii_setup_mode_an(eth->sgmii, sid);
@@ -423,6 +423,13 @@ static void mtk_mac_link_up(struct  
phylink_config *config,
 					   phylink_config);
 	u32 mcr = mtk_r32(mac->hw, MTK_MAC_MCR(mac->id));

+	if (phy_interface_mode_is_8023z(interface)) {
+		/* Decide how GMAC and SGMIISYS be mapped */
+		int sid = (MTK_HAS_CAPS(eth->soc->caps, MTK_SHARED_SGMII)) ?
+			   0 : mac->id;
+		mtk_sgmii_link_up(eth->sgmii, sid, speed, duplex);
+	}
+
 	mcr &= ~(MAC_MCR_SPEED_100 | MAC_MCR_SPEED_1000 |
 		 MAC_MCR_FORCE_DPX | MAC_MCR_FORCE_TX_FC |
 		 MAC_MCR_FORCE_RX_FC);
diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.h  
b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
index 454cfcd465fd..6f4b99bb7bfb 100644
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
@@ -932,7 +932,8 @@ int mtk_sgmii_init(struct mtk_sgmii *ss, struct  
device_node *np,
 		   u32 ana_rgc3);
 int mtk_sgmii_setup_mode_an(struct mtk_sgmii *ss, int id);
 int mtk_sgmii_setup_mode_force(struct mtk_sgmii *ss, int id,
-			       const struct phylink_link_state *state);
+			       phy_interface_t interface);
+void mtk_sgmii_link_up(struct mtk_sgmii *ss, int id, int speed,  
int duplex);
 void mtk_sgmii_restart_an(struct mtk_eth *eth, int mac_id);

 int mtk_gmac_sgmii_path_setup(struct mtk_eth *eth, int mac_id);
diff --git a/drivers/net/ethernet/mediatek/mtk_sgmii.c  
b/drivers/net/ethernet/mediatek/mtk_sgmii.c
index 32d83421226a..372c85c830b5 100644
--- a/drivers/net/ethernet/mediatek/mtk_sgmii.c
+++ b/drivers/net/ethernet/mediatek/mtk_sgmii.c
@@ -60,7 +60,7 @@ int mtk_sgmii_setup_mode_an(struct mtk_sgmii *ss, int id)
 }

 int mtk_sgmii_setup_mode_force(struct mtk_sgmii *ss, int id,
-			       const struct phylink_link_state *state)
+			       phy_interface_t interface)
 {
 	unsigned int val;
@@ -69,7 +69,7 @@ int mtk_sgmii_setup_mode_force(struct mtk_sgmii  
*ss, int id,

 	regmap_read(ss->regmap[id], ss->ana_rgc3, &val);
 	val &= ~RG_PHY_SPEED_MASK;
-	if (state->interface == PHY_INTERFACE_MODE_2500BASEX)
+	if (interface == PHY_INTERFACE_MODE_2500BASEX)
 		val |= RG_PHY_SPEED_3_125G;
 	regmap_write(ss->regmap[id], ss->ana_rgc3, val);
@@ -78,11 +78,33 @@ int mtk_sgmii_setup_mode_force(struct mtk_sgmii  
*ss, int id,
 	val &= ~SGMII_AN_ENABLE;
 	regmap_write(ss->regmap[id], SGMSYS_PCS_CONTROL_1, val);

+	if (interface == PHY_INTERFACE_MODE_1000BASEX ||
+	    interface == PHY_INTERFACE_MODE_2500BASEX) {
+		/* SGMII force mode setting */
+		regmap_read(ss->regmap[id], SGMSYS_SGMII_MODE, &val);
+		val &= ~SGMII_IF_MODE_MASK;
+		val |= SGMII_SPEED_1000;
+		val |= SGMII_DUPLEX_FULL;
+		regmap_write(ss->regmap[id], SGMSYS_SGMII_MODE, val);
+	}
+
+	/* Release PHYA power down state */
+	regmap_read(ss->regmap[id], SGMSYS_QPHY_PWR_STATE_CTRL, &val);
+	val &= ~SGMII_PHYA_PWD;
+	regmap_write(ss->regmap[id], SGMSYS_QPHY_PWR_STATE_CTRL, val);
+
+	return 0;
+}
+
+void mtk_sgmii_link_up(struct mtk_sgmii *ss, int id, int speed, int duplex)
+{
+	unsigned int val;
+
 	/* SGMII force mode setting */
 	regmap_read(ss->regmap[id], SGMSYS_SGMII_MODE, &val);
 	val &= ~SGMII_IF_MODE_MASK;

-	switch (state->speed) {
+	switch (speed) {
 	case SPEED_10:
 		val |= SGMII_SPEED_10;
 		break;
@@ -95,17 +117,10 @@ int mtk_sgmii_setup_mode_force(struct  
mtk_sgmii *ss, int id,
 		break;
 	}

-	if (state->duplex == DUPLEX_FULL)
+	if (duplex == DUPLEX_FULL)
 		val |= SGMII_DUPLEX_FULL;

 	regmap_write(ss->regmap[id], SGMSYS_SGMII_MODE, val);
-
-	/* Release PHYA power down state */
-	regmap_read(ss->regmap[id], SGMSYS_QPHY_PWR_STATE_CTRL, &val);
-	val &= ~SGMII_PHYA_PWD;
-	regmap_write(ss->regmap[id], SGMSYS_QPHY_PWR_STATE_CTRL, val);
-
-	return 0;
 }

 void mtk_sgmii_restart_an(struct mtk_eth *eth, int mac_id)
--
2.20.1
--
RMK's Patch system: https://www.armlinux.org.uk/developer/patches/
FTTP is here! 40Mbps down 10Mbps up. Decent connectivity at last!

Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help