mirror of
https://github.com/openwrt/openwrt.git
synced 2024-12-02 06:13:54 +08:00
kernel: 5.10: backport QCA83x PHY resume fix, DAC amplitude preferred master, debug reg names
Backport workaround for QCA8327 PHY resume, which does not properly support genphy_suspend/resume. Also add DAC amplitude fix for the QCA8327 PHY, set port to preferred master and add proper names to debug regs. Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com> Signed-off-by: Matthew Hagan <mnhagan88@gmail.com>
This commit is contained in:
parent
dee819272a
commit
d888ef5668
@ -0,0 +1,131 @@
|
||||
From ba3c01ee02ed0d821c9f241f179bbc9457542b8f Mon Sep 17 00:00:00 2001
|
||||
From: Ansuel Smith <ansuelsmth@gmail.com>
|
||||
Date: Sun, 10 Oct 2021 00:46:15 +0200
|
||||
Subject: net: phy: at803x: fix resume for QCA8327 phy
|
||||
|
||||
From Documentation phy resume triggers phy reset and restart
|
||||
auto-negotiation. Add a dedicated function to wait reset to finish as
|
||||
it was notice a regression where port sometime are not reliable after a
|
||||
suspend/resume session. The reset wait logic is copied from phy_poll_reset.
|
||||
Add dedicated suspend function to use genphy_suspend only with QCA8337
|
||||
phy and set only additional debug settings for QCA8327. With more test
|
||||
it was reported that QCA8327 doesn't proprely support this mode and
|
||||
using this cause the unreliability of the switch ports, especially the
|
||||
malfunction of the port0.
|
||||
|
||||
Fixes: 15b9df4ece17 ("net: phy: at803x: add resume/suspend function to qca83xx phy")
|
||||
Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
|
||||
Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||
---
|
||||
drivers/net/phy/at803x.c | 69 +++++++++++++++++++++++++++++++++++++++++++-----
|
||||
1 file changed, 63 insertions(+), 6 deletions(-)
|
||||
|
||||
--- a/drivers/net/phy/at803x.c
|
||||
+++ b/drivers/net/phy/at803x.c
|
||||
@@ -92,9 +92,14 @@
|
||||
#define AT803X_DEBUG_REG_5 0x05
|
||||
#define AT803X_DEBUG_TX_CLK_DLY_EN BIT(8)
|
||||
|
||||
+#define AT803X_DEBUG_REG_HIB_CTRL 0x0b
|
||||
+#define AT803X_DEBUG_HIB_CTRL_SEL_RST_80U BIT(10)
|
||||
+#define AT803X_DEBUG_HIB_CTRL_EN_ANY_CHANGE BIT(13)
|
||||
+
|
||||
#define AT803X_DEBUG_REG_3C 0x3C
|
||||
|
||||
#define AT803X_DEBUG_REG_3D 0x3D
|
||||
+#define AT803X_DEBUG_GATE_CLK_IN1000 BIT(6)
|
||||
|
||||
#define AT803X_DEBUG_REG_1F 0x1F
|
||||
#define AT803X_DEBUG_PLL_ON BIT(2)
|
||||
@@ -1220,6 +1225,58 @@ static int qca83xx_config_init(struct ph
|
||||
return 0;
|
||||
}
|
||||
|
||||
+static int qca83xx_resume(struct phy_device *phydev)
|
||||
+{
|
||||
+ int ret, val;
|
||||
+
|
||||
+ /* Skip reset if not suspended */
|
||||
+ if (!phydev->suspended)
|
||||
+ return 0;
|
||||
+
|
||||
+ /* Reinit the port, reset values set by suspend */
|
||||
+ qca83xx_config_init(phydev);
|
||||
+
|
||||
+ /* Reset the port on port resume */
|
||||
+ phy_set_bits(phydev, MII_BMCR, BMCR_RESET | BMCR_ANENABLE);
|
||||
+
|
||||
+ /* On resume from suspend the switch execute a reset and
|
||||
+ * restart auto-negotiation. Wait for reset to complete.
|
||||
+ */
|
||||
+ ret = phy_read_poll_timeout(phydev, MII_BMCR, val, !(val & BMCR_RESET),
|
||||
+ 50000, 600000, true);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ msleep(1);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int qca83xx_suspend(struct phy_device *phydev)
|
||||
+{
|
||||
+ u16 mask = 0;
|
||||
+
|
||||
+ /* Only QCA8337 support actual suspend.
|
||||
+ * QCA8327 cause port unreliability when phy suspend
|
||||
+ * is set.
|
||||
+ */
|
||||
+ if (phydev->drv->phy_id == QCA8337_PHY_ID) {
|
||||
+ genphy_suspend(phydev);
|
||||
+ } else {
|
||||
+ mask |= ~(BMCR_SPEED1000 | BMCR_FULLDPLX);
|
||||
+ phy_modify(phydev, MII_BMCR, mask, 0);
|
||||
+ }
|
||||
+
|
||||
+ at803x_debug_reg_mask(phydev, AT803X_DEBUG_REG_3D,
|
||||
+ AT803X_DEBUG_GATE_CLK_IN1000, 0);
|
||||
+
|
||||
+ at803x_debug_reg_mask(phydev, AT803X_DEBUG_REG_HIB_CTRL,
|
||||
+ AT803X_DEBUG_HIB_CTRL_EN_ANY_CHANGE |
|
||||
+ AT803X_DEBUG_HIB_CTRL_SEL_RST_80U, 0);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
static struct phy_driver at803x_driver[] = {
|
||||
{
|
||||
/* Qualcomm Atheros AR8035 */
|
||||
@@ -1329,8 +1386,8 @@ static struct phy_driver at803x_driver[]
|
||||
.get_sset_count = at803x_get_sset_count,
|
||||
.get_strings = at803x_get_strings,
|
||||
.get_stats = at803x_get_stats,
|
||||
- .suspend = genphy_suspend,
|
||||
- .resume = genphy_resume,
|
||||
+ .suspend = qca83xx_suspend,
|
||||
+ .resume = qca83xx_resume,
|
||||
}, {
|
||||
/* QCA8327-A from switch QCA8327-AL1A */
|
||||
.phy_id = QCA8327_A_PHY_ID,
|
||||
@@ -1344,8 +1401,8 @@ static struct phy_driver at803x_driver[]
|
||||
.get_sset_count = at803x_get_sset_count,
|
||||
.get_strings = at803x_get_strings,
|
||||
.get_stats = at803x_get_stats,
|
||||
- .suspend = genphy_suspend,
|
||||
- .resume = genphy_resume,
|
||||
+ .suspend = qca83xx_suspend,
|
||||
+ .resume = qca83xx_resume,
|
||||
}, {
|
||||
/* QCA8327-B from switch QCA8327-BL1A */
|
||||
.phy_id = QCA8327_B_PHY_ID,
|
||||
@@ -1359,8 +1416,8 @@ static struct phy_driver at803x_driver[]
|
||||
.get_sset_count = at803x_get_sset_count,
|
||||
.get_strings = at803x_get_strings,
|
||||
.get_stats = at803x_get_stats,
|
||||
- .suspend = genphy_suspend,
|
||||
- .resume = genphy_resume,
|
||||
+ .suspend = qca83xx_suspend,
|
||||
+ .resume = qca83xx_resume,
|
||||
}, };
|
||||
|
||||
module_phy_driver(at803x_driver);
|
@ -0,0 +1,91 @@
|
||||
From 1ca8311949aec5c9447645731ef1c6bc5bd71350 Mon Sep 17 00:00:00 2001
|
||||
From: Ansuel Smith <ansuelsmth@gmail.com>
|
||||
Date: Sun, 10 Oct 2021 00:46:16 +0200
|
||||
Subject: net: phy: at803x: add DAC amplitude fix for 8327 phy
|
||||
|
||||
QCA8327 internal phy require DAC amplitude adjustement set to +6% with
|
||||
100m speed. Also add additional define to report a change of the same
|
||||
reg in QCA8337. (different scope it does set 1000m voltage)
|
||||
Add link_change_notify function to set the proper amplitude adjustement
|
||||
on PHY_RUNNING state and disable on any other state.
|
||||
|
||||
Fixes: b4df02b562f4 ("net: phy: at803x: add support for qca 8327 A variant internal phy")
|
||||
Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
|
||||
Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||
---
|
||||
drivers/net/phy/at803x.c | 33 +++++++++++++++++++++++++++++++++
|
||||
1 file changed, 33 insertions(+)
|
||||
|
||||
--- a/drivers/net/phy/at803x.c
|
||||
+++ b/drivers/net/phy/at803x.c
|
||||
@@ -87,6 +87,8 @@
|
||||
#define AT803X_PSSR_MR_AN_COMPLETE 0x0200
|
||||
|
||||
#define AT803X_DEBUG_REG_0 0x00
|
||||
+#define QCA8327_DEBUG_MANU_CTRL_EN BIT(2)
|
||||
+#define QCA8337_DEBUG_MANU_CTRL_EN GENMASK(3, 2)
|
||||
#define AT803X_DEBUG_RX_CLK_DLY_EN BIT(15)
|
||||
|
||||
#define AT803X_DEBUG_REG_5 0x05
|
||||
@@ -1222,9 +1224,37 @@ static int qca83xx_config_init(struct ph
|
||||
break;
|
||||
}
|
||||
|
||||
+ /* QCA8327 require DAC amplitude adjustment for 100m set to +6%.
|
||||
+ * Disable on init and enable only with 100m speed following
|
||||
+ * qca original source code.
|
||||
+ */
|
||||
+ if (phydev->drv->phy_id == QCA8327_A_PHY_ID ||
|
||||
+ phydev->drv->phy_id == QCA8327_B_PHY_ID)
|
||||
+ at803x_debug_reg_mask(phydev, AT803X_DEBUG_REG_0,
|
||||
+ QCA8327_DEBUG_MANU_CTRL_EN, 0);
|
||||
+
|
||||
return 0;
|
||||
}
|
||||
|
||||
+static void qca83xx_link_change_notify(struct phy_device *phydev)
|
||||
+{
|
||||
+ /* QCA8337 doesn't require DAC Amplitude adjustement */
|
||||
+ if (phydev->drv->phy_id == QCA8337_PHY_ID)
|
||||
+ return;
|
||||
+
|
||||
+ /* Set DAC Amplitude adjustment to +6% for 100m on link running */
|
||||
+ if (phydev->state == PHY_RUNNING) {
|
||||
+ if (phydev->speed == SPEED_100)
|
||||
+ at803x_debug_reg_mask(phydev, AT803X_DEBUG_REG_0,
|
||||
+ QCA8327_DEBUG_MANU_CTRL_EN,
|
||||
+ QCA8327_DEBUG_MANU_CTRL_EN);
|
||||
+ } else {
|
||||
+ /* Reset DAC Amplitude adjustment */
|
||||
+ at803x_debug_reg_mask(phydev, AT803X_DEBUG_REG_0,
|
||||
+ QCA8327_DEBUG_MANU_CTRL_EN, 0);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
static int qca83xx_resume(struct phy_device *phydev)
|
||||
{
|
||||
int ret, val;
|
||||
@@ -1379,6 +1409,7 @@ static struct phy_driver at803x_driver[]
|
||||
.phy_id_mask = QCA8K_PHY_ID_MASK,
|
||||
.name = "Qualcomm Atheros 8337 internal PHY",
|
||||
/* PHY_GBIT_FEATURES */
|
||||
+ .link_change_notify = qca83xx_link_change_notify,
|
||||
.probe = at803x_probe,
|
||||
.flags = PHY_IS_INTERNAL,
|
||||
.config_init = qca83xx_config_init,
|
||||
@@ -1394,6 +1425,7 @@ static struct phy_driver at803x_driver[]
|
||||
.phy_id_mask = QCA8K_PHY_ID_MASK,
|
||||
.name = "Qualcomm Atheros 8327-A internal PHY",
|
||||
/* PHY_GBIT_FEATURES */
|
||||
+ .link_change_notify = qca83xx_link_change_notify,
|
||||
.probe = at803x_probe,
|
||||
.flags = PHY_IS_INTERNAL,
|
||||
.config_init = qca83xx_config_init,
|
||||
@@ -1409,6 +1441,7 @@ static struct phy_driver at803x_driver[]
|
||||
.phy_id_mask = QCA8K_PHY_ID_MASK,
|
||||
.name = "Qualcomm Atheros 8327-B internal PHY",
|
||||
/* PHY_GBIT_FEATURES */
|
||||
+ .link_change_notify = qca83xx_link_change_notify,
|
||||
.probe = at803x_probe,
|
||||
.flags = PHY_IS_INTERNAL,
|
||||
.config_init = qca83xx_config_init,
|
@ -0,0 +1,27 @@
|
||||
From 9d1c29b4028557a496be9c5eb2b4b86063700636 Mon Sep 17 00:00:00 2001
|
||||
From: Ansuel Smith <ansuelsmth@gmail.com>
|
||||
Date: Sun, 10 Oct 2021 00:46:17 +0200
|
||||
Subject: net: phy: at803x: enable prefer master for 83xx internal phy
|
||||
|
||||
From original QCA source code the port was set to prefer master as port
|
||||
type in 1000BASE-T mode. Apply the same settings also here.
|
||||
|
||||
Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
|
||||
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
|
||||
Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||
---
|
||||
drivers/net/phy/at803x.c | 3 +++
|
||||
1 file changed, 3 insertions(+)
|
||||
|
||||
--- a/drivers/net/phy/at803x.c
|
||||
+++ b/drivers/net/phy/at803x.c
|
||||
@@ -1233,6 +1233,9 @@ static int qca83xx_config_init(struct ph
|
||||
at803x_debug_reg_mask(phydev, AT803X_DEBUG_REG_0,
|
||||
QCA8327_DEBUG_MANU_CTRL_EN, 0);
|
||||
|
||||
+ /* Following original QCA sourcecode set port to prefer master */
|
||||
+ phy_set_bits(phydev, MII_CTRL1000, CTL1000_PREFER_MASTER);
|
||||
+
|
||||
return 0;
|
||||
}
|
||||
|
@ -0,0 +1,127 @@
|
||||
From 67999555ff42e91de7654488d9a7735bd9e84555 Mon Sep 17 00:00:00 2001
|
||||
From: Ansuel Smith <ansuelsmth@gmail.com>
|
||||
Date: Sun, 10 Oct 2021 00:46:18 +0200
|
||||
Subject: net: phy: at803x: better describe debug regs
|
||||
|
||||
Give a name to known debug regs from Documentation instead of using
|
||||
unknown hex values.
|
||||
|
||||
Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
|
||||
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
|
||||
Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||
---
|
||||
drivers/net/phy/at803x.c | 30 +++++++++++++++---------------
|
||||
1 file changed, 15 insertions(+), 15 deletions(-)
|
||||
|
||||
--- a/drivers/net/phy/at803x.c
|
||||
+++ b/drivers/net/phy/at803x.c
|
||||
@@ -86,12 +86,12 @@
|
||||
#define AT803X_PSSR 0x11 /*PHY-Specific Status Register*/
|
||||
#define AT803X_PSSR_MR_AN_COMPLETE 0x0200
|
||||
|
||||
-#define AT803X_DEBUG_REG_0 0x00
|
||||
+#define AT803X_DEBUG_ANALOG_TEST_CTRL 0x00
|
||||
#define QCA8327_DEBUG_MANU_CTRL_EN BIT(2)
|
||||
#define QCA8337_DEBUG_MANU_CTRL_EN GENMASK(3, 2)
|
||||
#define AT803X_DEBUG_RX_CLK_DLY_EN BIT(15)
|
||||
|
||||
-#define AT803X_DEBUG_REG_5 0x05
|
||||
+#define AT803X_DEBUG_SYSTEM_CTRL_MODE 0x05
|
||||
#define AT803X_DEBUG_TX_CLK_DLY_EN BIT(8)
|
||||
|
||||
#define AT803X_DEBUG_REG_HIB_CTRL 0x0b
|
||||
@@ -100,7 +100,7 @@
|
||||
|
||||
#define AT803X_DEBUG_REG_3C 0x3C
|
||||
|
||||
-#define AT803X_DEBUG_REG_3D 0x3D
|
||||
+#define AT803X_DEBUG_REG_GREEN 0x3D
|
||||
#define AT803X_DEBUG_GATE_CLK_IN1000 BIT(6)
|
||||
|
||||
#define AT803X_DEBUG_REG_1F 0x1F
|
||||
@@ -274,25 +274,25 @@ static int at803x_read_page(struct phy_d
|
||||
|
||||
static int at803x_enable_rx_delay(struct phy_device *phydev)
|
||||
{
|
||||
- return at803x_debug_reg_mask(phydev, AT803X_DEBUG_REG_0, 0,
|
||||
+ return at803x_debug_reg_mask(phydev, AT803X_DEBUG_ANALOG_TEST_CTRL, 0,
|
||||
AT803X_DEBUG_RX_CLK_DLY_EN);
|
||||
}
|
||||
|
||||
static int at803x_enable_tx_delay(struct phy_device *phydev)
|
||||
{
|
||||
- return at803x_debug_reg_mask(phydev, AT803X_DEBUG_REG_5, 0,
|
||||
+ return at803x_debug_reg_mask(phydev, AT803X_DEBUG_SYSTEM_CTRL_MODE, 0,
|
||||
AT803X_DEBUG_TX_CLK_DLY_EN);
|
||||
}
|
||||
|
||||
static int at803x_disable_rx_delay(struct phy_device *phydev)
|
||||
{
|
||||
- return at803x_debug_reg_mask(phydev, AT803X_DEBUG_REG_0,
|
||||
+ return at803x_debug_reg_mask(phydev, AT803X_DEBUG_ANALOG_TEST_CTRL,
|
||||
AT803X_DEBUG_RX_CLK_DLY_EN, 0);
|
||||
}
|
||||
|
||||
static int at803x_disable_tx_delay(struct phy_device *phydev)
|
||||
{
|
||||
- return at803x_debug_reg_mask(phydev, AT803X_DEBUG_REG_5,
|
||||
+ return at803x_debug_reg_mask(phydev, AT803X_DEBUG_SYSTEM_CTRL_MODE,
|
||||
AT803X_DEBUG_TX_CLK_DLY_EN, 0);
|
||||
}
|
||||
|
||||
@@ -1208,9 +1208,9 @@ static int qca83xx_config_init(struct ph
|
||||
switch (switch_revision) {
|
||||
case 1:
|
||||
/* For 100M waveform */
|
||||
- at803x_debug_reg_write(phydev, AT803X_DEBUG_REG_0, 0x02ea);
|
||||
+ at803x_debug_reg_write(phydev, AT803X_DEBUG_ANALOG_TEST_CTRL, 0x02ea);
|
||||
/* Turn on Gigabit clock */
|
||||
- at803x_debug_reg_write(phydev, AT803X_DEBUG_REG_3D, 0x68a0);
|
||||
+ at803x_debug_reg_write(phydev, AT803X_DEBUG_REG_GREEN, 0x68a0);
|
||||
break;
|
||||
|
||||
case 2:
|
||||
@@ -1218,8 +1218,8 @@ static int qca83xx_config_init(struct ph
|
||||
fallthrough;
|
||||
case 4:
|
||||
phy_write_mmd(phydev, MDIO_MMD_PCS, MDIO_AZ_DEBUG, 0x803f);
|
||||
- at803x_debug_reg_write(phydev, AT803X_DEBUG_REG_3D, 0x6860);
|
||||
- at803x_debug_reg_write(phydev, AT803X_DEBUG_REG_5, 0x2c46);
|
||||
+ at803x_debug_reg_write(phydev, AT803X_DEBUG_REG_GREEN, 0x6860);
|
||||
+ at803x_debug_reg_write(phydev, AT803X_DEBUG_SYSTEM_CTRL_MODE, 0x2c46);
|
||||
at803x_debug_reg_write(phydev, AT803X_DEBUG_REG_3C, 0x6000);
|
||||
break;
|
||||
}
|
||||
@@ -1230,7 +1230,7 @@ static int qca83xx_config_init(struct ph
|
||||
*/
|
||||
if (phydev->drv->phy_id == QCA8327_A_PHY_ID ||
|
||||
phydev->drv->phy_id == QCA8327_B_PHY_ID)
|
||||
- at803x_debug_reg_mask(phydev, AT803X_DEBUG_REG_0,
|
||||
+ at803x_debug_reg_mask(phydev, AT803X_DEBUG_ANALOG_TEST_CTRL,
|
||||
QCA8327_DEBUG_MANU_CTRL_EN, 0);
|
||||
|
||||
/* Following original QCA sourcecode set port to prefer master */
|
||||
@@ -1248,12 +1248,12 @@ static void qca83xx_link_change_notify(s
|
||||
/* Set DAC Amplitude adjustment to +6% for 100m on link running */
|
||||
if (phydev->state == PHY_RUNNING) {
|
||||
if (phydev->speed == SPEED_100)
|
||||
- at803x_debug_reg_mask(phydev, AT803X_DEBUG_REG_0,
|
||||
+ at803x_debug_reg_mask(phydev, AT803X_DEBUG_ANALOG_TEST_CTRL,
|
||||
QCA8327_DEBUG_MANU_CTRL_EN,
|
||||
QCA8327_DEBUG_MANU_CTRL_EN);
|
||||
} else {
|
||||
/* Reset DAC Amplitude adjustment */
|
||||
- at803x_debug_reg_mask(phydev, AT803X_DEBUG_REG_0,
|
||||
+ at803x_debug_reg_mask(phydev, AT803X_DEBUG_ANALOG_TEST_CTRL,
|
||||
QCA8327_DEBUG_MANU_CTRL_EN, 0);
|
||||
}
|
||||
}
|
||||
@@ -1300,7 +1300,7 @@ static int qca83xx_suspend(struct phy_de
|
||||
phy_modify(phydev, MII_BMCR, mask, 0);
|
||||
}
|
||||
|
||||
- at803x_debug_reg_mask(phydev, AT803X_DEBUG_REG_3D,
|
||||
+ at803x_debug_reg_mask(phydev, AT803X_DEBUG_REG_GREEN,
|
||||
AT803X_DEBUG_GATE_CLK_IN1000, 0);
|
||||
|
||||
at803x_debug_reg_mask(phydev, AT803X_DEBUG_REG_HIB_CTRL,
|
@ -20,7 +20,7 @@ Signed-off-by: David Bauer <mail@david-bauer.net>
|
||||
|
||||
--- a/drivers/net/phy/at803x.c
|
||||
+++ b/drivers/net/phy/at803x.c
|
||||
@@ -1025,6 +1025,34 @@ static int at803x_set_tunable(struct phy
|
||||
@@ -1032,6 +1032,34 @@ static int at803x_set_tunable(struct phy
|
||||
}
|
||||
}
|
||||
|
||||
@ -55,7 +55,7 @@ Signed-off-by: David Bauer <mail@david-bauer.net>
|
||||
static int at803x_cable_test_result_trans(u16 status)
|
||||
{
|
||||
switch (FIELD_GET(AT803X_CDT_STATUS_STAT_MASK, status)) {
|
||||
@@ -1274,7 +1302,7 @@ static struct phy_driver at803x_driver[]
|
||||
@@ -1364,7 +1392,7 @@ static struct phy_driver at803x_driver[]
|
||||
.resume = at803x_resume,
|
||||
.read_page = at803x_read_page,
|
||||
.write_page = at803x_write_page,
|
||||
|
Loading…
Reference in New Issue
Block a user