All of lore.kernel.org
 help / color / mirror / Atom feed
From: <alexandru.tachici@analog.com>
To: <netdev@vger.kernel.org>, <linux-kernel@vger.kernel.org>
Cc: <andrew@lunn.ch>, <davem@davemloft.net>, <kuba@kernel.org>,
	<linux@armlinux.org.uk>,
	Alexandru Tachici <alexandru.tachici@analog.com>
Subject: [PATCH 3/4] net: phy: adin1100: Add ethtool master-slave support
Date: Thu, 24 Jun 2021 17:53:52 +0300	[thread overview]
Message-ID: <20210624145353.6910-4-alexandru.tachici@analog.com> (raw)
In-Reply-To: <20210624145353.6910-1-alexandru.tachici@analog.com>

From: Alexandru Tachici <alexandru.tachici@analog.com>

Allow user to select the advertised master-slave
configuration through ethtool.

Signed-off-by: Alexandru Tachici <alexandru.tachici@analog.com>
---
 drivers/net/phy/adin1100.c | 78 +++++++++++++++++++++++++++++++++++++-
 1 file changed, 77 insertions(+), 1 deletion(-)

diff --git a/drivers/net/phy/adin1100.c b/drivers/net/phy/adin1100.c
index f0674a0e8e8a..a8ddf5a9879a 100644
--- a/drivers/net/phy/adin1100.c
+++ b/drivers/net/phy/adin1100.c
@@ -36,7 +36,11 @@ static const int phy_10_features_array[] = {
 
 #define ADIN_AN_STATUS				0x0201
 #define ADIN_AN_ADV_ABILITY_L			0x0202
+#define   ADIN_AN_ADV_FORCE_MS			BIT(12)
+
 #define ADIN_AN_ADV_ABILITY_M			0x0203
+#define   ADIN_AN_ADV_MST			BIT(4)
+
 #define ADIN_AN_ADV_ABILITY_H			0x0204U
 #define   ADIN_AN_ADV_B10L_TX_LVL_HI_ABL	BIT(13)
 #define   ADIN_AN_ADV_B10L_TX_LVL_HI_REQ	BIT(12)
@@ -68,6 +72,10 @@ static const int phy_10_features_array[] = {
 #define   ADIN_CRSM_SFT_PD_RDY			BIT(1)
 #define   ADIN_CRSM_SYS_RDY			BIT(0)
 
+#define AN_PHY_INST_STATUS			0x8030
+#define   ADIN_IS_CFG_SLV			BIT(2)
+#define   ADIN_IS_CFG_MST			BIT(3)
+
 #define ADIN_MAC_IF_LOOPBACK			0x803d
 #define   ADIN_MAC_IF_LOOPBACK_EN		BIT(0)
 #define   ADIN_MAC_IF_REMOTE_LOOPBACK_EN	BIT(2)
@@ -203,6 +211,7 @@ static int adin_read_lpa(struct phy_device *phydev)
 static int adin_read_status(struct phy_device *phydev)
 {
 	int ret;
+	int cfg;
 
 	ret = genphy_c45_read_link(phydev);
 	if (ret)
@@ -212,6 +221,8 @@ static int adin_read_status(struct phy_device *phydev)
 	phydev->duplex = DUPLEX_UNKNOWN;
 	phydev->pause = 0;
 	phydev->asym_pause = 0;
+	phydev->master_slave_get = MASTER_SLAVE_CFG_UNKNOWN;
+	phydev->master_slave_state = MASTER_SLAVE_STATE_UNKNOWN;
 
 	if (phydev->autoneg == AUTONEG_ENABLE) {
 		ret = adin_read_lpa(phydev);
@@ -226,7 +237,37 @@ static int adin_read_status(struct phy_device *phydev)
 		phydev->duplex = DUPLEX_FULL;
 	}
 
-	return ret;
+	ret = phy_read_mmd(phydev, MDIO_MMD_AN, ADIN_AN_ADV_ABILITY_L);
+	if (ret < 0)
+		return ret;
+
+	cfg = phy_read_mmd(phydev, MDIO_MMD_AN, ADIN_AN_ADV_ABILITY_M);
+	if (cfg < 0)
+		return cfg;
+
+	if (ret & ADIN_AN_ADV_FORCE_MS) {
+		if (cfg & ADIN_AN_ADV_MST)
+			phydev->master_slave_get = MASTER_SLAVE_CFG_MASTER_FORCE;
+		else
+			phydev->master_slave_get = MASTER_SLAVE_CFG_SLAVE_FORCE;
+	} else {
+		if (cfg & ADIN_AN_ADV_MST)
+			phydev->master_slave_get = MASTER_SLAVE_CFG_MASTER_PREFERRED;
+		else
+			phydev->master_slave_get = MASTER_SLAVE_CFG_SLAVE_PREFERRED;
+	}
+
+	ret = phy_read_mmd(phydev, MDIO_MMD_AN, AN_PHY_INST_STATUS);
+	if (ret < 0)
+		return ret;
+
+	if (ret & ADIN_IS_CFG_SLV)
+		phydev->master_slave_state = MASTER_SLAVE_STATE_SLAVE;
+
+	if (ret & ADIN_IS_CFG_MST)
+		phydev->master_slave_state = MASTER_SLAVE_STATE_MASTER;
+
+	return 0;
 }
 
 static int adin_config_aneg(struct phy_device *phydev)
@@ -240,6 +281,41 @@ static int adin_config_aneg(struct phy_device *phydev)
 	if (phydev->autoneg == AUTONEG_DISABLE)
 		return 0;
 
+	switch (phydev->master_slave_set) {
+	case MASTER_SLAVE_CFG_MASTER_FORCE:
+	case MASTER_SLAVE_CFG_SLAVE_FORCE:
+		ret = phy_set_bits_mmd(phydev, MDIO_MMD_AN, ADIN_AN_ADV_ABILITY_L,
+				       ADIN_AN_ADV_FORCE_MS);
+		if (ret < 0)
+			return ret;
+		break;
+	case MASTER_SLAVE_CFG_MASTER_PREFERRED:
+	case MASTER_SLAVE_CFG_SLAVE_PREFERRED:
+		ret = phy_clear_bits_mmd(phydev, MDIO_MMD_AN, ADIN_AN_ADV_ABILITY_L,
+					 ADIN_AN_ADV_FORCE_MS);
+		break;
+	default:
+		break;
+	}
+
+	switch (phydev->master_slave_set) {
+	case MASTER_SLAVE_CFG_MASTER_FORCE:
+	case MASTER_SLAVE_CFG_MASTER_PREFERRED:
+		ret = phy_set_bits_mmd(phydev, MDIO_MMD_AN, ADIN_AN_ADV_ABILITY_M, ADIN_AN_ADV_MST);
+		if (ret < 0)
+			return ret;
+		break;
+	case MASTER_SLAVE_CFG_SLAVE_FORCE:
+	case MASTER_SLAVE_CFG_SLAVE_PREFERRED:
+		ret = phy_clear_bits_mmd(phydev, MDIO_MMD_AN, ADIN_AN_ADV_ABILITY_M,
+					 ADIN_AN_ADV_MST);
+		if (ret < 0)
+			return ret;
+		break;
+	default:
+		break;
+	}
+
 	if (priv->tx_level_24v)
 		ret = phy_set_bits_mmd(phydev, MDIO_MMD_AN,
 				       ADIN_AN_ADV_ABILITY_H,
-- 
2.25.1


  parent reply	other threads:[~2021-06-24 14:45 UTC|newest]

Thread overview: 10+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-06-24 14:53 [PATCH 0/4] net: phy: adin1100: Add initial support for ADIN1100 industrial PHY alexandru.tachici
2021-06-24 14:53 ` [PATCH 1/4] " alexandru.tachici
2021-06-24 17:15   ` Andrew Lunn
2021-06-24 17:23   ` Andrew Lunn
2021-06-24 22:26   ` kernel test robot
2021-06-24 22:26     ` kernel test robot
2021-06-24 14:53 ` [PATCH 2/4] net: phy: adin1100: Add ethtool get_stats support alexandru.tachici
2021-06-24 17:19   ` Andrew Lunn
2021-06-24 14:53 ` alexandru.tachici [this message]
2021-06-24 14:53 ` [PATCH 4/4] net: phy: adin1100: Add SQI support alexandru.tachici

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20210624145353.6910-4-alexandru.tachici@analog.com \
    --to=alexandru.tachici@analog.com \
    --cc=andrew@lunn.ch \
    --cc=davem@davemloft.net \
    --cc=kuba@kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux@armlinux.org.uk \
    --cc=netdev@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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.