summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSerge Semin <fancer.lancer@gmail.com>2023-06-11 14:51:26 +0300
committerSerge Semin <fancer.lancer@gmail.com>2026-08-13 20:37:49 +0300
commit8f1ac2301e0eb597ceaae89f96b4b8bfe560a1c6 (patch)
tree6e555158b0eed23c7422249db67bbfb6f72a4470
parent01257fa022a94066cf30e7177a3ed3542c5944c5 (diff)
downloadlinux-8f1ac2301e0eb597ceaae89f96b4b8bfe560a1c6.tar.gz
linux-8f1ac2301e0eb597ceaae89f96b4b8bfe560a1c6.zip
net: pcs: xpcs: Add XGMII interface support
Natively DW XPCS (v3.xx) supports two upstream interfaces: XGMII and GMII/MII. Former one is responsible for the 10G link speed. It's a 32-bits interface normally connected to MAC and which is supposed to be used for the PCS-R and 10G PCS-X data paths. Despite of the USXGMII it doesn't support speed change. So just the only thing what needs to be done is to add the interface and features for the XGMII interface and rely on the auto-negotiation procedure to establish the link. Note DW xGMII PHY-mode support must be added to the STMMAC driver in order to have DW XGMAC/XPCS chain working correctly. TODO add some configs to the xpcs_config_xgmii() method. Signed-off-by: Serge Semin <fancer.lancer@gmail.com>
-rw-r--r--drivers/net/ethernet/stmicro/stmmac/stmmac_main.c13
-rw-r--r--drivers/net/pcs/pcs-xpcs.c22
2 files changed, 34 insertions, 1 deletions
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
index 44a40ff66ced..2fb13d0823ca 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
@@ -1089,7 +1089,15 @@ static void stmmac_mac_link_up(struct phylink_config *config,
old_ctrl = readl(priv->ioaddr + MAC_CTRL_REG);
ctrl = old_ctrl & ~priv->hw->link.speed_mask;
- if (interface == PHY_INTERFACE_MODE_USXGMII) {
+ if (interface == PHY_INTERFACE_MODE_XGMII) {
+ switch (speed) {
+ case SPEED_10000:
+ ctrl |= priv->hw->link.xgmii.speed10000;
+ break;
+ default:
+ return;
+ }
+ } else if (interface == PHY_INTERFACE_MODE_USXGMII) {
switch (speed) {
case SPEED_10000:
ctrl |= priv->hw->link.xgmii.speed10000;
@@ -1100,6 +1108,9 @@ static void stmmac_mac_link_up(struct phylink_config *config,
case SPEED_2500:
ctrl |= priv->hw->link.xgmii.speed2500;
break;
+ case SPEED_1000:
+ ctrl |= priv->hw->link.speed1000;
+ break;
default:
return;
}
diff --git a/drivers/net/pcs/pcs-xpcs.c b/drivers/net/pcs/pcs-xpcs.c
index cf8c918ce687..43b4fee4a5fd 100644
--- a/drivers/net/pcs/pcs-xpcs.c
+++ b/drivers/net/pcs/pcs-xpcs.c
@@ -19,6 +19,15 @@
#define phylink_pcs_to_xpcs(pl_pcs) \
container_of((pl_pcs), struct dw_xpcs, pcs)
+static const int xpcs_xgmii_features[] = {
+ ETHTOOL_LINK_MODE_Pause_BIT,
+ ETHTOOL_LINK_MODE_Asym_Pause_BIT,
+ ETHTOOL_LINK_MODE_Autoneg_BIT,
+ ETHTOOL_LINK_MODE_10000baseKX4_Full_BIT,
+ ETHTOOL_LINK_MODE_10000baseKR_Full_BIT,
+ __ETHTOOL_LINK_MODE_MASK_NBITS,
+};
+
static const int xpcs_usxgmii_features[] = {
ETHTOOL_LINK_MODE_Pause_BIT,
ETHTOOL_LINK_MODE_Asym_Pause_BIT,
@@ -356,6 +365,11 @@ static int xpcs_read_fault_c73(struct dw_xpcs *xpcs,
return 0;
}
+static void xpcs_link_up_xgmii(struct dw_xpcs *xpcs, int speed)
+{
+ /* TODO add some XGMII-related configs ...*/
+}
+
static void xpcs_link_up_usxgmii(struct dw_xpcs *xpcs, int speed)
{
int ret, speed_sel;
@@ -1254,6 +1268,10 @@ static void xpcs_link_up(struct phylink_pcs *pcs, unsigned int neg_mode,
struct dw_xpcs *xpcs = phylink_pcs_to_xpcs(pcs);
switch (interface) {
+ case PHY_INTERFACE_MODE_XGMII:
+ xpcs_link_up_xgmii(xpcs, speed);
+ break;
+
case PHY_INTERFACE_MODE_USXGMII:
xpcs_link_up_usxgmii(xpcs, speed);
break;
@@ -1401,6 +1419,10 @@ static int xpcs_read_ids(struct dw_xpcs *xpcs)
static const struct dw_xpcs_compat synopsys_xpcs_compat[] = {
{
+ .interface = PHY_INTERFACE_MODE_XGMII,
+ .supported = xpcs_xgmii_features,
+ .an_mode = DW_AN_C73,
+ }, {
.interface = PHY_INTERFACE_MODE_USXGMII,
.supported = xpcs_usxgmii_features,
.an_mode = DW_AN_C73,