Hello everyone,
This is the second iteration of the series introducing support for
2.5GBASET and 5GBASET to the network PHY infrastructure.
These 2 modes are described in the 802.3bz specifications, and allow to
use 2.5G and 5G speeds on cat5e/cat6 cables.
The required infrastructure code is added for 2.5GBASET and 5GBASET, but
only 2.5GBASET support is added to the Marvell10G driver. The reason is
because the 5GBASER interface mode used to communicate with the MAC
isn't implemented yet, and therefore this can't be tested.
This series has seen some rework since last time, see the full details
in the patches changelog. The main highlights are :
- Patch 1 moves the Pause ans Asym_Pause parameters update after
calling config_init. This allows us to change the phydev->supported
modes in config_init, while still forcing some quirks taken from
phydrv->features, to disable unsupported Pause modes. This was
proposed by Andrew.
- Patch 2 generalizes the way we mask-out modes we don't want to use
when forcing the link speed through DT or ethtool, by walking through
the PHY settings table, as proposed by Russell.
- Patch 4 implements automatic setting of TM, FIBRE and Backplane bits
from the list of supported linkmodes.
- In Patch 5, we only read abilities from the PMA. Pause parameters
aren't built from the genphy_c45_pma_read_abilities, as it was done
in the previous iteration of the patch. We also amke use of
linkmode_mod_bit to make sure we mask-out unsupported modes.
- In Patch 8, we manually check for the PMA device id to see if we have
to use a quirk when reading the 2.5G/5G Extended Abilities
Maxime Chevallier (10):
net: phy: Update PHY linkmodes after config_init
net: phy: Mask-out non-compatible modes when setting the max-speed
net: phy: Move of_set_phy_eee_broken to phy-core.c
net: phy: Automatically fill the generic TP, FIBRE and Backplane modes
net: phy: Extract genphy_c45_pma_read_abilities from marvell10g
net: phy: Add generic support for 2.5GBaseT and 5GBaseT
net: phy: marvell10g: Add support for 2.5GBASET
net: phy: marvell10g: Force reading of 2.5/5G
net: mvpp2: Add 2.5GBaseT support
net: phy: marvell10g: add support for the 88x2110 PHY
.../net/ethernet/marvell/mvpp2/mvpp2_main.c | 1 +
drivers/net/phy/marvell10g.c | 142 +++++------
drivers/net/phy/phy-c45.c | 111 ++++++++
drivers/net/phy/phy-core.c | 72 ++++++
drivers/net/phy/phy_device.c | 237 +++++++++---------
include/linux/linkmode.h | 6 +
include/linux/marvell_phy.h | 2 +
include/linux/phy.h | 3 +
include/uapi/linux/mdio.h | 16 ++
9 files changed, 405 insertions(+), 185 deletions(-)
--
2.19.2
Since of_set_phy_supported was moved to phy-core.c, we can also move
of_set_phy_eee_broken to the same location, so that we have all OF
functions in the same place.
This patch doesn't intend to introduce any change in behaviour.
Signed-off-by: Maxime Chevallier <[email protected]>
---
drivers/net/phy/phy-core.c | 27 +++++++++++++++++++++++++++
drivers/net/phy/phy_device.c | 28 ----------------------------
include/linux/phy.h | 1 +
3 files changed, 28 insertions(+), 28 deletions(-)
diff --git a/drivers/net/phy/phy-core.c b/drivers/net/phy/phy-core.c
index 8e54fe396553..9429b473c791 100644
--- a/drivers/net/phy/phy-core.c
+++ b/drivers/net/phy/phy-core.c
@@ -383,6 +383,33 @@ void of_set_phy_supported(struct phy_device *phydev)
__set_phy_supported(phydev, max_speed);
}
+void of_set_phy_eee_broken(struct phy_device *phydev)
+{
+ struct device_node *node = phydev->mdio.dev.of_node;
+ u32 broken = 0;
+
+ if (!IS_ENABLED(CONFIG_OF_MDIO))
+ return;
+
+ if (!node)
+ return;
+
+ if (of_property_read_bool(node, "eee-broken-100tx"))
+ broken |= MDIO_EEE_100TX;
+ if (of_property_read_bool(node, "eee-broken-1000t"))
+ broken |= MDIO_EEE_1000T;
+ if (of_property_read_bool(node, "eee-broken-10gt"))
+ broken |= MDIO_EEE_10GT;
+ if (of_property_read_bool(node, "eee-broken-1000kx"))
+ broken |= MDIO_EEE_1000KX;
+ if (of_property_read_bool(node, "eee-broken-10gkx4"))
+ broken |= MDIO_EEE_10GKX4;
+ if (of_property_read_bool(node, "eee-broken-10gkr"))
+ broken |= MDIO_EEE_10GKR;
+
+ phydev->eee_broken_modes = broken;
+}
+
/**
* phy_resolve_aneg_linkmode - resolve the advertisements into phy settings
* @phydev: The phy_device struct
diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c
index a4ab16992806..a4cbc5a6f09d 100644
--- a/drivers/net/phy/phy_device.c
+++ b/drivers/net/phy/phy_device.c
@@ -30,7 +30,6 @@
#include <linux/mdio.h>
#include <linux/io.h>
#include <linux/uaccess.h>
-#include <linux/of.h>
MODULE_DESCRIPTION("PHY library");
MODULE_AUTHOR("Andy Fleming");
@@ -2153,33 +2152,6 @@ bool phy_validate_pause(struct phy_device *phydev,
}
EXPORT_SYMBOL(phy_validate_pause);
-static void of_set_phy_eee_broken(struct phy_device *phydev)
-{
- struct device_node *node = phydev->mdio.dev.of_node;
- u32 broken = 0;
-
- if (!IS_ENABLED(CONFIG_OF_MDIO))
- return;
-
- if (!node)
- return;
-
- if (of_property_read_bool(node, "eee-broken-100tx"))
- broken |= MDIO_EEE_100TX;
- if (of_property_read_bool(node, "eee-broken-1000t"))
- broken |= MDIO_EEE_1000T;
- if (of_property_read_bool(node, "eee-broken-10gt"))
- broken |= MDIO_EEE_10GT;
- if (of_property_read_bool(node, "eee-broken-1000kx"))
- broken |= MDIO_EEE_1000KX;
- if (of_property_read_bool(node, "eee-broken-10gkx4"))
- broken |= MDIO_EEE_10GKX4;
- if (of_property_read_bool(node, "eee-broken-10gkr"))
- broken |= MDIO_EEE_10GKR;
-
- phydev->eee_broken_modes = broken;
-}
-
static bool phy_drv_supports_irq(struct phy_driver *phydrv)
{
return phydrv->config_intr && phydrv->ack_interrupt;
diff --git a/include/linux/phy.h b/include/linux/phy.h
index cfdd3de38410..017118061ecf 100644
--- a/include/linux/phy.h
+++ b/include/linux/phy.h
@@ -668,6 +668,7 @@ phy_lookup_setting(int speed, int duplex, const unsigned long *mask,
size_t phy_speeds(unsigned int *speeds, size_t size,
unsigned long *mask);
void of_set_phy_supported(struct phy_device *phydev);
+void of_set_phy_eee_broken(struct phy_device *phydev);
static inline bool __phy_is_started(struct phy_device *phydev)
{
--
2.19.2
PHY advertised and supported linkmodes contain both specific modes such
as 1000BASET Half/Full and generic ones such as TP that represent a
class of modes.
Since some modes such as Fibre, TP or Backplane match a wide range of
specific modes, we can automatically set these bits if one of the
specific modes it corresponds to is present in the list.
The 'TP' bit is set whenever there's a BaseT linkmode in
phydev->supported.
The 'FIBRE' bit is set for BaseL, BaseS and BaseE linkmodes.
Finally, the 'Backplane' is set whenever a BaseK mode is supported.
Signed-off-by: Maxime Chevallier <[email protected]>
---
drivers/net/phy/phy_device.c | 67 +++++++++++++++++++++++++++++++++++-
include/linux/linkmode.h | 6 ++++
2 files changed, 72 insertions(+), 1 deletion(-)
diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c
index a4cbc5a6f09d..942cfa7548c4 100644
--- a/drivers/net/phy/phy_device.c
+++ b/drivers/net/phy/phy_device.c
@@ -1066,15 +1066,80 @@ static int phy_poll_reset(struct phy_device *phydev)
* straightforward to maintain, since PHYs and MACs are subject to quirks and
* erratas. This function re-builds the list of the supported pause parameters
* by taking into account the parameters expressed in the driver's features
- * list.
+ * list. It also sets the generic bits indicating Twisted Pair, Fibre and
+ * Backaplane link modes support based on the detailed list that can be built
+ * from the PHY's ability list.
*/
static void phy_update_linkmodes(struct phy_device *phydev)
{
+ __ETHTOOL_DECLARE_LINK_MODE_MASK(phy_baset_features) = { 0, };
+ __ETHTOOL_DECLARE_LINK_MODE_MASK(phy_fibre_features) = { 0, };
+ __ETHTOOL_DECLARE_LINK_MODE_MASK(phy_backplane_features) = { 0, };
struct device_driver *drv = phydev->mdio.dev.driver;
struct phy_driver *phydrv = to_phy_driver(drv);
+ const int phy_baset_features_array[] = {
+ ETHTOOL_LINK_MODE_10baseT_Half_BIT,
+ ETHTOOL_LINK_MODE_10baseT_Full_BIT,
+ ETHTOOL_LINK_MODE_100baseT_Half_BIT,
+ ETHTOOL_LINK_MODE_100baseT_Full_BIT,
+ ETHTOOL_LINK_MODE_1000baseT_Half_BIT,
+ ETHTOOL_LINK_MODE_1000baseT_Full_BIT,
+ ETHTOOL_LINK_MODE_10000baseT_Full_BIT,
+ };
+
+ const int phy_fibre_features_array[] = {
+ ETHTOOL_LINK_MODE_40000baseSR4_Full_BIT,
+ ETHTOOL_LINK_MODE_40000baseLR4_Full_BIT,
+ ETHTOOL_LINK_MODE_56000baseSR4_Full_BIT,
+ ETHTOOL_LINK_MODE_56000baseLR4_Full_BIT,
+ ETHTOOL_LINK_MODE_25000baseSR_Full_BIT,
+ ETHTOOL_LINK_MODE_100000baseSR4_Full_BIT,
+ ETHTOOL_LINK_MODE_100000baseLR4_ER4_Full_BIT,
+ ETHTOOL_LINK_MODE_50000baseSR2_Full_BIT,
+ ETHTOOL_LINK_MODE_10000baseSR_Full_BIT,
+ ETHTOOL_LINK_MODE_10000baseLR_Full_BIT,
+ ETHTOOL_LINK_MODE_10000baseLRM_Full_BIT,
+ ETHTOOL_LINK_MODE_10000baseER_Full_BIT,
+ };
+
+ const int phy_backplane_features_array[] = {
+ ETHTOOL_LINK_MODE_1000baseKX_Full_BIT,
+ ETHTOOL_LINK_MODE_10000baseKX4_Full_BIT,
+ ETHTOOL_LINK_MODE_10000baseKR_Full_BIT,
+ ETHTOOL_LINK_MODE_20000baseKR2_Full_BIT,
+ ETHTOOL_LINK_MODE_40000baseKR4_Full_BIT,
+ ETHTOOL_LINK_MODE_56000baseKR4_Full_BIT,
+ ETHTOOL_LINK_MODE_25000baseKR_Full_BIT,
+ ETHTOOL_LINK_MODE_50000baseKR2_Full_BIT,
+ ETHTOOL_LINK_MODE_100000baseKR4_Full_BIT,
+ };
+
+ linkmode_set_bit_array(phy_baset_features_array,
+ ARRAY_SIZE(phy_baset_features_array),
+ phy_baset_features);
+
+ linkmode_set_bit_array(phy_fibre_features_array,
+ ARRAY_SIZE(phy_fibre_features_array),
+ phy_fibre_features);
+
+ linkmode_set_bit_array(phy_backplane_features_array,
+ ARRAY_SIZE(phy_backplane_features_array),
+ phy_backplane_features);
+
mutex_lock(&phydev->lock);
+ if (linkmode_intersects(phydev->supported, phy_baset_features))
+ linkmode_set_bit(ETHTOOL_LINK_MODE_TP_BIT, phydev->supported);
+
+ if (linkmode_intersects(phydev->supported, phy_fibre_features))
+ linkmode_set_bit(ETHTOOL_LINK_MODE_FIBRE_BIT,
+ phydev->supported);
+
+ if (linkmode_intersects(phydev->supported, phy_backplane_features))
+ linkmode_set_bit(ETHTOOL_LINK_MODE_Backplane_BIT,
+ phydev->supported);
+
/* The Pause Frame bits indicate that the PHY can support passing
* pause frames. During autonegotiation, the PHYs will determine if
* they should allow pause frames to pass. The MAC driver should then
diff --git a/include/linux/linkmode.h b/include/linux/linkmode.h
index a99c58866860..49ab6415e1e0 100644
--- a/include/linux/linkmode.h
+++ b/include/linux/linkmode.h
@@ -82,4 +82,10 @@ static inline int linkmode_equal(const unsigned long *src1,
return bitmap_equal(src1, src2, __ETHTOOL_LINK_MODE_MASK_NBITS);
}
+static inline bool linkmode_intersects(const unsigned long *src1,
+ const unsigned long *src2)
+{
+ return bitmap_intersects(src1, src2, __ETHTOOL_LINK_MODE_MASK_NBITS);
+}
+
#endif /* __LINKMODE_H */
--
2.19.2
The 802.3bz specification, based on previous by the NBASET alliance,
defines the 2.5GBaseT and 5GBaseT link modes for ethernet traffic on
cat5e, cat6 and cat7 cables.
These mode integrate with the already defined C45 MDIO PMA/PMD registers
set that added 10G support, by defining some previously reserved bits,
and adding a new register (2.5G/5G Extended abilities).
This commit adds the required definitions in include/uapi/linux/mdio.h
to support these modes, and detect when a link-partner advertises them.
It also adds support for these mode in the generic C45 PHY
infrastructure.
Signed-off-by: Maxime Chevallier <[email protected]>
---
V1 -> V2: Merged in code for reading 2.5G/5G abilities.
drivers/net/phy/phy-c45.c | 37 ++++++++++++++++++++++++++++++++++++
drivers/net/phy/phy_device.c | 2 ++
include/uapi/linux/mdio.h | 16 ++++++++++++++++
3 files changed, 55 insertions(+)
diff --git a/drivers/net/phy/phy-c45.c b/drivers/net/phy/phy-c45.c
index 32e72b170ea9..92897cb26557 100644
--- a/drivers/net/phy/phy-c45.c
+++ b/drivers/net/phy/phy-c45.c
@@ -47,6 +47,16 @@ int genphy_c45_pma_setup_forced(struct phy_device *phydev)
/* Assume 1000base-T */
ctrl2 |= MDIO_PMA_CTRL2_1000BT;
break;
+ case SPEED_2500:
+ ctrl1 |= MDIO_CTRL1_SPEED2_5G;
+ /* Assume 2.5Gbase-T */
+ ctrl2 |= MDIO_PMA_CTRL2_2_5GBT;
+ break;
+ case SPEED_5000:
+ ctrl1 |= MDIO_CTRL1_SPEED5G;
+ /* Assume 5Gbase-T */
+ ctrl2 |= MDIO_PMA_CTRL2_5GBT;
+ break;
case SPEED_10000:
ctrl1 |= MDIO_CTRL1_SPEED10G;
/* Assume 10Gbase-T */
@@ -179,6 +189,12 @@ int genphy_c45_read_lpa(struct phy_device *phydev)
if (val < 0)
return val;
+ if (val & MDIO_AN_10GBT_STAT_LP2_5G)
+ linkmode_set_bit(ETHTOOL_LINK_MODE_2500baseT_Full_BIT,
+ phydev->lp_advertising);
+ if (val & MDIO_AN_10GBT_STAT_LP5G)
+ linkmode_set_bit(ETHTOOL_LINK_MODE_5000baseT_Full_BIT,
+ phydev->lp_advertising);
if (val & MDIO_AN_10GBT_STAT_LP10G)
linkmode_set_bit(ETHTOOL_LINK_MODE_10000baseT_Full_BIT,
phydev->lp_advertising);
@@ -209,6 +225,12 @@ int genphy_c45_read_pma(struct phy_device *phydev)
case MDIO_PMA_CTRL1_SPEED1000:
phydev->speed = SPEED_1000;
break;
+ case MDIO_CTRL1_SPEED2_5G:
+ phydev->speed = SPEED_2500;
+ break;
+ case MDIO_CTRL1_SPEED5G:
+ phydev->speed = SPEED_5000;
+ break;
case MDIO_CTRL1_SPEED10G:
phydev->speed = SPEED_10000;
break;
@@ -324,6 +346,21 @@ int genphy_c45_pma_read_abilities(struct phy_device *phydev)
linkmode_mod_bit(ETHTOOL_LINK_MODE_10baseT_Half_BIT,
phydev->supported,
val & MDIO_PMA_EXTABLE_10BT);
+
+ if (val & MDIO_PMA_EXTABLE_NBT) {
+ val = phy_read_mmd(phydev, MDIO_MMD_PMAPMD,
+ MDIO_PMA_NG_EXTABLE);
+ if (val < 0)
+ return val;
+
+ linkmode_mod_bit(ETHTOOL_LINK_MODE_2500baseT_Full_BIT,
+ phydev->supported,
+ val & MDIO_PMA_NG_EXTABLE_2_5GBT);
+
+ linkmode_mod_bit(ETHTOOL_LINK_MODE_5000baseT_Full_BIT,
+ phydev->supported,
+ val & MDIO_PMA_NG_EXTABLE_5GBT);
+ }
}
return 0;
diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c
index 942cfa7548c4..13ac4bdb9b69 100644
--- a/drivers/net/phy/phy_device.c
+++ b/drivers/net/phy/phy_device.c
@@ -1085,6 +1085,8 @@ static void phy_update_linkmodes(struct phy_device *phydev)
ETHTOOL_LINK_MODE_100baseT_Full_BIT,
ETHTOOL_LINK_MODE_1000baseT_Half_BIT,
ETHTOOL_LINK_MODE_1000baseT_Full_BIT,
+ ETHTOOL_LINK_MODE_2500baseT_Full_BIT,
+ ETHTOOL_LINK_MODE_5000baseT_Full_BIT,
ETHTOOL_LINK_MODE_10000baseT_Full_BIT,
};
diff --git a/include/uapi/linux/mdio.h b/include/uapi/linux/mdio.h
index d435b00d64ad..546509898867 100644
--- a/include/uapi/linux/mdio.h
+++ b/include/uapi/linux/mdio.h
@@ -45,6 +45,7 @@
#define MDIO_AN_ADVERTISE 16 /* AN advertising (base page) */
#define MDIO_AN_LPA 19 /* AN LP abilities (base page) */
#define MDIO_PCS_EEE_ABLE 20 /* EEE Capability register */
+#define MDIO_PMA_NG_EXTABLE 21 /* 2.5G/5G PMA/PMD extended ability */
#define MDIO_PCS_EEE_WK_ERR 22 /* EEE wake error counter */
#define MDIO_PHYXS_LNSTAT 24 /* PHY XGXS lane state */
#define MDIO_AN_EEE_ADV 60 /* EEE advertisement */
@@ -92,6 +93,10 @@
#define MDIO_CTRL1_SPEED10G (MDIO_CTRL1_SPEEDSELEXT | 0x00)
/* 10PASS-TS/2BASE-TL */
#define MDIO_CTRL1_SPEED10P2B (MDIO_CTRL1_SPEEDSELEXT | 0x04)
+/* 2.5 Gb/s */
+#define MDIO_CTRL1_SPEED2_5G (MDIO_CTRL1_SPEEDSELEXT | 0x18)
+/* 5 Gb/s */
+#define MDIO_CTRL1_SPEED5G (MDIO_CTRL1_SPEEDSELEXT | 0x1c)
/* Status register 1. */
#define MDIO_STAT1_LPOWERABLE 0x0002 /* Low-power ability */
@@ -142,6 +147,8 @@
#define MDIO_PMA_CTRL2_1000BKX 0x000d /* 1000BASE-KX type */
#define MDIO_PMA_CTRL2_100BTX 0x000e /* 100BASE-TX type */
#define MDIO_PMA_CTRL2_10BT 0x000f /* 10BASE-T type */
+#define MDIO_PMA_CTRL2_2_5GBT 0x0030 /* 2.5GBaseT type */
+#define MDIO_PMA_CTRL2_5GBT 0x0031 /* 5GBaseT type */
#define MDIO_PCS_CTRL2_TYPE 0x0003 /* PCS type selection */
#define MDIO_PCS_CTRL2_10GBR 0x0000 /* 10GBASE-R type */
#define MDIO_PCS_CTRL2_10GBX 0x0001 /* 10GBASE-X type */
@@ -195,6 +202,7 @@
#define MDIO_PMA_EXTABLE_1000BKX 0x0040 /* 1000BASE-KX ability */
#define MDIO_PMA_EXTABLE_100BTX 0x0080 /* 100BASE-TX ability */
#define MDIO_PMA_EXTABLE_10BT 0x0100 /* 10BASE-T ability */
+#define MDIO_PMA_EXTABLE_NBT 0x4000 /* 2.5/5GBASE-T ability */
/* PHY XGXS lane state register. */
#define MDIO_PHYXS_LNSTAT_SYNC0 0x0001
@@ -231,9 +239,13 @@
#define MDIO_PCS_10GBRT_STAT2_BER 0x3f00
/* AN 10GBASE-T control register. */
+#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 */
/* AN 10GBASE-T status register. */
+#define MDIO_AN_10GBT_STAT_LP2_5G 0x0020 /* LP is 2.5GBT capable */
+#define MDIO_AN_10GBT_STAT_LP5G 0x0040 /* LP is 5GBT capable */
#define MDIO_AN_10GBT_STAT_LPTRR 0x0200 /* LP training reset req. */
#define MDIO_AN_10GBT_STAT_LPLTABLE 0x0400 /* LP loop timing ability */
#define MDIO_AN_10GBT_STAT_LP10G 0x0800 /* LP is 10GBT capable */
@@ -262,6 +274,10 @@
#define MDIO_EEE_10GKX4 0x0020 /* 10G KX4 EEE cap */
#define MDIO_EEE_10GKR 0x0040 /* 10G KR EEE cap */
+/* 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 */
+
/* LASI RX_ALARM control/status registers. */
#define MDIO_PMA_LASI_RX_PHYXSLFLT 0x0001 /* PHY XS RX local fault */
#define MDIO_PMA_LASI_RX_PCSLFLT 0x0008 /* PCS RX local fault */
--
2.19.2
As per 802.3bz, if bit 14 of (1.11) "PMA Extended Abilities" indicates
whether or not we should read register (1.21) "2.52/5G PMA Extended
Abilities", which contains information on the support of 2.5GBASET and
5GBASET.
After testing on several variants of PHYS of this family, it appears
that bit 14 in (1.11) isn't always set when it should be.
PHYs 88X3310 (on MacchiatoBin) and 88E2010 do support 2.5G and 5GBASET,
but don't have 1.11.14 set. Their register 1.21 is filled with the
correct values, indicating 2.5G and 5G support.
PHYs 88E2110 do have their 1.11.14 bit set, as it should.
Signed-off-by: Maxime Chevallier <[email protected]>
---
V1 -> V2: Use the PMA device id to identify which devices need this
quirk, based on Andrew's idea.
drivers/net/phy/marvell10g.c | 31 +++++++++++++++++++++++++++++++
1 file changed, 31 insertions(+)
diff --git a/drivers/net/phy/marvell10g.c b/drivers/net/phy/marvell10g.c
index 581b4b6e31e9..2593db608af7 100644
--- a/drivers/net/phy/marvell10g.c
+++ b/drivers/net/phy/marvell10g.c
@@ -232,6 +232,23 @@ static int mv3310_resume(struct phy_device *phydev)
return mv3310_hwmon_config(phydev, true);
}
+/* Some PHYs in the Alaska family such as the 88X3310 and the 88E2010
+ * don't set bit 14 in PMA Extended Abilities (1.11), although they do
+ * support 2.5GBASET and 5GBASET. For these models, we can still read their
+ * 2.5G/5G extended abilities register (1.21). We detect these models based on
+ * the PMA device identifier, with a mask matching models known to have this
+ * issue
+ */
+static bool mv3310_has_pma_ngbaset_quirk(struct phy_device *phydev)
+{
+ if (!(phydev->c45_ids.devices_in_package & MDIO_DEVS_PMAPMD))
+ return false;
+
+ /* Only some revisions of the 88X3310 family PMA seem to be impacted */
+ return (phydev->c45_ids.device_ids[MDIO_MMD_PMAPMD] & 0xfffffffe) ==
+ (MARVELL_PHY_ID_88X3310 & 0xfffffffe);
+}
+
static int mv3310_config_init(struct phy_device *phydev)
{
int ret, val;
@@ -261,6 +278,20 @@ static int mv3310_config_init(struct phy_device *phydev)
if (ret)
return ret;
+ if (mv3310_has_pma_ngbaset_quirk(phydev)) {
+ val = phy_read_mmd(phydev, MDIO_MMD_PMAPMD,
+ MDIO_PMA_NG_EXTABLE);
+ if (val < 0)
+ return val;
+
+ if (val & MDIO_PMA_NG_EXTABLE_2_5GBT)
+ __set_bit(ETHTOOL_LINK_MODE_2500baseT_Full_BIT,
+ phydev->supported);
+ if (val & MDIO_PMA_NG_EXTABLE_5GBT)
+ __set_bit(ETHTOOL_LINK_MODE_5000baseT_Full_BIT,
+ phydev->supported);
+ }
+
return 0;
}
--
2.19.2
The PPv2 controller is able to support 2.5G speeds, allowing to use
2.5GBASET in conjunction with PHYs that use 2500BASEX as their MII
interface when using this mode.
Signed-off-by: Maxime Chevallier <[email protected]>
---
drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c b/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c
index 5c0c26fd8363..6f36aed5bd0a 100644
--- a/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c
+++ b/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c
@@ -4410,6 +4410,7 @@ static void mvpp2_phylink_validate(struct net_device *dev,
case PHY_INTERFACE_MODE_2500BASEX:
phylink_set(mask, 1000baseT_Full);
phylink_set(mask, 1000baseX_Full);
+ phylink_set(mask, 2500baseT_Full);
phylink_set(mask, 2500baseX_Full);
break;
default:
--
2.19.2
This patch adds support for the 88x2110 PHY, which is similar to the
already supported 88x3310 PHY without the SFP interface.
It supports 10/100/1000BASET along with 2.5GBASET, 5GBASET and 10GBASET,
with the same interface modes that are used by the 3310.
This PHY don't have the same issue as the 88x3310 regarding 2.5/5G
abilities, and correctly follows the 802.3bz standard to list the
supported abilities.
Signed-off-by: Maxime Chevallier <[email protected]>
Suggested-by: Antoine Tenart <[email protected]>
---
V1 -> V2: Use a #define for the PHY ID, since we also do that for the
3310. Removed the mv2110_config_init implementation since we
now manually check for the PMA device id when using the quirk.
drivers/net/phy/marvell10g.c | 13 +++++++++++++
include/linux/marvell_phy.h | 1 +
2 files changed, 14 insertions(+)
diff --git a/drivers/net/phy/marvell10g.c b/drivers/net/phy/marvell10g.c
index 2593db608af7..fa4847662c81 100644
--- a/drivers/net/phy/marvell10g.c
+++ b/drivers/net/phy/marvell10g.c
@@ -508,12 +508,25 @@ static struct phy_driver mv3310_drivers[] = {
.aneg_done = mv3310_aneg_done,
.read_status = mv3310_read_status,
},
+ {
+ .phy_id = MARVELL_PHY_ID_88E2110,
+ .phy_id_mask = MARVELL_PHY_ID_MASK,
+ .name = "mv88x2110",
+ .features = PHY_10GBIT_FEATURES,
+ .probe = mv3310_probe,
+ .soft_reset = gen10g_no_soft_reset,
+ .config_init = mv3310_config_init,
+ .config_aneg = mv3310_config_aneg,
+ .aneg_done = mv3310_aneg_done,
+ .read_status = mv3310_read_status,
+ },
};
module_phy_driver(mv3310_drivers);
static struct mdio_device_id __maybe_unused mv3310_tbl[] = {
{ MARVELL_PHY_ID_88X3310, MARVELL_PHY_ID_MASK },
+ { MARVELL_PHY_ID_88E2110, MARVELL_PHY_ID_MASK },
{ },
};
MODULE_DEVICE_TABLE(mdio, mv3310_tbl);
diff --git a/include/linux/marvell_phy.h b/include/linux/marvell_phy.h
index 5851d68d828a..8596a861940e 100644
--- a/include/linux/marvell_phy.h
+++ b/include/linux/marvell_phy.h
@@ -21,6 +21,7 @@
#define MARVELL_PHY_ID_88E1545 0x01410ea0
#define MARVELL_PHY_ID_88E3016 0x01410e60
#define MARVELL_PHY_ID_88X3310 0x002b09aa
+#define MARVELL_PHY_ID_88E2110 0x002b09b8
/* The MV88e6390 Ethernet switch contains embedded PHYs. These PHYs do
* not have a model ID. So the switch driver traps reads to the ID2
--
2.19.2
The Marvell Alaska family of PHYs supports 2.5GBaseT and 5GBaseT modes,
as defined in the 802.3bz specification.
When the link partner requests a 2.5GBASET link, the PHY will
reconfigure it's MII interface to 2500BASEX.
At 5G, the PHY will reconfigure it's interface to 5GBASE-R, but this
mode isn't supported by any MAC for now.
This was tested with :
- The 88X3310, which is on the MacchiatoBin
- The 88E2010, an Alaska PHY that has no fiber interfaces, and is
limited to 5G maximum speed.
Signed-off-by: Maxime Chevallier <[email protected]>
---
V1 -> V2: Use a #define for the 88X3310 PHY ID, since it's reused in
various places in the code. Rebased on Heiner Kallweit's patch
introducing the phy_modify_mmd accessor.
drivers/net/phy/marvell10g.c | 30 ++++++++++++++++++++++--------
include/linux/marvell_phy.h | 1 +
2 files changed, 23 insertions(+), 8 deletions(-)
diff --git a/drivers/net/phy/marvell10g.c b/drivers/net/phy/marvell10g.c
index 07df87b81369..581b4b6e31e9 100644
--- a/drivers/net/phy/marvell10g.c
+++ b/drivers/net/phy/marvell10g.c
@@ -238,6 +238,7 @@ static int mv3310_config_init(struct phy_device *phydev)
/* Check that the PHY interface type is compatible */
if (phydev->interface != PHY_INTERFACE_MODE_SGMII &&
+ phydev->interface != PHY_INTERFACE_MODE_2500BASEX &&
phydev->interface != PHY_INTERFACE_MODE_XAUI &&
phydev->interface != PHY_INTERFACE_MODE_RXAUI &&
phydev->interface != PHY_INTERFACE_MODE_10GKR)
@@ -307,8 +308,18 @@ static int mv3310_config_aneg(struct phy_device *phydev)
else
reg = 0;
+ if (linkmode_test_bit(ETHTOOL_LINK_MODE_2500baseT_Full_BIT,
+ phydev->advertising))
+ reg |= MDIO_AN_10GBT_CTRL_ADV2_5G;
+ if (linkmode_test_bit(ETHTOOL_LINK_MODE_5000baseT_Full_BIT,
+ phydev->advertising))
+ reg |= MDIO_AN_10GBT_CTRL_ADV5G;
+
ret = phy_modify_mmd(phydev, MDIO_MMD_AN, MDIO_AN_10GBT_CTRL,
- MDIO_AN_10GBT_CTRL_ADV10G, reg);
+ MDIO_AN_10GBT_CTRL_ADV10G |
+ MDIO_AN_10GBT_CTRL_ADV5G |
+ MDIO_AN_10GBT_CTRL_ADV2_5G, reg);
+
if (ret < 0)
return ret;
if (ret > 0)
@@ -337,17 +348,20 @@ static int mv3310_aneg_done(struct phy_device *phydev)
static void mv3310_update_interface(struct phy_device *phydev)
{
if ((phydev->interface == PHY_INTERFACE_MODE_SGMII ||
+ phydev->interface == PHY_INTERFACE_MODE_2500BASEX ||
phydev->interface == PHY_INTERFACE_MODE_10GKR) && phydev->link) {
/* The PHY automatically switches its serdes interface (and
- * active PHYXS instance) between Cisco SGMII and 10GBase-KR
- * modes according to the speed. Florian suggests setting
- * phydev->interface to communicate this to the MAC. Only do
- * this if we are already in either SGMII or 10GBase-KR mode.
+ * active PHYXS instance) between Cisco SGMII, 10GBase-KR and
+ * 2500BaseX modes according to the speed. Florian suggests
+ * setting phydev->interface to communicate this to the MAC.
+ * Only do this if we are already in one of the above modes.
*/
if (phydev->speed == SPEED_10000)
phydev->interface = PHY_INTERFACE_MODE_10GKR;
+ else if (phydev->speed == SPEED_2500)
+ phydev->interface = PHY_INTERFACE_MODE_2500BASEX;
else if (phydev->speed >= SPEED_10 &&
- phydev->speed < SPEED_10000)
+ phydev->speed < SPEED_2500)
phydev->interface = PHY_INTERFACE_MODE_SGMII;
}
}
@@ -450,7 +464,7 @@ static int mv3310_read_status(struct phy_device *phydev)
static struct phy_driver mv3310_drivers[] = {
{
- .phy_id = 0x002b09aa,
+ .phy_id = MARVELL_PHY_ID_88X3310,
.phy_id_mask = MARVELL_PHY_ID_MASK,
.name = "mv88x3310",
.features = PHY_10GBIT_FEATURES,
@@ -468,7 +482,7 @@ static struct phy_driver mv3310_drivers[] = {
module_phy_driver(mv3310_drivers);
static struct mdio_device_id __maybe_unused mv3310_tbl[] = {
- { 0x002b09aa, MARVELL_PHY_ID_MASK },
+ { MARVELL_PHY_ID_88X3310, MARVELL_PHY_ID_MASK },
{ },
};
MODULE_DEVICE_TABLE(mdio, mv3310_tbl);
diff --git a/include/linux/marvell_phy.h b/include/linux/marvell_phy.h
index 1eb6f244588d..5851d68d828a 100644
--- a/include/linux/marvell_phy.h
+++ b/include/linux/marvell_phy.h
@@ -20,6 +20,7 @@
#define MARVELL_PHY_ID_88E1540 0x01410eb0
#define MARVELL_PHY_ID_88E1545 0x01410ea0
#define MARVELL_PHY_ID_88E3016 0x01410e60
+#define MARVELL_PHY_ID_88X3310 0x002b09aa
/* The MV88e6390 Ethernet switch contains embedded PHYs. These PHYs do
* not have a model ID. So the switch driver traps reads to the ID2
--
2.19.2
When setting a PHY's max speed using either the max-speed DT property
or ethtool, we should mask-out all non-compatible modes according to the
settings table, instead of just the 10/100BASET modes.
Signed-off-by: Maxime Chevallier <[email protected]>
Suggested-by: Russell King <[email protected]>
---
drivers/net/phy/phy-core.c | 45 ++++++++++++++++++++++++++++++
drivers/net/phy/phy_device.c | 53 ------------------------------------
include/linux/phy.h | 1 +
3 files changed, 46 insertions(+), 53 deletions(-)
diff --git a/drivers/net/phy/phy-core.c b/drivers/net/phy/phy-core.c
index 7d6aad287f84..8e54fe396553 100644
--- a/drivers/net/phy/phy-core.c
+++ b/drivers/net/phy/phy-core.c
@@ -4,6 +4,7 @@
*/
#include <linux/export.h>
#include <linux/phy.h>
+#include <linux/of.h>
const char *phy_speed_to_str(int speed)
{
@@ -338,6 +339,50 @@ size_t phy_speeds(unsigned int *speeds, size_t size,
return count;
}
+static int __set_phy_supported(struct phy_device *phydev, u32 max_speed)
+{
+ const struct phy_setting *p;
+ int i;
+
+ for (i = 0, p = settings; i < ARRAY_SIZE(settings); i++, p++) {
+ if (p->speed > max_speed)
+ linkmode_clear_bit(p->bit, phydev->supported);
+ else
+ break;
+ }
+
+ return 0;
+}
+
+int phy_set_max_speed(struct phy_device *phydev, u32 max_speed)
+{
+ int err;
+
+ err = __set_phy_supported(phydev, max_speed);
+ if (err)
+ return err;
+
+ linkmode_copy(phydev->advertising, phydev->supported);
+
+ return 0;
+}
+EXPORT_SYMBOL(phy_set_max_speed);
+
+void of_set_phy_supported(struct phy_device *phydev)
+{
+ struct device_node *node = phydev->mdio.dev.of_node;
+ u32 max_speed;
+
+ if (!IS_ENABLED(CONFIG_OF_MDIO))
+ return;
+
+ if (!node)
+ return;
+
+ if (!of_property_read_u32(node, "max-speed", &max_speed))
+ __set_phy_supported(phydev, max_speed);
+}
+
/**
* phy_resolve_aneg_linkmode - resolve the advertisements into phy settings
* @phydev: The phy_device struct
diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c
index 18a10565efd4..a4ab16992806 100644
--- a/drivers/net/phy/phy_device.c
+++ b/drivers/net/phy/phy_device.c
@@ -2023,44 +2023,6 @@ int genphy_loopback(struct phy_device *phydev, bool enable)
}
EXPORT_SYMBOL(genphy_loopback);
-static int __set_phy_supported(struct phy_device *phydev, u32 max_speed)
-{
- switch (max_speed) {
- case SPEED_10:
- linkmode_clear_bit(ETHTOOL_LINK_MODE_100baseT_Half_BIT,
- phydev->supported);
- linkmode_clear_bit(ETHTOOL_LINK_MODE_100baseT_Full_BIT,
- phydev->supported);
- /* fall through */
- case SPEED_100:
- linkmode_clear_bit(ETHTOOL_LINK_MODE_1000baseT_Half_BIT,
- phydev->supported);
- linkmode_clear_bit(ETHTOOL_LINK_MODE_1000baseT_Full_BIT,
- phydev->supported);
- break;
- case SPEED_1000:
- break;
- default:
- return -ENOTSUPP;
- }
-
- return 0;
-}
-
-int phy_set_max_speed(struct phy_device *phydev, u32 max_speed)
-{
- int err;
-
- err = __set_phy_supported(phydev, max_speed);
- if (err)
- return err;
-
- linkmode_copy(phydev->advertising, phydev->supported);
-
- return 0;
-}
-EXPORT_SYMBOL(phy_set_max_speed);
-
/**
* phy_remove_link_mode - Remove a supported link mode
* @phydev: phy_device structure to remove link mode from
@@ -2191,21 +2153,6 @@ bool phy_validate_pause(struct phy_device *phydev,
}
EXPORT_SYMBOL(phy_validate_pause);
-static void of_set_phy_supported(struct phy_device *phydev)
-{
- struct device_node *node = phydev->mdio.dev.of_node;
- u32 max_speed;
-
- if (!IS_ENABLED(CONFIG_OF_MDIO))
- return;
-
- if (!node)
- return;
-
- if (!of_property_read_u32(node, "max-speed", &max_speed))
- __set_phy_supported(phydev, max_speed);
-}
-
static void of_set_phy_eee_broken(struct phy_device *phydev)
{
struct device_node *node = phydev->mdio.dev.of_node;
diff --git a/include/linux/phy.h b/include/linux/phy.h
index 237dd035858a..cfdd3de38410 100644
--- a/include/linux/phy.h
+++ b/include/linux/phy.h
@@ -667,6 +667,7 @@ phy_lookup_setting(int speed, int duplex, const unsigned long *mask,
bool exact);
size_t phy_speeds(unsigned int *speeds, size_t size,
unsigned long *mask);
+void of_set_phy_supported(struct phy_device *phydev);
static inline bool __phy_is_started(struct phy_device *phydev)
{
--
2.19.2
Marvell 10G PHY driver has a generic way of initializing the supported
link modes by reading the PHY's C45 PMA abilities. This can be made
generic, since these registers are part of the 802.3 specifications.
This commit extracts the config_init link_mode initialization code from
marvell10g and uses it to introduce the genphy_c45_pma_read_abilities
function.
Only PMA modes are read, it's still up to the caller to set the Pause
parameters.
Signed-off-by: Maxime Chevallier <[email protected]>
---
V1 -> V2: The Pause parameters setting stays in marvell10g. Make use of
linkmode_mod_bit. Renamed the function from
genphy_c45_read_abilities to genphy_c45_pma_read_abilities, as
advised by Andrew.
drivers/net/phy/marvell10g.c | 78 ++++--------------------------------
drivers/net/phy/phy-c45.c | 74 ++++++++++++++++++++++++++++++++++
include/linux/phy.h | 1 +
3 files changed, 83 insertions(+), 70 deletions(-)
diff --git a/drivers/net/phy/marvell10g.c b/drivers/net/phy/marvell10g.c
index 296a537cdfcb..07df87b81369 100644
--- a/drivers/net/phy/marvell10g.c
+++ b/drivers/net/phy/marvell10g.c
@@ -234,8 +234,7 @@ static int mv3310_resume(struct phy_device *phydev)
static int mv3310_config_init(struct phy_device *phydev)
{
- __ETHTOOL_DECLARE_LINK_MODE_MASK(supported) = { 0, };
- int val;
+ int ret, val;
/* Check that the PHY interface type is compatible */
if (phydev->interface != PHY_INTERFACE_MODE_SGMII &&
@@ -244,8 +243,8 @@ static int mv3310_config_init(struct phy_device *phydev)
phydev->interface != PHY_INTERFACE_MODE_10GKR)
return -ENODEV;
- __set_bit(ETHTOOL_LINK_MODE_Pause_BIT, supported);
- __set_bit(ETHTOOL_LINK_MODE_Asym_Pause_BIT, supported);
+ __set_bit(ETHTOOL_LINK_MODE_Pause_BIT, phydev->supported);
+ __set_bit(ETHTOOL_LINK_MODE_Asym_Pause_BIT, phydev->supported);
if (phydev->c45_ids.devices_in_package & MDIO_DEVS_AN) {
val = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_STAT1);
@@ -253,74 +252,13 @@ static int mv3310_config_init(struct phy_device *phydev)
return val;
if (val & MDIO_AN_STAT1_ABLE)
- __set_bit(ETHTOOL_LINK_MODE_Autoneg_BIT, supported);
+ __set_bit(ETHTOOL_LINK_MODE_Autoneg_BIT,
+ phydev->supported);
}
- val = phy_read_mmd(phydev, MDIO_MMD_PMAPMD, MDIO_STAT2);
- if (val < 0)
- return val;
-
- /* Ethtool does not support the WAN mode bits */
- if (val & (MDIO_PMA_STAT2_10GBSR | MDIO_PMA_STAT2_10GBLR |
- MDIO_PMA_STAT2_10GBER | MDIO_PMA_STAT2_10GBLX4 |
- MDIO_PMA_STAT2_10GBSW | MDIO_PMA_STAT2_10GBLW |
- MDIO_PMA_STAT2_10GBEW))
- __set_bit(ETHTOOL_LINK_MODE_FIBRE_BIT, supported);
- if (val & MDIO_PMA_STAT2_10GBSR)
- __set_bit(ETHTOOL_LINK_MODE_10000baseSR_Full_BIT, supported);
- if (val & MDIO_PMA_STAT2_10GBLR)
- __set_bit(ETHTOOL_LINK_MODE_10000baseLR_Full_BIT, supported);
- if (val & MDIO_PMA_STAT2_10GBER)
- __set_bit(ETHTOOL_LINK_MODE_10000baseER_Full_BIT, supported);
-
- if (val & MDIO_PMA_STAT2_EXTABLE) {
- val = phy_read_mmd(phydev, MDIO_MMD_PMAPMD, MDIO_PMA_EXTABLE);
- if (val < 0)
- return val;
-
- if (val & (MDIO_PMA_EXTABLE_10GBT | MDIO_PMA_EXTABLE_1000BT |
- MDIO_PMA_EXTABLE_100BTX | MDIO_PMA_EXTABLE_10BT))
- __set_bit(ETHTOOL_LINK_MODE_TP_BIT, supported);
- if (val & MDIO_PMA_EXTABLE_10GBLRM)
- __set_bit(ETHTOOL_LINK_MODE_FIBRE_BIT, supported);
- if (val & (MDIO_PMA_EXTABLE_10GBKX4 | MDIO_PMA_EXTABLE_10GBKR |
- MDIO_PMA_EXTABLE_1000BKX))
- __set_bit(ETHTOOL_LINK_MODE_Backplane_BIT, supported);
- if (val & MDIO_PMA_EXTABLE_10GBLRM)
- __set_bit(ETHTOOL_LINK_MODE_10000baseLRM_Full_BIT,
- supported);
- if (val & MDIO_PMA_EXTABLE_10GBT)
- __set_bit(ETHTOOL_LINK_MODE_10000baseT_Full_BIT,
- supported);
- if (val & MDIO_PMA_EXTABLE_10GBKX4)
- __set_bit(ETHTOOL_LINK_MODE_10000baseKX4_Full_BIT,
- supported);
- if (val & MDIO_PMA_EXTABLE_10GBKR)
- __set_bit(ETHTOOL_LINK_MODE_10000baseKR_Full_BIT,
- supported);
- if (val & MDIO_PMA_EXTABLE_1000BT)
- __set_bit(ETHTOOL_LINK_MODE_1000baseT_Full_BIT,
- supported);
- if (val & MDIO_PMA_EXTABLE_1000BKX)
- __set_bit(ETHTOOL_LINK_MODE_1000baseKX_Full_BIT,
- supported);
- if (val & MDIO_PMA_EXTABLE_100BTX) {
- __set_bit(ETHTOOL_LINK_MODE_100baseT_Full_BIT,
- supported);
- __set_bit(ETHTOOL_LINK_MODE_100baseT_Half_BIT,
- supported);
- }
- if (val & MDIO_PMA_EXTABLE_10BT) {
- __set_bit(ETHTOOL_LINK_MODE_10baseT_Full_BIT,
- supported);
- __set_bit(ETHTOOL_LINK_MODE_10baseT_Half_BIT,
- supported);
- }
- }
-
- linkmode_copy(phydev->supported, supported);
- linkmode_and(phydev->advertising, phydev->advertising,
- phydev->supported);
+ ret = genphy_c45_pma_read_abilities(phydev);
+ if (ret)
+ return ret;
return 0;
}
diff --git a/drivers/net/phy/phy-c45.c b/drivers/net/phy/phy-c45.c
index c92d0fb7ec4f..32e72b170ea9 100644
--- a/drivers/net/phy/phy-c45.c
+++ b/drivers/net/phy/phy-c45.c
@@ -256,6 +256,80 @@ int genphy_c45_read_mdix(struct phy_device *phydev)
}
EXPORT_SYMBOL_GPL(genphy_c45_read_mdix);
+/**
+ * genphy_c45_pma_read_abilities - read supported link modes from PMA
+ * @phydev: target phy_device struct
+ *
+ * Read the supported link modes from the PMA Status 2 (1.8) register. If bit
+ * 1.8.9 is set, the list of supported modes is build using the values in the
+ * PMA Extended Abilities (1.11) register, indicating 1000BASET an 10G related
+ * modes. If bit 1.11.14 is set, then the list is also extended with the modes
+ * in the 2.5G/5G PMA Extended register (1.21), indicating if 2.5GBASET and
+ * 5GBASET are supported.
+ */
+int genphy_c45_pma_read_abilities(struct phy_device *phydev)
+{
+ int val;
+
+ val = phy_read_mmd(phydev, MDIO_MMD_PMAPMD, MDIO_STAT2);
+ if (val < 0)
+ return val;
+
+ linkmode_mod_bit(ETHTOOL_LINK_MODE_10000baseSR_Full_BIT,
+ phydev->supported,
+ val & MDIO_PMA_STAT2_10GBSR);
+
+ linkmode_mod_bit(ETHTOOL_LINK_MODE_10000baseLR_Full_BIT,
+ phydev->supported,
+ val & MDIO_PMA_STAT2_10GBLR);
+
+ linkmode_mod_bit(ETHTOOL_LINK_MODE_10000baseER_Full_BIT,
+ phydev->supported,
+ val & MDIO_PMA_STAT2_10GBER);
+
+ if (val & MDIO_PMA_STAT2_EXTABLE) {
+ val = phy_read_mmd(phydev, MDIO_MMD_PMAPMD, MDIO_PMA_EXTABLE);
+ if (val < 0)
+ return val;
+
+ linkmode_mod_bit(ETHTOOL_LINK_MODE_10000baseLRM_Full_BIT,
+ phydev->supported,
+ val & MDIO_PMA_EXTABLE_10GBLRM);
+ linkmode_mod_bit(ETHTOOL_LINK_MODE_10000baseT_Full_BIT,
+ phydev->supported,
+ val & MDIO_PMA_EXTABLE_10GBT);
+ linkmode_mod_bit(ETHTOOL_LINK_MODE_10000baseKX4_Full_BIT,
+ phydev->supported,
+ val & MDIO_PMA_EXTABLE_10GBKX4);
+ linkmode_mod_bit(ETHTOOL_LINK_MODE_10000baseKR_Full_BIT,
+ phydev->supported,
+ val & MDIO_PMA_EXTABLE_10GBKR);
+ linkmode_mod_bit(ETHTOOL_LINK_MODE_1000baseT_Full_BIT,
+ phydev->supported,
+ val & MDIO_PMA_EXTABLE_1000BT);
+ linkmode_mod_bit(ETHTOOL_LINK_MODE_1000baseKX_Full_BIT,
+ phydev->supported,
+ val & MDIO_PMA_EXTABLE_1000BKX);
+
+ linkmode_mod_bit(ETHTOOL_LINK_MODE_100baseT_Full_BIT,
+ phydev->supported,
+ val & MDIO_PMA_EXTABLE_100BTX);
+ linkmode_mod_bit(ETHTOOL_LINK_MODE_100baseT_Half_BIT,
+ phydev->supported,
+ val & MDIO_PMA_EXTABLE_100BTX);
+
+ linkmode_mod_bit(ETHTOOL_LINK_MODE_10baseT_Full_BIT,
+ phydev->supported,
+ val & MDIO_PMA_EXTABLE_10BT);
+ linkmode_mod_bit(ETHTOOL_LINK_MODE_10baseT_Half_BIT,
+ phydev->supported,
+ val & MDIO_PMA_EXTABLE_10BT);
+ }
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(genphy_c45_pma_read_abilities);
+
/* The gen10g_* functions are the old Clause 45 stub */
int gen10g_config_aneg(struct phy_device *phydev)
diff --git a/include/linux/phy.h b/include/linux/phy.h
index 017118061ecf..863d0e00db89 100644
--- a/include/linux/phy.h
+++ b/include/linux/phy.h
@@ -1102,6 +1102,7 @@ int genphy_c45_read_pma(struct phy_device *phydev);
int genphy_c45_pma_setup_forced(struct phy_device *phydev);
int genphy_c45_an_disable_aneg(struct phy_device *phydev);
int genphy_c45_read_mdix(struct phy_device *phydev);
+int genphy_c45_pma_read_abilities(struct phy_device *phydev);
/* The gen10g_* functions are the old Clause 45 stub */
int gen10g_config_aneg(struct phy_device *phydev);
--
2.19.2
We want to be able to update a PHY's supported list in the config_init
callback, so move the Pause parameters settings from phydrv->features
after calling config_init to make sure these parameters aren't
overwritten.
Signed-off-by: Maxime Chevallier <[email protected]>
---
drivers/net/phy/phy_device.c | 89 +++++++++++++++++++++++-------------
1 file changed, 58 insertions(+), 31 deletions(-)
diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c
index 891e0178b97f..18a10565efd4 100644
--- a/drivers/net/phy/phy_device.c
+++ b/drivers/net/phy/phy_device.c
@@ -1059,6 +1059,59 @@ static int phy_poll_reset(struct phy_device *phydev)
return 0;
}
+/**
+ * phy_update_linkmodes - Update and sanitize linkmodes and pause parameters
+ * @phydev: The PHY device whose parameters we want to update.
+ *
+ * Description: The list of supported and advertised linkmodes is not
+ * straightforward to maintain, since PHYs and MACs are subject to quirks and
+ * erratas. This function re-builds the list of the supported pause parameters
+ * by taking into account the parameters expressed in the driver's features
+ * list.
+ */
+static void phy_update_linkmodes(struct phy_device *phydev)
+{
+ struct device_driver *drv = phydev->mdio.dev.driver;
+ struct phy_driver *phydrv = to_phy_driver(drv);
+
+ mutex_lock(&phydev->lock);
+
+ /* The Pause Frame bits indicate that the PHY can support passing
+ * pause frames. During autonegotiation, the PHYs will determine if
+ * they should allow pause frames to pass. The MAC driver should then
+ * use that result to determine whether to enable flow control via
+ * pause frames.
+ *
+ * Normally, PHY drivers should not set the Pause bits, and instead
+ * allow phylib to do that. However, there may be some situations
+ * (e.g. hardware erratum) where the driver wants to set only one
+ * of these bits.
+ */
+ if (test_bit(ETHTOOL_LINK_MODE_Pause_BIT, phydrv->features) ||
+ test_bit(ETHTOOL_LINK_MODE_Asym_Pause_BIT, phydrv->features)) {
+ linkmode_clear_bit(ETHTOOL_LINK_MODE_Pause_BIT,
+ phydev->supported);
+ linkmode_clear_bit(ETHTOOL_LINK_MODE_Asym_Pause_BIT,
+ phydev->supported);
+ if (test_bit(ETHTOOL_LINK_MODE_Pause_BIT, phydrv->features))
+ linkmode_set_bit(ETHTOOL_LINK_MODE_Pause_BIT,
+ phydev->supported);
+ if (test_bit(ETHTOOL_LINK_MODE_Asym_Pause_BIT,
+ phydrv->features))
+ linkmode_set_bit(ETHTOOL_LINK_MODE_Asym_Pause_BIT,
+ phydev->supported);
+ } else {
+ linkmode_set_bit(ETHTOOL_LINK_MODE_Pause_BIT,
+ phydev->supported);
+ linkmode_set_bit(ETHTOOL_LINK_MODE_Asym_Pause_BIT,
+ phydev->supported);
+ }
+
+ linkmode_copy(phydev->advertising, phydev->supported);
+
+ mutex_unlock(&phydev->lock);
+}
+
int phy_init_hw(struct phy_device *phydev)
{
int ret = 0;
@@ -1082,6 +1135,11 @@ int phy_init_hw(struct phy_device *phydev)
if (phydev->drv->config_init)
ret = phydev->drv->config_init(phydev);
+ /* Update and sanitize the supported and advertised linkmodes, since
+ * they might have been changed in config_init
+ */
+ phy_update_linkmodes(phydev);
+
return ret;
}
EXPORT_SYMBOL(phy_init_hw);
@@ -2221,37 +2279,6 @@ static int phy_probe(struct device *dev)
*/
of_set_phy_eee_broken(phydev);
- /* The Pause Frame bits indicate that the PHY can support passing
- * pause frames. During autonegotiation, the PHYs will determine if
- * they should allow pause frames to pass. The MAC driver should then
- * use that result to determine whether to enable flow control via
- * pause frames.
- *
- * Normally, PHY drivers should not set the Pause bits, and instead
- * allow phylib to do that. However, there may be some situations
- * (e.g. hardware erratum) where the driver wants to set only one
- * of these bits.
- */
- if (test_bit(ETHTOOL_LINK_MODE_Pause_BIT, phydrv->features) ||
- test_bit(ETHTOOL_LINK_MODE_Asym_Pause_BIT, phydrv->features)) {
- linkmode_clear_bit(ETHTOOL_LINK_MODE_Pause_BIT,
- phydev->supported);
- linkmode_clear_bit(ETHTOOL_LINK_MODE_Asym_Pause_BIT,
- phydev->supported);
- if (test_bit(ETHTOOL_LINK_MODE_Pause_BIT, phydrv->features))
- linkmode_set_bit(ETHTOOL_LINK_MODE_Pause_BIT,
- phydev->supported);
- if (test_bit(ETHTOOL_LINK_MODE_Asym_Pause_BIT,
- phydrv->features))
- linkmode_set_bit(ETHTOOL_LINK_MODE_Asym_Pause_BIT,
- phydev->supported);
- } else {
- linkmode_set_bit(ETHTOOL_LINK_MODE_Pause_BIT,
- phydev->supported);
- linkmode_set_bit(ETHTOOL_LINK_MODE_Asym_Pause_BIT,
- phydev->supported);
- }
-
/* Set the state to READY by default */
phydev->state = PHY_READY;
--
2.19.2
Hello everyone,
On Thu, 7 Feb 2019 10:49:30 +0100
Maxime Chevallier <[email protected]> wrote:
>We want to be able to update a PHY's supported list in the config_init
>callback, so move the Pause parameters settings from phydrv->features
>after calling config_init to make sure these parameters aren't
>overwritten.
I realised that I did not include updating the modes according to the
limitations imposed by of_set_phy_supported in this series. If there's
a speed limitation set in the DT, it could be overwritten by
config_init.
I'll respin the series with this addition, sorry about that.
Maxime
On Thu, Feb 07, 2019 at 10:49:30AM +0100, Maxime Chevallier wrote:
> We want to be able to update a PHY's supported list in the config_init
> callback, so move the Pause parameters settings from phydrv->features
> after calling config_init to make sure these parameters aren't
> overwritten.
Hi Maxime
I have a patch which makes some core changes to support PHY doing
runtime feature detection. I would prefer to use them, than this.
Either I or Heiner will post them soon.
Andrew
Hello Andrew,
On Thu, 7 Feb 2019 14:48:07 +0100
Andrew Lunn <[email protected]> wrote:
>On Thu, Feb 07, 2019 at 10:49:30AM +0100, Maxime Chevallier wrote:
>> We want to be able to update a PHY's supported list in the config_init
>> callback, so move the Pause parameters settings from phydrv->features
>> after calling config_init to make sure these parameters aren't
>> overwritten.
>
>Hi Maxime
>
>I have a patch which makes some core changes to support PHY doing
>runtime feature detection. I would prefer to use them, than this.
>
>Either I or Heiner will post them soon.
Sure, no problem, thanks for doing this. I'll be happy to review and
test that on my side.
As I said, I lack the big picture view on that part so my approach was
pretty naive, I'm glad you can take care of this :)
Thanks,
Maxime
On Thu, Feb 07, 2019 at 10:49:31AM +0100, Maxime Chevallier wrote:
> When setting a PHY's max speed using either the max-speed DT property
> or ethtool, we should mask-out all non-compatible modes according to the
> settings table, instead of just the 10/100BASET modes.
>
> Signed-off-by: Maxime Chevallier <[email protected]>
> Suggested-by: Russell King <[email protected]>
Reviewed-by: Andrew Lunn <[email protected]>
Andrew
On Thu, Feb 07, 2019 at 10:49:32AM +0100, Maxime Chevallier wrote:
> Since of_set_phy_supported was moved to phy-core.c, we can also move
> of_set_phy_eee_broken to the same location, so that we have all OF
> functions in the same place.
>
> This patch doesn't intend to introduce any change in behaviour.
>
> Signed-off-by: Maxime Chevallier <[email protected]>
Reviewed-by: Andrew Lunn <[email protected]>
Andrew
On Thu, Feb 07, 2019 at 10:49:33AM +0100, Maxime Chevallier wrote:
> PHY advertised and supported linkmodes contain both specific modes such
> as 1000BASET Half/Full and generic ones such as TP that represent a
> class of modes.
>
> Since some modes such as Fibre, TP or Backplane match a wide range of
> specific modes, we can automatically set these bits if one of the
> specific modes it corresponds to is present in the list.
>
> The 'TP' bit is set whenever there's a BaseT linkmode in
> phydev->supported.
>
> The 'FIBRE' bit is set for BaseL, BaseS and BaseE linkmodes.
>
> Finally, the 'Backplane' is set whenever a BaseK mode is supported.
Hi Maxime
Interesting idea.
But what exactly are we supposed to be representing here? That PHY
can do these modes, or that the port exists on the device? The
marvell10g can do fibre, but do all boards have an SFP/SFF, or do some
only have an RJ-45 for TP? Are there boards without TP and just
SFP/SFF?
Is there documentation in ethtool which gives a clue as to what is
expected?
Thanks
Andrew
> if (phydev->speed == SPEED_10000)
> phydev->interface = PHY_INTERFACE_MODE_10GKR;
> + else if (phydev->speed == SPEED_2500)
> + phydev->interface = PHY_INTERFACE_MODE_2500BASEX;
> else if (phydev->speed >= SPEED_10 &&
> - phydev->speed < SPEED_10000)
> + phydev->speed < SPEED_2500)
> phydev->interface = PHY_INTERFACE_MODE_SGMII;
> }
Maybe swap to a switch statement?
> static struct phy_driver mv3310_drivers[] = {
> {
> - .phy_id = 0x002b09aa,
> + .phy_id = MARVELL_PHY_ID_88X3310,
What does the datasheet say about the lower nibble? Often it is a
silicon revision field, so you don't match on it. But 0xa is a rather
odd revision.
Thanks
Andrew
On Thu, Feb 07, 2019 at 10:49:38AM +0100, Maxime Chevallier wrote:
> The PPv2 controller is able to support 2.5G speeds, allowing to use
> 2.5GBASET in conjunction with PHYs that use 2500BASEX as their MII
> interface when using this mode.
>
> Signed-off-by: Maxime Chevallier <[email protected]>
Reviewed-by: Andrew Lunn <[email protected]>
Andrew
Hello Andrew,
On Thu, 7 Feb 2019 15:09:39 +0100
Andrew Lunn <[email protected]> wrote:
>On Thu, Feb 07, 2019 at 10:49:33AM +0100, Maxime Chevallier wrote:
>> PHY advertised and supported linkmodes contain both specific modes such
>> as 1000BASET Half/Full and generic ones such as TP that represent a
>> class of modes.
>>
>> Since some modes such as Fibre, TP or Backplane match a wide range of
>> specific modes, we can automatically set these bits if one of the
>> specific modes it corresponds to is present in the list.
>>
>> The 'TP' bit is set whenever there's a BaseT linkmode in
>> phydev->supported.
>>
>> The 'FIBRE' bit is set for BaseL, BaseS and BaseE linkmodes.
>>
>> Finally, the 'Backplane' is set whenever a BaseK mode is supported.
>
>Hi Maxime
>
>Interesting idea.
>
>But what exactly are we supposed to be representing here? That PHY
>can do these modes, or that the port exists on the device? The
>marvell10g can do fibre, but do all boards have an SFP/SFF, or do some
>only have an RJ-45 for TP? Are there boards without TP and just
>SFP/SFF?
My understanding is that this would represent what the PHY is capable
of, at least when set in the supported field, but I agree that this
doesn't reflect what's on the device.
I extrapolated this logic from the ability detection in marvell10g,
that would set these bits according to the abilities reported by the
PHY. This was done based on the PHY register values, instead of the
linkmodes in the 'supported' field.
>Is there documentation in ethtool which gives a clue as to what is
>expected?
Not really, at least to my knowledge. I think this would be used by
"ethtool -s ethX port tp|fibre|aui|etc". Maybe this could be useful if
we decide to implement port selection with ethtool on the MCBin, but I'm
getting a bit ahead of myself.
Thanks,
Maxime
On 07.02.2019 14:55, Maxime Chevallier wrote:
> Hello Andrew,
>
> On Thu, 7 Feb 2019 14:48:07 +0100
> Andrew Lunn <[email protected]> wrote:
>
>> On Thu, Feb 07, 2019 at 10:49:30AM +0100, Maxime Chevallier wrote:
>>> We want to be able to update a PHY's supported list in the config_init
>>> callback, so move the Pause parameters settings from phydrv->features
>>> after calling config_init to make sure these parameters aren't
>>> overwritten.
>>
>> Hi Maxime
>>
>> I have a patch which makes some core changes to support PHY doing
>> runtime feature detection. I would prefer to use them, than this.
>>
>> Either I or Heiner will post them soon.
>
> Sure, no problem, thanks for doing this. I'll be happy to review and
> test that on my side.
>
The second version of the patch set comes in time because I was just
about to submit parts of it on Maxime's behalf. We may have some
dependencies between adding the get_features callback in phy_driver
and this patch set. Maybe the patch set needs to be splitted.
I think tomorrow or the day after I can have a closer look at this.
> As I said, I lack the big picture view on that part so my approach was
> pretty naive, I'm glad you can take care of this :)
>
Don't be so self-effacing, it's good work :)
> Thanks,
>
> Maxime
>
Heiner
On Thu, Feb 07, 2019 at 10:49:36AM +0100, Maxime Chevallier wrote:
> The Marvell Alaska family of PHYs supports 2.5GBaseT and 5GBaseT modes,
> as defined in the 802.3bz specification.
>
> When the link partner requests a 2.5GBASET link, the PHY will
> reconfigure it's MII interface to 2500BASEX.
>
> At 5G, the PHY will reconfigure it's interface to 5GBASE-R, but this
> mode isn't supported by any MAC for now.
>
> This was tested with :
> - The 88X3310, which is on the MacchiatoBin
Hi Maxime,
Looking deeper at this, I think we actually need an additional patch at
the beginning of your series.
The default AN advertisement in 7.32 is 0x1181 - which includes the
2.5G and 5G modes. We need to clear these bits, so that when the 10G
mode disabled via ethtool, we do not switch to 2.5G or 5G speed (both
of which are not currently reported as supported.) Such a patch needs
backporting to stable kernels.
> - The 88E2010, an Alaska PHY that has no fiber interfaces, and is
> limited to 5G maximum speed.
>
> Signed-off-by: Maxime Chevallier <[email protected]>
> ---
> V1 -> V2: Use a #define for the 88X3310 PHY ID, since it's reused in
> various places in the code. Rebased on Heiner Kallweit's patch
> introducing the phy_modify_mmd accessor.
>
> drivers/net/phy/marvell10g.c | 30 ++++++++++++++++++++++--------
> include/linux/marvell_phy.h | 1 +
> 2 files changed, 23 insertions(+), 8 deletions(-)
>
> diff --git a/drivers/net/phy/marvell10g.c b/drivers/net/phy/marvell10g.c
> index 07df87b81369..581b4b6e31e9 100644
> --- a/drivers/net/phy/marvell10g.c
> +++ b/drivers/net/phy/marvell10g.c
> @@ -238,6 +238,7 @@ static int mv3310_config_init(struct phy_device *phydev)
>
> /* Check that the PHY interface type is compatible */
> if (phydev->interface != PHY_INTERFACE_MODE_SGMII &&
> + phydev->interface != PHY_INTERFACE_MODE_2500BASEX &&
> phydev->interface != PHY_INTERFACE_MODE_XAUI &&
> phydev->interface != PHY_INTERFACE_MODE_RXAUI &&
> phydev->interface != PHY_INTERFACE_MODE_10GKR)
> @@ -307,8 +308,18 @@ static int mv3310_config_aneg(struct phy_device *phydev)
> else
> reg = 0;
>
> + if (linkmode_test_bit(ETHTOOL_LINK_MODE_2500baseT_Full_BIT,
> + phydev->advertising))
> + reg |= MDIO_AN_10GBT_CTRL_ADV2_5G;
> + if (linkmode_test_bit(ETHTOOL_LINK_MODE_5000baseT_Full_BIT,
> + phydev->advertising))
> + reg |= MDIO_AN_10GBT_CTRL_ADV5G;
> +
> ret = phy_modify_mmd(phydev, MDIO_MMD_AN, MDIO_AN_10GBT_CTRL,
> - MDIO_AN_10GBT_CTRL_ADV10G, reg);
> + MDIO_AN_10GBT_CTRL_ADV10G |
> + MDIO_AN_10GBT_CTRL_ADV5G |
> + MDIO_AN_10GBT_CTRL_ADV2_5G, reg);
> +
> if (ret < 0)
> return ret;
> if (ret > 0)
> @@ -337,17 +348,20 @@ static int mv3310_aneg_done(struct phy_device *phydev)
> static void mv3310_update_interface(struct phy_device *phydev)
> {
> if ((phydev->interface == PHY_INTERFACE_MODE_SGMII ||
> + phydev->interface == PHY_INTERFACE_MODE_2500BASEX ||
> phydev->interface == PHY_INTERFACE_MODE_10GKR) && phydev->link) {
> /* The PHY automatically switches its serdes interface (and
> - * active PHYXS instance) between Cisco SGMII and 10GBase-KR
> - * modes according to the speed. Florian suggests setting
> - * phydev->interface to communicate this to the MAC. Only do
> - * this if we are already in either SGMII or 10GBase-KR mode.
> + * active PHYXS instance) between Cisco SGMII, 10GBase-KR and
> + * 2500BaseX modes according to the speed. Florian suggests
> + * setting phydev->interface to communicate this to the MAC.
> + * Only do this if we are already in one of the above modes.
> */
> if (phydev->speed == SPEED_10000)
> phydev->interface = PHY_INTERFACE_MODE_10GKR;
> + else if (phydev->speed == SPEED_2500)
> + phydev->interface = PHY_INTERFACE_MODE_2500BASEX;
> else if (phydev->speed >= SPEED_10 &&
> - phydev->speed < SPEED_10000)
> + phydev->speed < SPEED_2500)
> phydev->interface = PHY_INTERFACE_MODE_SGMII;
> }
> }
> @@ -450,7 +464,7 @@ static int mv3310_read_status(struct phy_device *phydev)
>
> static struct phy_driver mv3310_drivers[] = {
> {
> - .phy_id = 0x002b09aa,
> + .phy_id = MARVELL_PHY_ID_88X3310,
> .phy_id_mask = MARVELL_PHY_ID_MASK,
> .name = "mv88x3310",
> .features = PHY_10GBIT_FEATURES,
> @@ -468,7 +482,7 @@ static struct phy_driver mv3310_drivers[] = {
> module_phy_driver(mv3310_drivers);
>
> static struct mdio_device_id __maybe_unused mv3310_tbl[] = {
> - { 0x002b09aa, MARVELL_PHY_ID_MASK },
> + { MARVELL_PHY_ID_88X3310, MARVELL_PHY_ID_MASK },
> { },
> };
> MODULE_DEVICE_TABLE(mdio, mv3310_tbl);
> diff --git a/include/linux/marvell_phy.h b/include/linux/marvell_phy.h
> index 1eb6f244588d..5851d68d828a 100644
> --- a/include/linux/marvell_phy.h
> +++ b/include/linux/marvell_phy.h
> @@ -20,6 +20,7 @@
> #define MARVELL_PHY_ID_88E1540 0x01410eb0
> #define MARVELL_PHY_ID_88E1545 0x01410ea0
> #define MARVELL_PHY_ID_88E3016 0x01410e60
> +#define MARVELL_PHY_ID_88X3310 0x002b09aa
>
> /* The MV88e6390 Ethernet switch contains embedded PHYs. These PHYs do
> * not have a model ID. So the switch driver traps reads to the ID2
> --
> 2.19.2
>
>
--
RMK's Patch system: https://www.armlinux.org.uk/developer/patches/
FTTC broadband for 0.8mile line in suburbia: sync at 12.1Mbps down 622kbps up
According to speedtest.net: 11.9Mbps down 500kbps up
On 07.02.2019 10:49, Maxime Chevallier wrote:
> Hello everyone,
>
> This is the second iteration of the series introducing support for
> 2.5GBASET and 5GBASET to the network PHY infrastructure.
>
> These 2 modes are described in the 802.3bz specifications, and allow to
> use 2.5G and 5G speeds on cat5e/cat6 cables.
>
> The required infrastructure code is added for 2.5GBASET and 5GBASET, but
> only 2.5GBASET support is added to the Marvell10G driver. The reason is
> because the 5GBASER interface mode used to communicate with the MAC
> isn't implemented yet, and therefore this can't be tested.
>
> This series has seen some rework since last time, see the full details
> in the patches changelog. The main highlights are :
>
> - Patch 1 moves the Pause ans Asym_Pause parameters update after
> calling config_init. This allows us to change the phydev->supported
> modes in config_init, while still forcing some quirks taken from
> phydrv->features, to disable unsupported Pause modes. This was
> proposed by Andrew.
>
> - Patch 2 generalizes the way we mask-out modes we don't want to use
> when forcing the link speed through DT or ethtool, by walking through
> the PHY settings table, as proposed by Russell.
>
> - Patch 4 implements automatic setting of TM, FIBRE and Backplane bits
> from the list of supported linkmodes.
>
> - In Patch 5, we only read abilities from the PMA. Pause parameters
> aren't built from the genphy_c45_pma_read_abilities, as it was done
> in the previous iteration of the patch. We also amke use of
> linkmode_mod_bit to make sure we mask-out unsupported modes.
>
> - In Patch 8, we manually check for the PMA device id to see if we have
> to use a quirk when reading the 2.5G/5G Extended Abilities
>
> Maxime Chevallier (10):
> net: phy: Update PHY linkmodes after config_init
> net: phy: Mask-out non-compatible modes when setting the max-speed
> net: phy: Move of_set_phy_eee_broken to phy-core.c
> net: phy: Automatically fill the generic TP, FIBRE and Backplane modes
> net: phy: Extract genphy_c45_pma_read_abilities from marvell10g
> net: phy: Add generic support for 2.5GBaseT and 5GBaseT
> net: phy: marvell10g: Add support for 2.5GBASET
> net: phy: marvell10g: Force reading of 2.5/5G
> net: mvpp2: Add 2.5GBaseT support
> net: phy: marvell10g: add support for the 88x2110 PHY
>
> .../net/ethernet/marvell/mvpp2/mvpp2_main.c | 1 +
> drivers/net/phy/marvell10g.c | 142 +++++------
> drivers/net/phy/phy-c45.c | 111 ++++++++
> drivers/net/phy/phy-core.c | 72 ++++++
> drivers/net/phy/phy_device.c | 237 +++++++++---------
> include/linux/linkmode.h | 6 +
> include/linux/marvell_phy.h | 2 +
> include/linux/phy.h | 3 +
> include/uapi/linux/mdio.h | 16 ++
> 9 files changed, 405 insertions(+), 185 deletions(-)
>
Hi Maxime,
Andrew and me are working on Aquantia PHY support and he handed over
to me a patch series which includes parts of the first version of your
series. Having said that I'm especially interested in your patches
5 and 6. Because your series is somewhat bigger and there are a few
review comments, preparing the next round may take time.
I'd propose that you extract generic patches being submission-ready
and split the patch series into two. I think the following patches
would be candidates for the first series: 2, 3, 5, 6
(provided they have no dependency on the other patches)
Based on that both of us can go on with our work.
Andrew, what do you think?
Heiner
> I'd propose that you extract generic patches being submission-ready
> and split the patch series into two. I think the following patches
> would be candidates for the first series: 2, 3, 5, 6
> (provided they have no dependency on the other patches)
> Based on that both of us can go on with our work.
>
> Andrew, what do you think?
Yes, that would help.
Heiner, can you also submit the .get_features patches soon. That is
another important piece of the puzzle for both drivers.
Thanks
Andrew
On 09.02.2019 17:25, Andrew Lunn wrote:
>> I'd propose that you extract generic patches being submission-ready
>> and split the patch series into two. I think the following patches
>> would be candidates for the first series: 2, 3, 5, 6
>> (provided they have no dependency on the other patches)
>> Based on that both of us can go on with our work.
>>
>> Andrew, what do you think?
>
> Yes, that would help.
>
> Heiner, can you also submit the .get_features patches soon. That is
> another important piece of the puzzle for both drivers.
>
Just submitted it few hours ago.
https://patchwork.ozlabs.org/patch/1039237/
> Thanks
> Andrew
>
Heiner
Hello Heiner,
>Hi Maxime,
>
>Andrew and me are working on Aquantia PHY support and he handed over
>to me a patch series which includes parts of the first version of your
>series. Having said that I'm especially interested in your patches
>5 and 6. Because your series is somewhat bigger and there are a few
>review comments, preparing the next round may take time.
>
>I'd propose that you extract generic patches being submission-ready
>and split the patch series into two. I think the following patches
>would be candidates for the first series: 2, 3, 5, 6
>(provided they have no dependency on the other patches)
>Based on that both of us can go on with our work.
Sure, I'll sent that shortly. Thanks for the help,
Maxime
Hello Russell,
On Thu, 7 Feb 2019 23:48:24 +0000
Russell King - ARM Linux admin <[email protected]> wrote:
>On Thu, Feb 07, 2019 at 10:49:36AM +0100, Maxime Chevallier wrote:
>> The Marvell Alaska family of PHYs supports 2.5GBaseT and 5GBaseT modes,
>> as defined in the 802.3bz specification.
>>
>> When the link partner requests a 2.5GBASET link, the PHY will
>> reconfigure it's MII interface to 2500BASEX.
>>
>> At 5G, the PHY will reconfigure it's interface to 5GBASE-R, but this
>> mode isn't supported by any MAC for now.
>>
>> This was tested with :
>> - The 88X3310, which is on the MacchiatoBin
>
>Hi Maxime,
>
>Looking deeper at this, I think we actually need an additional patch at
>the beginning of your series.
>
>The default AN advertisement in 7.32 is 0x1181 - which includes the
>2.5G and 5G modes. We need to clear these bits, so that when the 10G
>mode disabled via ethtool, we do not switch to 2.5G or 5G speed (both
>of which are not currently reported as supported.) Such a patch needs
>backporting to stable kernels.
Good catch. The issue seems fixed by Andrew's patch :
3de97f3c6308 ("net: phy: marvell10g: use genphy_c45_an_config_aneg")
However, the fix should indeed be backported to the -stable trees, I've
been able to repdocude this on 4.20. I'll take care of sending a patch
to -net for that.
Thanks for reporting this,
Maxime