2023-11-26 06:08:58

by Luo Jie

[permalink] [raw]
Subject: [PATCH v6 0/6] add qca8084 ethernet phy driver

QCA8084 is four-port PHY with maximum link capability 2.5G,
which supports the interface mode qusgmii and sgmii mode,
there are two PCSs available to connected with ethernet port.

QCA8084 can work in switch mode or PHY mode.
For switch mode, both PCS0 and PCS1 work on sgmii mode.
For PHY mode, PCS1 works on qusgmii mode.
The fourth PHY connected with PCS0 works on sgmii mode.

Besides this PHY driver patches, the PCS driver is also needed
to bring up the qca8084 device, which mainly configurs PCS
and clocks.

Changes in v3:
* pick the two patches to introduce the interface mode
10g-qxgmii from Vladimir Oltean([email protected]).
* add the function phydev_id_is_qca808x to identify the
PHY qca8081 and qca8084.
* update the interface mode name PHY_INTERFACE_MODE_QUSGMII
to PHY_INTERFACE_MODE_10G_QXGMII.

Changes in v4:
* remove the following patch:
<net: phylink: move phylink_pcs_neg_mode() to phylink.c>.
* split out 10g_qxgmii change of ethernet-controller.yaml.

Changes in v5:
* update the author of the patch below.
<introduce core support for phy-mode = "10g-qxgmii">.

Changes in v6:
* drop the "inline" keyword.
* apply the patches with "--max-line-length=80".

Luo Jie (4):
net: phy: at803x: add QCA8084 ethernet phy support
net: phy: at803x: add the function phydev_id_is_qca808x
net: phy: at803x: Add qca8084_config_init function
net: phy: qca8084: add qca8084_link_change_notify

Vladimir Oltean (2):
net: phy: introduce core support for phy-mode = "10g-qxgmii"
dt-bindings: net: ethernet-controller: add 10g-qxgmii mode

.../bindings/net/ethernet-controller.yaml | 1 +
Documentation/networking/phy.rst | 6 +
drivers/net/phy/at803x.c | 139 +++++++++++++++++-
drivers/net/phy/phy-core.c | 1 +
drivers/net/phy/phylink.c | 11 +-
include/linux/phy.h | 4 +
include/linux/phylink.h | 2 +
7 files changed, 156 insertions(+), 8 deletions(-)


base-commit: 8c9660f6515396aba78d1168d2e17951d653ebf2
--
2.42.0


2023-11-26 06:09:04

by Luo Jie

[permalink] [raw]
Subject: [PATCH v6 1/6] net: phy: introduce core support for phy-mode = "10g-qxgmii"

From: Vladimir Oltean <[email protected]>

10G-QXGMII is a MAC-to-PHY interface defined by the USXGMII multiport
specification. It uses the same signaling as USXGMII, but it multiplexes
4 ports over the link, resulting in a maximum speed of 2.5G per port.

Some in-tree SoCs like the NXP LS1028A use "usxgmii" when they mean
either the single-port USXGMII or the quad-port 10G-QXGMII variant, and
they could get away just fine with that thus far. But there is a need to
distinguish between the 2 as far as SerDes drivers are concerned.

Signed-off-by: Vladimir Oltean <[email protected]>
Signed-off-by: Luo Jie <[email protected]>
---
Documentation/networking/phy.rst | 6 ++++++
drivers/net/phy/phy-core.c | 1 +
drivers/net/phy/phylink.c | 11 +++++++++--
include/linux/phy.h | 4 ++++
include/linux/phylink.h | 2 ++
5 files changed, 22 insertions(+), 2 deletions(-)

diff --git a/Documentation/networking/phy.rst b/Documentation/networking/phy.rst
index 1283240d7620..f64641417c54 100644
--- a/Documentation/networking/phy.rst
+++ b/Documentation/networking/phy.rst
@@ -327,6 +327,12 @@ Some of the interface modes are described below:
This is the Penta SGMII mode, it is similar to QSGMII but it combines 5
SGMII lines into a single link compared to 4 on QSGMII.

+``PHY_INTERFACE_MODE_10G_QXGMII``
+ Represents the 10G-QXGMII PHY-MAC interface as defined by the Cisco USXGMII
+ Multiport Copper Interface document. It supports 4 ports over a 10.3125 GHz
+ SerDes lane, each port having speeds of 2.5G / 1G / 100M / 10M achieved
+ through symbol replication. The PCS expects the standard USXGMII code word.
+
Pause frames / flow control
===========================

diff --git a/drivers/net/phy/phy-core.c b/drivers/net/phy/phy-core.c
index 966c93cbe616..1cd58723d6d0 100644
--- a/drivers/net/phy/phy-core.c
+++ b/drivers/net/phy/phy-core.c
@@ -141,6 +141,7 @@ int phy_interface_num_ports(phy_interface_t interface)
return 1;
case PHY_INTERFACE_MODE_QSGMII:
case PHY_INTERFACE_MODE_QUSGMII:
+ case PHY_INTERFACE_MODE_10G_QXGMII:
return 4;
case PHY_INTERFACE_MODE_PSGMII:
return 5;
diff --git a/drivers/net/phy/phylink.c b/drivers/net/phy/phylink.c
index c276f9482f78..803251299342 100644
--- a/drivers/net/phy/phylink.c
+++ b/drivers/net/phy/phylink.c
@@ -218,6 +218,7 @@ static int phylink_interface_max_speed(phy_interface_t interface)
return SPEED_1000;

case PHY_INTERFACE_MODE_2500BASEX:
+ case PHY_INTERFACE_MODE_10G_QXGMII:
return SPEED_2500;

case PHY_INTERFACE_MODE_5GBASER:
@@ -487,7 +488,11 @@ static unsigned long phylink_get_capabilities(phy_interface_t interface,

switch (interface) {
case PHY_INTERFACE_MODE_USXGMII:
- caps |= MAC_10000FD | MAC_5000FD | MAC_2500FD;
+ caps |= MAC_10000FD | MAC_5000FD;
+ fallthrough;
+
+ case PHY_INTERFACE_MODE_10G_QXGMII:
+ caps |= MAC_2500FD;
fallthrough;

case PHY_INTERFACE_MODE_RGMII_TXID:
@@ -905,6 +910,7 @@ static int phylink_parse_mode(struct phylink *pl,
phylink_set(pl->supported, 25000baseSR_Full);
fallthrough;
case PHY_INTERFACE_MODE_USXGMII:
+ case PHY_INTERFACE_MODE_10G_QXGMII:
case PHY_INTERFACE_MODE_10GKR:
case PHY_INTERFACE_MODE_10GBASER:
phylink_set(pl->supported, 10baseT_Half);
@@ -1777,7 +1783,8 @@ static int phylink_bringup_phy(struct phylink *pl, struct phy_device *phy,
if (phy->is_c45 && config.rate_matching == RATE_MATCH_NONE &&
interface != PHY_INTERFACE_MODE_RXAUI &&
interface != PHY_INTERFACE_MODE_XAUI &&
- interface != PHY_INTERFACE_MODE_USXGMII)
+ interface != PHY_INTERFACE_MODE_USXGMII &&
+ interface != PHY_INTERFACE_MODE_10G_QXGMII)
config.interface = PHY_INTERFACE_MODE_NA;
else
config.interface = interface;
diff --git a/include/linux/phy.h b/include/linux/phy.h
index e5f1f41e399c..b4ea3fa172a2 100644
--- a/include/linux/phy.h
+++ b/include/linux/phy.h
@@ -125,6 +125,7 @@ extern const int phy_10gbit_features_array[1];
* @PHY_INTERFACE_MODE_10GKR: 10GBASE-KR - with Clause 73 AN
* @PHY_INTERFACE_MODE_QUSGMII: Quad Universal SGMII
* @PHY_INTERFACE_MODE_1000BASEKX: 1000Base-KX - with Clause 73 AN
+ * @PHY_INTERFACE_MODE_10G_QXGMII: 10G-QXGMII - 4 ports over 10G USXGMII
* @PHY_INTERFACE_MODE_MAX: Book keeping
*
* Describes the interface between the MAC and PHY.
@@ -165,6 +166,7 @@ typedef enum {
PHY_INTERFACE_MODE_10GKR,
PHY_INTERFACE_MODE_QUSGMII,
PHY_INTERFACE_MODE_1000BASEKX,
+ PHY_INTERFACE_MODE_10G_QXGMII,
PHY_INTERFACE_MODE_MAX,
} phy_interface_t;

@@ -286,6 +288,8 @@ static inline const char *phy_modes(phy_interface_t interface)
return "100base-x";
case PHY_INTERFACE_MODE_QUSGMII:
return "qusgmii";
+ case PHY_INTERFACE_MODE_10G_QXGMII:
+ return "10g-qxgmii";
default:
return "unknown";
}
diff --git a/include/linux/phylink.h b/include/linux/phylink.h
index 875439ab45de..92bd2726cc8a 100644
--- a/include/linux/phylink.h
+++ b/include/linux/phylink.h
@@ -128,6 +128,7 @@ static inline unsigned int phylink_pcs_neg_mode(unsigned int mode,
case PHY_INTERFACE_MODE_QSGMII:
case PHY_INTERFACE_MODE_QUSGMII:
case PHY_INTERFACE_MODE_USXGMII:
+ case PHY_INTERFACE_MODE_10G_QXGMII:
/* These protocols are designed for use with a PHY which
* communicates its negotiation result back to the MAC via
* inband communication. Note: there exist PHYs that run
@@ -680,6 +681,7 @@ static inline int phylink_get_link_timer_ns(phy_interface_t interface)
case PHY_INTERFACE_MODE_SGMII:
case PHY_INTERFACE_MODE_QSGMII:
case PHY_INTERFACE_MODE_USXGMII:
+ case PHY_INTERFACE_MODE_10G_QXGMII:
return 1600000;

case PHY_INTERFACE_MODE_1000BASEX:
--
2.42.0

2023-11-26 06:09:07

by Luo Jie

[permalink] [raw]
Subject: [PATCH v6 6/6] net: phy: qca8084: add qca8084_link_change_notify

When the link is changed, qca8084 needs to do the fifo reset and
adjust the IPG level for the qusgmii link speed 1000M.

Signed-off-by: Luo Jie <[email protected]>
---
drivers/net/phy/at803x.c | 41 ++++++++++++++++++++++++++++++++++++++++
1 file changed, 41 insertions(+)

diff --git a/drivers/net/phy/at803x.c b/drivers/net/phy/at803x.c
index c0d5d4410e89..16ea022744ce 100644
--- a/drivers/net/phy/at803x.c
+++ b/drivers/net/phy/at803x.c
@@ -289,6 +289,13 @@
#define QCA8084_MSE_THRESHOLD 0x800a
#define QCA8084_MSE_THRESHOLD_2P5G_VAL 0x51c6

+#define QCA8084_FIFO_CONTROL 0x19
+#define QCA8084_FIFO_MAC_2_PHY BIT(1)
+#define QCA8084_FIFO_PHY_2_MAC BIT(0)
+
+#define QCA8084_MMD7_IPG_OP 0x901d
+#define QCA8084_IPG_10_TO_11_EN BIT(0)
+
MODULE_DESCRIPTION("Qualcomm Atheros AR803x and QCA808X PHY driver");
MODULE_AUTHOR("Matus Ujhelyi");
MODULE_LICENSE("GPL");
@@ -2114,6 +2121,39 @@ static int qca8084_config_init(struct phy_device *phydev)
QCA8084_MSE_THRESHOLD_2P5G_VAL);
}

+static void qca8084_link_change_notify(struct phy_device *phydev)
+{
+ int ret;
+
+ ret = phy_modify(phydev, QCA8084_FIFO_CONTROL,
+ QCA8084_FIFO_MAC_2_PHY | QCA8084_FIFO_PHY_2_MAC,
+ 0);
+ if (ret)
+ return;
+
+ /* If the PHY works on PHY_INTERFACE_MODE_10G_QXGMII mode, the fifo
+ * needs to be kept as reset state in link down status.
+ */
+ if (phydev->interface != PHY_INTERFACE_MODE_10G_QXGMII ||
+ phydev->link) {
+ msleep(50);
+ ret = phy_modify(phydev, QCA8084_FIFO_CONTROL,
+ QCA8084_FIFO_MAC_2_PHY |
+ QCA8084_FIFO_PHY_2_MAC,
+ QCA8084_FIFO_MAC_2_PHY |
+ QCA8084_FIFO_PHY_2_MAC);
+ if (ret)
+ return;
+ }
+
+ /* Enable IPG 10 to 11 tuning on link speed 1000M of QUSGMII mode. */
+ if (phydev->interface == PHY_INTERFACE_MODE_10G_QXGMII)
+ phy_modify_mmd(phydev, MDIO_MMD_AN, QCA8084_MMD7_IPG_OP,
+ QCA8084_IPG_10_TO_11_EN,
+ phydev->speed == SPEED_1000 ?
+ QCA8084_IPG_10_TO_11_EN : 0);
+}
+
static struct phy_driver at803x_driver[] = {
{
/* Qualcomm Atheros AR8035 */
@@ -2312,6 +2352,7 @@ static struct phy_driver at803x_driver[] = {
.cable_test_start = qca808x_cable_test_start,
.cable_test_get_status = qca808x_cable_test_get_status,
.config_init = qca8084_config_init,
+ .link_change_notify = qca8084_link_change_notify,
}, };

module_phy_driver(at803x_driver);
--
2.42.0

2023-11-26 06:09:12

by Luo Jie

[permalink] [raw]
Subject: [PATCH v6 4/6] net: phy: at803x: add the function phydev_id_is_qca808x

The function phydev_id_is_qca808x is applicable to the
PHY qca8081 and qca8084.

Signed-off-by: Luo Jie <[email protected]>
---
drivers/net/phy/at803x.c | 18 ++++++++++++------
1 file changed, 12 insertions(+), 6 deletions(-)

diff --git a/drivers/net/phy/at803x.c b/drivers/net/phy/at803x.c
index f376d794d170..430547f304f7 100644
--- a/drivers/net/phy/at803x.c
+++ b/drivers/net/phy/at803x.c
@@ -1165,6 +1165,12 @@ static void at803x_link_change_notify(struct phy_device *phydev)
}
}

+static bool phydev_id_is_qca808x(struct phy_device *phydev)
+{
+ return phydev_id_compare(phydev, QCA8081_PHY_ID) ||
+ phydev_id_compare(phydev, QCA8084_PHY_ID);
+}
+
static int at803x_read_specific_status(struct phy_device *phydev)
{
int ss;
@@ -1184,8 +1190,8 @@ static int at803x_read_specific_status(struct phy_device *phydev)
if (sfc < 0)
return sfc;

- /* qca8081 takes the different bits for speed value from at803x */
- if (phydev->drv->phy_id == QCA8081_PHY_ID)
+ /* qca808x takes the different bits for speed value from at803x */
+ if (phydev_id_is_qca808x(phydev))
speed = FIELD_GET(QCA808X_SS_SPEED_MASK, ss);
else
speed = FIELD_GET(AT803X_SS_SPEED_MASK, ss);
@@ -1316,7 +1322,7 @@ static int at803x_config_aneg(struct phy_device *phydev)
*/
ret = 0;

- if (phydev->drv->phy_id == QCA8081_PHY_ID) {
+ if (phydev_id_is_qca808x(phydev)) {
int phy_ctrl = 0;

/* The reg MII_BMCR also needs to be configured for force mode, the
@@ -1470,8 +1476,8 @@ static int at803x_cdt_start(struct phy_device *phydev, int pair)
{
u16 cdt;

- /* qca8081 takes the different bit 15 to enable CDT test */
- if (phydev->drv->phy_id == QCA8081_PHY_ID)
+ /* qca808x takes the different bit 15 to enable CDT test */
+ if (phydev_id_is_qca808x(phydev))
cdt = QCA808X_CDT_ENABLE_TEST |
QCA808X_CDT_LENGTH_UNIT |
QCA808X_CDT_INTER_CHECK_DIS;
@@ -1487,7 +1493,7 @@ static int at803x_cdt_wait_for_completion(struct phy_device *phydev)
int val, ret;
u16 cdt_en;

- if (phydev->drv->phy_id == QCA8081_PHY_ID)
+ if (phydev_id_is_qca808x(phydev))
cdt_en = QCA808X_CDT_ENABLE_TEST;
else
cdt_en = AT803X_CDT_ENABLE_TEST;
--
2.42.0

2023-11-26 06:09:15

by Luo Jie

[permalink] [raw]
Subject: [PATCH v6 5/6] net: phy: at803x: Add qca8084_config_init function

Configure MSE detect threshold and ADC clock edge invert.

Signed-off-by: Luo Jie <[email protected]>
---
drivers/net/phy/at803x.c | 30 ++++++++++++++++++++++++++++++
1 file changed, 30 insertions(+)

diff --git a/drivers/net/phy/at803x.c b/drivers/net/phy/at803x.c
index 430547f304f7..c0d5d4410e89 100644
--- a/drivers/net/phy/at803x.c
+++ b/drivers/net/phy/at803x.c
@@ -280,6 +280,15 @@
#define QCA8081_PHY_SERDES_MMD1_FIFO_CTRL 0x9072
#define QCA8081_PHY_FIFO_RSTN BIT(11)

+/* QCA8084 ADC clock edge */
+#define QCA8084_ADC_CLK_SEL 0x8b80
+#define QCA8084_ADC_CLK_SEL_ACLK GENMASK(7, 4)
+#define QCA8084_ADC_CLK_SEL_ACLK_FALL 0xf
+#define QCA8084_ADC_CLK_SEL_ACLK_RISE 0x0
+
+#define QCA8084_MSE_THRESHOLD 0x800a
+#define QCA8084_MSE_THRESHOLD_2P5G_VAL 0x51c6
+
MODULE_DESCRIPTION("Qualcomm Atheros AR803x and QCA808X PHY driver");
MODULE_AUTHOR("Matus Ujhelyi");
MODULE_LICENSE("GPL");
@@ -2085,6 +2094,26 @@ static void qca808x_link_change_notify(struct phy_device *phydev)
QCA8081_PHY_FIFO_RSTN, phydev->link ? QCA8081_PHY_FIFO_RSTN : 0);
}

+static int qca8084_config_init(struct phy_device *phydev)
+{
+ int ret;
+
+ /* Invert ADC clock edge */
+ ret = at803x_debug_reg_mask(phydev, QCA8084_ADC_CLK_SEL,
+ QCA8084_ADC_CLK_SEL_ACLK,
+ FIELD_PREP(QCA8084_ADC_CLK_SEL_ACLK,
+ QCA8084_ADC_CLK_SEL_ACLK_FALL));
+ if (ret < 0)
+ return ret;
+
+ /* Adjust MSE threshold value to avoid link issue with
+ * some link partner.
+ */
+ return phy_write_mmd(phydev, MDIO_MMD_PMAPMD,
+ QCA8084_MSE_THRESHOLD,
+ QCA8084_MSE_THRESHOLD_2P5G_VAL);
+}
+
static struct phy_driver at803x_driver[] = {
{
/* Qualcomm Atheros AR8035 */
@@ -2282,6 +2311,7 @@ static struct phy_driver at803x_driver[] = {
.soft_reset = qca808x_soft_reset,
.cable_test_start = qca808x_cable_test_start,
.cable_test_get_status = qca808x_cable_test_get_status,
+ .config_init = qca8084_config_init,
}, };

module_phy_driver(at803x_driver);
--
2.42.0

2023-11-26 06:09:17

by Luo Jie

[permalink] [raw]
Subject: [PATCH v6 3/6] net: phy: at803x: add QCA8084 ethernet phy support

Add qca8084 PHY support, which is four-port PHY with maximum
link capability 2.5G, the features of each port is almost same
as QCA8081 and slave seed config is not needed.

Three kind of interface modes supported by qca8084.
PHY_INTERFACE_MODE_10G_QXGMII, PHY_INTERFACE_MODE_2500BASEX and
PHY_INTERFACE_MODE_SGMII.

The PCS(serdes) and clock are also needed to be configured to
bringup qca8084 PHY, which will be added in the pcs driver.

The additional CDT configurations used for qca8084.

Signed-off-by: Luo Jie <[email protected]>
---
drivers/net/phy/at803x.c | 50 ++++++++++++++++++++++++++++++++++++++++
1 file changed, 50 insertions(+)

diff --git a/drivers/net/phy/at803x.c b/drivers/net/phy/at803x.c
index 37fb033e1c29..f376d794d170 100644
--- a/drivers/net/phy/at803x.c
+++ b/drivers/net/phy/at803x.c
@@ -176,6 +176,7 @@
#define AT8030_PHY_ID_MASK 0xffffffef

#define QCA8081_PHY_ID 0x004dd101
+#define QCA8084_PHY_ID 0x004dd180

#define QCA8327_A_PHY_ID 0x004dd033
#define QCA8327_B_PHY_ID 0x004dd034
@@ -1760,6 +1761,9 @@ static bool qca808x_is_prefer_master(struct phy_device *phydev)

static bool qca808x_has_fast_retrain_or_slave_seed(struct phy_device *phydev)
{
+ if (phydev_id_compare(phydev, QCA8084_PHY_ID))
+ return false;
+
return linkmode_test_bit(ETHTOOL_LINK_MODE_2500baseT_Full_BIT, phydev->supported);
}

@@ -1824,6 +1828,23 @@ static int qca808x_read_status(struct phy_device *phydev)
return ret;

if (phydev->link) {
+ /* There are two PCSs available for QCA8084, which support the
+ * following interface modes.
+ *
+ * 1. PHY_INTERFACE_MODE_10G_QXGMII utilizes PCS1 for all
+ * available 4 ports, which is for all link speeds.
+ *
+ * 2. PHY_INTERFACE_MODE_2500BASEX utilizes PCS0 for the
+ * fourth port, which is only for the link speed 2500M same
+ * as QCA8081.
+ *
+ * 3. PHY_INTERFACE_MODE_SGMII utilizes PCS0 for the fourth
+ * port, which is for the link speed 10M, 100M and 1000M same
+ * as QCA8081.
+ */
+ if (phydev->interface == PHY_INTERFACE_MODE_10G_QXGMII)
+ return 0;
+
if (phydev->speed == SPEED_2500)
phydev->interface = PHY_INTERFACE_MODE_2500BASEX;
else
@@ -1958,6 +1979,14 @@ static int qca808x_cable_test_start(struct phy_device *phydev)
phy_write_mmd(phydev, MDIO_MMD_PCS, 0x807a, 0xc060);
phy_write_mmd(phydev, MDIO_MMD_PCS, 0x807e, 0xb060);

+ if (phydev_id_compare(phydev, QCA8084_PHY_ID)) {
+ /* Adjust the positive and negative pulse thereshold of CDT */
+ phy_write_mmd(phydev, MDIO_MMD_PCS, 0x8075, 0xa060);
+
+ /* Disable the near echo bypass */
+ phy_modify_mmd(phydev, MDIO_MMD_PCS, 0x807f, BIT(15), 0);
+ }
+
return 0;
}

@@ -2227,6 +2256,26 @@ static struct phy_driver at803x_driver[] = {
.cable_test_start = qca808x_cable_test_start,
.cable_test_get_status = qca808x_cable_test_get_status,
.link_change_notify = qca808x_link_change_notify,
+}, {
+ /* Qualcomm QCA8084 */
+ PHY_ID_MATCH_MODEL(QCA8084_PHY_ID),
+ .name = "Qualcomm QCA8084",
+ .flags = PHY_POLL_CABLE_TEST,
+ .probe = at803x_probe,
+ .config_intr = at803x_config_intr,
+ .handle_interrupt = at803x_handle_interrupt,
+ .get_tunable = at803x_get_tunable,
+ .set_tunable = at803x_set_tunable,
+ .set_wol = at803x_set_wol,
+ .get_wol = at803x_get_wol,
+ .get_features = qca808x_get_features,
+ .config_aneg = at803x_config_aneg,
+ .suspend = genphy_suspend,
+ .resume = genphy_resume,
+ .read_status = qca808x_read_status,
+ .soft_reset = qca808x_soft_reset,
+ .cable_test_start = qca808x_cable_test_start,
+ .cable_test_get_status = qca808x_cable_test_get_status,
}, };

module_phy_driver(at803x_driver);
@@ -2242,6 +2291,7 @@ static struct mdio_device_id __maybe_unused atheros_tbl[] = {
{ PHY_ID_MATCH_EXACT(QCA8327_B_PHY_ID) },
{ PHY_ID_MATCH_EXACT(QCA9561_PHY_ID) },
{ PHY_ID_MATCH_EXACT(QCA8081_PHY_ID) },
+ { PHY_ID_MATCH_MODEL(QCA8084_PHY_ID) },
{ }
};

--
2.42.0

2023-11-26 06:09:22

by Luo Jie

[permalink] [raw]
Subject: [PATCH v6 2/6] dt-bindings: net: ethernet-controller: add 10g-qxgmii mode

From: Vladimir Oltean <[email protected]>

Add the new interface mode 10g-qxgmii, which is similar to
usxgmii but extend to 4 channels to support maximum of 4
ports with the link speed 10M/100M/1G/2.5G.

Signed-off-by: Vladimir Oltean <[email protected]>
Signed-off-by: Luo Jie <[email protected]>
Acked-by: Conor Dooley <[email protected]>
---
Documentation/devicetree/bindings/net/ethernet-controller.yaml | 1 +
1 file changed, 1 insertion(+)

diff --git a/Documentation/devicetree/bindings/net/ethernet-controller.yaml b/Documentation/devicetree/bindings/net/ethernet-controller.yaml
index d14d123ad7a0..0ef6103c5fd8 100644
--- a/Documentation/devicetree/bindings/net/ethernet-controller.yaml
+++ b/Documentation/devicetree/bindings/net/ethernet-controller.yaml
@@ -104,6 +104,7 @@ properties:
- usxgmii
- 10gbase-r
- 25gbase-r
+ - 10g-qxgmii

phy-mode:
$ref: "#/properties/phy-connection-type"
--
2.42.0

2023-11-26 17:20:40

by Andrew Lunn

[permalink] [raw]
Subject: Re: [PATCH v6 1/6] net: phy: introduce core support for phy-mode = "10g-qxgmii"

On Sun, Nov 26, 2023 at 02:07:27PM +0800, Luo Jie wrote:
> From: Vladimir Oltean <[email protected]>
>
> 10G-QXGMII is a MAC-to-PHY interface defined by the USXGMII multiport
> specification. It uses the same signaling as USXGMII, but it multiplexes
> 4 ports over the link, resulting in a maximum speed of 2.5G per port.
>
> Some in-tree SoCs like the NXP LS1028A use "usxgmii" when they mean
> either the single-port USXGMII or the quad-port 10G-QXGMII variant, and
> they could get away just fine with that thus far. But there is a need to
> distinguish between the 2 as far as SerDes drivers are concerned.

Can this is split into two patches?

> switch (interface) {
> case PHY_INTERFACE_MODE_USXGMII:
> - caps |= MAC_10000FD | MAC_5000FD | MAC_2500FD;
> + caps |= MAC_10000FD | MAC_5000FD;
> + fallthrough;

This change seems to refer to the second paragraph, where as the rest
of the code is about the first. Or does splitting this cause a bisect
problem?

Andrew

2023-11-26 17:25:04

by Andrew Lunn

[permalink] [raw]
Subject: Re: [PATCH v6 2/6] dt-bindings: net: ethernet-controller: add 10g-qxgmii mode

On Sun, Nov 26, 2023 at 02:07:28PM +0800, Luo Jie wrote:
> From: Vladimir Oltean <[email protected]>
>
> Add the new interface mode 10g-qxgmii, which is similar to
> usxgmii but extend to 4 channels to support maximum of 4
> ports with the link speed 10M/100M/1G/2.5G.
>
> Signed-off-by: Vladimir Oltean <[email protected]>
> Signed-off-by: Luo Jie <[email protected]>
> Acked-by: Conor Dooley <[email protected]>

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

Andrew

2023-11-26 17:31:31

by Andrew Lunn

[permalink] [raw]
Subject: Re: [PATCH v6 3/6] net: phy: at803x: add QCA8084 ethernet phy support

> + /* There are two PCSs available for QCA8084, which support the
> + * following interface modes.
> + *
> + * 1. PHY_INTERFACE_MODE_10G_QXGMII utilizes PCS1 for all
> + * available 4 ports, which is for all link speeds.
> + *
> + * 2. PHY_INTERFACE_MODE_2500BASEX utilizes PCS0 for the
> + * fourth port, which is only for the link speed 2500M same
> + * as QCA8081.
> + *
> + * 3. PHY_INTERFACE_MODE_SGMII utilizes PCS0 for the fourth
> + * port, which is for the link speed 10M, 100M and 1000M same
> + * as QCA8081.
> + */

How are these 3 modes configured? I don't see any software
configuration of this in these drivers. Can it only by configured by
strapping?

I think there should be some validation of the phydev->interface
mode. Are ports 1-3 set to PHY_INTERFACE_MODE_10G_QXGMII? Is port 4
interface mode consistent with the strapping?

Andrew

2023-11-27 06:13:13

by Luo Jie

[permalink] [raw]
Subject: Re: [PATCH v6 1/6] net: phy: introduce core support for phy-mode = "10g-qxgmii"



On 11/27/2023 1:20 AM, Andrew Lunn wrote:
> On Sun, Nov 26, 2023 at 02:07:27PM +0800, Luo Jie wrote:
>> From: Vladimir Oltean <[email protected]>
>>
>> 10G-QXGMII is a MAC-to-PHY interface defined by the USXGMII multiport
>> specification. It uses the same signaling as USXGMII, but it multiplexes
>> 4 ports over the link, resulting in a maximum speed of 2.5G per port.
>>
>> Some in-tree SoCs like the NXP LS1028A use "usxgmii" when they mean
>> either the single-port USXGMII or the quad-port 10G-QXGMII variant, and
>> they could get away just fine with that thus far. But there is a need to
>> distinguish between the 2 as far as SerDes drivers are concerned.
>
> Can this is split into two patches?

This patch is a single logical for introducing the mode 10g-qxgmii,
looks it's better to keep it within a single patch.

>
>> switch (interface) {
>> case PHY_INTERFACE_MODE_USXGMII:
>> - caps |= MAC_10000FD | MAC_5000FD | MAC_2500FD;
>> + caps |= MAC_10000FD | MAC_5000FD;
>> + fallthrough;
>
> This change seems to refer to the second paragraph, where as the rest
> of the code is about the first. Or does splitting this cause a bisect
> problem?
>
> Andrew

Since the caps change is related to the new added interface mode
10g-qxgmii, it is reasonable to keep the changes integrated here.

2023-11-27 06:23:19

by Luo Jie

[permalink] [raw]
Subject: Re: [PATCH v6 3/6] net: phy: at803x: add QCA8084 ethernet phy support



On 11/27/2023 1:31 AM, Andrew Lunn wrote:
>> + /* There are two PCSs available for QCA8084, which support the
>> + * following interface modes.
>> + *
>> + * 1. PHY_INTERFACE_MODE_10G_QXGMII utilizes PCS1 for all
>> + * available 4 ports, which is for all link speeds.
>> + *
>> + * 2. PHY_INTERFACE_MODE_2500BASEX utilizes PCS0 for the
>> + * fourth port, which is only for the link speed 2500M same
>> + * as QCA8081.
>> + *
>> + * 3. PHY_INTERFACE_MODE_SGMII utilizes PCS0 for the fourth
>> + * port, which is for the link speed 10M, 100M and 1000M same
>> + * as QCA8081.
>> + */
>
> How are these 3 modes configured? I don't see any software
> configuration of this in these drivers. Can it only by configured by
> strapping?

The interface mode is passed in the .config_init, which is configured
by the PCS driver, the hardware register is located in the PCS, this
driver will be pushed later.

>
> I think there should be some validation of the phydev->interface
> mode. Are ports 1-3 set to PHY_INTERFACE_MODE_10G_QXGMII? Is port 4
> interface mode consistent with the strapping?
>
> Andrew

All ports(1-4) can be PHY_INTERFACE_MODE_10G_QXGMII, if port4 is
connected with PCS0, which will works on sgmii/2500basex mode,
these configuration is controlled by register instead of boot strapping.

2023-11-27 08:44:22

by Russell King (Oracle)

[permalink] [raw]
Subject: Re: [PATCH v6 1/6] net: phy: introduce core support for phy-mode = "10g-qxgmii"

On Sun, Nov 26, 2023 at 06:20:16PM +0100, Andrew Lunn wrote:
> On Sun, Nov 26, 2023 at 02:07:27PM +0800, Luo Jie wrote:
> > switch (interface) {
> > case PHY_INTERFACE_MODE_USXGMII:
> > - caps |= MAC_10000FD | MAC_5000FD | MAC_2500FD;
> > + caps |= MAC_10000FD | MAC_5000FD;
> > + fallthrough;
>
> This change seems to refer to the second paragraph, where as the rest
> of the code is about the first. Or does splitting this cause a bisect
> problem?

I'm not sure what you're referring to here, and by over-trimming the
context, this probably gives an insight into a misunderstanding.

This hunk (and the next) does _not_ change what USXGMII ends up with.
It moves MAC_2500FD to be under the 10G_QXGMII case from the USXGMII
case, and we will _fallthrough_ from the USXGMII case into thte
10G_QXGMII case. So, USXGMII still ends up with MAC_2500FD.

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

2023-11-27 18:10:42

by Andrew Lunn

[permalink] [raw]
Subject: Re: [PATCH v6 3/6] net: phy: at803x: add QCA8084 ethernet phy support

On Mon, Nov 27, 2023 at 02:21:46PM +0800, Jie Luo wrote:
>
>
> On 11/27/2023 1:31 AM, Andrew Lunn wrote:
> > > + /* There are two PCSs available for QCA8084, which support the
> > > + * following interface modes.
> > > + *
> > > + * 1. PHY_INTERFACE_MODE_10G_QXGMII utilizes PCS1 for all
> > > + * available 4 ports, which is for all link speeds.
> > > + *
> > > + * 2. PHY_INTERFACE_MODE_2500BASEX utilizes PCS0 for the
> > > + * fourth port, which is only for the link speed 2500M same
> > > + * as QCA8081.
> > > + *
> > > + * 3. PHY_INTERFACE_MODE_SGMII utilizes PCS0 for the fourth
> > > + * port, which is for the link speed 10M, 100M and 1000M same
> > > + * as QCA8081.
> > > + */
> >
> > How are these 3 modes configured? I don't see any software
> > configuration of this in these drivers. Can it only by configured by
> > strapping?
>
> The interface mode is passed in the .config_init, which is configured
> by the PCS driver, the hardware register is located in the PCS, this
> driver will be pushed later.

Is this the same as how the syqca807x works? Can the PCS driver be
shared by these two drivers?

What i don't like at the moment is that we have two driver
developments going on at once for hardware which seems very similar,
but no apparent cooperation?

Andrew

2023-11-28 07:17:35

by Luo Jie

[permalink] [raw]
Subject: Re: [PATCH v6 3/6] net: phy: at803x: add QCA8084 ethernet phy support



On 11/27/2023 9:22 PM, Andrew Lunn wrote:
> On Mon, Nov 27, 2023 at 02:21:46PM +0800, Jie Luo wrote:
>>
>>
>> On 11/27/2023 1:31 AM, Andrew Lunn wrote:
>>>> + /* There are two PCSs available for QCA8084, which support the
>>>> + * following interface modes.
>>>> + *
>>>> + * 1. PHY_INTERFACE_MODE_10G_QXGMII utilizes PCS1 for all
>>>> + * available 4 ports, which is for all link speeds.
>>>> + *
>>>> + * 2. PHY_INTERFACE_MODE_2500BASEX utilizes PCS0 for the
>>>> + * fourth port, which is only for the link speed 2500M same
>>>> + * as QCA8081.
>>>> + *
>>>> + * 3. PHY_INTERFACE_MODE_SGMII utilizes PCS0 for the fourth
>>>> + * port, which is for the link speed 10M, 100M and 1000M same
>>>> + * as QCA8081.
>>>> + */
>>>
>>> How are these 3 modes configured? I don't see any software
>>> configuration of this in these drivers. Can it only by configured by
>>> strapping?
>>
>> The interface mode is passed in the .config_init, which is configured
>> by the PCS driver, the hardware register is located in the PCS, this
>> driver will be pushed later.
>
> Is this the same as how the syqca807x works? Can the PCS driver be
> shared by these two drivers?

I am not sure syqca807x, would you point me the code path of this driver?

>
> What i don't like at the moment is that we have two driver
> developments going on at once for hardware which seems very similar,
> but no apparent cooperation?
>
> Andrew

The PCS of qca8084 is the PHY PCS, which should be new PCS driver,
in the previous chips, we don't have this kind of PHY PCS.

2023-11-28 09:03:13

by Russell King (Oracle)

[permalink] [raw]
Subject: Re: [PATCH v6 3/6] net: phy: at803x: add QCA8084 ethernet phy support

On Tue, Nov 28, 2023 at 03:16:45PM +0800, Jie Luo wrote:
> > > The interface mode is passed in the .config_init, which is configured
> > > by the PCS driver, the hardware register is located in the PCS, this
> > > driver will be pushed later.
> >
> > Is this the same as how the syqca807x works? Can the PCS driver be
> > shared by these two drivers?
>
> I am not sure syqca807x, would you point me the code path of this driver?
>
> >
> > What i don't like at the moment is that we have two driver
> > developments going on at once for hardware which seems very similar,
> > but no apparent cooperation?
> >
> > Andrew
>
> The PCS of qca8084 is the PHY PCS, which should be new PCS driver,
> in the previous chips, we don't have this kind of PHY PCS.

No. PCS drivers are for MAC-side PCS drivers, not PHY-side PCS drivers.

+-------------
| PHY
MAC---PCS --- link --- PCS --- ...
^ | ^
| +--|----------
For this PCS |
Not for this PCS

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

2023-11-28 09:52:25

by Luo Jie

[permalink] [raw]
Subject: Re: [PATCH v6 3/6] net: phy: at803x: add QCA8084 ethernet phy support



On 11/28/2023 5:00 PM, Russell King (Oracle) wrote:
> On Tue, Nov 28, 2023 at 03:16:45PM +0800, Jie Luo wrote:
>>>> The interface mode is passed in the .config_init, which is configured
>>>> by the PCS driver, the hardware register is located in the PCS, this
>>>> driver will be pushed later.
>>>
>>> Is this the same as how the syqca807x works? Can the PCS driver be
>>> shared by these two drivers?
>>
>> I am not sure syqca807x, would you point me the code path of this driver?
>>
>>>
>>> What i don't like at the moment is that we have two driver
>>> developments going on at once for hardware which seems very similar,
>>> but no apparent cooperation?
>>>
>>> Andrew
>>
>> The PCS of qca8084 is the PHY PCS, which should be new PCS driver,
>> in the previous chips, we don't have this kind of PHY PCS.
>
> No. PCS drivers are for MAC-side PCS drivers, not PHY-side PCS drivers.
>
> +-------------
> | PHY
> MAC---PCS --- link --- PCS --- ...
> ^ | ^
> | +--|----------
> For this PCS |
> Not for this PCS
>

The PCS drivers in drivers/net/pcs/ should be in PHY side, such as
pcs-lynx.c and pcs-xpcs.c, they are configuring the MDIO device
registers.

2023-11-28 10:38:27

by Russell King (Oracle)

[permalink] [raw]
Subject: Re: [PATCH v6 3/6] net: phy: at803x: add QCA8084 ethernet phy support

On Tue, Nov 28, 2023 at 05:50:41PM +0800, Jie Luo wrote:
>
>
> On 11/28/2023 5:00 PM, Russell King (Oracle) wrote:
> > On Tue, Nov 28, 2023 at 03:16:45PM +0800, Jie Luo wrote:
> > > > > The interface mode is passed in the .config_init, which is configured
> > > > > by the PCS driver, the hardware register is located in the PCS, this
> > > > > driver will be pushed later.
> > > >
> > > > Is this the same as how the syqca807x works? Can the PCS driver be
> > > > shared by these two drivers?
> > >
> > > I am not sure syqca807x, would you point me the code path of this driver?
> > >
> > > >
> > > > What i don't like at the moment is that we have two driver
> > > > developments going on at once for hardware which seems very similar,
> > > > but no apparent cooperation?
> > > >
> > > > Andrew
> > >
> > > The PCS of qca8084 is the PHY PCS, which should be new PCS driver,
> > > in the previous chips, we don't have this kind of PHY PCS.
> >
> > No. PCS drivers are for MAC-side PCS drivers, not PHY-side PCS drivers.
> >
> > +-------------
> > | PHY
> > MAC---PCS --- link --- PCS --- ...
> > ^ | ^
> > | +--|----------
> > For this PCS |
> > Not for this PCS
> >
>
> The PCS drivers in drivers/net/pcs/ should be in PHY side, such as
> pcs-lynx.c and pcs-xpcs.c, they are configuring the MDIO device
> registers.

Wrong. No they are not. Just because they are accessed via MDIO does
not mean they are in the PHY. MDIO can be used for more than just the
PHY, and is on a lot of platforms.

LX2160A for example has many MDIO buses, and the PCSes (of which there
are multiple inside the chip, and use pcs-lynx) are accessed through
the MDIO bus specific to each port. They are not MMIO mapped.

The same is true on stmmac platforms, where xpcs is used - xpcs is the
_MAC_ side PCS.

Sorry but you are wrong.

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

2023-11-29 10:34:59

by Luo Jie

[permalink] [raw]
Subject: Re: [PATCH v6 3/6] net: phy: at803x: add QCA8084 ethernet phy support



On 11/28/2023 6:35 PM, Russell King (Oracle) wrote:
> On Tue, Nov 28, 2023 at 05:50:41PM +0800, Jie Luo wrote:
>>
>>
>> On 11/28/2023 5:00 PM, Russell King (Oracle) wrote:
>>> On Tue, Nov 28, 2023 at 03:16:45PM +0800, Jie Luo wrote:
>>>>>> The interface mode is passed in the .config_init, which is configured
>>>>>> by the PCS driver, the hardware register is located in the PCS, this
>>>>>> driver will be pushed later.
>>>>>
>>>>> Is this the same as how the syqca807x works? Can the PCS driver be
>>>>> shared by these two drivers?
>>>>
>>>> I am not sure syqca807x, would you point me the code path of this driver?
>>>>
>>>>>
>>>>> What i don't like at the moment is that we have two driver
>>>>> developments going on at once for hardware which seems very similar,
>>>>> but no apparent cooperation?
>>>>>
>>>>> Andrew
>>>>
>>>> The PCS of qca8084 is the PHY PCS, which should be new PCS driver,
>>>> in the previous chips, we don't have this kind of PHY PCS.
>>>
>>> No. PCS drivers are for MAC-side PCS drivers, not PHY-side PCS drivers.
>>>
>>> +-------------
>>> | PHY
>>> MAC---PCS --- link --- PCS --- ...
>>> ^ | ^
>>> | +--|----------
>>> For this PCS |
>>> Not for this PCS
>>>
>>
>> The PCS drivers in drivers/net/pcs/ should be in PHY side, such as
>> pcs-lynx.c and pcs-xpcs.c, they are configuring the MDIO device
>> registers.
>
> Wrong. No they are not. Just because they are accessed via MDIO does
> not mean they are in the PHY. MDIO can be used for more than just the
> PHY, and is on a lot of platforms.
>
> LX2160A for example has many MDIO buses, and the PCSes (of which there
> are multiple inside the chip, and use pcs-lynx) are accessed through
> the MDIO bus specific to each port. They are not MMIO mapped.
>
> The same is true on stmmac platforms, where xpcs is used - xpcs is the
> _MAC_ side PCS.
>
> Sorry but you are wrong.
>

OK, but it creates the PCS driver based on the MDIO device in pcs-lynx.c
looks like this PCS is located in PHY device from hardware perspective.

2023-11-29 12:05:18

by Vladimir Oltean

[permalink] [raw]
Subject: Re: [PATCH v6 3/6] net: phy: at803x: add QCA8084 ethernet phy support

On Wed, Nov 29, 2023 at 06:34:16PM +0800, Jie Luo wrote:
> > > The PCS drivers in drivers/net/pcs/ should be in PHY side, such as
> > > pcs-lynx.c and pcs-xpcs.c, they are configuring the MDIO device
> > > registers.
> >
> > Wrong. No they are not. Just because they are accessed via MDIO does
> > not mean they are in the PHY. MDIO can be used for more than just the
> > PHY, and is on a lot of platforms.
> >
> > LX2160A for example has many MDIO buses, and the PCSes (of which there
> > are multiple inside the chip, and use pcs-lynx) are accessed through
> > the MDIO bus specific to each port. They are not MMIO mapped.
> >
> > The same is true on stmmac platforms, where xpcs is used - xpcs is the
> > _MAC_ side PCS.
> >
> > Sorry but you are wrong.
> >
>
> OK, but it creates the PCS driver based on the MDIO device in pcs-lynx.c
> looks like this PCS is located in PHY device from hardware perspective.

In some ways, this contradiction has a potato-patato aspect to it.
As Russell says, NXP devices do have internal SGMII/USXGMII/10GBASE-R
ports which use pcs-lynx.c to access the registers of the PCS layer
(which are on MDIO buses internal to the SoC). They could legally be
called PHYs, because they have all the layers that 802.3 says a PHY
should have: a PCS, a PMA and a PMD.

But what phylib understands a phy_device to be is a more restricted
definition than just "a PHY - any PHY". Originally, phylib considered a
struct phy_device to be something (a discrete chip) that has pins and a
phy_interface_t towards its host side, and pins + an ethtool_link_mode_bit_indices
on its media side.

Traditionally, the media side is exclusively copper (BASE-T, BASE-T1) or
fiber (BASE-SX/LX).

A struct phy_device was then also used with PHY_INTERFACE_MODE_INTERNAL
to represent the built-in BASE-T PHYs that are embedded within certain
small/medium business Ethernet switches. And then, more and more other
similar embedded copper PHYs.

The idea is that (1) a phy_device connects to a remote system, and
(2) the phylib API does not have insight into the components of the
PHY it controls: PCS, PMA, PMD. It's all just a monolithic struct phy_device.

Because there are serial phy_interface_t modes where the MAC also need a
PHY to even connect to the phylib PHY, a problem presented itself:
phylib only has support for a single phy_device. So a new framework
appeared: phylink, which uses the unmodified phylib layer for the
external PHY, but models the MAC-side PHY using a different API. Later
on, that API became the phylink_pcs.

To muddy the waters, a phylink_pcs structure usually connects to another
local component as described above, like a phylib PHY (on-board or on an
SFP module). But it can also connect directly to a remote system (like a
phy_device would). But the phylink_pcs is always integrated in silicon
with the MAC, and the "media side" of it is a phy_interface_t type, not
an ethtool_link_mode_bit_indices type.

Having a separate phylink_pcs is what allows us to work around phylib's
limitation of having a single phy_device. The reverse is also true: you
can have a single phylink_pcs, and that belongs to the client MAC driver.

The other layers (PMA/PMD) of the MAC-side PHY are modeled in the kernel
as a struct phy (https://docs.kernel.org/driver-api/phy/index.html), and
we have the phy_set_mode_ext() API for reconfiguring this layer to a
different mode. Again, this is not applicable for phylib PHYs, which are
monolithic.

Given the above definitions, what NXP has and drives with pcs-lynx.c is
not a struct phy_device, but a MAC-side PCS represented by a phylink_pcs.
It absolutely does not matter that the register access method for the
PCS is an internal MDIO bus. FWIW, the PMA/PMD layer is at
drivers/phy/freescale/phy-fsl-lynx-28g.c.

So, if put into the proper context, what Russell is saying is correct,
but I think you need a bit of history to not get even more confused
about why it is the way it is.

2023-12-01 08:06:44

by Luo Jie

[permalink] [raw]
Subject: Re: [PATCH v6 3/6] net: phy: at803x: add QCA8084 ethernet phy support



On 11/29/2023 8:04 PM, Vladimir Oltean wrote:
> On Wed, Nov 29, 2023 at 06:34:16PM +0800, Jie Luo wrote:
>>>> The PCS drivers in drivers/net/pcs/ should be in PHY side, such as
>>>> pcs-lynx.c and pcs-xpcs.c, they are configuring the MDIO device
>>>> registers.
>>>
>>> Wrong. No they are not. Just because they are accessed via MDIO does
>>> not mean they are in the PHY. MDIO can be used for more than just the
>>> PHY, and is on a lot of platforms.
>>>
>>> LX2160A for example has many MDIO buses, and the PCSes (of which there
>>> are multiple inside the chip, and use pcs-lynx) are accessed through
>>> the MDIO bus specific to each port. They are not MMIO mapped.
>>>
>>> The same is true on stmmac platforms, where xpcs is used - xpcs is the
>>> _MAC_ side PCS.
>>>
>>> Sorry but you are wrong.
>>>
>>
>> OK, but it creates the PCS driver based on the MDIO device in pcs-lynx.c
>> looks like this PCS is located in PHY device from hardware perspective.
>
> In some ways, this contradiction has a potato-patato aspect to it.
> As Russell says, NXP devices do have internal SGMII/USXGMII/10GBASE-R
> ports which use pcs-lynx.c to access the registers of the PCS layer
> (which are on MDIO buses internal to the SoC). They could legally be
> called PHYs, because they have all the layers that 802.3 says a PHY
> should have: a PCS, a PMA and a PMD.
>
> But what phylib understands a phy_device to be is a more restricted
> definition than just "a PHY - any PHY". Originally, phylib considered a
> struct phy_device to be something (a discrete chip) that has pins and a
> phy_interface_t towards its host side, and pins + an ethtool_link_mode_bit_indices
> on its media side.
>
> Traditionally, the media side is exclusively copper (BASE-T, BASE-T1) or
> fiber (BASE-SX/LX).
>
> A struct phy_device was then also used with PHY_INTERFACE_MODE_INTERNAL
> to represent the built-in BASE-T PHYs that are embedded within certain
> small/medium business Ethernet switches. And then, more and more other
> similar embedded copper PHYs.
>
> The idea is that (1) a phy_device connects to a remote system, and
> (2) the phylib API does not have insight into the components of the
> PHY it controls: PCS, PMA, PMD. It's all just a monolithic struct phy_device.
>
> Because there are serial phy_interface_t modes where the MAC also need a
> PHY to even connect to the phylib PHY, a problem presented itself:
> phylib only has support for a single phy_device. So a new framework
> appeared: phylink, which uses the unmodified phylib layer for the
> external PHY, but models the MAC-side PHY using a different API. Later
> on, that API became the phylink_pcs.
>
> To muddy the waters, a phylink_pcs structure usually connects to another
> local component as described above, like a phylib PHY (on-board or on an
> SFP module). But it can also connect directly to a remote system (like a
> phy_device would). But the phylink_pcs is always integrated in silicon
> with the MAC, and the "media side" of it is a phy_interface_t type, not
> an ethtool_link_mode_bit_indices type.
>
> Having a separate phylink_pcs is what allows us to work around phylib's
> limitation of having a single phy_device. The reverse is also true: you
> can have a single phylink_pcs, and that belongs to the client MAC driver.
>
> The other layers (PMA/PMD) of the MAC-side PHY are modeled in the kernel
> as a struct phy (https://docs.kernel.org/driver-api/phy/index.html), and
> we have the phy_set_mode_ext() API for reconfiguring this layer to a
> different mode. Again, this is not applicable for phylib PHYs, which are
> monolithic.
>
> Given the above definitions, what NXP has and drives with pcs-lynx.c is
> not a struct phy_device, but a MAC-side PCS represented by a phylink_pcs.
> It absolutely does not matter that the register access method for the
> PCS is an internal MDIO bus. FWIW, the PMA/PMD layer is at
> drivers/phy/freescale/phy-fsl-lynx-28g.c.
>
> So, if put into the proper context, what Russell is saying is correct,
> but I think you need a bit of history to not get even more confused
> about why it is the way it is.

Thanks Vladimir for the detail information, i just get this message,
which is helpful to me.