summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSerge Semin <fancer.lancer@gmail.com>2023-07-04 12:39:29 +0300
committerSerge Semin <fancer.lancer@gmail.com>2026-08-13 20:37:49 +0300
commit86dbffcd35b16e5182e88eb90e44b6fee1bf2b45 (patch)
tree44f9f54f43749731ab7e2119da9c02ea64f2b73a
parent8f1ac2301e0eb597ceaae89f96b4b8bfe560a1c6 (diff)
downloadlinux-86dbffcd35b16e5182e88eb90e44b6fee1bf2b45.tar.gz
linux-86dbffcd35b16e5182e88eb90e44b6fee1bf2b45.zip
net: pcs: xpcs: Drop compat arg from soft-reset method
It's very much inconvenient to have the soft-reset method requiring the xpcs_compat structure instance passed. The later one is found based on the PHY-interface type which isn't always available. Such design makes an ordinary reset-method context depended and unnecessary limits its usage area. Indeed based on [1,2] all Soft-RST flags exported by the PMA/PMD, PCS, AN or MII MMDs are _shared_. It means it resets all the DWX_xpcs internal blocks including CSRs, but except the Management Interface (MDIO, MCI, APB). Thus it doesn't really matter which MMDs soft-reset flag is set, the result will be the same. So the AN-mode-depended code can be freely dropped from the soft-reset method. But depending on the DW XPCS device capabilities (basically it depends on the IP-core synthesize parameters) it can lack some of the MMDs. In order to solve that difficulty the Vendor-Specific 1 MMD can be utilized. It is also called as Control MMD and exports some generic device info about the device including a list of the available MMDs: PMA/PMD, XS/PCS, AN or MII. This MMD persists on all the DW XPCS device [3]. Thus it can be freely utilize to cross-platformly determine actual MMD to perform the soft-reset. [1] DesignWare® Cores Ethernet PCS, Version 3.11b, June 2015, p.111. [2] DesignWare® Cores Ethernet PCS, Version 3.11b, June 2015, p.268. [3] DesignWare® Cores Ethernet PCS, Version 3.11b, June 2015, p.269. Signed-off-by: Serge Semin <fancer.lancer@gmail.com>
-rw-r--r--drivers/net/pcs/pcs-xpcs.c38
-rw-r--r--drivers/net/pcs/pcs-xpcs.h8
2 files changed, 23 insertions, 23 deletions
diff --git a/drivers/net/pcs/pcs-xpcs.c b/drivers/net/pcs/pcs-xpcs.c
index 43b4fee4a5fd..3b30c8bad1d4 100644
--- a/drivers/net/pcs/pcs-xpcs.c
+++ b/drivers/net/pcs/pcs-xpcs.c
@@ -285,24 +285,18 @@ static int xpcs_poll_reset(struct dw_xpcs *xpcs, int dev)
return ret;
}
-static int xpcs_soft_reset(struct dw_xpcs *xpcs,
- const struct dw_xpcs_compat *compat)
+static int xpcs_soft_reset(struct dw_xpcs *xpcs)
{
int ret, dev;
- switch (compat->an_mode) {
- case DW_AN_C73:
- case DW_10GBASER:
- dev = MDIO_MMD_PCS;
- break;
- case DW_AN_C37_SGMII:
- case DW_2500BASEX:
- case DW_AN_C37_1000BASEX:
+ if (xpcs->mmd_ctrl & DW_SR_CTRL_MII_MMD_EN)
dev = MDIO_MMD_VEND2;
- break;
- default:
+ else if (xpcs->mmd_ctrl & DW_SR_CTRL_PCS_XS_MMD_EN)
+ dev = MDIO_MMD_PCS;
+ else if (xpcs->mmd_ctrl & DW_SR_CTRL_PMA_MMD_EN)
+ dev = MDIO_MMD_PMAPMD;
+ else
return -EINVAL;
- }
ret = xpcs_write(xpcs, dev, MII_BMCR, BMCR_RESET);
if (ret < 0)
@@ -733,7 +727,6 @@ static int xpcs_switch_interface_mode(struct dw_xpcs *xpcs,
static void xpcs_pre_config(struct phylink_pcs *pcs, phy_interface_t interface)
{
struct dw_xpcs *xpcs = phylink_pcs_to_xpcs(pcs);
- const struct dw_xpcs_compat *compat;
int ret;
ret = xpcs_switch_interface_mode(xpcs, interface);
@@ -744,14 +737,7 @@ static void xpcs_pre_config(struct phylink_pcs *pcs, phy_interface_t interface)
if (!xpcs->need_reset)
return;
- compat = xpcs_find_compat(xpcs, interface);
- if (!compat) {
- dev_err(&xpcs->mdiodev->dev, "unsupported interface %s\n",
- phy_modes(interface));
- return;
- }
-
- ret = xpcs_soft_reset(xpcs, compat);
+ ret = xpcs_soft_reset(xpcs);
if (ret)
dev_err(&xpcs->mdiodev->dev, "soft reset failed: %pe\n",
ERR_PTR(ret));
@@ -1015,7 +1001,7 @@ static int xpcs_get_state_c73(struct dw_xpcs *xpcs,
/* ... and then we check the faults. */
ret = xpcs_read_fault_c73(xpcs, state, pcs_stat1);
if (ret) {
- ret = xpcs_soft_reset(xpcs, compat);
+ ret = xpcs_soft_reset(xpcs);
if (ret)
return ret;
@@ -1627,6 +1613,12 @@ static struct dw_xpcs *xpcs_create(struct mdio_device *mdiodev)
if (ret)
goto out_clear_clks;
+ ret = xpcs_read(xpcs, MDIO_MMD_VEND1, DW_SR_CTRL_MMD_CTRL);
+ if (ret < 0)
+ goto out_clear_clks;
+
+ xpcs->mmd_ctrl = ret;
+
xpcs_get_interfaces(xpcs, xpcs->pcs.supported_interfaces);
if (xpcs->info.pma == WX_TXGBE_XPCS_PMA_10G_ID ||
diff --git a/drivers/net/pcs/pcs-xpcs.h b/drivers/net/pcs/pcs-xpcs.h
index 929fa238445e..7805881e391d 100644
--- a/drivers/net/pcs/pcs-xpcs.h
+++ b/drivers/net/pcs/pcs-xpcs.h
@@ -52,6 +52,13 @@
#define DW_C73_2500KX BIT(0)
#define DW_C73_5000KR BIT(1)
+/* VR_CTRL_MMD */
+#define DW_SR_CTRL_MMD_CTRL 0x0009
+#define DW_SR_CTRL_AN_MMD_EN BIT(0)
+#define DW_SR_CTRL_PCS_XS_MMD_EN BIT(1)
+#define DW_SR_CTRL_MII_MMD_EN BIT(2)
+#define DW_SR_CTRL_PMA_MMD_EN BIT(3)
+
/* Clause 37 Defines */
/* VR MII MMD registers offsets */
#define DW_VR_MII_DIG_CTRL1 0x8000
@@ -110,6 +117,7 @@ struct dw_xpcs {
const struct dw_xpcs_desc *desc;
struct mdio_device *mdiodev;
struct clk_bulk_data clks[DW_XPCS_NUM_CLKS];
+ u16 mmd_ctrl;
struct phylink_pcs pcs;
phy_interface_t interface;
bool need_reset;