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
next prev 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.