2024-04-02 20:11:48

by Pawel Dembicki

[permalink] [raw]
Subject: [PATCH net-next v3 1/3] net: phy: marvell: add basic support of 88E308X/88E609X family

This patch implements only basic support.

It covers PHY used in multiple IC:
PHY: 88E3082, 88E3083
Switch: 88E6096, 88E6097

Signed-off-by: Pawel Dembicki <[email protected]>

---
v3,v2:
- resend only

drivers/net/phy/marvell.c | 13 +++++++++++++
include/linux/marvell_phy.h | 1 +
2 files changed, 14 insertions(+)

diff --git a/drivers/net/phy/marvell.c b/drivers/net/phy/marvell.c
index 42ed013385bf..fae7eb57ee2c 100644
--- a/drivers/net/phy/marvell.c
+++ b/drivers/net/phy/marvell.c
@@ -3289,6 +3289,18 @@ static struct phy_driver marvell_drivers[] = {
.get_strings = marvell_get_strings,
.get_stats = marvell_get_stats,
},
+ {
+ .phy_id = MARVELL_PHY_ID_88E3082,
+ .phy_id_mask = MARVELL_PHY_ID_MASK,
+ .name = "Marvell 88E308X/88E609X Family",
+ /* PHY_BASIC_FEATURES */
+ .probe = marvell_probe,
+ .config_init = marvell_config_init,
+ .aneg_done = marvell_aneg_done,
+ .read_status = marvell_read_status,
+ .resume = genphy_resume,
+ .suspend = genphy_suspend,
+ },
{
.phy_id = MARVELL_PHY_ID_88E1112,
.phy_id_mask = MARVELL_PHY_ID_MASK,
@@ -3742,6 +3754,7 @@ module_phy_driver(marvell_drivers);

static struct mdio_device_id __maybe_unused marvell_tbl[] = {
{ MARVELL_PHY_ID_88E1101, MARVELL_PHY_ID_MASK },
+ { MARVELL_PHY_ID_88E3082, MARVELL_PHY_ID_MASK },
{ MARVELL_PHY_ID_88E1112, MARVELL_PHY_ID_MASK },
{ MARVELL_PHY_ID_88E1111, MARVELL_PHY_ID_MASK },
{ MARVELL_PHY_ID_88E1111_FINISAR, MARVELL_PHY_ID_MASK },
diff --git a/include/linux/marvell_phy.h b/include/linux/marvell_phy.h
index 693eba9869e4..88254f9aec2b 100644
--- a/include/linux/marvell_phy.h
+++ b/include/linux/marvell_phy.h
@@ -7,6 +7,7 @@

/* Known PHY IDs */
#define MARVELL_PHY_ID_88E1101 0x01410c60
+#define MARVELL_PHY_ID_88E3082 0x01410c80
#define MARVELL_PHY_ID_88E1112 0x01410c90
#define MARVELL_PHY_ID_88E1111 0x01410cc0
#define MARVELL_PHY_ID_88E1118 0x01410e10
--
2.25.1



2024-04-02 20:12:58

by Pawel Dembicki

[permalink] [raw]
Subject: [PATCH net-next v3 3/3] net: phy: marvell: implement cable-test for 88E308X/88E609X family

This commit implements VCT in 88E308X/88E609X Family.

It require two workarounds with some magic configuration.
Regular use require only one register configuration. But Open Circuit
require second workaround.
It cause implementation two phases for fault length measuring.

Fast Ethernet PHY have implemented very simple version of VCT. It's
complitley different than vct5 or vct7.

Signed-off-by: Pawel Dembicki <[email protected]>

---
v3:
- resend only
v2:
- change 'm88e3082_vct_distrfln_2_cm' to static
- simplify 'm88e3082_vct_cable_test_get_status'
- replace magic numbers in MII_BMCR configuration
- remove unnecessary backup of MII_BMCR register
- use ETHTOOL_A_CABLE_RESULT_CODE_IMPEDANCE_MISMATCH for impedance
mismatch

drivers/net/phy/marvell.c | 208 ++++++++++++++++++++++++++++++++++++++
1 file changed, 208 insertions(+)

diff --git a/drivers/net/phy/marvell.c b/drivers/net/phy/marvell.c
index fae7eb57ee2c..7c00f47e4ded 100644
--- a/drivers/net/phy/marvell.c
+++ b/drivers/net/phy/marvell.c
@@ -279,6 +279,23 @@
#define MII_VCT7_CTRL_METERS BIT(10)
#define MII_VCT7_CTRL_CENTIMETERS 0

+#define MII_VCT_TXPINS 0x1A
+#define MII_VCT_RXPINS 0x1B
+#define MII_VCT_TXPINS_ENVCT BIT(15)
+#define MII_VCT_TXRXPINS_VCTTST GENMASK(14, 13)
+#define MII_VCT_TXRXPINS_VCTTST_SHIFT 13
+#define MII_VCT_TXRXPINS_VCTTST_OK 0
+#define MII_VCT_TXRXPINS_VCTTST_SHORT 1
+#define MII_VCT_TXRXPINS_VCTTST_OPEN 2
+#define MII_VCT_TXRXPINS_VCTTST_FAIL 3
+#define MII_VCT_TXRXPINS_AMPRFLN GENMASK(12, 8)
+#define MII_VCT_TXRXPINS_AMPRFLN_SHIFT 8
+#define MII_VCT_TXRXPINS_DISTRFLN GENMASK(7, 0)
+#define MII_VCT_TXRXPINS_DISTRFLN_MAX 0xff
+
+#define M88E3082_PAIR_A BIT(0)
+#define M88E3082_PAIR_B BIT(1)
+
#define LPA_PAUSE_FIBER 0x180
#define LPA_PAUSE_ASYM_FIBER 0x100

@@ -301,6 +318,12 @@ static struct marvell_hw_stat marvell_hw_stats[] = {
{ "phy_receive_errors_fiber", 1, 21, 16},
};

+enum {
+ M88E3082_VCT_OFF,
+ M88E3082_VCT_PHASE1,
+ M88E3082_VCT_PHASE2,
+};
+
struct marvell_priv {
u64 stats[ARRAY_SIZE(marvell_hw_stats)];
char *hwmon_name;
@@ -310,6 +333,7 @@ struct marvell_priv {
u32 last;
u32 step;
s8 pair;
+ u8 vct_phase;
};

static int marvell_read_page(struct phy_device *phydev)
@@ -2417,6 +2441,188 @@ static int marvell_vct7_cable_test_get_status(struct phy_device *phydev,
return 0;
}

+static int m88e3082_vct_cable_test_start(struct phy_device *phydev)
+{
+ struct marvell_priv *priv = phydev->priv;
+ int ret;
+
+ /* It needs some magic workarounds described in VCT manual for this PHY.
+ */
+ ret = phy_write(phydev, 29, 0x0003);
+ if (ret < 0)
+ return ret;
+
+ ret = phy_write(phydev, 30, 0x6440);
+ if (ret < 0)
+ return ret;
+
+ if (priv->vct_phase == M88E3082_VCT_PHASE1) {
+ ret = phy_write(phydev, 29, 0x000a);
+ if (ret < 0)
+ return ret;
+
+ ret = phy_write(phydev, 30, 0x0002);
+ if (ret < 0)
+ return ret;
+ }
+
+ ret = phy_write(phydev, MII_BMCR,
+ BMCR_RESET | BMCR_SPEED100 | BMCR_FULLDPLX);
+ if (ret < 0)
+ return ret;
+
+ ret = phy_write(phydev, MII_VCT_TXPINS, MII_VCT_TXPINS_ENVCT);
+ if (ret < 0)
+ return ret;
+
+ ret = phy_write(phydev, 29, 0x0003);
+ if (ret < 0)
+ return ret;
+
+ ret = phy_write(phydev, 30, 0x0);
+ if (ret < 0)
+ return ret;
+
+ if (priv->vct_phase == M88E3082_VCT_OFF) {
+ priv->vct_phase = M88E3082_VCT_PHASE1;
+ priv->pair = 0;
+
+ return 0;
+ }
+
+ ret = phy_write(phydev, 29, 0x000a);
+ if (ret < 0)
+ return ret;
+
+ ret = phy_write(phydev, 30, 0x0);
+ if (ret < 0)
+ return ret;
+
+ priv->vct_phase = M88E3082_VCT_PHASE2;
+
+ return 0;
+}
+
+static int m88e3082_vct_cable_test_report_trans(int result, u8 distance)
+{
+ switch (result) {
+ case MII_VCT_TXRXPINS_VCTTST_OK:
+ if (distance == MII_VCT_TXRXPINS_DISTRFLN_MAX)
+ return ETHTOOL_A_CABLE_RESULT_CODE_OK;
+ return ETHTOOL_A_CABLE_RESULT_CODE_IMPEDANCE_MISMATCH;
+ case MII_VCT_TXRXPINS_VCTTST_SHORT:
+ return ETHTOOL_A_CABLE_RESULT_CODE_SAME_SHORT;
+ case MII_VCT_TXRXPINS_VCTTST_OPEN:
+ return ETHTOOL_A_CABLE_RESULT_CODE_OPEN;
+ default:
+ return ETHTOOL_A_CABLE_RESULT_CODE_UNSPEC;
+ }
+}
+
+static u32 m88e3082_vct_distrfln_2_cm(u8 distrfln)
+{
+ if (distrfln < 24)
+ return 0;
+
+ /* Original function for meters: y = 0.7861x - 18.862 */
+ return (7861 * distrfln - 188620) / 100;
+}
+
+static int m88e3082_vct_cable_test_get_status(struct phy_device *phydev,
+ bool *finished)
+{
+ u8 tx_vcttst_res, rx_vcttst_res, tx_distrfln, rx_distrfln;
+ struct marvell_priv *priv = phydev->priv;
+ int ret, tx_result, rx_result;
+ bool done_phase = true;
+
+ *finished = false;
+
+ ret = phy_read(phydev, MII_VCT_TXPINS);
+ if (ret < 0)
+ return ret;
+ else if (ret & MII_VCT_TXPINS_ENVCT)
+ return 0;
+
+ tx_distrfln = ret & MII_VCT_TXRXPINS_DISTRFLN;
+ tx_vcttst_res = (ret & MII_VCT_TXRXPINS_VCTTST) >>
+ MII_VCT_TXRXPINS_VCTTST_SHIFT;
+
+ ret = phy_read(phydev, MII_VCT_RXPINS);
+ if (ret < 0)
+ return ret;
+
+ rx_distrfln = ret & MII_VCT_TXRXPINS_DISTRFLN;
+ rx_vcttst_res = (ret & MII_VCT_TXRXPINS_VCTTST) >>
+ MII_VCT_TXRXPINS_VCTTST_SHIFT;
+
+ *finished = true;
+
+ switch (priv->vct_phase) {
+ case M88E3082_VCT_PHASE1:
+ tx_result = m88e3082_vct_cable_test_report_trans(tx_vcttst_res,
+ tx_distrfln);
+ rx_result = m88e3082_vct_cable_test_report_trans(rx_vcttst_res,
+ rx_distrfln);
+
+ ethnl_cable_test_result(phydev, ETHTOOL_A_CABLE_PAIR_A,
+ tx_result);
+ ethnl_cable_test_result(phydev, ETHTOOL_A_CABLE_PAIR_B,
+ rx_result);
+
+ if (tx_vcttst_res == MII_VCT_TXRXPINS_VCTTST_OPEN) {
+ done_phase = false;
+ priv->pair |= M88E3082_PAIR_A;
+ } else if (tx_distrfln < MII_VCT_TXRXPINS_DISTRFLN_MAX) {
+ u8 pair = ETHTOOL_A_CABLE_PAIR_A;
+ u32 cm = m88e3082_vct_distrfln_2_cm(tx_distrfln);
+
+ ethnl_cable_test_fault_length(phydev, pair, cm);
+ }
+
+ if (rx_vcttst_res == MII_VCT_TXRXPINS_VCTTST_OPEN) {
+ done_phase = false;
+ priv->pair |= M88E3082_PAIR_B;
+ } else if (rx_distrfln < MII_VCT_TXRXPINS_DISTRFLN_MAX) {
+ u8 pair = ETHTOOL_A_CABLE_PAIR_B;
+ u32 cm = m88e3082_vct_distrfln_2_cm(rx_distrfln);
+
+ ethnl_cable_test_fault_length(phydev, pair, cm);
+ }
+
+ break;
+ case M88E3082_VCT_PHASE2:
+ if (priv->pair & M88E3082_PAIR_A &&
+ tx_vcttst_res == MII_VCT_TXRXPINS_VCTTST_OPEN &&
+ tx_distrfln < MII_VCT_TXRXPINS_DISTRFLN_MAX) {
+ u8 pair = ETHTOOL_A_CABLE_PAIR_A;
+ u32 cm = m88e3082_vct_distrfln_2_cm(tx_distrfln);
+
+ ethnl_cable_test_fault_length(phydev, pair, cm);
+ }
+ if (priv->pair & M88E3082_PAIR_B &&
+ rx_vcttst_res == MII_VCT_TXRXPINS_VCTTST_OPEN &&
+ rx_distrfln < MII_VCT_TXRXPINS_DISTRFLN_MAX) {
+ u8 pair = ETHTOOL_A_CABLE_PAIR_B;
+ u32 cm = m88e3082_vct_distrfln_2_cm(rx_distrfln);
+
+ ethnl_cable_test_fault_length(phydev, pair, cm);
+ }
+
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ if (!done_phase) {
+ *finished = false;
+ return m88e3082_vct_cable_test_start(phydev);
+ }
+ if (*finished)
+ priv->vct_phase = M88E3082_VCT_OFF;
+ return 0;
+}
+
#ifdef CONFIG_HWMON
struct marvell_hwmon_ops {
int (*config)(struct phy_device *phydev);
@@ -3300,6 +3506,8 @@ static struct phy_driver marvell_drivers[] = {
.read_status = marvell_read_status,
.resume = genphy_resume,
.suspend = genphy_suspend,
+ .cable_test_start = m88e3082_vct_cable_test_start,
+ .cable_test_get_status = m88e3082_vct_cable_test_get_status,
},
{
.phy_id = MARVELL_PHY_ID_88E1112,
--
2.25.1


2024-04-02 20:38:51

by Pawel Dembicki

[permalink] [raw]
Subject: [PATCH net-next v3 2/3] net: ethtool: Add impedance mismatch result code to cable test

Some PHYs can recognize during a cable test if the impedance in the cable
is okay. They can detect reflections caused by impedance discontinuity
between a regular 100 Ohm cable and an abnormal part with a higher or
lower impedance.

This commit introduces a new result code:
ETHTOOL_A_CABLE_RESULT_CODE_IMPEDANCE_MISMATCH,
which represents the results of a cable test indicating issues with
impedance integrity.

Signed-off-by: Pawel Dembicki <[email protected]>
---
v3:
- added enum description
- improve commit message
v2:
- introduce patch

include/uapi/linux/ethtool_netlink.h | 4 ++++
1 file changed, 4 insertions(+)

diff --git a/include/uapi/linux/ethtool_netlink.h b/include/uapi/linux/ethtool_netlink.h
index 3f89074aa06c..accbb1a231df 100644
--- a/include/uapi/linux/ethtool_netlink.h
+++ b/include/uapi/linux/ethtool_netlink.h
@@ -515,6 +515,10 @@ enum {
ETHTOOL_A_CABLE_RESULT_CODE_OPEN,
ETHTOOL_A_CABLE_RESULT_CODE_SAME_SHORT,
ETHTOOL_A_CABLE_RESULT_CODE_CROSS_SHORT,
+ /* detected reflection caused by the impedance discontinuity between
+ * a regular 100 Ohm cable and a part with the abnormal impedance value
+ */
+ ETHTOOL_A_CABLE_RESULT_CODE_IMPEDANCE_MISMATCH,
};

enum {
--
2.25.1


2024-04-02 23:36:59

by Andrew Lunn

[permalink] [raw]
Subject: Re: [PATCH net-next v3 1/3] net: phy: marvell: add basic support of 88E308X/88E609X family

On Tue, Apr 02, 2024 at 10:11:18PM +0200, Pawel Dembicki wrote:
> This patch implements only basic support.
>
> It covers PHY used in multiple IC:
> PHY: 88E3082, 88E3083
> Switch: 88E6096, 88E6097
>
> Signed-off-by: Pawel Dembicki <[email protected]>

Reviewed-by: Andrew Lunn <[email protected]>

Andrew

2024-04-02 23:37:47

by Andrew Lunn

[permalink] [raw]
Subject: Re: [PATCH net-next v3 2/3] net: ethtool: Add impedance mismatch result code to cable test

On Tue, Apr 02, 2024 at 10:11:19PM +0200, Pawel Dembicki wrote:
> Some PHYs can recognize during a cable test if the impedance in the cable
> is okay. They can detect reflections caused by impedance discontinuity
> between a regular 100 Ohm cable and an abnormal part with a higher or
> lower impedance.
>
> This commit introduces a new result code:
> ETHTOOL_A_CABLE_RESULT_CODE_IMPEDANCE_MISMATCH,
> which represents the results of a cable test indicating issues with
> impedance integrity.
>
> Signed-off-by: Pawel Dembicki <[email protected]>

Reviewed-by: Andrew Lunn <[email protected]>

Andrew

2024-04-02 23:39:32

by Andrew Lunn

[permalink] [raw]
Subject: Re: [PATCH net-next v3 3/3] net: phy: marvell: implement cable-test for 88E308X/88E609X family

On Tue, Apr 02, 2024 at 10:11:20PM +0200, Pawel Dembicki wrote:
> This commit implements VCT in 88E308X/88E609X Family.
>
> It require two workarounds with some magic configuration.
> Regular use require only one register configuration. But Open Circuit
> require second workaround.
> It cause implementation two phases for fault length measuring.
>
> Fast Ethernet PHY have implemented very simple version of VCT. It's
> complitley different than vct5 or vct7.
>
> Signed-off-by: Pawel Dembicki <[email protected]>

Reviewed-by: Andrew Lunn <[email protected]>

Andrew

2024-04-03 07:41:18

by Russell King (Oracle)

[permalink] [raw]
Subject: Re: [PATCH net-next v3 1/3] net: phy: marvell: add basic support of 88E308X/88E609X family

On Tue, Apr 02, 2024 at 10:11:18PM +0200, Pawel Dembicki wrote:
> This patch implements only basic support.
>
> It covers PHY used in multiple IC:
> PHY: 88E3082, 88E3083
> Switch: 88E6096, 88E6097
>
> Signed-off-by: Pawel Dembicki <[email protected]>

Reviewed-by: Russell King (Oracle) <[email protected]>

Thanks!

--
RMK's Patch system: https://www.armlinux.org.uk/developer/patches/
FTTP is here! 80Mbps down 10Mbps up. Decent connectivity at last!

2024-04-04 02:51:08

by patchwork-bot+netdevbpf

[permalink] [raw]
Subject: Re: [PATCH net-next v3 1/3] net: phy: marvell: add basic support of 88E308X/88E609X family

Hello:

This series was applied to netdev/net-next.git (main)
by Jakub Kicinski <[email protected]>:

On Tue, 2 Apr 2024 22:11:18 +0200 you wrote:
> This patch implements only basic support.
>
> It covers PHY used in multiple IC:
> PHY: 88E3082, 88E3083
> Switch: 88E6096, 88E6097
>
> Signed-off-by: Pawel Dembicki <[email protected]>
>
> [...]

Here is the summary with links:
- [net-next,v3,1/3] net: phy: marvell: add basic support of 88E308X/88E609X family
https://git.kernel.org/netdev/net-next/c/ada9841e3e66
- [net-next,v3,2/3] net: ethtool: Add impedance mismatch result code to cable test
https://git.kernel.org/netdev/net-next/c/9cc8a6e62624
- [net-next,v3,3/3] net: phy: marvell: implement cable-test for 88E308X/88E609X family
https://git.kernel.org/netdev/net-next/c/a9e4230d0b22

You are awesome, thank you!
--
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html