All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH net-next v1] net: phy: at803x: add mdix configuration support for AR9331 and AR8035
@ 2020-07-19  8:05 Oleksij Rempel
  2020-07-19 15:04 ` Andrew Lunn
  2020-07-20  1:07 ` David Miller
  0 siblings, 2 replies; 3+ messages in thread
From: Oleksij Rempel @ 2020-07-19  8:05 UTC (permalink / raw)
  To: Andrew Lunn, Florian Fainelli, Heiner Kallweit
  Cc: Oleksij Rempel, David S. Miller, kernel, linux-kernel, netdev,
	Russell King

This patch add MDIX configuration ability for AR9331 and AR8035. Theoretically
it should work on other Atheros PHYs, but I was able to test only this
two.

Since I have no certified reference HW able to detect or configure MDIX, this
functionality was confirmed by oscilloscope.

Signed-off-by: Oleksij Rempel <o.rempel@pengutronix.de>
---
 drivers/net/phy/at803x.c | 78 ++++++++++++++++++++++++++++++++++++++++
 1 file changed, 78 insertions(+)

diff --git a/drivers/net/phy/at803x.c b/drivers/net/phy/at803x.c
index 96c61aa75bd7..101651b2de54 100644
--- a/drivers/net/phy/at803x.c
+++ b/drivers/net/phy/at803x.c
@@ -21,6 +21,17 @@
 #include <linux/regulator/consumer.h>
 #include <dt-bindings/net/qca-ar803x.h>
 
+#define AT803X_SPECIFIC_FUNCTION_CONTROL	0x10
+#define AT803X_SFC_ASSERT_CRS			BIT(11)
+#define AT803X_SFC_FORCE_LINK			BIT(10)
+#define AT803X_SFC_MDI_CROSSOVER_MODE_M		GENMASK(6, 5)
+#define AT803X_SFC_AUTOMATIC_CROSSOVER		0x3
+#define AT803X_SFC_MANUAL_MDIX			0x1
+#define AT803X_SFC_MANUAL_MDI			0x0
+#define AT803X_SFC_SQE_TEST			BIT(2)
+#define AT803X_SFC_POLARITY_REVERSAL		BIT(1)
+#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)
@@ -703,6 +714,12 @@ static int at803x_read_status(struct phy_device *phydev)
 		return ss;
 
 	if (ss & AT803X_SS_SPEED_DUPLEX_RESOLVED) {
+		int sfc;
+
+		sfc = phy_read(phydev, AT803X_SPECIFIC_FUNCTION_CONTROL);
+		if (sfc < 0)
+			return sfc;
+
 		switch (ss & AT803X_SS_SPEED_MASK) {
 		case AT803X_SS_SPEED_10:
 			phydev->speed = SPEED_10;
@@ -718,10 +735,23 @@ static int at803x_read_status(struct phy_device *phydev)
 			phydev->duplex = DUPLEX_FULL;
 		else
 			phydev->duplex = DUPLEX_HALF;
+
 		if (ss & AT803X_SS_MDIX)
 			phydev->mdix = ETH_TP_MDI_X;
 		else
 			phydev->mdix = ETH_TP_MDI;
+
+		switch (FIELD_GET(AT803X_SFC_MDI_CROSSOVER_MODE_M, sfc)) {
+		case AT803X_SFC_MANUAL_MDI:
+			phydev->mdix_ctrl = ETH_TP_MDI;
+			break;
+		case AT803X_SFC_MANUAL_MDIX:
+			phydev->mdix_ctrl = ETH_TP_MDI_X;
+			break;
+		case AT803X_SFC_AUTOMATIC_CROSSOVER:
+			phydev->mdix_ctrl = ETH_TP_MDI_AUTO;
+			break;
+		}
 	}
 
 	if (phydev->autoneg == AUTONEG_ENABLE && phydev->autoneg_complete)
@@ -730,6 +760,50 @@ static int at803x_read_status(struct phy_device *phydev)
 	return 0;
 }
 
+static int at803x_config_mdix(struct phy_device *phydev, u8 ctrl)
+{
+	u16 val;
+
+	switch (ctrl) {
+	case ETH_TP_MDI:
+		val = AT803X_SFC_MANUAL_MDI;
+		break;
+	case ETH_TP_MDI_X:
+		val = AT803X_SFC_MANUAL_MDIX;
+		break;
+	case ETH_TP_MDI_AUTO:
+		val = AT803X_SFC_AUTOMATIC_CROSSOVER;
+		break;
+	default:
+		return 0;
+	}
+
+	return phy_modify_changed(phydev, AT803X_SPECIFIC_FUNCTION_CONTROL,
+			  AT803X_SFC_MDI_CROSSOVER_MODE_M,
+			  FIELD_PREP(AT803X_SFC_MDI_CROSSOVER_MODE_M, val));
+}
+
+static int at803x_config_aneg(struct phy_device *phydev)
+{
+	int ret;
+
+	ret = at803x_config_mdix(phydev, phydev->mdix_ctrl);
+	if (ret < 0)
+		return ret;
+
+	/* Changes of the midx bits are disruptive to the normal operation;
+	 * therefore any changes to these registers must be followed by a
+	 * software reset to take effect.
+	 */
+	if (ret == 1) {
+		ret = genphy_soft_reset(phydev);
+		if (ret < 0)
+			return ret;
+	}
+
+	return genphy_config_aneg(phydev);
+}
+
 static int at803x_get_downshift(struct phy_device *phydev, u8 *d)
 {
 	int val;
@@ -979,6 +1053,7 @@ static struct phy_driver at803x_driver[] = {
 	.flags			= PHY_POLL_CABLE_TEST,
 	.probe			= at803x_probe,
 	.remove			= at803x_remove,
+	.config_aneg		= at803x_config_aneg,
 	.config_init		= at803x_config_init,
 	.soft_reset		= genphy_soft_reset,
 	.set_wol		= at803x_set_wol,
@@ -1061,6 +1136,9 @@ static struct phy_driver at803x_driver[] = {
 	.config_intr		= &at803x_config_intr,
 	.cable_test_start	= at803x_cable_test_start,
 	.cable_test_get_status	= at803x_cable_test_get_status,
+	.read_status		= at803x_read_status,
+	.soft_reset		= genphy_soft_reset,
+	.config_aneg		= at803x_config_aneg,
 } };
 
 module_phy_driver(at803x_driver);
-- 
2.27.0


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

* Re: [PATCH net-next v1] net: phy: at803x: add mdix configuration support for AR9331 and AR8035
  2020-07-19  8:05 [PATCH net-next v1] net: phy: at803x: add mdix configuration support for AR9331 and AR8035 Oleksij Rempel
@ 2020-07-19 15:04 ` Andrew Lunn
  2020-07-20  1:07 ` David Miller
  1 sibling, 0 replies; 3+ messages in thread
From: Andrew Lunn @ 2020-07-19 15:04 UTC (permalink / raw)
  To: Oleksij Rempel
  Cc: Florian Fainelli, Heiner Kallweit, David S. Miller, kernel,
	linux-kernel, netdev, Russell King

On Sun, Jul 19, 2020 at 10:05:30AM +0200, Oleksij Rempel wrote:
> This patch add MDIX configuration ability for AR9331 and AR8035. Theoretically
> it should work on other Atheros PHYs, but I was able to test only this
> two.
> 
> Since I have no certified reference HW able to detect or configure MDIX, this
> functionality was confirmed by oscilloscope.
> 
> Signed-off-by: Oleksij Rempel <o.rempel@pengutronix.de>
> ---
>  drivers/net/phy/at803x.c | 78 ++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 78 insertions(+)
> 
> diff --git a/drivers/net/phy/at803x.c b/drivers/net/phy/at803x.c
> index 96c61aa75bd7..101651b2de54 100644
> --- a/drivers/net/phy/at803x.c
> +++ b/drivers/net/phy/at803x.c
> @@ -21,6 +21,17 @@
>  #include <linux/regulator/consumer.h>
>  #include <dt-bindings/net/qca-ar803x.h>
>  
> +#define AT803X_SPECIFIC_FUNCTION_CONTROL	0x10
> +#define AT803X_SFC_ASSERT_CRS			BIT(11)
> +#define AT803X_SFC_FORCE_LINK			BIT(10)
> +#define AT803X_SFC_MDI_CROSSOVER_MODE_M		GENMASK(6, 5)
> +#define AT803X_SFC_AUTOMATIC_CROSSOVER		0x3
> +#define AT803X_SFC_MANUAL_MDIX			0x1
> +#define AT803X_SFC_MANUAL_MDI			0x0

Interestingly, these are the same bits as for the Marvell PHY. I had a
quick look at 802.3. The functionality is standardized, but not the
registers.

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

    Andrew

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

* Re: [PATCH net-next v1] net: phy: at803x: add mdix configuration support for AR9331 and AR8035
  2020-07-19  8:05 [PATCH net-next v1] net: phy: at803x: add mdix configuration support for AR9331 and AR8035 Oleksij Rempel
  2020-07-19 15:04 ` Andrew Lunn
@ 2020-07-20  1:07 ` David Miller
  1 sibling, 0 replies; 3+ messages in thread
From: David Miller @ 2020-07-20  1:07 UTC (permalink / raw)
  To: o.rempel
  Cc: andrew, f.fainelli, hkallweit1, kernel, linux-kernel, netdev, linux

From: Oleksij Rempel <o.rempel@pengutronix.de>
Date: Sun, 19 Jul 2020 10:05:30 +0200

> This patch add MDIX configuration ability for AR9331 and AR8035. Theoretically
> it should work on other Atheros PHYs, but I was able to test only this
> two.
> 
> Since I have no certified reference HW able to detect or configure MDIX, this
> functionality was confirmed by oscilloscope.
> 
> Signed-off-by: Oleksij Rempel <o.rempel@pengutronix.de>

Applied, thank you.

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

end of thread, other threads:[~2020-07-20  1:07 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-07-19  8:05 [PATCH net-next v1] net: phy: at803x: add mdix configuration support for AR9331 and AR8035 Oleksij Rempel
2020-07-19 15:04 ` Andrew Lunn
2020-07-20  1:07 ` David Miller

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.