summaryrefslogtreecommitdiff
path: root/drivers/net/pcs/pcs-xpcs.c
diff options
context:
space:
mode:
authorJiawen Wu <jiawenwu@trustnetic.com>2023-08-23 14:19:29 +0800
committerDavid S. Miller <davem@davemloft.net>2023-08-25 07:42:58 +0100
commitf629acc6f21043fdc80ae93cdafa6713888db0fd (patch)
tree653643f82483cc090bee727d2f73e65aaf83e80d /drivers/net/pcs/pcs-xpcs.c
parentd55595f04dcc8bd6f6ff33f451dda8de3f1232da (diff)
net: pcs: xpcs: support to switch mode for Wangxun NICs
According to chapter 6 of DesignWare Cores Ethernet PCS (version 3.20a) and custom design manual, add a configuration flow for switching interface mode. If the interface changes, the following setting is required: 1. wait VR_XS_PCS_DIG_STS bit(4, 2) [PSEQ_STATE] = 100b (Power-Good) 2. write SR_XS_PCS_CTRL2 to select various PCS type 3. write SR_PMA_CTRL1 and/or SR_XS_PCS_CTRL1 for link speed 4. program PMA registers 5. write VR_XS_PCS_DIG_CTRL1 bit(15) [VR_RST] = 1b (Vendor-Specific Soft Reset) 6. wait for VR_XS_PCS_DIG_CTRL1 bit(15) [VR_RST] to get cleared Only 10GBASE-R/SGMII/1000BASE-X modes are planned for the current Wangxun devices. And there is a quirk for Wangxun devices to switch mode although the interface in phylink state has not changed, since PCS will change to default 10GBASE-R when the ethernet driver(txgbe) do LAN reset. Signed-off-by: Jiawen Wu <jiawenwu@trustnetic.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/pcs/pcs-xpcs.c')
-rw-r--r--drivers/net/pcs/pcs-xpcs.c13
1 files changed, 8 insertions, 5 deletions
diff --git a/drivers/net/pcs/pcs-xpcs.c b/drivers/net/pcs/pcs-xpcs.c
index 8b56b2f9f24d..4cd011405376 100644
--- a/drivers/net/pcs/pcs-xpcs.c
+++ b/drivers/net/pcs/pcs-xpcs.c
@@ -228,12 +228,12 @@ static int xpcs_write_vendor(struct dw_xpcs *xpcs, int dev, int reg,
return xpcs_write(xpcs, dev, DW_VENDOR | reg, val);
}
-static int xpcs_read_vpcs(struct dw_xpcs *xpcs, int reg)
+int xpcs_read_vpcs(struct dw_xpcs *xpcs, int reg)
{
return xpcs_read_vendor(xpcs, MDIO_MMD_PCS, reg);
}
-static int xpcs_write_vpcs(struct dw_xpcs *xpcs, int reg, u16 val)
+int xpcs_write_vpcs(struct dw_xpcs *xpcs, int reg, u16 val)
{
return xpcs_write_vendor(xpcs, MDIO_MMD_PCS, reg, val);
}
@@ -841,6 +841,12 @@ int xpcs_do_config(struct dw_xpcs *xpcs, phy_interface_t interface,
if (!compat)
return -ENODEV;
+ if (xpcs->dev_flag == DW_DEV_TXGBE) {
+ ret = txgbe_xpcs_switch_mode(xpcs, interface);
+ if (ret)
+ return ret;
+ }
+
switch (compat->an_mode) {
case DW_10GBASER:
break;
@@ -1313,9 +1319,6 @@ static struct dw_xpcs *xpcs_create(struct mdio_device *mdiodev,
xpcs->pcs.ops = &xpcs_phylink_ops;
xpcs->pcs.neg_mode = true;
- if (compat->an_mode == DW_10GBASER)
- return xpcs;
-
xpcs->pcs.poll = true;
if (xpcs->dev_flag != DW_DEV_TXGBE) {