forked from openwrt/openwrt
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
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>
- Loading branch information
Showing
5 changed files
with
378 additions
and
2 deletions.
There are no files selected for viewing
131 changes: 131 additions & 0 deletions
131
.../linux/generic/backport-5.10/796-v5.16-01-net-phy-at803x-fix-resume-for-QCA8327-phy.patch
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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); |
91 changes: 91 additions & 0 deletions
91
...eneric/backport-5.10/796-v5.16-02-net-phy-at803x-add-DAC-amplitude-fix-for-8327-phy.patch
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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, |
27 changes: 27 additions & 0 deletions
27
...ric/backport-5.10/796-v5.16-03-net-phy-at803x-enable-prefer-master-for-83xx-interna.patch
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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; | ||
} | ||
|
127 changes: 127 additions & 0 deletions
127
.../linux/generic/backport-5.10/796-v5.16-04-net-phy-at803x-better-describe-debug-regs.patch
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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, |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters