[][sync access syscfg0 safe protect]
[Description]
Fix Ethernet ping fail seldom issue when reboot from colgin.
-- syscfg0 access is not thread safe.
-- when mtk_open(eth0) and mtk_open(eth1) occur at the same time
-- Add spin_lock to protect.
[Release-log]
Change-Id: I94aae8b96ac766aef512751f6cd1f87c1db2a214
Reviewed-on: https://gerrit.mediatek.inc/c/openwrt/feeds/mtk_openwrt_feeds/+/5597031
diff --git a/target/linux/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_eth_path.c b/target/linux/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_eth_path.c
index 86160e6..dcb3c8a 100755
--- a/target/linux/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_eth_path.c
+++ b/target/linux/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_eth_path.c
@@ -130,6 +130,8 @@
unsigned int val = 0;
bool updated = true;
+ spin_lock(ð->syscfg0_lock);
+
switch (path) {
case MTK_ETH_PATH_GMAC1_SGMII:
val = SYSCFG0_SGMII_GMAC1;
@@ -157,6 +159,8 @@
regmap_update_bits(eth->ethsys, ETHSYS_SYSCFG0,
SYSCFG0_SGMII_MASK, val);
+ spin_unlock(ð->syscfg0_lock);
+
dev_dbg(eth->dev, "path %s in %s updated = %d\n",
mtk_eth_path_name(path), __func__, updated);
@@ -168,6 +172,8 @@
unsigned int val = 0;
bool updated = true;
+ spin_lock(ð->syscfg0_lock);
+
regmap_read(eth->ethsys, ETHSYS_SYSCFG0, &val);
switch (path) {
@@ -188,6 +194,8 @@
regmap_update_bits(eth->ethsys, ETHSYS_SYSCFG0,
SYSCFG0_SGMII_MASK, val);
+ spin_unlock(ð->syscfg0_lock);
+
dev_dbg(eth->dev, "path %s in %s updated = %d\n",
mtk_eth_path_name(path), __func__, updated);
diff --git a/target/linux/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_eth_soc.c b/target/linux/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_eth_soc.c
index d7dbc3f..6efe1e7 100755
--- a/target/linux/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+++ b/target/linux/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_eth_soc.c
@@ -342,10 +342,12 @@
}
/* put the gmac into the right mode */
+ spin_lock(ð->syscfg0_lock);
regmap_read(eth->ethsys, ETHSYS_SYSCFG0, &val);
val &= ~SYSCFG0_GE_MODE(SYSCFG0_GE_MASK, mac->id);
val |= SYSCFG0_GE_MODE(ge_mode, mac->id);
regmap_write(eth->ethsys, ETHSYS_SYSCFG0, val);
+ spin_unlock(ð->syscfg0_lock);
mac->interface = state->interface;
}
@@ -356,6 +358,7 @@
/* The path GMAC to SGMII will be enabled once the SGMIISYS is
* being setup done.
*/
+ spin_lock(ð->syscfg0_lock);
regmap_read(eth->ethsys, ETHSYS_SYSCFG0, &val);
regmap_update_bits(eth->ethsys, ETHSYS_SYSCFG0,
@@ -373,11 +376,14 @@
else if (phylink_autoneg_inband(mode))
err = mtk_sgmii_setup_mode_an(eth->sgmii, sid);
- if (err)
+ if (err) {
+ spin_unlock(ð->syscfg0_lock);
goto init_err;
+ }
regmap_update_bits(eth->ethsys, ETHSYS_SYSCFG0,
SYSCFG0_SGMII_MASK, val);
+ spin_unlock(ð->syscfg0_lock);
} else if (phylink_autoneg_inband(mode)) {
dev_err(eth->dev,
"In-band mode not supported in non SGMII mode!\n");
@@ -3420,6 +3426,7 @@
spin_lock_init(ð->page_lock);
spin_lock_init(ð->tx_irq_lock);
spin_lock_init(ð->rx_irq_lock);
+ spin_lock_init(ð->syscfg0_lock);
if (!MTK_HAS_CAPS(eth->soc->caps, MTK_SOC_MT7628)) {
eth->ethsys = syscon_regmap_lookup_by_phandle(pdev->dev.of_node,
diff --git a/target/linux/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_eth_soc.h b/target/linux/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_eth_soc.h
index 00c5280..a31c4f6 100755
--- a/target/linux/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_eth_soc.h
+++ b/target/linux/mediatek/files-5.4/drivers/net/ethernet/mediatek/mtk_eth_soc.h
@@ -1221,6 +1221,7 @@
u32 tx_int_status_reg;
u32 rx_dma_l4_valid;
int ip_align;
+ spinlock_t syscfg0_lock;
};
/* struct mtk_mac - the structure that holds the info about the MACs of the