>From 7e36cef5d954cc17586194b8e0b3c58fe0dfe592 Mon Sep 17 00:00:00 2001 From: Serge Semin Date: Tue, 4 Jul 2023 12:39:29 +0300 Subject: [PATCH] net: pcs: xpcs: Drop compat arg from soft-reset method MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 --- drivers/net/pcs/pcs-xpcs.c | 31 ++++++++++++++++--------------- drivers/net/pcs/pcs-xpcs.h | 7 +++++++ include/linux/pcs/pcs-xpcs.h | 1 + 3 files changed, 24 insertions(+), 15 deletions(-) diff --git a/drivers/net/pcs/pcs-xpcs.c b/drivers/net/pcs/pcs-xpcs.c index 014ca2b067f4..81c166726636 100644 --- a/drivers/net/pcs/pcs-xpcs.c +++ b/drivers/net/pcs/pcs-xpcs.c @@ -271,24 +271,18 @@ static int xpcs_poll_reset(struct dw_xpcs *xpcs, int dev) return (ret & MDIO_CTRL1_RESET) ? -ETIMEDOUT : 0; } -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, MDIO_CTRL1, MDIO_CTRL1_RESET); if (ret < 0) @@ -935,7 +929,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; @@ -1485,17 +1479,24 @@ static int xpcs_init_id(struct dw_xpcs *xpcs) static int xpcs_init_iface(struct dw_xpcs *xpcs, phy_interface_t interface) { const struct dw_xpcs_compat *compat; + int ret; compat = xpcs_find_compat(xpcs->desc, interface); if (!compat) return -EINVAL; + ret = xpcs_read(xpcs, MDIO_MMD_VEND1, DW_SR_CTRL_MMD_CTRL); + if (ret < 0) + return ret; + + xpcs->mmd_ctrl = ret; + if (xpcs->info.pma == WX_TXGBE_XPCS_PMA_10G_ID) { xpcs->pcs.poll = false; return 0; } - return xpcs_soft_reset(xpcs, compat); + return xpcs_soft_reset(xpcs); } static struct dw_xpcs *xpcs_create(struct mdio_device *mdiodev, diff --git a/drivers/net/pcs/pcs-xpcs.h b/drivers/net/pcs/pcs-xpcs.h index fa05adfae220..774b71801cc0 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_MMD_CTRL 0x0000 diff --git a/include/linux/pcs/pcs-xpcs.h b/include/linux/pcs/pcs-xpcs.h index b4a4eb6c8866..241a1a959406 100644 --- a/include/linux/pcs/pcs-xpcs.h +++ b/include/linux/pcs/pcs-xpcs.h @@ -59,6 +59,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; }; -- 2.46.1