From: hucheng cheng.hu911@gmail.com
Subject: [PATCH] net: stmmac: dwmac-rk: fix SGMII 10M/100M speed configuration for RK3568
When using the SGMII interface on the Rockchip RK3568 platform, the network link
works fine at 1000M speed. However, when the link speed negotiates down to 10M
or 100M, the Ethernet link fails or cannot transfer packets properly.
I've reported this issue to you before.
This is because the dynamic link speed change callback rk_fix_speed() only handles
RGMII and RMII modes, leaving the internal XPCS (Physical Coding Sublayer) MII_BMCR
register unconfigured for SGMII mode when the link rate changes.
Fix this by introducing a set_sgmii_speed callback for RK3568. When the link
speed changes, it dynamically updates the MII_BMCR register of the XPCS via
xpcs_write() to match the negotiated speed (10M/100M/1000M).
Fixes: 22e1b8b871c5 ("net: stmmac: dwmac-rk: Add SGMII and QSGMII support for RK3568")
Signed-off-by: hucheng cheng.hu911@gmail.com
drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c | 37 +++++++++++++++++-
1 file changed, 35 insertions(+), 2 deletions(-)
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c
index c73d14723..4cd6b94dc 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c
@@ -40,6 +40,7 @@ struct rk_gmac_ops {
void (*set_to_qsgmii)(struct rk_priv_data *bsp_priv);
void (*set_rgmii_speed)(struct rk_priv_data *bsp_priv, int speed);
void (*set_rmii_speed)(struct rk_priv_data *bsp_priv, int speed);
- void (*set_sgmii_speed)(struct rk_priv_data *bsp_priv, int speed);
void (*set_clock_selection)(struct rk_priv_data *bsp_priv, bool input,
bool enable);
void (*integrated_phy_power)(struct rk_priv_data *bsp_priv, bool up);
@@ -200,10 +202,10 @@ static int xpcs_setup(struct rk_priv_data *bsp_priv, int mode)
SR_MII_CTRL_AN_ENABLE);
}
} else {
-
val = xpcs_read(bsp_priv, SR_MII_OFFSET(id) + VR_MII_DIG_CTRL1);
-
xpcs_write(bsp_priv, SR_MII_OFFSET(id) + VR_MII_DIG_CTRL1,
-
val = xpcs_read(bsp_priv, SR_MII_OFFSET(0) + VR_MII_DIG_CTRL1);
-
xpcs_write(bsp_priv, SR_MII_OFFSET(0) + VR_MII_DIG_CTRL1,
val | MII_MAC_AUTO_SW);
-
xpcs_write(bsp_priv, SR_MII_OFFSET(id) + MII_BMCR,
-
xpcs_write(bsp_priv, SR_MII_OFFSET(0) + MII_BMCR,
SR_MII_CTRL_AN_ENABLE);
}
@@ -1888,7 +1890,33 @@ static void rk3568_set_gmac_speed(struct rk_priv_data *bsp_priv, int speed)
dev_err(dev, "%s: set clk_mac_speed rate %ld failed %d\n",
func, rate, ret);
}
+static void rk3568_set_gmac_sgmii_speed(struct rk_priv_data *bsp_priv, int speed)
+{
- struct device *dev = &bsp_priv->pdev->dev;
- unsigned int ctrl;
- /* Only gmac1 supports SGMII speed configuration for port1 */
- if (!bsp_priv->id)
-
- switch (speed) {
- case 10:
-
-
- case 100:
-
-
- case 1000:
-
-
- default:
-
dev_err(dev, "unknown speed value for GMAC speed=%d\n", speed);
-
- }
- xpcs_write(bsp_priv, SR_MII_OFFSET(bsp_priv->id) + MII_BMCR,
-
+}
+
static const struct rk_gmac_ops rk3568_ops = {
.set_to_rgmii = rk3568_set_to_rgmii,
.set_to_rmii = rk3568_set_to_rmii,
@@ -1896,6 +1924,7 @@ static const struct rk_gmac_ops rk3568_ops = {
.set_to_qsgmii = rk3568_set_to_qsgmii,
.set_rgmii_speed = rk3568_set_gmac_speed,
.set_rmii_speed = rk3568_set_gmac_speed,
- .set_sgmii_speed = rk3568_set_gmac_sgmii_speed,
.regs_valid = true,
.regs = {
0xfe2a0000, /* gmac0 */
@@ -2910,6 +2939,9 @@ static void rk_fix_speed(void *priv, unsigned int speed)
bsp_priv->ops->set_rmii_speed(bsp_priv, speed);
break;
case PHY_INTERFACE_MODE_SGMII:
-
if (bsp_priv->ops && bsp_priv->ops->set_sgmii_speed)
-
bsp_priv->ops->set_sgmii_speed(bsp_priv, speed);
-
case PHY_INTERFACE_MODE_QSGMII:
break;
default:
--
From: hucheng cheng.hu911@gmail.com
Subject: [PATCH] net: stmmac: dwmac-rk: fix SGMII 10M/100M speed configuration for RK3568
When using the SGMII interface on the Rockchip RK3568 platform, the network link
works fine at 1000M speed. However, when the link speed negotiates down to 10M
or 100M, the Ethernet link fails or cannot transfer packets properly.
I've reported this issue to you before.
This is because the dynamic link speed change callback
rk_fix_speed()only handlesRGMII and RMII modes, leaving the internal XPCS (Physical Coding Sublayer)
MII_BMCRregister unconfigured for SGMII mode when the link rate changes.
Fix this by introducing a
set_sgmii_speedcallback for RK3568. When the linkspeed changes, it dynamically updates the
MII_BMCRregister of the XPCS viaxpcs_write()to match the negotiated speed (10M/100M/1000M).Fixes: 22e1b8b871c5 ("net: stmmac: dwmac-rk: Add SGMII and QSGMII support for RK3568")
Signed-off-by: hucheng cheng.hu911@gmail.com
drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c | 37 +++++++++++++++++-
1 file changed, 35 insertions(+), 2 deletions(-)
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c
index c73d14723..4cd6b94dc 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c
@@ -40,6 +40,7 @@ struct rk_gmac_ops {
void (*set_to_qsgmii)(struct rk_priv_data *bsp_priv);
void (*set_rgmii_speed)(struct rk_priv_data *bsp_priv, int speed);
void (*set_rmii_speed)(struct rk_priv_data *bsp_priv, int speed);
void (*set_clock_selection)(struct rk_priv_data *bsp_priv, bool input,
bool enable);
void (*integrated_phy_power)(struct rk_priv_data *bsp_priv, bool up);
@@ -200,10 +202,10 @@ static int xpcs_setup(struct rk_priv_data *bsp_priv, int mode)
SR_MII_CTRL_AN_ENABLE);
}
} else {
@@ -1888,7 +1890,33 @@ static void rk3568_set_gmac_speed(struct rk_priv_data *bsp_priv, int speed)
dev_err(dev, "%s: set clk_mac_speed rate %ld failed %d\n",
func, rate, ret);
}
+static void rk3568_set_gmac_sgmii_speed(struct rk_priv_data *bsp_priv, int speed)
+{
+}
+
static const struct rk_gmac_ops rk3568_ops = {
.set_to_rgmii = rk3568_set_to_rgmii,
.set_to_rmii = rk3568_set_to_rmii,
@@ -1896,6 +1924,7 @@ static const struct rk_gmac_ops rk3568_ops = {
.set_to_qsgmii = rk3568_set_to_qsgmii,
.set_rgmii_speed = rk3568_set_gmac_speed,
.set_rmii_speed = rk3568_set_gmac_speed,
.regs_valid = true,
.regs = {
0xfe2a0000, /* gmac0 */
@@ -2910,6 +2939,9 @@ static void rk_fix_speed(void *priv, unsigned int speed)
bsp_priv->ops->set_rmii_speed(bsp_priv, speed);
break;
case PHY_INTERFACE_MODE_SGMII:
break;
default:
--