diff options
| author | Serge Semin <fancer.lancer@gmail.com> | 2023-07-04 12:39:29 +0300 |
|---|---|---|
| committer | Serge Semin <fancer.lancer@gmail.com> | 2026-08-13 20:37:49 +0300 |
| commit | 86dbffcd35b16e5182e88eb90e44b6fee1bf2b45 (patch) | |
| tree | 44f9f54f43749731ab7e2119da9c02ea64f2b73a | |
| parent | 8f1ac2301e0eb597ceaae89f96b4b8bfe560a1c6 (diff) | |
| download | linux-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.c | 38 | ||||
| -rw-r--r-- | drivers/net/pcs/pcs-xpcs.h | 8 |
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; |
