All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v3 0/13] net: phy: Add qca8081 ethernet phy driver
@ 2021-10-18  3:33 Luo Jie
  2021-10-18  3:33 ` [PATCH v3 01/13] net: phy: at803x: replace AT803X_DEVICE_ADDR with MDIO_MMD_PCS Luo Jie
                   ` (12 more replies)
  0 siblings, 13 replies; 36+ messages in thread
From: Luo Jie @ 2021-10-18  3:33 UTC (permalink / raw)
  To: andrew, hkallweit1, linux, davem, kuba
  Cc: netdev, linux-kernel, sricharan, Luo Jie

This patch series add the qca8081 ethernet phy driver support, which
improve the wol feature, leverage at803x phy driver and add the fast
retrain, master/slave seed and CDT feature.

Changes in v3:
	* correct a typo "excpet".
	* remove the suffix "PHY" from phy name.

Changes in v2:
	* add definitions of fast retrain related registers in mdio.h.
	* break up the patch into small patches.
	* improve the at803x legacy code.

Changes in v1:
	* merge qca8081 phy driver into at803x.
	* add cdt feature.
	* leverage at803x phy driver helpers.

Luo Jie (13):
  net: phy: at803x: replace AT803X_DEVICE_ADDR with MDIO_MMD_PCS
  net: phy: at803x: use phy_modify()
  net: phy: at803x: improve the WOL feature
  net: phy: at803x: use GENMASK() for speed status
  net: phy: add qca8081 ethernet phy driver
  net: phy: add qca8081 read_status
  net: phy: add qca8081 get_features
  net: phy: add qca8081 config_aneg
  net: phy: add constants for fast retrain related register
  net: phy: add qca8081 config_init
  net: phy: add qca8081 soft_reset and enable master/slave seed
  net: phy: adjust qca8081 master/slave seed value if link down
  net: phy: add qca8081 cdt feature

 drivers/net/phy/at803x.c  | 572 +++++++++++++++++++++++++++++++++++---
 include/uapi/linux/mdio.h |  10 +
 2 files changed, 536 insertions(+), 46 deletions(-)

-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project


^ permalink raw reply	[flat|nested] 36+ messages in thread

* [PATCH v3 01/13] net: phy: at803x: replace AT803X_DEVICE_ADDR with MDIO_MMD_PCS
  2021-10-18  3:33 [PATCH v3 0/13] net: phy: Add qca8081 ethernet phy driver Luo Jie
@ 2021-10-18  3:33 ` Luo Jie
  2021-10-18 18:33   ` Andrew Lunn
  2021-10-18  3:33 ` [PATCH v3 02/13] net: phy: at803x: use phy_modify() Luo Jie
                   ` (11 subsequent siblings)
  12 siblings, 1 reply; 36+ messages in thread
From: Luo Jie @ 2021-10-18  3:33 UTC (permalink / raw)
  To: andrew, hkallweit1, linux, davem, kuba
  Cc: netdev, linux-kernel, sricharan, Luo Jie

Replace AT803X_DEVICE_ADDR with MDIO_MMD_PCS defined in mdio.h.

Signed-off-by: Luo Jie <luoj@codeaurora.org>
---
 drivers/net/phy/at803x.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/net/phy/at803x.c b/drivers/net/phy/at803x.c
index bdac087058b2..5843b5b742f8 100644
--- a/drivers/net/phy/at803x.c
+++ b/drivers/net/phy/at803x.c
@@ -70,7 +70,6 @@
 #define AT803X_CDT_STATUS_DELTA_TIME_MASK	GENMASK(7, 0)
 #define AT803X_LED_CONTROL			0x18
 
-#define AT803X_DEVICE_ADDR			0x03
 #define AT803X_LOC_MAC_ADDR_0_15_OFFSET		0x804C
 #define AT803X_LOC_MAC_ADDR_16_31_OFFSET	0x804B
 #define AT803X_LOC_MAC_ADDR_32_47_OFFSET	0x804A
@@ -329,7 +328,8 @@ static int at803x_set_wol(struct phy_device *phydev,
 	const u8 *mac;
 	int ret;
 	u32 value;
-	unsigned int i, offsets[] = {
+	unsigned int i;
+	const unsigned int offsets[] = {
 		AT803X_LOC_MAC_ADDR_32_47_OFFSET,
 		AT803X_LOC_MAC_ADDR_16_31_OFFSET,
 		AT803X_LOC_MAC_ADDR_0_15_OFFSET,
@@ -345,7 +345,7 @@ static int at803x_set_wol(struct phy_device *phydev,
 			return -EINVAL;
 
 		for (i = 0; i < 3; i++)
-			phy_write_mmd(phydev, AT803X_DEVICE_ADDR, offsets[i],
+			phy_write_mmd(phydev, MDIO_MMD_PCS, offsets[i],
 				      mac[(i * 2) + 1] | (mac[(i * 2)] << 8));
 
 		value = phy_read(phydev, AT803X_INTR_ENABLE);
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project


^ permalink raw reply related	[flat|nested] 36+ messages in thread

* [PATCH v3 02/13] net: phy: at803x: use phy_modify()
  2021-10-18  3:33 [PATCH v3 0/13] net: phy: Add qca8081 ethernet phy driver Luo Jie
  2021-10-18  3:33 ` [PATCH v3 01/13] net: phy: at803x: replace AT803X_DEVICE_ADDR with MDIO_MMD_PCS Luo Jie
@ 2021-10-18  3:33 ` Luo Jie
  2021-10-18 18:34   ` Andrew Lunn
  2021-10-18  3:33 ` [PATCH v3 03/13] net: phy: at803x: improve the WOL feature Luo Jie
                   ` (10 subsequent siblings)
  12 siblings, 1 reply; 36+ messages in thread
From: Luo Jie @ 2021-10-18  3:33 UTC (permalink / raw)
  To: andrew, hkallweit1, linux, davem, kuba
  Cc: netdev, linux-kernel, sricharan, Luo Jie

Convert at803x_set_wol to use phy_modify.

Signed-off-by: Luo Jie <luoj@codeaurora.org>
---
 drivers/net/phy/at803x.c | 8 ++------
 1 file changed, 2 insertions(+), 6 deletions(-)

diff --git a/drivers/net/phy/at803x.c b/drivers/net/phy/at803x.c
index 5843b5b742f8..c5e145ff5ec8 100644
--- a/drivers/net/phy/at803x.c
+++ b/drivers/net/phy/at803x.c
@@ -348,16 +348,12 @@ static int at803x_set_wol(struct phy_device *phydev,
 			phy_write_mmd(phydev, MDIO_MMD_PCS, offsets[i],
 				      mac[(i * 2) + 1] | (mac[(i * 2)] << 8));
 
-		value = phy_read(phydev, AT803X_INTR_ENABLE);
-		value |= AT803X_INTR_ENABLE_WOL;
-		ret = phy_write(phydev, AT803X_INTR_ENABLE, value);
+		ret = phy_modify(phydev, AT803X_INTR_ENABLE, 0, AT803X_INTR_ENABLE_WOL);
 		if (ret)
 			return ret;
 		value = phy_read(phydev, AT803X_INTR_STATUS);
 	} else {
-		value = phy_read(phydev, AT803X_INTR_ENABLE);
-		value &= (~AT803X_INTR_ENABLE_WOL);
-		ret = phy_write(phydev, AT803X_INTR_ENABLE, value);
+		ret = phy_modify(phydev, AT803X_INTR_ENABLE, AT803X_INTR_ENABLE_WOL, 0);
 		if (ret)
 			return ret;
 		value = phy_read(phydev, AT803X_INTR_STATUS);
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project


^ permalink raw reply related	[flat|nested] 36+ messages in thread

* [PATCH v3 03/13] net: phy: at803x: improve the WOL feature
  2021-10-18  3:33 [PATCH v3 0/13] net: phy: Add qca8081 ethernet phy driver Luo Jie
  2021-10-18  3:33 ` [PATCH v3 01/13] net: phy: at803x: replace AT803X_DEVICE_ADDR with MDIO_MMD_PCS Luo Jie
  2021-10-18  3:33 ` [PATCH v3 02/13] net: phy: at803x: use phy_modify() Luo Jie
@ 2021-10-18  3:33 ` Luo Jie
  2021-10-18 18:41   ` Andrew Lunn
  2021-10-18  3:33 ` [PATCH v3 04/13] net: phy: at803x: use GENMASK() for speed status Luo Jie
                   ` (9 subsequent siblings)
  12 siblings, 1 reply; 36+ messages in thread
From: Luo Jie @ 2021-10-18  3:33 UTC (permalink / raw)
  To: andrew, hkallweit1, linux, davem, kuba
  Cc: netdev, linux-kernel, sricharan, Luo Jie

The wol feature is controlled by the MMD3.8012 bit5,
need to set this bit when the wol function is enabled.

The reg18 bit0 is for enabling WOL interrupt, when wol
occurs, the wol interrupt status reg19 bit0 is set to 1.

Signed-off-by: Luo Jie <luoj@codeaurora.org>
---
 drivers/net/phy/at803x.c | 27 +++++++++++++++++++++------
 1 file changed, 21 insertions(+), 6 deletions(-)

diff --git a/drivers/net/phy/at803x.c b/drivers/net/phy/at803x.c
index c5e145ff5ec8..2f7d96bd1be8 100644
--- a/drivers/net/phy/at803x.c
+++ b/drivers/net/phy/at803x.c
@@ -70,6 +70,8 @@
 #define AT803X_CDT_STATUS_DELTA_TIME_MASK	GENMASK(7, 0)
 #define AT803X_LED_CONTROL			0x18
 
+#define AT803X_PHY_MMD3_WOL_CTRL		0x8012
+#define AT803X_WOL_EN				BIT(5)
 #define AT803X_LOC_MAC_ADDR_0_15_OFFSET		0x804C
 #define AT803X_LOC_MAC_ADDR_16_31_OFFSET	0x804B
 #define AT803X_LOC_MAC_ADDR_32_47_OFFSET	0x804A
@@ -327,7 +329,6 @@ static int at803x_set_wol(struct phy_device *phydev,
 	struct net_device *ndev = phydev->attached_dev;
 	const u8 *mac;
 	int ret;
-	u32 value;
 	unsigned int i;
 	const unsigned int offsets[] = {
 		AT803X_LOC_MAC_ADDR_32_47_OFFSET,
@@ -348,18 +349,29 @@ static int at803x_set_wol(struct phy_device *phydev,
 			phy_write_mmd(phydev, MDIO_MMD_PCS, offsets[i],
 				      mac[(i * 2) + 1] | (mac[(i * 2)] << 8));
 
+		/* Enable WOL function */
+		ret = phy_modify_mmd(phydev, MDIO_MMD_PCS, AT803X_PHY_MMD3_WOL_CTRL,
+				0, AT803X_WOL_EN);
+		if (ret)
+			return ret;
+		/* Enable WOL interrupt */
 		ret = phy_modify(phydev, AT803X_INTR_ENABLE, 0, AT803X_INTR_ENABLE_WOL);
 		if (ret)
 			return ret;
-		value = phy_read(phydev, AT803X_INTR_STATUS);
 	} else {
+		/* Disable WoL function */
+		ret = phy_modify_mmd(phydev, MDIO_MMD_PCS, AT803X_PHY_MMD3_WOL_CTRL,
+				AT803X_WOL_EN, 0);
+		if (ret)
+			return ret;
+		/* Disable WOL interrupt */
 		ret = phy_modify(phydev, AT803X_INTR_ENABLE, AT803X_INTR_ENABLE_WOL, 0);
 		if (ret)
 			return ret;
-		value = phy_read(phydev, AT803X_INTR_STATUS);
 	}
 
-	return ret;
+	/* Clear WOL status */
+	return phy_read(phydev, AT803X_INTR_STATUS);
 }
 
 static void at803x_get_wol(struct phy_device *phydev,
@@ -370,8 +382,11 @@ static void at803x_get_wol(struct phy_device *phydev,
 	wol->supported = WAKE_MAGIC;
 	wol->wolopts = 0;
 
-	value = phy_read(phydev, AT803X_INTR_ENABLE);
-	if (value & AT803X_INTR_ENABLE_WOL)
+	value = phy_read_mmd(phydev, MDIO_MMD_PCS, AT803X_PHY_MMD3_WOL_CTRL);
+	if (value < 0)
+		return;
+
+	if (value & AT803X_WOL_EN)
 		wol->wolopts |= WAKE_MAGIC;
 }
 
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project


^ permalink raw reply related	[flat|nested] 36+ messages in thread

* [PATCH v3 04/13] net: phy: at803x: use GENMASK() for speed status
  2021-10-18  3:33 [PATCH v3 0/13] net: phy: Add qca8081 ethernet phy driver Luo Jie
                   ` (2 preceding siblings ...)
  2021-10-18  3:33 ` [PATCH v3 03/13] net: phy: at803x: improve the WOL feature Luo Jie
@ 2021-10-18  3:33 ` Luo Jie
  2021-10-18 18:41   ` Andrew Lunn
  2021-10-18  3:33 ` [PATCH v3 05/13] net: phy: add qca8081 ethernet phy driver Luo Jie
                   ` (8 subsequent siblings)
  12 siblings, 1 reply; 36+ messages in thread
From: Luo Jie @ 2021-10-18  3:33 UTC (permalink / raw)
  To: andrew, hkallweit1, linux, davem, kuba
  Cc: netdev, linux-kernel, sricharan, Luo Jie

Use GENMASK() for the current speed value.

Signed-off-by: Luo Jie <luoj@codeaurora.org>
---
 drivers/net/phy/at803x.c | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/drivers/net/phy/at803x.c b/drivers/net/phy/at803x.c
index 2f7d96bd1be8..0b69e77a0510 100644
--- a/drivers/net/phy/at803x.c
+++ b/drivers/net/phy/at803x.c
@@ -33,10 +33,10 @@
 #define AT803X_SFC_DISABLE_JABBER		BIT(0)
 
 #define AT803X_SPECIFIC_STATUS			0x11
-#define AT803X_SS_SPEED_MASK			(3 << 14)
-#define AT803X_SS_SPEED_1000			(2 << 14)
-#define AT803X_SS_SPEED_100			(1 << 14)
-#define AT803X_SS_SPEED_10			(0 << 14)
+#define AT803X_SS_SPEED_MASK			GENMASK(15, 14)
+#define AT803X_SS_SPEED_1000			2
+#define AT803X_SS_SPEED_100			1
+#define AT803X_SS_SPEED_10			0
 #define AT803X_SS_DUPLEX			BIT(13)
 #define AT803X_SS_SPEED_DUPLEX_RESOLVED		BIT(11)
 #define AT803X_SS_MDIX				BIT(6)
@@ -969,7 +969,7 @@ static int at803x_read_status(struct phy_device *phydev)
 		if (sfc < 0)
 			return sfc;
 
-		switch (ss & AT803X_SS_SPEED_MASK) {
+		switch (FIELD_GET(AT803X_SS_SPEED_MASK, ss)) {
 		case AT803X_SS_SPEED_10:
 			phydev->speed = SPEED_10;
 			break;
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project


^ permalink raw reply related	[flat|nested] 36+ messages in thread

* [PATCH v3 05/13] net: phy: add qca8081 ethernet phy driver
  2021-10-18  3:33 [PATCH v3 0/13] net: phy: Add qca8081 ethernet phy driver Luo Jie
                   ` (3 preceding siblings ...)
  2021-10-18  3:33 ` [PATCH v3 04/13] net: phy: at803x: use GENMASK() for speed status Luo Jie
@ 2021-10-18  3:33 ` Luo Jie
  2021-10-18 18:47   ` Andrew Lunn
  2021-10-18  3:33 ` [PATCH v3 06/13] net: phy: add qca8081 read_status Luo Jie
                   ` (7 subsequent siblings)
  12 siblings, 1 reply; 36+ messages in thread
From: Luo Jie @ 2021-10-18  3:33 UTC (permalink / raw)
  To: andrew, hkallweit1, linux, davem, kuba
  Cc: netdev, linux-kernel, sricharan, Luo Jie

qca8081 is a single port ethernet phy chip that supports
10/100/1000/2500 Mbps mode.

Add the basic phy driver features, and reuse the at803x
phy driver functions.

Signed-off-by: Luo Jie <luoj@codeaurora.org>
---
 drivers/net/phy/at803x.c | 17 ++++++++++++++++-
 1 file changed, 16 insertions(+), 1 deletion(-)

diff --git a/drivers/net/phy/at803x.c b/drivers/net/phy/at803x.c
index 0b69e77a0510..0df474628461 100644
--- a/drivers/net/phy/at803x.c
+++ b/drivers/net/phy/at803x.c
@@ -155,6 +155,8 @@
 #define QCA8337_PHY_ID				0x004dd036
 #define QCA8K_PHY_ID_MASK			0xffffffff
 
+#define QCA8081_PHY_ID				0x004dd101
+
 #define QCA8K_DEVFLAGS_REVISION_MASK		GENMASK(2, 0)
 
 #define AT803X_PAGE_FIBER			0
@@ -164,7 +166,7 @@
 #define AT803X_KEEP_PLL_ENABLED			BIT(0)
 #define AT803X_DISABLE_SMARTEEE			BIT(1)
 
-MODULE_DESCRIPTION("Qualcomm Atheros AR803x PHY driver");
+MODULE_DESCRIPTION("Qualcomm Atheros AR803x and QCA808X PHY driver");
 MODULE_AUTHOR("Matus Ujhelyi");
 MODULE_LICENSE("GPL");
 
@@ -1431,6 +1433,18 @@ static struct phy_driver at803x_driver[] = {
 	.get_sset_count = at803x_get_sset_count,
 	.get_strings = at803x_get_strings,
 	.get_stats = at803x_get_stats,
+}, {
+	/* Qualcomm QCA8081 */
+	PHY_ID_MATCH_EXACT(QCA8081_PHY_ID),
+	.name			= "Qualcomm QCA8081",
+	.config_intr		= at803x_config_intr,
+	.handle_interrupt	= at803x_handle_interrupt,
+	.get_tunable		= at803x_get_tunable,
+	.set_tunable		= at803x_set_tunable,
+	.set_wol		= at803x_set_wol,
+	.get_wol		= at803x_get_wol,
+	.suspend		= genphy_suspend,
+	.resume			= genphy_resume,
 }, };
 
 module_phy_driver(at803x_driver);
@@ -1441,6 +1455,7 @@ static struct mdio_device_id __maybe_unused atheros_tbl[] = {
 	{ PHY_ID_MATCH_EXACT(ATH8032_PHY_ID) },
 	{ PHY_ID_MATCH_EXACT(ATH8035_PHY_ID) },
 	{ PHY_ID_MATCH_EXACT(ATH9331_PHY_ID) },
+	{ PHY_ID_MATCH_EXACT(QCA8081_PHY_ID) },
 	{ }
 };
 
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project


^ permalink raw reply related	[flat|nested] 36+ messages in thread

* [PATCH v3 06/13] net: phy: add qca8081 read_status
  2021-10-18  3:33 [PATCH v3 0/13] net: phy: Add qca8081 ethernet phy driver Luo Jie
                   ` (4 preceding siblings ...)
  2021-10-18  3:33 ` [PATCH v3 05/13] net: phy: add qca8081 ethernet phy driver Luo Jie
@ 2021-10-18  3:33 ` Luo Jie
  2021-10-18 21:42   ` Andrew Lunn
  2021-10-18  3:33 ` [PATCH v3 07/13] net: phy: add qca8081 get_features Luo Jie
                   ` (6 subsequent siblings)
  12 siblings, 1 reply; 36+ messages in thread
From: Luo Jie @ 2021-10-18  3:33 UTC (permalink / raw)
  To: andrew, hkallweit1, linux, davem, kuba
  Cc: netdev, linux-kernel, sricharan, Luo Jie

1. Separate the function at803x_read_specific_status from
the at803x_read_status, since it can be reused by the
read_status of qca8081 phy driver excepting adding the
2500M speed.

2. Add the qca8081 read_status function qca808x_read_status.

Signed-off-by: Luo Jie <luoj@codeaurora.org>
---
 drivers/net/phy/at803x.c | 95 ++++++++++++++++++++++++++++++----------
 1 file changed, 73 insertions(+), 22 deletions(-)

diff --git a/drivers/net/phy/at803x.c b/drivers/net/phy/at803x.c
index 0df474628461..42d3f8ccca94 100644
--- a/drivers/net/phy/at803x.c
+++ b/drivers/net/phy/at803x.c
@@ -41,6 +41,9 @@
 #define AT803X_SS_SPEED_DUPLEX_RESOLVED		BIT(11)
 #define AT803X_SS_MDIX				BIT(6)
 
+#define QCA808X_SS_SPEED_MASK			GENMASK(9, 7)
+#define QCA808X_SS_SPEED_2500			4
+
 #define AT803X_INTR_ENABLE			0x12
 #define AT803X_INTR_ENABLE_AUTONEG_ERR		BIT(15)
 #define AT803X_INTR_ENABLE_SPEED_CHANGED	BIT(14)
@@ -934,27 +937,9 @@ static void at803x_link_change_notify(struct phy_device *phydev)
 	}
 }
 
-static int at803x_read_status(struct phy_device *phydev)
+static int at803x_read_specific_status(struct phy_device *phydev)
 {
-	int ss, err, old_link = phydev->link;
-
-	/* Update the link, but return if there was an error */
-	err = genphy_update_link(phydev);
-	if (err)
-		return err;
-
-	/* why bother the PHY if nothing can have changed */
-	if (phydev->autoneg == AUTONEG_ENABLE && old_link && phydev->link)
-		return 0;
-
-	phydev->speed = SPEED_UNKNOWN;
-	phydev->duplex = DUPLEX_UNKNOWN;
-	phydev->pause = 0;
-	phydev->asym_pause = 0;
-
-	err = genphy_read_lpa(phydev);
-	if (err < 0)
-		return err;
+	int ss;
 
 	/* Read the AT8035 PHY-Specific Status register, which indicates the
 	 * speed and duplex that the PHY is actually using, irrespective of
@@ -965,13 +950,19 @@ static int at803x_read_status(struct phy_device *phydev)
 		return ss;
 
 	if (ss & AT803X_SS_SPEED_DUPLEX_RESOLVED) {
-		int sfc;
+		int sfc, speed;
 
 		sfc = phy_read(phydev, AT803X_SPECIFIC_FUNCTION_CONTROL);
 		if (sfc < 0)
 			return sfc;
 
-		switch (FIELD_GET(AT803X_SS_SPEED_MASK, ss)) {
+		/* qca8081 takes the different bits for speed value from at803x */
+		if (phydev->drv->phy_id == QCA8081_PHY_ID)
+			speed = FIELD_GET(QCA808X_SS_SPEED_MASK, ss);
+		else
+			speed = FIELD_GET(AT803X_SS_SPEED_MASK, ss);
+
+		switch (speed) {
 		case AT803X_SS_SPEED_10:
 			phydev->speed = SPEED_10;
 			break;
@@ -981,6 +972,9 @@ static int at803x_read_status(struct phy_device *phydev)
 		case AT803X_SS_SPEED_1000:
 			phydev->speed = SPEED_1000;
 			break;
+		case QCA808X_SS_SPEED_2500:
+			phydev->speed = SPEED_2500;
+			break;
 		}
 		if (ss & AT803X_SS_DUPLEX)
 			phydev->duplex = DUPLEX_FULL;
@@ -1005,6 +999,35 @@ static int at803x_read_status(struct phy_device *phydev)
 		}
 	}
 
+	return 0;
+}
+
+static int at803x_read_status(struct phy_device *phydev)
+{
+	int err, old_link = phydev->link;
+
+	/* Update the link, but return if there was an error */
+	err = genphy_update_link(phydev);
+	if (err)
+		return err;
+
+	/* why bother the PHY if nothing can have changed */
+	if (phydev->autoneg == AUTONEG_ENABLE && old_link && phydev->link)
+		return 0;
+
+	phydev->speed = SPEED_UNKNOWN;
+	phydev->duplex = DUPLEX_UNKNOWN;
+	phydev->pause = 0;
+	phydev->asym_pause = 0;
+
+	err = genphy_read_lpa(phydev);
+	if (err < 0)
+		return err;
+
+	err = at803x_read_specific_status(phydev);
+	if (err < 0)
+		return err;
+
 	if (phydev->autoneg == AUTONEG_ENABLE && phydev->autoneg_complete)
 		phy_resolve_aneg_pause(phydev);
 
@@ -1324,6 +1347,33 @@ static int qca83xx_config_init(struct phy_device *phydev)
 	return 0;
 }
 
+static int qca808x_read_status(struct phy_device *phydev)
+{
+	int ret;
+
+	ret = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_AN_10GBT_STAT);
+	if (ret < 0)
+		return ret;
+
+	linkmode_mod_bit(ETHTOOL_LINK_MODE_2500baseT_Full_BIT, phydev->lp_advertising,
+			ret & MDIO_AN_10GBT_STAT_LP2_5G);
+
+	ret = genphy_read_status(phydev);
+	if (ret)
+		return ret;
+
+	ret = at803x_read_specific_status(phydev);
+	if (ret < 0)
+		return ret;
+
+	if (phydev->link && phydev->speed == SPEED_2500)
+		phydev->interface = PHY_INTERFACE_MODE_2500BASEX;
+	else
+		phydev->interface = PHY_INTERFACE_MODE_SMII;
+
+	return 0;
+}
+
 static struct phy_driver at803x_driver[] = {
 {
 	/* Qualcomm Atheros AR8035 */
@@ -1445,6 +1495,7 @@ static struct phy_driver at803x_driver[] = {
 	.get_wol		= at803x_get_wol,
 	.suspend		= genphy_suspend,
 	.resume			= genphy_resume,
+	.read_status		= qca808x_read_status,
 }, };
 
 module_phy_driver(at803x_driver);
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project


^ permalink raw reply related	[flat|nested] 36+ messages in thread

* [PATCH v3 07/13] net: phy: add qca8081 get_features
  2021-10-18  3:33 [PATCH v3 0/13] net: phy: Add qca8081 ethernet phy driver Luo Jie
                   ` (5 preceding siblings ...)
  2021-10-18  3:33 ` [PATCH v3 06/13] net: phy: add qca8081 read_status Luo Jie
@ 2021-10-18  3:33 ` Luo Jie
  2021-10-18 21:44   ` Andrew Lunn
  2021-10-18  3:33 ` [PATCH v3 08/13] net: phy: add qca8081 config_aneg Luo Jie
                   ` (5 subsequent siblings)
  12 siblings, 1 reply; 36+ messages in thread
From: Luo Jie @ 2021-10-18  3:33 UTC (permalink / raw)
  To: andrew, hkallweit1, linux, davem, kuba
  Cc: netdev, linux-kernel, sricharan, Luo Jie

Reuse the at803x phy driver get_features excepting
adding 2500M capability.

Signed-off-by: Luo Jie <luoj@codeaurora.org>
---
 drivers/net/phy/at803x.c | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/drivers/net/phy/at803x.c b/drivers/net/phy/at803x.c
index 42d3f8ccca94..0c22ef735230 100644
--- a/drivers/net/phy/at803x.c
+++ b/drivers/net/phy/at803x.c
@@ -719,6 +719,15 @@ static int at803x_get_features(struct phy_device *phydev)
 	if (err)
 		return err;
 
+	if (phydev->drv->phy_id == QCA8081_PHY_ID) {
+		err = phy_read_mmd(phydev, MDIO_MMD_PMAPMD, MDIO_PMA_NG_EXTABLE);
+		if (err < 0)
+			return err;
+
+		linkmode_mod_bit(ETHTOOL_LINK_MODE_2500baseT_Full_BIT, phydev->supported,
+				err & MDIO_PMA_NG_EXTABLE_2_5GBT);
+	}
+
 	if (phydev->drv->phy_id != ATH8031_PHY_ID)
 		return 0;
 
@@ -1493,6 +1502,7 @@ static struct phy_driver at803x_driver[] = {
 	.set_tunable		= at803x_set_tunable,
 	.set_wol		= at803x_set_wol,
 	.get_wol		= at803x_get_wol,
+	.get_features		= at803x_get_features,
 	.suspend		= genphy_suspend,
 	.resume			= genphy_resume,
 	.read_status		= qca808x_read_status,
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project


^ permalink raw reply related	[flat|nested] 36+ messages in thread

* [PATCH v3 08/13] net: phy: add qca8081 config_aneg
  2021-10-18  3:33 [PATCH v3 0/13] net: phy: Add qca8081 ethernet phy driver Luo Jie
                   ` (6 preceding siblings ...)
  2021-10-18  3:33 ` [PATCH v3 07/13] net: phy: add qca8081 get_features Luo Jie
@ 2021-10-18  3:33 ` Luo Jie
  2021-10-18 21:37   ` Andrew Lunn
  2021-10-18  3:33 ` [PATCH v3 09/13] net: phy: add constants for fast retrain related register Luo Jie
                   ` (4 subsequent siblings)
  12 siblings, 1 reply; 36+ messages in thread
From: Luo Jie @ 2021-10-18  3:33 UTC (permalink / raw)
  To: andrew, hkallweit1, linux, davem, kuba
  Cc: netdev, linux-kernel, sricharan, Luo Jie

Reuse at803x phy driver config_aneg excepting
adding 2500M auto-negotiation.

Signed-off-by: Luo Jie <luoj@codeaurora.org>
---
 drivers/net/phy/at803x.c | 26 +++++++++++++++++++++++++-
 1 file changed, 25 insertions(+), 1 deletion(-)

diff --git a/drivers/net/phy/at803x.c b/drivers/net/phy/at803x.c
index 0c22ef735230..c124d3fe40fb 100644
--- a/drivers/net/phy/at803x.c
+++ b/drivers/net/phy/at803x.c
@@ -1084,7 +1084,30 @@ static int at803x_config_aneg(struct phy_device *phydev)
 			return ret;
 	}
 
-	return genphy_config_aneg(phydev);
+	/* Do not restart auto-negotiation by setting ret to 0 defautly,
+	 * when calling __genphy_config_aneg later.
+	 */
+	ret = 0;
+
+	if (phydev->drv->phy_id == QCA8081_PHY_ID) {
+		int phy_ctrl = 0;
+
+		/* The reg MII_BMCR also needs to be configured for force mode, the
+		 * genphy_config_aneg is also needed.
+		 */
+		if (phydev->autoneg == AUTONEG_DISABLE)
+			genphy_c45_pma_setup_forced(phydev);
+
+		if (linkmode_test_bit(ETHTOOL_LINK_MODE_2500baseT_Full_BIT, phydev->advertising))
+			phy_ctrl = MDIO_AN_10GBT_CTRL_ADV2_5G;
+
+		ret = phy_modify_mmd_changed(phydev, MDIO_MMD_AN, MDIO_AN_10GBT_CTRL,
+				MDIO_AN_10GBT_CTRL_ADV2_5G, phy_ctrl);
+		if (ret < 0)
+			return ret;
+	}
+
+	return __genphy_config_aneg(phydev, ret);
 }
 
 static int at803x_get_downshift(struct phy_device *phydev, u8 *d)
@@ -1503,6 +1526,7 @@ static struct phy_driver at803x_driver[] = {
 	.set_wol		= at803x_set_wol,
 	.get_wol		= at803x_get_wol,
 	.get_features		= at803x_get_features,
+	.config_aneg		= at803x_config_aneg,
 	.suspend		= genphy_suspend,
 	.resume			= genphy_resume,
 	.read_status		= qca808x_read_status,
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project


^ permalink raw reply related	[flat|nested] 36+ messages in thread

* [PATCH v3 09/13] net: phy: add constants for fast retrain related register
  2021-10-18  3:33 [PATCH v3 0/13] net: phy: Add qca8081 ethernet phy driver Luo Jie
                   ` (7 preceding siblings ...)
  2021-10-18  3:33 ` [PATCH v3 08/13] net: phy: add qca8081 config_aneg Luo Jie
@ 2021-10-18  3:33 ` Luo Jie
  2021-10-18  3:33 ` [PATCH v3 10/13] net: phy: add qca8081 config_init Luo Jie
                   ` (3 subsequent siblings)
  12 siblings, 0 replies; 36+ messages in thread
From: Luo Jie @ 2021-10-18  3:33 UTC (permalink / raw)
  To: andrew, hkallweit1, linux, davem, kuba
  Cc: netdev, linux-kernel, sricharan, Luo Jie

Add constants for 2.5G and 5G fast retrain capability
in 10G AN control register, fast retrain status and
control register and THP bypass register into mdio.h.

Signed-off-by: Luo Jie <luoj@codeaurora.org>
---
 include/uapi/linux/mdio.h | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/include/uapi/linux/mdio.h b/include/uapi/linux/mdio.h
index bdf77dffa5a4..7276e7c3dc0a 100644
--- a/include/uapi/linux/mdio.h
+++ b/include/uapi/linux/mdio.h
@@ -53,12 +53,14 @@
 #define MDIO_AN_EEE_LPABLE	61	/* EEE link partner ability */
 #define MDIO_AN_EEE_ADV2	62	/* EEE advertisement 2 */
 #define MDIO_AN_EEE_LPABLE2	63	/* EEE link partner ability 2 */
+#define MDIO_AN_CTRL2		64	/* AN THP bypass request control */
 
 /* Media-dependent registers. */
 #define MDIO_PMA_10GBT_SWAPPOL	130	/* 10GBASE-T pair swap & polarity */
 #define MDIO_PMA_10GBT_TXPWR	131	/* 10GBASE-T TX power control */
 #define MDIO_PMA_10GBT_SNR	133	/* 10GBASE-T SNR margin, lane A.
 					 * Lanes B-D are numbered 134-136. */
+#define MDIO_PMA_10GBR_FSRT_CSR	147	/* 10GBASE-R fast retrain status and control */
 #define MDIO_PMA_10GBR_FECABLE	170	/* 10GBASE-R FEC ability */
 #define MDIO_PCS_10GBX_STAT1	24	/* 10GBASE-X PCS status 1 */
 #define MDIO_PCS_10GBRT_STAT1	32	/* 10GBASE-R/-T PCS status 1 */
@@ -239,6 +241,9 @@
 #define MDIO_PMA_10GBR_FECABLE_ABLE	0x0001	/* FEC ability */
 #define MDIO_PMA_10GBR_FECABLE_ERRABLE	0x0002	/* FEC error indic. ability */
 
+/* PMA 10GBASE-R Fast Retrain status and control register. */
+#define MDIO_PMA_10GBR_FSRT_ENABLE	0x0001	/* Fast retrain enable */
+
 /* PCS 10GBASE-R/-T status register 1. */
 #define MDIO_PCS_10GBRT_STAT1_BLKLK	0x0001	/* Block lock attained */
 
@@ -247,6 +252,8 @@
 #define MDIO_PCS_10GBRT_STAT2_BER	0x3f00
 
 /* AN 10GBASE-T control register. */
+#define MDIO_AN_10GBT_CTRL_ADVLPTIMING	0x0001	/* Advertise loop timing */
+#define MDIO_AN_10GBT_CTRL_ADVFSRT2_5G	0x0020	/* Advertise 2.5GBASE-T fast retrain */
 #define MDIO_AN_10GBT_CTRL_ADV2_5G	0x0080	/* Advertise 2.5GBASE-T */
 #define MDIO_AN_10GBT_CTRL_ADV5G	0x0100	/* Advertise 5GBASE-T */
 #define MDIO_AN_10GBT_CTRL_ADV10G	0x1000	/* Advertise 10GBASE-T */
@@ -289,6 +296,9 @@
 #define MDIO_EEE_2_5GT		0x0001	/* 2.5GT EEE cap */
 #define MDIO_EEE_5GT		0x0002	/* 5GT EEE cap */
 
+/* AN MultiGBASE-T AN control 2 */
+#define MDIO_AN_THP_BP2_5GT	0x0008	/* 2.5GT THP bypass request */
+
 /* 2.5G/5G Extended abilities register. */
 #define MDIO_PMA_NG_EXTABLE_2_5GBT	0x0001	/* 2.5GBASET ability */
 #define MDIO_PMA_NG_EXTABLE_5GBT	0x0002	/* 5GBASET ability */
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project


^ permalink raw reply related	[flat|nested] 36+ messages in thread

* [PATCH v3 10/13] net: phy: add qca8081 config_init
  2021-10-18  3:33 [PATCH v3 0/13] net: phy: Add qca8081 ethernet phy driver Luo Jie
                   ` (8 preceding siblings ...)
  2021-10-18  3:33 ` [PATCH v3 09/13] net: phy: add constants for fast retrain related register Luo Jie
@ 2021-10-18  3:33 ` Luo Jie
  2021-10-18 21:47   ` Andrew Lunn
  2021-10-18  3:33 ` [PATCH v3 11/13] net: phy: add qca8081 soft_reset and enable master/slave seed Luo Jie
                   ` (2 subsequent siblings)
  12 siblings, 1 reply; 36+ messages in thread
From: Luo Jie @ 2021-10-18  3:33 UTC (permalink / raw)
  To: andrew, hkallweit1, linux, davem, kuba
  Cc: netdev, linux-kernel, sricharan, Luo Jie

Add the qca8081 phy driver config_init function, which includes:
1. Enable fast restrain.
2. Add 802.3az configurations.
3. initialize ADC threshold as 100mv.

Signed-off-by: Luo Jie <luoj@codeaurora.org>
---
 drivers/net/phy/at803x.c | 119 +++++++++++++++++++++++++++++++++++++++
 1 file changed, 119 insertions(+)

diff --git a/drivers/net/phy/at803x.c b/drivers/net/phy/at803x.c
index c124d3fe40fb..8ab2084b9614 100644
--- a/drivers/net/phy/at803x.c
+++ b/drivers/net/phy/at803x.c
@@ -169,6 +169,51 @@
 #define AT803X_KEEP_PLL_ENABLED			BIT(0)
 #define AT803X_DISABLE_SMARTEEE			BIT(1)
 
+/* ADC threshold */
+#define QCA808X_PHY_DEBUG_ADC_THRESHOLD		0x2c80
+#define QCA808X_ADC_THRESHOLD_MASK		GENMASK(7, 0)
+#define QCA808X_ADC_THRESHOLD_80MV		0
+#define QCA808X_ADC_THRESHOLD_100MV		0xf0
+#define QCA808X_ADC_THRESHOLD_200MV		0x0f
+#define QCA808X_ADC_THRESHOLD_300MV		0xff
+
+/* CLD control */
+#define QCA808X_PHY_MMD3_ADDR_CLD_CTRL7		0x8007
+#define QCA808X_8023AZ_AFE_CTRL_MASK		GENMASK(8, 4)
+#define QCA808X_8023AZ_AFE_EN			0x90
+
+/* AZ control */
+#define QCA808X_PHY_MMD3_AZ_TRAINING_CTRL	0x8008
+#define QCA808X_MMD3_AZ_TRAINING_VAL		0x1c32
+
+#define QCA808X_PHY_MMD1_MSE_THRESHOLD_20DB	0x8014
+#define QCA808X_MSE_THRESHOLD_20DB_VALUE	0x529
+
+#define QCA808X_PHY_MMD1_MSE_THRESHOLD_17DB	0x800E
+#define QCA808X_MSE_THRESHOLD_17DB_VALUE	0x341
+
+#define QCA808X_PHY_MMD1_MSE_THRESHOLD_27DB	0x801E
+#define QCA808X_MSE_THRESHOLD_27DB_VALUE	0x419
+
+#define QCA808X_PHY_MMD1_MSE_THRESHOLD_28DB	0x8020
+#define QCA808X_MSE_THRESHOLD_28DB_VALUE	0x341
+
+#define QCA808X_PHY_MMD7_TOP_OPTION1		0x901c
+#define QCA808X_TOP_OPTION1_DATA		0x0
+
+#define QCA808X_PHY_MMD3_DEBUG_1		0xa100
+#define QCA808X_MMD3_DEBUG_1_VALUE		0x9203
+#define QCA808X_PHY_MMD3_DEBUG_2		0xa101
+#define QCA808X_MMD3_DEBUG_2_VALUE		0x48ad
+#define QCA808X_PHY_MMD3_DEBUG_3		0xa103
+#define QCA808X_MMD3_DEBUG_3_VALUE		0x1698
+#define QCA808X_PHY_MMD3_DEBUG_4		0xa105
+#define QCA808X_MMD3_DEBUG_4_VALUE		0x8001
+#define QCA808X_PHY_MMD3_DEBUG_5		0xa106
+#define QCA808X_MMD3_DEBUG_5_VALUE		0x1111
+#define QCA808X_PHY_MMD3_DEBUG_6		0xa011
+#define QCA808X_MMD3_DEBUG_6_VALUE		0x5f85
+
 MODULE_DESCRIPTION("Qualcomm Atheros AR803x and QCA808X PHY driver");
 MODULE_AUTHOR("Matus Ujhelyi");
 MODULE_LICENSE("GPL");
@@ -1379,6 +1424,79 @@ static int qca83xx_config_init(struct phy_device *phydev)
 	return 0;
 }
 
+static int qca808x_phy_fast_retrain_config(struct phy_device *phydev)
+{
+	int ret;
+
+	ret = phy_write_mmd(phydev, MDIO_MMD_AN, MDIO_AN_10GBT_CTRL,
+			MDIO_AN_10GBT_CTRL_ADV2_5G |
+			MDIO_AN_10GBT_CTRL_ADVFSRT2_5G |
+			MDIO_AN_10GBT_CTRL_ADVLPTIMING);
+	if (ret)
+		return ret;
+
+	ret = phy_write_mmd(phydev, MDIO_MMD_PMAPMD, MDIO_PMA_10GBR_FSRT_CSR,
+			MDIO_PMA_10GBR_FSRT_ENABLE);
+	if (ret)
+		return ret;
+
+	ret = phy_write_mmd(phydev, MDIO_MMD_AN, MDIO_AN_CTRL2, MDIO_AN_THP_BP2_5GT);
+	if (ret)
+		return ret;
+
+	phy_write_mmd(phydev, MDIO_MMD_AN, QCA808X_PHY_MMD7_TOP_OPTION1,
+			QCA808X_TOP_OPTION1_DATA);
+
+	phy_write_mmd(phydev, MDIO_MMD_PMAPMD, QCA808X_PHY_MMD1_MSE_THRESHOLD_20DB,
+			QCA808X_MSE_THRESHOLD_20DB_VALUE);
+	phy_write_mmd(phydev, MDIO_MMD_PMAPMD, QCA808X_PHY_MMD1_MSE_THRESHOLD_17DB,
+			QCA808X_MSE_THRESHOLD_17DB_VALUE);
+	phy_write_mmd(phydev, MDIO_MMD_PMAPMD, QCA808X_PHY_MMD1_MSE_THRESHOLD_27DB,
+			QCA808X_MSE_THRESHOLD_27DB_VALUE);
+	phy_write_mmd(phydev, MDIO_MMD_PMAPMD, QCA808X_PHY_MMD1_MSE_THRESHOLD_28DB,
+			QCA808X_MSE_THRESHOLD_28DB_VALUE);
+	phy_write_mmd(phydev, MDIO_MMD_PCS, QCA808X_PHY_MMD3_DEBUG_1,
+			QCA808X_MMD3_DEBUG_1_VALUE);
+	phy_write_mmd(phydev, MDIO_MMD_PCS, QCA808X_PHY_MMD3_DEBUG_4,
+			QCA808X_MMD3_DEBUG_4_VALUE);
+	phy_write_mmd(phydev, MDIO_MMD_PCS, QCA808X_PHY_MMD3_DEBUG_5,
+			QCA808X_MMD3_DEBUG_5_VALUE);
+	phy_write_mmd(phydev, MDIO_MMD_PCS, QCA808X_PHY_MMD3_DEBUG_3,
+			QCA808X_MMD3_DEBUG_3_VALUE);
+	phy_write_mmd(phydev, MDIO_MMD_PCS, QCA808X_PHY_MMD3_DEBUG_6,
+			QCA808X_MMD3_DEBUG_6_VALUE);
+	phy_write_mmd(phydev, MDIO_MMD_PCS, QCA808X_PHY_MMD3_DEBUG_2,
+			QCA808X_MMD3_DEBUG_2_VALUE);
+
+	return 0;
+}
+
+static int qca808x_config_init(struct phy_device *phydev)
+{
+	int ret;
+
+	/* Active adc&vga on 802.3az for the link 1000M and 100M */
+	ret = phy_modify_mmd(phydev, MDIO_MMD_PCS, QCA808X_PHY_MMD3_ADDR_CLD_CTRL7,
+			QCA808X_8023AZ_AFE_CTRL_MASK, QCA808X_8023AZ_AFE_EN);
+	if (ret)
+		return ret;
+
+	/* Adjust the threshold on 802.3az for the link 1000M */
+	ret = phy_write_mmd(phydev, MDIO_MMD_PCS,
+			QCA808X_PHY_MMD3_AZ_TRAINING_CTRL, QCA808X_MMD3_AZ_TRAINING_VAL);
+	if (ret)
+		return ret;
+
+	/* Config the fast retrain for the link 2500M */
+	ret = qca808x_phy_fast_retrain_config(phydev);
+	if (ret)
+		return ret;
+
+	/* Configure adc threshold as 100mv for the link 10M */
+	return at803x_debug_reg_mask(phydev, QCA808X_PHY_DEBUG_ADC_THRESHOLD,
+			QCA808X_ADC_THRESHOLD_MASK, QCA808X_ADC_THRESHOLD_100MV);
+}
+
 static int qca808x_read_status(struct phy_device *phydev)
 {
 	int ret;
@@ -1530,6 +1648,7 @@ static struct phy_driver at803x_driver[] = {
 	.suspend		= genphy_suspend,
 	.resume			= genphy_resume,
 	.read_status		= qca808x_read_status,
+	.config_init		= qca808x_config_init,
 }, };
 
 module_phy_driver(at803x_driver);
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project


^ permalink raw reply related	[flat|nested] 36+ messages in thread

* [PATCH v3 11/13] net: phy: add qca8081 soft_reset and enable master/slave seed
  2021-10-18  3:33 [PATCH v3 0/13] net: phy: Add qca8081 ethernet phy driver Luo Jie
                   ` (9 preceding siblings ...)
  2021-10-18  3:33 ` [PATCH v3 10/13] net: phy: add qca8081 config_init Luo Jie
@ 2021-10-18  3:33 ` Luo Jie
  2021-10-18  3:33 ` [PATCH v3 12/13] net: phy: adjust qca8081 master/slave seed value if link down Luo Jie
  2021-10-18  3:33 ` [PATCH v3 13/13] net: phy: add qca8081 cdt feature Luo Jie
  12 siblings, 0 replies; 36+ messages in thread
From: Luo Jie @ 2021-10-18  3:33 UTC (permalink / raw)
  To: andrew, hkallweit1, linux, davem, kuba
  Cc: netdev, linux-kernel, sricharan, Luo Jie

qca8081 phy is a single port phy, configure
phy the lower seed value to make it linked as slave
mode easier.

Signed-off-by: Luo Jie <luoj@codeaurora.org>
---
 drivers/net/phy/at803x.c | 47 ++++++++++++++++++++++++++++++++++++++++
 1 file changed, 47 insertions(+)

diff --git a/drivers/net/phy/at803x.c b/drivers/net/phy/at803x.c
index 8ab2084b9614..5d007f89e9d3 100644
--- a/drivers/net/phy/at803x.c
+++ b/drivers/net/phy/at803x.c
@@ -214,6 +214,12 @@
 #define QCA808X_PHY_MMD3_DEBUG_6		0xa011
 #define QCA808X_MMD3_DEBUG_6_VALUE		0x5f85
 
+/* master/slave seed config */
+#define QCA808X_PHY_DEBUG_LOCAL_SEED		9
+#define QCA808X_MASTER_SLAVE_SEED_ENABLE	BIT(1)
+#define QCA808X_MASTER_SLAVE_SEED_CFG		GENMASK(12, 2)
+#define QCA808X_MASTER_SLAVE_SEED_RANGE		0x32
+
 MODULE_DESCRIPTION("Qualcomm Atheros AR803x and QCA808X PHY driver");
 MODULE_AUTHOR("Matus Ujhelyi");
 MODULE_LICENSE("GPL");
@@ -1471,6 +1477,25 @@ static int qca808x_phy_fast_retrain_config(struct phy_device *phydev)
 	return 0;
 }
 
+static int qca808x_phy_ms_random_seed_set(struct phy_device *phydev)
+{
+	u16 seed_value = (prandom_u32() % QCA808X_MASTER_SLAVE_SEED_RANGE) << 2;
+
+	return at803x_debug_reg_mask(phydev, QCA808X_PHY_DEBUG_LOCAL_SEED,
+			QCA808X_MASTER_SLAVE_SEED_CFG, seed_value);
+}
+
+static int qca808x_phy_ms_seed_enable(struct phy_device *phydev, bool enable)
+{
+	u16 seed_enable = 0;
+
+	if (enable)
+		seed_enable = QCA808X_MASTER_SLAVE_SEED_ENABLE;
+
+	return at803x_debug_reg_mask(phydev, QCA808X_PHY_DEBUG_LOCAL_SEED,
+			QCA808X_MASTER_SLAVE_SEED_ENABLE, seed_enable);
+}
+
 static int qca808x_config_init(struct phy_device *phydev)
 {
 	int ret;
@@ -1492,6 +1517,16 @@ static int qca808x_config_init(struct phy_device *phydev)
 	if (ret)
 		return ret;
 
+	/* Configure lower ramdom seed to make phy linked as slave mode */
+	ret = qca808x_phy_ms_random_seed_set(phydev);
+	if (ret)
+		return ret;
+
+	/* Enable seed */
+	ret = qca808x_phy_ms_seed_enable(phydev, true);
+	if (ret)
+		return ret;
+
 	/* Configure adc threshold as 100mv for the link 10M */
 	return at803x_debug_reg_mask(phydev, QCA808X_PHY_DEBUG_ADC_THRESHOLD,
 			QCA808X_ADC_THRESHOLD_MASK, QCA808X_ADC_THRESHOLD_100MV);
@@ -1524,6 +1559,17 @@ static int qca808x_read_status(struct phy_device *phydev)
 	return 0;
 }
 
+static int qca808x_soft_reset(struct phy_device *phydev)
+{
+	int ret;
+
+	ret = genphy_soft_reset(phydev);
+	if (ret < 0)
+		return ret;
+
+	return qca808x_phy_ms_seed_enable(phydev, true);
+}
+
 static struct phy_driver at803x_driver[] = {
 {
 	/* Qualcomm Atheros AR8035 */
@@ -1649,6 +1695,7 @@ static struct phy_driver at803x_driver[] = {
 	.resume			= genphy_resume,
 	.read_status		= qca808x_read_status,
 	.config_init		= qca808x_config_init,
+	.soft_reset		= qca808x_soft_reset,
 }, };
 
 module_phy_driver(at803x_driver);
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project


^ permalink raw reply related	[flat|nested] 36+ messages in thread

* [PATCH v3 12/13] net: phy: adjust qca8081 master/slave seed value if link down
  2021-10-18  3:33 [PATCH v3 0/13] net: phy: Add qca8081 ethernet phy driver Luo Jie
                   ` (10 preceding siblings ...)
  2021-10-18  3:33 ` [PATCH v3 11/13] net: phy: add qca8081 soft_reset and enable master/slave seed Luo Jie
@ 2021-10-18  3:33 ` Luo Jie
  2021-10-18 22:04   ` Andrew Lunn
  2021-10-18  3:33 ` [PATCH v3 13/13] net: phy: add qca8081 cdt feature Luo Jie
  12 siblings, 1 reply; 36+ messages in thread
From: Luo Jie @ 2021-10-18  3:33 UTC (permalink / raw)
  To: andrew, hkallweit1, linux, davem, kuba
  Cc: netdev, linux-kernel, sricharan, Luo Jie

1. The master/slave seed needs to be updated when the link can't
be created.

2. The case where two qca8081 PHYs are connected each other and
master/slave seed is generated as the same value also needs
to be considered, so adding this code change into read_status
instead of link_change_notify.

Signed-off-by: Luo Jie <luoj@codeaurora.org>
---
 drivers/net/phy/at803x.c | 16 ++++++++++++++++
 1 file changed, 16 insertions(+)

diff --git a/drivers/net/phy/at803x.c b/drivers/net/phy/at803x.c
index 5d007f89e9d3..77aaf9e72781 100644
--- a/drivers/net/phy/at803x.c
+++ b/drivers/net/phy/at803x.c
@@ -1556,6 +1556,22 @@ static int qca808x_read_status(struct phy_device *phydev)
 	else
 		phydev->interface = PHY_INTERFACE_MODE_SMII;
 
+	/* generate seed as a lower random value to make PHY linked as SLAVE easily,
+	 * except for master/slave configuration fault detected.
+	 * the reason for not putting this code into the function link_change_notify is
+	 * the corner case where the link partner is also the qca8081 PHY and the seed
+	 * value is configured as the same value, the link can't be up and no link change
+	 * occurs.
+	 */
+	if (!phydev->link) {
+		if (phydev->master_slave_state == MASTER_SLAVE_STATE_ERR) {
+			qca808x_phy_ms_seed_enable(phydev, false);
+		} else {
+			qca808x_phy_ms_random_seed_set(phydev);
+			qca808x_phy_ms_seed_enable(phydev, true);
+		}
+	}
+
 	return 0;
 }
 
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project


^ permalink raw reply related	[flat|nested] 36+ messages in thread

* [PATCH v3 13/13] net: phy: add qca8081 cdt feature
  2021-10-18  3:33 [PATCH v3 0/13] net: phy: Add qca8081 ethernet phy driver Luo Jie
                   ` (11 preceding siblings ...)
  2021-10-18  3:33 ` [PATCH v3 12/13] net: phy: adjust qca8081 master/slave seed value if link down Luo Jie
@ 2021-10-18  3:33 ` Luo Jie
  12 siblings, 0 replies; 36+ messages in thread
From: Luo Jie @ 2021-10-18  3:33 UTC (permalink / raw)
  To: andrew, hkallweit1, linux, davem, kuba
  Cc: netdev, linux-kernel, sricharan, Luo Jie

To perform CDT of qca8081 phy:
1. disable hibernation.
2. force phy working in MDI mode.
3. force phy working in 1000BASE-T mode.
4. configure the related thresholds.

Signed-off-by: Luo Jie <luoj@codeaurora.org>
---
 drivers/net/phy/at803x.c | 193 ++++++++++++++++++++++++++++++++++++++-
 1 file changed, 190 insertions(+), 3 deletions(-)

diff --git a/drivers/net/phy/at803x.c b/drivers/net/phy/at803x.c
index 77aaf9e72781..f0928300b0d2 100644
--- a/drivers/net/phy/at803x.c
+++ b/drivers/net/phy/at803x.c
@@ -220,6 +220,32 @@
 #define QCA808X_MASTER_SLAVE_SEED_CFG		GENMASK(12, 2)
 #define QCA808X_MASTER_SLAVE_SEED_RANGE		0x32
 
+/* Hibernation yields lower power consumpiton in contrast with normal operation mode.
+ * when the copper cable is unplugged, the PHY enters into hibernation mode in about 10s.
+ */
+#define QCA808X_DBG_AN_TEST			0xb
+#define QCA808X_HIBERNATION_EN			BIT(15)
+
+#define QCA808X_CDT_ENABLE_TEST			BIT(15)
+#define QCA808X_CDT_INTER_CHECK_DIS		BIT(13)
+#define QCA808X_CDT_LENGTH_UNIT			BIT(10)
+
+#define QCA808X_MMD3_CDT_STATUS			0x8064
+#define QCA808X_MMD3_CDT_DIAG_PAIR_A		0x8065
+#define QCA808X_MMD3_CDT_DIAG_PAIR_B		0x8066
+#define QCA808X_MMD3_CDT_DIAG_PAIR_C		0x8067
+#define QCA808X_MMD3_CDT_DIAG_PAIR_D		0x8068
+#define QCA808X_CDT_DIAG_LENGTH			GENMASK(7, 0)
+
+#define QCA808X_CDT_CODE_PAIR_A			GENMASK(15, 12)
+#define QCA808X_CDT_CODE_PAIR_B			GENMASK(11, 8)
+#define QCA808X_CDT_CODE_PAIR_C			GENMASK(7, 4)
+#define QCA808X_CDT_CODE_PAIR_D			GENMASK(3, 0)
+#define QCA808X_CDT_STATUS_STAT_FAIL		0
+#define QCA808X_CDT_STATUS_STAT_NORMAL		1
+#define QCA808X_CDT_STATUS_STAT_OPEN		2
+#define QCA808X_CDT_STATUS_STAT_SHORT		3
+
 MODULE_DESCRIPTION("Qualcomm Atheros AR803x and QCA808X PHY driver");
 MODULE_AUTHOR("Matus Ujhelyi");
 MODULE_LICENSE("GPL");
@@ -1294,8 +1320,14 @@ static int at803x_cdt_start(struct phy_device *phydev, int pair)
 {
 	u16 cdt;
 
-	cdt = FIELD_PREP(AT803X_CDT_MDI_PAIR_MASK, pair) |
-	      AT803X_CDT_ENABLE_TEST;
+	/* qca8081 takes the different bit 15 to enable CDT test */
+	if (phydev->drv->phy_id == QCA8081_PHY_ID)
+		cdt = QCA808X_CDT_ENABLE_TEST |
+			QCA808X_CDT_LENGTH_UNIT |
+			QCA808X_CDT_INTER_CHECK_DIS;
+	else
+		cdt = FIELD_PREP(AT803X_CDT_MDI_PAIR_MASK, pair) |
+			AT803X_CDT_ENABLE_TEST;
 
 	return phy_write(phydev, AT803X_CDT, cdt);
 }
@@ -1303,10 +1335,16 @@ static int at803x_cdt_start(struct phy_device *phydev, int pair)
 static int at803x_cdt_wait_for_completion(struct phy_device *phydev)
 {
 	int val, ret;
+	u16 cdt_en;
+
+	if (phydev->drv->phy_id == QCA8081_PHY_ID)
+		cdt_en = QCA808X_CDT_ENABLE_TEST;
+	else
+		cdt_en = AT803X_CDT_ENABLE_TEST;
 
 	/* One test run takes about 25ms */
 	ret = phy_read_poll_timeout(phydev, AT803X_CDT, val,
-				    !(val & AT803X_CDT_ENABLE_TEST),
+				    !(val & cdt_en),
 				    30000, 100000, true);
 
 	return ret < 0 ? ret : 0;
@@ -1586,6 +1624,153 @@ static int qca808x_soft_reset(struct phy_device *phydev)
 	return qca808x_phy_ms_seed_enable(phydev, true);
 }
 
+static bool qca808x_cdt_fault_length_valid(int cdt_code)
+{
+	switch (cdt_code) {
+	case QCA808X_CDT_STATUS_STAT_SHORT:
+	case QCA808X_CDT_STATUS_STAT_OPEN:
+		return true;
+	default:
+		return false;
+	}
+}
+
+static int qca808x_cable_test_result_trans(int cdt_code)
+{
+	switch (cdt_code) {
+	case QCA808X_CDT_STATUS_STAT_NORMAL:
+		return ETHTOOL_A_CABLE_RESULT_CODE_OK;
+	case QCA808X_CDT_STATUS_STAT_SHORT:
+		return ETHTOOL_A_CABLE_RESULT_CODE_SAME_SHORT;
+	case QCA808X_CDT_STATUS_STAT_OPEN:
+		return ETHTOOL_A_CABLE_RESULT_CODE_OPEN;
+	case QCA808X_CDT_STATUS_STAT_FAIL:
+	default:
+		return ETHTOOL_A_CABLE_RESULT_CODE_UNSPEC;
+	}
+}
+
+static int qca808x_cdt_fault_length(struct phy_device *phydev, int pair)
+{
+	int val;
+	u32 cdt_length_reg = 0;
+
+	switch (pair) {
+	case ETHTOOL_A_CABLE_PAIR_A:
+		cdt_length_reg = QCA808X_MMD3_CDT_DIAG_PAIR_A;
+		break;
+	case ETHTOOL_A_CABLE_PAIR_B:
+		cdt_length_reg = QCA808X_MMD3_CDT_DIAG_PAIR_B;
+		break;
+	case ETHTOOL_A_CABLE_PAIR_C:
+		cdt_length_reg = QCA808X_MMD3_CDT_DIAG_PAIR_C;
+		break;
+	case ETHTOOL_A_CABLE_PAIR_D:
+		cdt_length_reg = QCA808X_MMD3_CDT_DIAG_PAIR_D;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	val = phy_read_mmd(phydev, MDIO_MMD_PCS, cdt_length_reg);
+	if (val < 0)
+		return val;
+
+	return (FIELD_GET(QCA808X_CDT_DIAG_LENGTH, val) * 824) / 10;
+}
+
+static int qca808x_cable_test_start(struct phy_device *phydev)
+{
+	int ret;
+
+	/* perform CDT with the following configs:
+	 * 1. disable hibernation.
+	 * 2. force PHY working in MDI mode.
+	 * 3. for PHY working in 1000BaseT.
+	 * 4. configure the threshold.
+	 */
+
+	ret = at803x_debug_reg_mask(phydev, QCA808X_DBG_AN_TEST, QCA808X_HIBERNATION_EN, 0);
+	if (ret < 0)
+		return ret;
+
+	ret = at803x_config_mdix(phydev, ETH_TP_MDI);
+	if (ret < 0)
+		return ret;
+
+	/* Force 1000base-T needs to configure PMA/PMD and MII_BMCR */
+	phydev->duplex = DUPLEX_FULL;
+	phydev->speed = SPEED_1000;
+	ret = genphy_c45_pma_setup_forced(phydev);
+	if (ret < 0)
+		return ret;
+
+	ret = genphy_setup_forced(phydev);
+	if (ret < 0)
+		return ret;
+
+	/* configure the thresholds for open, short, pair ok test */
+	phy_write_mmd(phydev, MDIO_MMD_PCS, 0x8074, 0xc040);
+	phy_write_mmd(phydev, MDIO_MMD_PCS, 0x8076, 0xc040);
+	phy_write_mmd(phydev, MDIO_MMD_PCS, 0x8077, 0xa060);
+	phy_write_mmd(phydev, MDIO_MMD_PCS, 0x8078, 0xc050);
+	phy_write_mmd(phydev, MDIO_MMD_PCS, 0x807a, 0xc060);
+	phy_write_mmd(phydev, MDIO_MMD_PCS, 0x807e, 0xb060);
+
+	return 0;
+}
+
+static int qca808x_cable_test_get_status(struct phy_device *phydev, bool *finished)
+{
+	int ret, val;
+	int pair_a, pair_b, pair_c, pair_d;
+
+	*finished = false;
+
+	ret = at803x_cdt_start(phydev, 0);
+	if (ret)
+		return ret;
+
+	ret = at803x_cdt_wait_for_completion(phydev);
+	if (ret)
+		return ret;
+
+	val = phy_read_mmd(phydev, MDIO_MMD_PCS, QCA808X_MMD3_CDT_STATUS);
+	if (val < 0)
+		return val;
+
+	pair_a = FIELD_GET(QCA808X_CDT_CODE_PAIR_A, val);
+	pair_b = FIELD_GET(QCA808X_CDT_CODE_PAIR_B, val);
+	pair_c = FIELD_GET(QCA808X_CDT_CODE_PAIR_C, val);
+	pair_d = FIELD_GET(QCA808X_CDT_CODE_PAIR_D, val);
+
+	ethnl_cable_test_result(phydev, ETHTOOL_A_CABLE_PAIR_A,
+				qca808x_cable_test_result_trans(pair_a));
+	ethnl_cable_test_result(phydev, ETHTOOL_A_CABLE_PAIR_B,
+				qca808x_cable_test_result_trans(pair_b));
+	ethnl_cable_test_result(phydev, ETHTOOL_A_CABLE_PAIR_C,
+				qca808x_cable_test_result_trans(pair_c));
+	ethnl_cable_test_result(phydev, ETHTOOL_A_CABLE_PAIR_D,
+				qca808x_cable_test_result_trans(pair_d));
+
+	if (qca808x_cdt_fault_length_valid(pair_a))
+		ethnl_cable_test_fault_length(phydev, ETHTOOL_A_CABLE_PAIR_A,
+				qca808x_cdt_fault_length(phydev, ETHTOOL_A_CABLE_PAIR_A));
+	if (qca808x_cdt_fault_length_valid(pair_b))
+		ethnl_cable_test_fault_length(phydev, ETHTOOL_A_CABLE_PAIR_B,
+				qca808x_cdt_fault_length(phydev, ETHTOOL_A_CABLE_PAIR_B));
+	if (qca808x_cdt_fault_length_valid(pair_c))
+		ethnl_cable_test_fault_length(phydev, ETHTOOL_A_CABLE_PAIR_C,
+				qca808x_cdt_fault_length(phydev, ETHTOOL_A_CABLE_PAIR_C));
+	if (qca808x_cdt_fault_length_valid(pair_d))
+		ethnl_cable_test_fault_length(phydev, ETHTOOL_A_CABLE_PAIR_D,
+				qca808x_cdt_fault_length(phydev, ETHTOOL_A_CABLE_PAIR_D));
+
+	*finished = true;
+
+	return 0;
+}
+
 static struct phy_driver at803x_driver[] = {
 {
 	/* Qualcomm Atheros AR8035 */
@@ -1712,6 +1897,8 @@ static struct phy_driver at803x_driver[] = {
 	.read_status		= qca808x_read_status,
 	.config_init		= qca808x_config_init,
 	.soft_reset		= qca808x_soft_reset,
+	.cable_test_start	= qca808x_cable_test_start,
+	.cable_test_get_status	= qca808x_cable_test_get_status,
 }, };
 
 module_phy_driver(at803x_driver);
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project


^ permalink raw reply related	[flat|nested] 36+ messages in thread

* Re: [PATCH v3 01/13] net: phy: at803x: replace AT803X_DEVICE_ADDR with MDIO_MMD_PCS
  2021-10-18  3:33 ` [PATCH v3 01/13] net: phy: at803x: replace AT803X_DEVICE_ADDR with MDIO_MMD_PCS Luo Jie
@ 2021-10-18 18:33   ` Andrew Lunn
  0 siblings, 0 replies; 36+ messages in thread
From: Andrew Lunn @ 2021-10-18 18:33 UTC (permalink / raw)
  To: Luo Jie; +Cc: hkallweit1, linux, davem, kuba, netdev, linux-kernel, sricharan

On Mon, Oct 18, 2021 at 11:33:21AM +0800, Luo Jie wrote:
> Replace AT803X_DEVICE_ADDR with MDIO_MMD_PCS defined in mdio.h.
> 
> Signed-off-by: Luo Jie <luoj@codeaurora.org>

Reviewed-by: Andrew Lunn <andrew@lunn.ch>

    Andrew

^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: [PATCH v3 02/13] net: phy: at803x: use phy_modify()
  2021-10-18  3:33 ` [PATCH v3 02/13] net: phy: at803x: use phy_modify() Luo Jie
@ 2021-10-18 18:34   ` Andrew Lunn
  0 siblings, 0 replies; 36+ messages in thread
From: Andrew Lunn @ 2021-10-18 18:34 UTC (permalink / raw)
  To: Luo Jie; +Cc: hkallweit1, linux, davem, kuba, netdev, linux-kernel, sricharan

On Mon, Oct 18, 2021 at 11:33:22AM +0800, Luo Jie wrote:
> Convert at803x_set_wol to use phy_modify.
> 
> Signed-off-by: Luo Jie <luoj@codeaurora.org>

Reviewed-by: Andrew Lunn <andrew@lunn.ch>

    Andrew

^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: [PATCH v3 03/13] net: phy: at803x: improve the WOL feature
  2021-10-18  3:33 ` [PATCH v3 03/13] net: phy: at803x: improve the WOL feature Luo Jie
@ 2021-10-18 18:41   ` Andrew Lunn
  2021-10-19 11:46     ` Jie Luo
  0 siblings, 1 reply; 36+ messages in thread
From: Andrew Lunn @ 2021-10-18 18:41 UTC (permalink / raw)
  To: Luo Jie; +Cc: hkallweit1, linux, davem, kuba, netdev, linux-kernel, sricharan

> @@ -348,18 +349,29 @@ static int at803x_set_wol(struct phy_device *phydev,
>  			phy_write_mmd(phydev, MDIO_MMD_PCS, offsets[i],
>  				      mac[(i * 2) + 1] | (mac[(i * 2)] << 8));
>  
> +		/* Enable WOL function */
> +		ret = phy_modify_mmd(phydev, MDIO_MMD_PCS, AT803X_PHY_MMD3_WOL_CTRL,
> +				0, AT803X_WOL_EN);
> +		if (ret)
> +			return ret;
> +		/* Enable WOL interrupt */
>  		ret = phy_modify(phydev, AT803X_INTR_ENABLE, 0, AT803X_INTR_ENABLE_WOL);
>  		if (ret)
>  			return ret;
> -		value = phy_read(phydev, AT803X_INTR_STATUS);
>  	} else {
> +		/* Disable WoL function */
> +		ret = phy_modify_mmd(phydev, MDIO_MMD_PCS, AT803X_PHY_MMD3_WOL_CTRL,
> +				AT803X_WOL_EN, 0);
> +		if (ret)
> +			return ret;
> +		/* Disable WOL interrupt */
>  		ret = phy_modify(phydev, AT803X_INTR_ENABLE, AT803X_INTR_ENABLE_WOL, 0);
>  		if (ret)
>  			return ret;
> -		value = phy_read(phydev, AT803X_INTR_STATUS);
>  	}
>  
> -	return ret;
> +	/* Clear WOL status */
> +	return phy_read(phydev, AT803X_INTR_STATUS);

It looks like you could be clearing other interrupt bits which have
not been serviced yet. Is it possible to clear just WoL?

Also, you are returning the contents of the interrupt status register?
You should probably be returning 0 if the read was successful.

    Andrew

^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: [PATCH v3 04/13] net: phy: at803x: use GENMASK() for speed status
  2021-10-18  3:33 ` [PATCH v3 04/13] net: phy: at803x: use GENMASK() for speed status Luo Jie
@ 2021-10-18 18:41   ` Andrew Lunn
  0 siblings, 0 replies; 36+ messages in thread
From: Andrew Lunn @ 2021-10-18 18:41 UTC (permalink / raw)
  To: Luo Jie; +Cc: hkallweit1, linux, davem, kuba, netdev, linux-kernel, sricharan

On Mon, Oct 18, 2021 at 11:33:24AM +0800, Luo Jie wrote:
> Use GENMASK() for the current speed value.
> 
> Signed-off-by: Luo Jie <luoj@codeaurora.org>

Reviewed-by: Andrew Lunn <andrew@lunn.ch>

    Andrew

^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: [PATCH v3 05/13] net: phy: add qca8081 ethernet phy driver
  2021-10-18  3:33 ` [PATCH v3 05/13] net: phy: add qca8081 ethernet phy driver Luo Jie
@ 2021-10-18 18:47   ` Andrew Lunn
  2021-10-19 11:48     ` Jie Luo
  0 siblings, 1 reply; 36+ messages in thread
From: Andrew Lunn @ 2021-10-18 18:47 UTC (permalink / raw)
  To: Luo Jie; +Cc: hkallweit1, linux, davem, kuba, netdev, linux-kernel, sricharan

> @@ -1441,6 +1455,7 @@ static struct mdio_device_id __maybe_unused atheros_tbl[] = {
>  	{ PHY_ID_MATCH_EXACT(ATH8032_PHY_ID) },
>  	{ PHY_ID_MATCH_EXACT(ATH8035_PHY_ID) },
>  	{ PHY_ID_MATCH_EXACT(ATH9331_PHY_ID) },
> +	{ PHY_ID_MATCH_EXACT(QCA8081_PHY_ID) },
>  	{ }

What tree is this against? I have:

static struct mdio_device_id __maybe_unused atheros_tbl[] = {
        { ATH8030_PHY_ID, AT8030_PHY_ID_MASK },
        { PHY_ID_MATCH_EXACT(ATH8031_PHY_ID) },
        { PHY_ID_MATCH_EXACT(ATH8032_PHY_ID) },
        { PHY_ID_MATCH_EXACT(ATH8035_PHY_ID) },
        { PHY_ID_MATCH_EXACT(ATH9331_PHY_ID) },
        { PHY_ID_MATCH_EXACT(QCA8337_PHY_ID) },
        { PHY_ID_MATCH_EXACT(QCA8327_A_PHY_ID) },
        { PHY_ID_MATCH_EXACT(QCA8327_B_PHY_ID) },
        { PHY_ID_MATCH_EXACT(QCA9561_PHY_ID) },
        { }
};

	Andrew

^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: [PATCH v3 08/13] net: phy: add qca8081 config_aneg
  2021-10-18  3:33 ` [PATCH v3 08/13] net: phy: add qca8081 config_aneg Luo Jie
@ 2021-10-18 21:37   ` Andrew Lunn
  2021-10-19 12:12     ` Jie Luo
  0 siblings, 1 reply; 36+ messages in thread
From: Andrew Lunn @ 2021-10-18 21:37 UTC (permalink / raw)
  To: Luo Jie; +Cc: hkallweit1, linux, davem, kuba, netdev, linux-kernel, sricharan

On Mon, Oct 18, 2021 at 11:33:28AM +0800, Luo Jie wrote:
> Reuse at803x phy driver config_aneg excepting
> adding 2500M auto-negotiation.
> 
> Signed-off-by: Luo Jie <luoj@codeaurora.org>
> ---
>  drivers/net/phy/at803x.c | 26 +++++++++++++++++++++++++-
>  1 file changed, 25 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/net/phy/at803x.c b/drivers/net/phy/at803x.c
> index 0c22ef735230..c124d3fe40fb 100644
> --- a/drivers/net/phy/at803x.c
> +++ b/drivers/net/phy/at803x.c
> @@ -1084,7 +1084,30 @@ static int at803x_config_aneg(struct phy_device *phydev)
>  			return ret;
>  	}
>  
> -	return genphy_config_aneg(phydev);
> +	/* Do not restart auto-negotiation by setting ret to 0 defautly,
> +	 * when calling __genphy_config_aneg later.
> +	 */
> +	ret = 0;
> +
> +	if (phydev->drv->phy_id == QCA8081_PHY_ID) {
> +		int phy_ctrl = 0;
> +
> +		/* The reg MII_BMCR also needs to be configured for force mode, the
> +		 * genphy_config_aneg is also needed.
> +		 */
> +		if (phydev->autoneg == AUTONEG_DISABLE)
> +			genphy_c45_pma_setup_forced(phydev);
> +
> +		if (linkmode_test_bit(ETHTOOL_LINK_MODE_2500baseT_Full_BIT, phydev->advertising))
> +			phy_ctrl = MDIO_AN_10GBT_CTRL_ADV2_5G;
> +
> +		ret = phy_modify_mmd_changed(phydev, MDIO_MMD_AN, MDIO_AN_10GBT_CTRL,
> +				MDIO_AN_10GBT_CTRL_ADV2_5G, phy_ctrl);

Does the PHY also have MDIO_MMD_AN, MDIO_AN_ADVERTISE ? I'm wondering
if you can use genphy_c45_an_config_aneg()

   Andrew

^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: [PATCH v3 06/13] net: phy: add qca8081 read_status
  2021-10-18  3:33 ` [PATCH v3 06/13] net: phy: add qca8081 read_status Luo Jie
@ 2021-10-18 21:42   ` Andrew Lunn
  2021-10-19 12:10     ` Jie Luo
  0 siblings, 1 reply; 36+ messages in thread
From: Andrew Lunn @ 2021-10-18 21:42 UTC (permalink / raw)
  To: Luo Jie; +Cc: hkallweit1, linux, davem, kuba, netdev, linux-kernel, sricharan

> +static int qca808x_read_status(struct phy_device *phydev)
> +{
> +	int ret;
> +
> +	ret = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_AN_10GBT_STAT);
> +	if (ret < 0)
> +		return ret;
> +
> +	linkmode_mod_bit(ETHTOOL_LINK_MODE_2500baseT_Full_BIT, phydev->lp_advertising,
> +			ret & MDIO_AN_10GBT_STAT_LP2_5G);
> +

Could genphy_c45_read_lpa() be used here?

      Andrew

^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: [PATCH v3 07/13] net: phy: add qca8081 get_features
  2021-10-18  3:33 ` [PATCH v3 07/13] net: phy: add qca8081 get_features Luo Jie
@ 2021-10-18 21:44   ` Andrew Lunn
  2021-10-20  6:39     ` Jie Luo
  0 siblings, 1 reply; 36+ messages in thread
From: Andrew Lunn @ 2021-10-18 21:44 UTC (permalink / raw)
  To: Luo Jie; +Cc: hkallweit1, linux, davem, kuba, netdev, linux-kernel, sricharan

On Mon, Oct 18, 2021 at 11:33:27AM +0800, Luo Jie wrote:
> Reuse the at803x phy driver get_features excepting
> adding 2500M capability.
> 
> Signed-off-by: Luo Jie <luoj@codeaurora.org>
> ---
>  drivers/net/phy/at803x.c | 10 ++++++++++
>  1 file changed, 10 insertions(+)
> 
> diff --git a/drivers/net/phy/at803x.c b/drivers/net/phy/at803x.c
> index 42d3f8ccca94..0c22ef735230 100644
> --- a/drivers/net/phy/at803x.c
> +++ b/drivers/net/phy/at803x.c
> @@ -719,6 +719,15 @@ static int at803x_get_features(struct phy_device *phydev)
>  	if (err)
>  		return err;
>  
> +	if (phydev->drv->phy_id == QCA8081_PHY_ID) {
> +		err = phy_read_mmd(phydev, MDIO_MMD_PMAPMD, MDIO_PMA_NG_EXTABLE);
> +		if (err < 0)
> +			return err;
> +
> +		linkmode_mod_bit(ETHTOOL_LINK_MODE_2500baseT_Full_BIT, phydev->supported,
> +				err & MDIO_PMA_NG_EXTABLE_2_5GBT);
> +	}

genphy_c45_pma_read_abilities()?

	Andrew

^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: [PATCH v3 10/13] net: phy: add qca8081 config_init
  2021-10-18  3:33 ` [PATCH v3 10/13] net: phy: add qca8081 config_init Luo Jie
@ 2021-10-18 21:47   ` Andrew Lunn
  2021-10-20  7:07     ` Jie Luo
  0 siblings, 1 reply; 36+ messages in thread
From: Andrew Lunn @ 2021-10-18 21:47 UTC (permalink / raw)
  To: Luo Jie; +Cc: hkallweit1, linux, davem, kuba, netdev, linux-kernel, sricharan

> +static int qca808x_phy_fast_retrain_config(struct phy_device *phydev)
> +{
> +	int ret;
> +
> +	ret = phy_write_mmd(phydev, MDIO_MMD_AN, MDIO_AN_10GBT_CTRL,
> +			MDIO_AN_10GBT_CTRL_ADV2_5G |
> +			MDIO_AN_10GBT_CTRL_ADVFSRT2_5G |
> +			MDIO_AN_10GBT_CTRL_ADVLPTIMING);
> +	if (ret)
> +		return ret;
> +
> +	ret = phy_write_mmd(phydev, MDIO_MMD_PMAPMD, MDIO_PMA_10GBR_FSRT_CSR,
> +			MDIO_PMA_10GBR_FSRT_ENABLE);
> +	if (ret)
> +		return ret;
> +
> +	ret = phy_write_mmd(phydev, MDIO_MMD_AN, MDIO_AN_CTRL2, MDIO_AN_THP_BP2_5GT);
> +	if (ret)
> +		return ret;

Could that be made generic and put into phy-c45.c? Is there anything
specific to your PHY here?

	 Andrew

^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: [PATCH v3 12/13] net: phy: adjust qca8081 master/slave seed value if link down
  2021-10-18  3:33 ` [PATCH v3 12/13] net: phy: adjust qca8081 master/slave seed value if link down Luo Jie
@ 2021-10-18 22:04   ` Andrew Lunn
  2021-10-20 13:27     ` Jie Luo
  0 siblings, 1 reply; 36+ messages in thread
From: Andrew Lunn @ 2021-10-18 22:04 UTC (permalink / raw)
  To: Luo Jie; +Cc: hkallweit1, linux, davem, kuba, netdev, linux-kernel, sricharan

On Mon, Oct 18, 2021 at 11:33:32AM +0800, Luo Jie wrote:
> 1. The master/slave seed needs to be updated when the link can't
> be created.
> 
> 2. The case where two qca8081 PHYs are connected each other and
> master/slave seed is generated as the same value also needs
> to be considered, so adding this code change into read_status
> instead of link_change_notify.
> 
> Signed-off-by: Luo Jie <luoj@codeaurora.org>
> ---
>  drivers/net/phy/at803x.c | 16 ++++++++++++++++
>  1 file changed, 16 insertions(+)
> 
> diff --git a/drivers/net/phy/at803x.c b/drivers/net/phy/at803x.c
> index 5d007f89e9d3..77aaf9e72781 100644
> --- a/drivers/net/phy/at803x.c
> +++ b/drivers/net/phy/at803x.c
> @@ -1556,6 +1556,22 @@ static int qca808x_read_status(struct phy_device *phydev)
>  	else
>  		phydev->interface = PHY_INTERFACE_MODE_SMII;
>  
> +	/* generate seed as a lower random value to make PHY linked as SLAVE easily,
> +	 * except for master/slave configuration fault detected.
> +	 * the reason for not putting this code into the function link_change_notify is
> +	 * the corner case where the link partner is also the qca8081 PHY and the seed
> +	 * value is configured as the same value, the link can't be up and no link change
> +	 * occurs.
> +	 */
> +	if (!phydev->link) {
> +		if (phydev->master_slave_state == MASTER_SLAVE_STATE_ERR) {
> +			qca808x_phy_ms_seed_enable(phydev, false);
> +		} else {
> +			qca808x_phy_ms_random_seed_set(phydev);
> +			qca808x_phy_ms_seed_enable(phydev, true);
> +		}
> +	}

Are you assuming here that the status is polled once a second, and
each poll you choose a new seed and see if it succeeds? What happens
when interrupts are used, not polling?

     Andrew

^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: [PATCH v3 03/13] net: phy: at803x: improve the WOL feature
  2021-10-18 18:41   ` Andrew Lunn
@ 2021-10-19 11:46     ` Jie Luo
  2021-10-19 12:29       ` Andrew Lunn
  0 siblings, 1 reply; 36+ messages in thread
From: Jie Luo @ 2021-10-19 11:46 UTC (permalink / raw)
  To: Andrew Lunn, Luo Jie
  Cc: hkallweit1, linux, davem, kuba, netdev, linux-kernel, sricharan


On 10/19/2021 2:41 AM, Andrew Lunn wrote:
>> @@ -348,18 +349,29 @@ static int at803x_set_wol(struct phy_device *phydev,
>>   			phy_write_mmd(phydev, MDIO_MMD_PCS, offsets[i],
>>   				      mac[(i * 2) + 1] | (mac[(i * 2)] << 8));
>>   
>> +		/* Enable WOL function */
>> +		ret = phy_modify_mmd(phydev, MDIO_MMD_PCS, AT803X_PHY_MMD3_WOL_CTRL,
>> +				0, AT803X_WOL_EN);
>> +		if (ret)
>> +			return ret;
>> +		/* Enable WOL interrupt */
>>   		ret = phy_modify(phydev, AT803X_INTR_ENABLE, 0, AT803X_INTR_ENABLE_WOL);
>>   		if (ret)
>>   			return ret;
>> -		value = phy_read(phydev, AT803X_INTR_STATUS);
>>   	} else {
>> +		/* Disable WoL function */
>> +		ret = phy_modify_mmd(phydev, MDIO_MMD_PCS, AT803X_PHY_MMD3_WOL_CTRL,
>> +				AT803X_WOL_EN, 0);
>> +		if (ret)
>> +			return ret;
>> +		/* Disable WOL interrupt */
>>   		ret = phy_modify(phydev, AT803X_INTR_ENABLE, AT803X_INTR_ENABLE_WOL, 0);
>>   		if (ret)
>>   			return ret;
>> -		value = phy_read(phydev, AT803X_INTR_STATUS);
>>   	}
>>   
>> -	return ret;
>> +	/* Clear WOL status */
>> +	return phy_read(phydev, AT803X_INTR_STATUS);
> It looks like you could be clearing other interrupt bits which have
> not been serviced yet. Is it possible to clear just WoL?

Hi Andrew,

when this register AT803X_INTR_STATUS bits are cleared after read, we 
can't clear only WOL interrupt here.

>
> Also, you are returning the contents of the interrupt status register?
> You should probably be returning 0 if the read was successful.
thanks for this comments, will correct it in the next patch set.
>
>      Andrew

^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: [PATCH v3 05/13] net: phy: add qca8081 ethernet phy driver
  2021-10-18 18:47   ` Andrew Lunn
@ 2021-10-19 11:48     ` Jie Luo
  0 siblings, 0 replies; 36+ messages in thread
From: Jie Luo @ 2021-10-19 11:48 UTC (permalink / raw)
  To: Andrew Lunn, Luo Jie
  Cc: hkallweit1, linux, davem, kuba, netdev, linux-kernel, sricharan


On 10/19/2021 2:47 AM, Andrew Lunn wrote:
>> @@ -1441,6 +1455,7 @@ static struct mdio_device_id __maybe_unused atheros_tbl[] = {
>>   	{ PHY_ID_MATCH_EXACT(ATH8032_PHY_ID) },
>>   	{ PHY_ID_MATCH_EXACT(ATH8035_PHY_ID) },
>>   	{ PHY_ID_MATCH_EXACT(ATH9331_PHY_ID) },
>> +	{ PHY_ID_MATCH_EXACT(QCA8081_PHY_ID) },
>>   	{ }
> What tree is this against? I have:
>
> static struct mdio_device_id __maybe_unused atheros_tbl[] = {
>          { ATH8030_PHY_ID, AT8030_PHY_ID_MASK },
>          { PHY_ID_MATCH_EXACT(ATH8031_PHY_ID) },
>          { PHY_ID_MATCH_EXACT(ATH8032_PHY_ID) },
>          { PHY_ID_MATCH_EXACT(ATH8035_PHY_ID) },
>          { PHY_ID_MATCH_EXACT(ATH9331_PHY_ID) },
>          { PHY_ID_MATCH_EXACT(QCA8337_PHY_ID) },
>          { PHY_ID_MATCH_EXACT(QCA8327_A_PHY_ID) },
>          { PHY_ID_MATCH_EXACT(QCA8327_B_PHY_ID) },
>          { PHY_ID_MATCH_EXACT(QCA9561_PHY_ID) },
>          { }
> };
>
> 	Andrew
will update it based on the latest tree in the next patch set.

^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: [PATCH v3 06/13] net: phy: add qca8081 read_status
  2021-10-18 21:42   ` Andrew Lunn
@ 2021-10-19 12:10     ` Jie Luo
  2021-10-19 12:31       ` Andrew Lunn
  0 siblings, 1 reply; 36+ messages in thread
From: Jie Luo @ 2021-10-19 12:10 UTC (permalink / raw)
  To: Andrew Lunn, Luo Jie
  Cc: hkallweit1, linux, davem, kuba, netdev, linux-kernel, sricharan


On 10/19/2021 5:42 AM, Andrew Lunn wrote:
>> +static int qca808x_read_status(struct phy_device *phydev)
>> +{
>> +	int ret;
>> +
>> +	ret = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_AN_10GBT_STAT);
>> +	if (ret < 0)
>> +		return ret;
>> +
>> +	linkmode_mod_bit(ETHTOOL_LINK_MODE_2500baseT_Full_BIT, phydev->lp_advertising,
>> +			ret & MDIO_AN_10GBT_STAT_LP2_5G);
>> +
> Could genphy_c45_read_lpa() be used here?
>
>        Andrew

Hi Andrew,

Thanks for the comments,  the MDIO_STAT1 of PHY does not follow the 
standard, bit0~bit6 of MDIO_STAT1 are

always 0, genphy_c45_read_lpa can't be used.


^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: [PATCH v3 08/13] net: phy: add qca8081 config_aneg
  2021-10-18 21:37   ` Andrew Lunn
@ 2021-10-19 12:12     ` Jie Luo
  0 siblings, 0 replies; 36+ messages in thread
From: Jie Luo @ 2021-10-19 12:12 UTC (permalink / raw)
  To: Andrew Lunn, Luo Jie
  Cc: hkallweit1, linux, davem, kuba, netdev, linux-kernel, sricharan


On 10/19/2021 5:37 AM, Andrew Lunn wrote:
> On Mon, Oct 18, 2021 at 11:33:28AM +0800, Luo Jie wrote:
>> Reuse at803x phy driver config_aneg excepting
>> adding 2500M auto-negotiation.
>>
>> Signed-off-by: Luo Jie <luoj@codeaurora.org>
>> ---
>>   drivers/net/phy/at803x.c | 26 +++++++++++++++++++++++++-
>>   1 file changed, 25 insertions(+), 1 deletion(-)
>>
>> diff --git a/drivers/net/phy/at803x.c b/drivers/net/phy/at803x.c
>> index 0c22ef735230..c124d3fe40fb 100644
>> --- a/drivers/net/phy/at803x.c
>> +++ b/drivers/net/phy/at803x.c
>> @@ -1084,7 +1084,30 @@ static int at803x_config_aneg(struct phy_device *phydev)
>>   			return ret;
>>   	}
>>   
>> -	return genphy_config_aneg(phydev);
>> +	/* Do not restart auto-negotiation by setting ret to 0 defautly,
>> +	 * when calling __genphy_config_aneg later.
>> +	 */
>> +	ret = 0;
>> +
>> +	if (phydev->drv->phy_id == QCA8081_PHY_ID) {
>> +		int phy_ctrl = 0;
>> +
>> +		/* The reg MII_BMCR also needs to be configured for force mode, the
>> +		 * genphy_config_aneg is also needed.
>> +		 */
>> +		if (phydev->autoneg == AUTONEG_DISABLE)
>> +			genphy_c45_pma_setup_forced(phydev);
>> +
>> +		if (linkmode_test_bit(ETHTOOL_LINK_MODE_2500baseT_Full_BIT, phydev->advertising))
>> +			phy_ctrl = MDIO_AN_10GBT_CTRL_ADV2_5G;
>> +
>> +		ret = phy_modify_mmd_changed(phydev, MDIO_MMD_AN, MDIO_AN_10GBT_CTRL,
>> +				MDIO_AN_10GBT_CTRL_ADV2_5G, phy_ctrl);
> Does the PHY also have MDIO_MMD_AN, MDIO_AN_ADVERTISE ? I'm wondering
> if you can use genphy_c45_an_config_aneg()
>
>     Andrew
Thanks Andrew for this comments, since the PHY does not have the regiser 
MDIO_AN_ADVERTISE,

genphy_c45_an_config_aneg can't be used here.


^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: [PATCH v3 03/13] net: phy: at803x: improve the WOL feature
  2021-10-19 11:46     ` Jie Luo
@ 2021-10-19 12:29       ` Andrew Lunn
  2021-10-19 12:42         ` Jie Luo
  0 siblings, 1 reply; 36+ messages in thread
From: Andrew Lunn @ 2021-10-19 12:29 UTC (permalink / raw)
  To: Jie Luo
  Cc: Luo Jie, hkallweit1, linux, davem, kuba, netdev, linux-kernel, sricharan

> Hi Andrew,
> 
> when this register AT803X_INTR_STATUS bits are cleared after read, we can't
> clear only WOL interrupt here.

O.K. But you do have the value of the interrupt status register. So
you could call phy_trigger_machine(phydev) if there are any other
interrupt pending. They won't get lost that way.

	  Andrew

^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: [PATCH v3 06/13] net: phy: add qca8081 read_status
  2021-10-19 12:10     ` Jie Luo
@ 2021-10-19 12:31       ` Andrew Lunn
  2021-10-19 12:48         ` Jie Luo
  0 siblings, 1 reply; 36+ messages in thread
From: Andrew Lunn @ 2021-10-19 12:31 UTC (permalink / raw)
  To: Jie Luo
  Cc: Luo Jie, hkallweit1, linux, davem, kuba, netdev, linux-kernel, sricharan

On Tue, Oct 19, 2021 at 08:10:15PM +0800, Jie Luo wrote:
> 
> On 10/19/2021 5:42 AM, Andrew Lunn wrote:
> > > +static int qca808x_read_status(struct phy_device *phydev)
> > > +{
> > > +	int ret;
> > > +
> > > +	ret = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_AN_10GBT_STAT);
> > > +	if (ret < 0)
> > > +		return ret;
> > > +
> > > +	linkmode_mod_bit(ETHTOOL_LINK_MODE_2500baseT_Full_BIT, phydev->lp_advertising,
> > > +			ret & MDIO_AN_10GBT_STAT_LP2_5G);
> > > +
> > Could genphy_c45_read_lpa() be used here?
> > 
> >        Andrew
> 
> Hi Andrew,
> 
> Thanks for the comments,  the MDIO_STAT1 of PHY does not follow the
> standard, bit0~bit6 of MDIO_STAT1 are
> 
> always 0, genphy_c45_read_lpa can't be used.

O.K. It is a shame the hardware partially follow the standard, but
breaks it as well. Why go to the effort of partially following it,
when you don't gain anything from it because you need custom code
anyway?

	Andrew

^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: [PATCH v3 03/13] net: phy: at803x: improve the WOL feature
  2021-10-19 12:29       ` Andrew Lunn
@ 2021-10-19 12:42         ` Jie Luo
  0 siblings, 0 replies; 36+ messages in thread
From: Jie Luo @ 2021-10-19 12:42 UTC (permalink / raw)
  To: Andrew Lunn
  Cc: Luo Jie, hkallweit1, linux, davem, kuba, netdev, linux-kernel, sricharan


On 10/19/2021 8:29 PM, Andrew Lunn wrote:
>> Hi Andrew,
>>
>> when this register AT803X_INTR_STATUS bits are cleared after read, we can't
>> clear only WOL interrupt here.
> O.K. But you do have the value of the interrupt status register. So
> you could call phy_trigger_machine(phydev) if there are any other
> interrupt pending. They won't get lost that way.
>
> 	  Andrew
This make sense, thanks for this comment, will add it in the next patch set.

^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: [PATCH v3 06/13] net: phy: add qca8081 read_status
  2021-10-19 12:31       ` Andrew Lunn
@ 2021-10-19 12:48         ` Jie Luo
  0 siblings, 0 replies; 36+ messages in thread
From: Jie Luo @ 2021-10-19 12:48 UTC (permalink / raw)
  To: Andrew Lunn
  Cc: Luo Jie, hkallweit1, linux, davem, kuba, netdev, linux-kernel, sricharan


On 10/19/2021 8:31 PM, Andrew Lunn wrote:
> On Tue, Oct 19, 2021 at 08:10:15PM +0800, Jie Luo wrote:
>> On 10/19/2021 5:42 AM, Andrew Lunn wrote:
>>>> +static int qca808x_read_status(struct phy_device *phydev)
>>>> +{
>>>> +	int ret;
>>>> +
>>>> +	ret = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_AN_10GBT_STAT);
>>>> +	if (ret < 0)
>>>> +		return ret;
>>>> +
>>>> +	linkmode_mod_bit(ETHTOOL_LINK_MODE_2500baseT_Full_BIT, phydev->lp_advertising,
>>>> +			ret & MDIO_AN_10GBT_STAT_LP2_5G);
>>>> +
>>> Could genphy_c45_read_lpa() be used here?
>>>
>>>         Andrew
>> Hi Andrew,
>>
>> Thanks for the comments,  the MDIO_STAT1 of PHY does not follow the
>> standard, bit0~bit6 of MDIO_STAT1 are
>>
>> always 0, genphy_c45_read_lpa can't be used.
> O.K. It is a shame the hardware partially follow the standard, but
> breaks it as well. Why go to the effort of partially following it,
> when you don't gain anything from it because you need custom code
> anyway?
>
> 	Andrew

Hi Andrew,

Thanks for the suggestion. qca8081 PHY indeed add 2.5G capability based 
on the

general 1G PHY, i will feedback this to the HW design team, thanks for 
this comments.


^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: [PATCH v3 07/13] net: phy: add qca8081 get_features
  2021-10-18 21:44   ` Andrew Lunn
@ 2021-10-20  6:39     ` Jie Luo
  2021-10-20 12:20       ` Andrew Lunn
  0 siblings, 1 reply; 36+ messages in thread
From: Jie Luo @ 2021-10-20  6:39 UTC (permalink / raw)
  To: Andrew Lunn, Luo Jie
  Cc: hkallweit1, linux, davem, kuba, netdev, linux-kernel, sricharan


On 10/19/2021 5:44 AM, Andrew Lunn wrote:
> On Mon, Oct 18, 2021 at 11:33:27AM +0800, Luo Jie wrote:
>> Reuse the at803x phy driver get_features excepting
>> adding 2500M capability.
>>
>> Signed-off-by: Luo Jie<luoj@codeaurora.org>
>> ---
>>   drivers/net/phy/at803x.c | 10 ++++++++++
>>   1 file changed, 10 insertions(+)
>>
>> diff --git a/drivers/net/phy/at803x.c b/drivers/net/phy/at803x.c
>> index 42d3f8ccca94..0c22ef735230 100644
>> --- a/drivers/net/phy/at803x.c
>> +++ b/drivers/net/phy/at803x.c
>> @@ -719,6 +719,15 @@ static int at803x_get_features(struct phy_device *phydev)
>>   	if (err)
>>   		return err;
>>   
>> +	if (phydev->drv->phy_id == QCA8081_PHY_ID) {
>> +		err = phy_read_mmd(phydev, MDIO_MMD_PMAPMD, MDIO_PMA_NG_EXTABLE);
>> +		if (err < 0)
>> +			return err;
>> +
>> +		linkmode_mod_bit(ETHTOOL_LINK_MODE_2500baseT_Full_BIT, phydev->supported,
>> +				err & MDIO_PMA_NG_EXTABLE_2_5GBT);
>> +	}
> genphy_c45_pma_read_abilities()?
>
> 	Andrew

Hi Andrew,

Thanks for this comment, if we use genphy_c45_pma_read_abilities here, 
the ETHTOOL_LINK_MODE_Autoneg_BIT

will be lost, since MDIO_MMD_AN.MDIO_STAT1 does not have bit 
MDIO_AN_STAT1_ABLE.



^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: [PATCH v3 10/13] net: phy: add qca8081 config_init
  2021-10-18 21:47   ` Andrew Lunn
@ 2021-10-20  7:07     ` Jie Luo
  0 siblings, 0 replies; 36+ messages in thread
From: Jie Luo @ 2021-10-20  7:07 UTC (permalink / raw)
  To: Andrew Lunn, Luo Jie
  Cc: hkallweit1, linux, davem, kuba, netdev, linux-kernel, sricharan


On 10/19/2021 5:47 AM, Andrew Lunn wrote:
>> +static int qca808x_phy_fast_retrain_config(struct phy_device *phydev)
>> +{
>> +	int ret;
>> +
>> +	ret = phy_write_mmd(phydev, MDIO_MMD_AN, MDIO_AN_10GBT_CTRL,
>> +			MDIO_AN_10GBT_CTRL_ADV2_5G |
>> +			MDIO_AN_10GBT_CTRL_ADVFSRT2_5G |
>> +			MDIO_AN_10GBT_CTRL_ADVLPTIMING);
>> +	if (ret)
>> +		return ret;
>> +
>> +	ret = phy_write_mmd(phydev, MDIO_MMD_PMAPMD, MDIO_PMA_10GBR_FSRT_CSR,
>> +			MDIO_PMA_10GBR_FSRT_ENABLE);
>> +	if (ret)
>> +		return ret;
>> +
>> +	ret = phy_write_mmd(phydev, MDIO_MMD_AN, MDIO_AN_CTRL2, MDIO_AN_THP_BP2_5GT);
>> +	if (ret)
>> +		return ret;
> Could that be made generic and put into phy-c45.c? Is there anything
> specific to your PHY here?
>
> 	 Andrew

Hi Andrew,

Thanks for the comments, there is no specific to the PHY, will put it 
into phy-c45.c in the next patch set.


^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: [PATCH v3 07/13] net: phy: add qca8081 get_features
  2021-10-20  6:39     ` Jie Luo
@ 2021-10-20 12:20       ` Andrew Lunn
  0 siblings, 0 replies; 36+ messages in thread
From: Andrew Lunn @ 2021-10-20 12:20 UTC (permalink / raw)
  To: Jie Luo
  Cc: Luo Jie, hkallweit1, linux, davem, kuba, netdev, linux-kernel, sricharan

On Wed, Oct 20, 2021 at 02:39:57PM +0800, Jie Luo wrote:
> 
> On 10/19/2021 5:44 AM, Andrew Lunn wrote:
> > On Mon, Oct 18, 2021 at 11:33:27AM +0800, Luo Jie wrote:
> > > Reuse the at803x phy driver get_features excepting
> > > adding 2500M capability.
> > > 
> > > Signed-off-by: Luo Jie<luoj@codeaurora.org>
> > > ---
> > >   drivers/net/phy/at803x.c | 10 ++++++++++
> > >   1 file changed, 10 insertions(+)
> > > 
> > > diff --git a/drivers/net/phy/at803x.c b/drivers/net/phy/at803x.c
> > > index 42d3f8ccca94..0c22ef735230 100644
> > > --- a/drivers/net/phy/at803x.c
> > > +++ b/drivers/net/phy/at803x.c
> > > @@ -719,6 +719,15 @@ static int at803x_get_features(struct phy_device *phydev)
> > >   	if (err)
> > >   		return err;
> > > +	if (phydev->drv->phy_id == QCA8081_PHY_ID) {
> > > +		err = phy_read_mmd(phydev, MDIO_MMD_PMAPMD, MDIO_PMA_NG_EXTABLE);
> > > +		if (err < 0)
> > > +			return err;
> > > +
> > > +		linkmode_mod_bit(ETHTOOL_LINK_MODE_2500baseT_Full_BIT, phydev->supported,
> > > +				err & MDIO_PMA_NG_EXTABLE_2_5GBT);
> > > +	}
> > genphy_c45_pma_read_abilities()?
> > 
> > 	Andrew
> 
> Hi Andrew,
> 
> Thanks for this comment, if we use genphy_c45_pma_read_abilities here, the
> ETHTOOL_LINK_MODE_Autoneg_BIT
> 
> will be lost, since MDIO_MMD_AN.MDIO_STAT1 does not have bit
> MDIO_AN_STAT1_ABLE.
 
Yes, if your PHY breaks the standard, the helpers are not much use,
that assume standard compliment PHYs.

     Andrew

^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: [PATCH v3 12/13] net: phy: adjust qca8081 master/slave seed value if link down
  2021-10-18 22:04   ` Andrew Lunn
@ 2021-10-20 13:27     ` Jie Luo
  0 siblings, 0 replies; 36+ messages in thread
From: Jie Luo @ 2021-10-20 13:27 UTC (permalink / raw)
  To: Andrew Lunn, Luo Jie
  Cc: hkallweit1, linux, davem, kuba, netdev, linux-kernel, sricharan


On 10/19/2021 6:04 AM, Andrew Lunn wrote:
> On Mon, Oct 18, 2021 at 11:33:32AM +0800, Luo Jie wrote:
>> 1. The master/slave seed needs to be updated when the link can't
>> be created.
>>
>> 2. The case where two qca8081 PHYs are connected each other and
>> master/slave seed is generated as the same value also needs
>> to be considered, so adding this code change into read_status
>> instead of link_change_notify.
>>
>> Signed-off-by: Luo Jie <luoj@codeaurora.org>
>> ---
>>   drivers/net/phy/at803x.c | 16 ++++++++++++++++
>>   1 file changed, 16 insertions(+)
>>
>> diff --git a/drivers/net/phy/at803x.c b/drivers/net/phy/at803x.c
>> index 5d007f89e9d3..77aaf9e72781 100644
>> --- a/drivers/net/phy/at803x.c
>> +++ b/drivers/net/phy/at803x.c
>> @@ -1556,6 +1556,22 @@ static int qca808x_read_status(struct phy_device *phydev)
>>   	else
>>   		phydev->interface = PHY_INTERFACE_MODE_SMII;
>>   
>> +	/* generate seed as a lower random value to make PHY linked as SLAVE easily,
>> +	 * except for master/slave configuration fault detected.
>> +	 * the reason for not putting this code into the function link_change_notify is
>> +	 * the corner case where the link partner is also the qca8081 PHY and the seed
>> +	 * value is configured as the same value, the link can't be up and no link change
>> +	 * occurs.
>> +	 */
>> +	if (!phydev->link) {
>> +		if (phydev->master_slave_state == MASTER_SLAVE_STATE_ERR) {
>> +			qca808x_phy_ms_seed_enable(phydev, false);
>> +		} else {
>> +			qca808x_phy_ms_random_seed_set(phydev);
>> +			qca808x_phy_ms_seed_enable(phydev, true);
>> +		}
>> +	}
> Are you assuming here that the status is polled once a second, and
> each poll you choose a new seed and see if it succeeds? What happens
> when interrupts are used, not polling?
>
>       Andrew

Hi Andrew,

yes, this code assumes that the PHY POLL is used, and choose a new 
random seed value

on each poll if no link is created.

when the interrupts is used, this corner case seems can't be covered 
since there is

no related interrupt occurs when the seed is configured as same value.


^ permalink raw reply	[flat|nested] 36+ messages in thread

end of thread, other threads:[~2021-10-20 13:27 UTC | newest]

Thread overview: 36+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-10-18  3:33 [PATCH v3 0/13] net: phy: Add qca8081 ethernet phy driver Luo Jie
2021-10-18  3:33 ` [PATCH v3 01/13] net: phy: at803x: replace AT803X_DEVICE_ADDR with MDIO_MMD_PCS Luo Jie
2021-10-18 18:33   ` Andrew Lunn
2021-10-18  3:33 ` [PATCH v3 02/13] net: phy: at803x: use phy_modify() Luo Jie
2021-10-18 18:34   ` Andrew Lunn
2021-10-18  3:33 ` [PATCH v3 03/13] net: phy: at803x: improve the WOL feature Luo Jie
2021-10-18 18:41   ` Andrew Lunn
2021-10-19 11:46     ` Jie Luo
2021-10-19 12:29       ` Andrew Lunn
2021-10-19 12:42         ` Jie Luo
2021-10-18  3:33 ` [PATCH v3 04/13] net: phy: at803x: use GENMASK() for speed status Luo Jie
2021-10-18 18:41   ` Andrew Lunn
2021-10-18  3:33 ` [PATCH v3 05/13] net: phy: add qca8081 ethernet phy driver Luo Jie
2021-10-18 18:47   ` Andrew Lunn
2021-10-19 11:48     ` Jie Luo
2021-10-18  3:33 ` [PATCH v3 06/13] net: phy: add qca8081 read_status Luo Jie
2021-10-18 21:42   ` Andrew Lunn
2021-10-19 12:10     ` Jie Luo
2021-10-19 12:31       ` Andrew Lunn
2021-10-19 12:48         ` Jie Luo
2021-10-18  3:33 ` [PATCH v3 07/13] net: phy: add qca8081 get_features Luo Jie
2021-10-18 21:44   ` Andrew Lunn
2021-10-20  6:39     ` Jie Luo
2021-10-20 12:20       ` Andrew Lunn
2021-10-18  3:33 ` [PATCH v3 08/13] net: phy: add qca8081 config_aneg Luo Jie
2021-10-18 21:37   ` Andrew Lunn
2021-10-19 12:12     ` Jie Luo
2021-10-18  3:33 ` [PATCH v3 09/13] net: phy: add constants for fast retrain related register Luo Jie
2021-10-18  3:33 ` [PATCH v3 10/13] net: phy: add qca8081 config_init Luo Jie
2021-10-18 21:47   ` Andrew Lunn
2021-10-20  7:07     ` Jie Luo
2021-10-18  3:33 ` [PATCH v3 11/13] net: phy: add qca8081 soft_reset and enable master/slave seed Luo Jie
2021-10-18  3:33 ` [PATCH v3 12/13] net: phy: adjust qca8081 master/slave seed value if link down Luo Jie
2021-10-18 22:04   ` Andrew Lunn
2021-10-20 13:27     ` Jie Luo
2021-10-18  3:33 ` [PATCH v3 13/13] net: phy: add qca8081 cdt feature Luo Jie

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.