From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mail-pj2-f2.google.com (mail-pj2-f2.google.com [74.125.227.130]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 6173C3A2E2B for ; Sun, 13 Sep 2026 18:59:26 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=74.125.227.130 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789325968; cv=none; b=Ky0yR2qioI0SkwMDSfggh4FT3Wy7MYH5qhVjQd8fPz04ktp9IptX/C9pZT/D6wihPPpda+taC09MRTKJ70iAMly4gZKfsJUuUm66hpYCak2DQpoVPZCsCImmPh4nck9deFADVkW/a4yqNc3c5n4MpPcKLGwZisZ8qtPLlOsGDUE= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789325968; c=relaxed/simple; bh=gWvVNB1m2Bm2R+CKFSLbBbPCu/GkRF+C5uYpyZkg/fA=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=J7o+ZjsjUDZgJoUoJ9m6e/bY3G1ukXrCCO0o4o05f19p5hIssbC2zZ11M5+CiK0RDz5GP7w1AvyhpMa3T9J8rk1lMQtftkcobcBxFT9lCGWkbtH09LfNkYes0wOy/BIdPt6aN6nSnojy8x9Z138SMcbH3M6KF3As0o7B3EIk6AY= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=qd8W8Pcd; arc=none smtp.client-ip=74.125.227.130 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="qd8W8Pcd" Received: by mail-pj2-f2.google.com with SMTP id d9443c01a7336-2db39df9c51so9590935ad.1 for ; Sun, 13 Sep 2026 11:59:26 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1789325966; x=1789930766; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=qN2MkU81Lz1KMvwh0OIvKliZyK5cNgEHJk5t3+uaHA8=; b=qd8W8Pcd2DvP2UIRAPKW8ZpN/yaDrD8Twz+cGeINpQw24vp3jTfppLFCmssImrIvlA pg0bD3IAvodaCwsMh3qrrsyiHbcw59A+N47tROUml77seQYfKeFU4LTlYVOAHMUEv0xl xF+Qk6voro0f5dcRKIQHN3GRlysiJ655JCZtfboXEah7AT8+/uhjcBnQjhuRn9PClCO8 vAKg1ur/t7IPCkYUn9I9KtQ66MHd2zB8ajpupfiIQlYI5U3DmXn4Lj0b1W5OKRQ+/EY1 pPWFJU216UKnBcTqznHSQ4f1FpNjK2rcAXnwtAjHldtiZDq5avx8t8f1DVt74GS8xDMJ VjuQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1789325966; x=1789930766; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to:content-type; bh=qN2MkU81Lz1KMvwh0OIvKliZyK5cNgEHJk5t3+uaHA8=; b=ZGzt7yfHDUiVmFQLcA27fJqsvxjLeSZkF7vOf94d1an012mvudkRgxxGzTWqkChLYl hCNjqN05ydtQbEIJE3h8ORoNupzNio4aMKknRIHKDzBl4/amcw/btkgdmTDlf3TxixCF lwTqtNicxYbccnKzt9pdss+TCSbOZTkjaXz4dNPyBQtRaMb7dC7cOlVOpD5xAWXsTVrf 6LSR/lTyh2Qdvq6S44cHWfgwlNj73I6kVc7ZEmYQznkBogrEuwKr1QQdojJelb+ajs/R eBwrtNlq4F7d5ZmhFCJhX9UIgNNS+sxqHM/XTS9q004MbfgspqWmtx0SQPJ8q9MjFMih AEbw== X-Forwarded-Encrypted: i=1; AKwUvBw1bTWCkI5vDQy/KfjckgM1pMRCxbmJQqv9uS87HOvoF5NsZIdqGKjoQz4s0ryOlDk3+SFP5eI=@vger.kernel.org X-Gm-Message-State: AFuF++kfgLXLpBl3p4woKeKFCdZ7ZSP9YJL8JRe3HzSgaZsIiAj7Cy6G 7pPsegqc0R/6T+XQSxx7lLQZKzsJlpF91uwXueKkbv5nCCdk9L9jD/7y X-Gm-Gg: AYBFou0DFsfncZ4l8rKQ6jM/OtBZfzUtbiZzh6CtbfQWAlLnRjFiJt+JLf9IITPCY2n pHCf66vLOqV7VWLeExeQjEvqLPYywwBbfOxk0bIf+19VjehYs2yCvnxny8mWyNzDa9RA/I5bBQv PTAwYxSbSs1L0ly4t1fMKRwVwh/HAN6JirzlvCaAyab2bN0469RJLEmo3CvKW6Y2zx2cqZVvCzS 9HifajUjRJL1NPkIPAzoJxEgm0TeKShG2vvuNPJgmQEZmsnO1AadV+LZh1blv8ONgkzL7OOoi6Z 4mOFrlQC+pkzuMXgwptbom0K52xOkiL0KPAieRiPcF3jRx1hr4a/wL+/M77986/G6fTf3LOkcpc i8Nre/MHrXDD1vShpSlDKEAksKOQvvEKgUML9tkNaD8ilw3U4acIvD3c27sFU+66mERoFyf5JKf qKJBWwiRLase1btUXnLtpGIvuRQ5HvLpmivBYtiNpXuvyWH36GgdobTo3KEVeU12xNk620CWI= X-Received: by 2002:a17:903:8c5:b0:2da:eb8f:b4e4 with SMTP id d9443c01a7336-2dd2a1dd9e4mr233613235ad.7.1789325965545; Sun, 13 Sep 2026 11:59:25 -0700 (PDT) Received: from server.lan ([168.138.199.194]) by smtp.gmail.com with ESMTPSA id d9443c01a7336-2dd2cca6b7bsm36808655ad.3.2026.09.13.11.59.16 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 13 Sep 2026 11:59:24 -0700 (PDT) From: Coia Prant To: Andrew Lunn , "David S . Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Heiko Stuebner , Vinod Koul , Maxime Chevallier , Maxime Coquelin , Alexandre Torgue , Lad Prabhakar , Romain Gantois , Heiner Kallweit , Coia Prant Cc: Neil Armstrong , Russell King , Shawn Lin , David Heidelberg , netdev@vger.kernel.org, linux-rockchip@lists.infradead.org, devicetree@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, linux-phy@lists.infradead.org, linux-stm32@st-md-mailman.stormreply.com, linux-renesas-soc@vger.kernel.org Subject: [PATCH net-next v5 01/11] net: stmmac: move XPCS lifetime management to platform drivers Date: Mon, 14 Sep 2026 02:58:36 +0800 Message-ID: <20260913185849.907479-2-coiaprant@gmail.com> X-Mailer: git-send-email 2.47.3 In-Reply-To: <20260913185849.907479-1-coiaprant@gmail.com> References: <20260913185849.907479-1-coiaprant@gmail.com> Precedence: bulk X-Mailing-List: netdev@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit The current XPCS creation logic in stmmac_pcs_setup() is problematic for several reasons. First, if a device tree specifies a "pcs-handle" but no select_pcs() callback is provided by the platform driver, the created XPCS is never used. The phylink framework requires select_pcs() to actually return the PCS to the core, so the pcs-handle property becomes effectively useless without the matching callback. This is confusing for developers who expect that specifying a pcs-handle in their device tree should be sufficient to enable the PCS. Second, and more critically, when a platform driver sets pcs_init() and creates an XPCS inside that callback, the common code afterwards still runs unconditionally and overwrites priv->hw->xpcs with the local xpcs variable, which stays NULL. The platform driver has no way to prevent this override because the common code runs after the platform-specific initialization. After commit 93f84152e4ae ("net: stmmac: clean up stmmac_mac_select_pcs()"), the common code no longer falls back to priv->hw->phylink_pcs if select_pcs() is not set. This change reinforces that each platform must manage its own PCS life cycle explicitly, but the XPCS creation code in stmmac_pcs_setup() was not updated to match this new expectation, leaving a gap where platform drivers have no clean way to take control of XPCS creation. Address all of these issues by simplifying the existing pcs_init() and pcs_exit() dispatch in stmmac_pcs_setup() and stmmac_pcs_clean(). The common stmmac_pcs_setup() now calls plat->pcs_init() if present, and stmmac_pcs_clean() calls plat->pcs_exit() if present, removing the confusing and error-prone XPCS creation logic from the common code. Platforms that do not need an XPCS simply leave the callbacks as NULL and no change in behavior occurs. Platforms that do need an XPCS can now create it with the exact configuration they require, including wrapping it with custom phylink_pcs_ops when necessary. The Intel mGbE glue is updated to create its XPCS inside its own pcs_init() implementation, and the renesas-gbeth, rzn1 and socfpga pcs_exit() callbacks now explicitly clear priv->hw->phylink_pcs after destroying the PCS to avoid dangling pointer references. Reviewed-by: Maxime Chevallier Signed-off-by: Coia Prant --- .../net/ethernet/stmicro/stmmac/dwmac-intel.c | 44 +++++++++++++++++-- .../stmicro/stmmac/dwmac-renesas-gbeth.c | 7 ++- .../net/ethernet/stmicro/stmmac/dwmac-rzn1.c | 7 ++- .../ethernet/stmicro/stmmac/dwmac-socfpga.c | 7 ++- .../net/ethernet/stmicro/stmmac/stmmac_mdio.c | 39 +++------------- 5 files changed, 62 insertions(+), 42 deletions(-) diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-intel.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-intel.c index f5f9fa67ecd77..4308dccbf2570 100644 --- a/drivers/net/ethernet/stmicro/stmmac/dwmac-intel.c +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-intel.c @@ -603,13 +603,47 @@ static void common_default_data(struct plat_stmmacenet_data *plat) plat->mdio_bus_data->needs_reset = true; } +static int intel_mgbe_pcs_init(struct stmmac_priv *priv) +{ + struct fwnode_handle *devnode, *pcsnode; + struct dw_xpcs *xpcs; + int addr; + + devnode = dev_fwnode(priv->device); + + if (fwnode_property_present(devnode, "pcs-handle")) { + pcsnode = fwnode_find_reference(devnode, "pcs-handle", 0); + xpcs = xpcs_create_fwnode(pcsnode); + fwnode_handle_put(pcsnode); + } else { + addr = ffs(priv->plat->mdio_bus_data->pcs_mask) - 1; + xpcs = xpcs_create_mdiodev(priv->mii, addr); + } + + if (IS_ERR(xpcs)) + return PTR_ERR(xpcs); + + xpcs_config_eee_mult_fact(xpcs, priv->plat->mult_fact_100ns); + + priv->hw->xpcs = xpcs; + return 0; +} + +static void intel_mgbe_pcs_exit(struct stmmac_priv *priv) +{ + if (!priv->hw->xpcs) + return; + + xpcs_destroy(priv->hw->xpcs); + priv->hw->xpcs = NULL; +} + static struct phylink_pcs *intel_mgbe_select_pcs(struct stmmac_priv *priv, phy_interface_t interface) { - /* plat->mdio_bus_data->has_xpcs has been set true, so there - * should always be an XPCS. The original code would always - * return this if present. - */ + if (!priv->hw->xpcs) + return NULL; + return xpcs_to_phylink_pcs(priv->hw->xpcs); } @@ -733,6 +767,8 @@ static int intel_mgbe_common_data(struct pci_dev *pdev, plat->phy_interface == PHY_INTERFACE_MODE_1000BASEX) { plat->mdio_bus_data->pcs_mask = BIT_U32(INTEL_MGBE_XPCS_ADDR); plat->default_an_inband = true; + plat->pcs_init = intel_mgbe_pcs_init; + plat->pcs_exit = intel_mgbe_pcs_exit; plat->select_pcs = intel_mgbe_select_pcs; } diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-renesas-gbeth.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-renesas-gbeth.c index 19f34e18bfef2..9af32c26f9c14 100644 --- a/drivers/net/ethernet/stmicro/stmmac/dwmac-renesas-gbeth.c +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-renesas-gbeth.c @@ -81,8 +81,11 @@ static int renesas_gmac_pcs_init(struct stmmac_priv *priv) static void renesas_gmac_pcs_exit(struct stmmac_priv *priv) { - if (priv->hw->phylink_pcs) - miic_destroy(priv->hw->phylink_pcs); + if (!priv->hw->phylink_pcs) + return; + + miic_destroy(priv->hw->phylink_pcs); + priv->hw->phylink_pcs = NULL; } static struct phylink_pcs *renesas_gmac_select_pcs(struct stmmac_priv *priv, diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-rzn1.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-rzn1.c index 13634965bc19a..01df4776edb3f 100644 --- a/drivers/net/ethernet/stmicro/stmmac/dwmac-rzn1.c +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-rzn1.c @@ -35,8 +35,11 @@ static int rzn1_dwmac_pcs_init(struct stmmac_priv *priv) static void rzn1_dwmac_pcs_exit(struct stmmac_priv *priv) { - if (priv->hw->phylink_pcs) - miic_destroy(priv->hw->phylink_pcs); + if (!priv->hw->phylink_pcs) + return; + + miic_destroy(priv->hw->phylink_pcs); + priv->hw->phylink_pcs = NULL; } static struct phylink_pcs *rzn1_dwmac_select_pcs(struct stmmac_priv *priv, diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-socfpga.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-socfpga.c index 1d7f0a57d2889..6d4bc1fe8f751 100644 --- a/drivers/net/ethernet/stmicro/stmmac/dwmac-socfpga.c +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-socfpga.c @@ -539,8 +539,11 @@ static int socfpga_dwmac_pcs_init(struct stmmac_priv *priv) static void socfpga_dwmac_pcs_exit(struct stmmac_priv *priv) { - if (priv->hw->phylink_pcs) - lynx_pcs_destroy(priv->hw->phylink_pcs); + if (!priv->hw->phylink_pcs) + return; + + lynx_pcs_destroy(priv->hw->phylink_pcs); + priv->hw->phylink_pcs = NULL; } static struct phylink_pcs *socfpga_dwmac_select_pcs(struct stmmac_priv *priv, diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c index afe98ff5bdcb0..7396b68899c66 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c @@ -426,35 +426,14 @@ int stmmac_mdio_reset(struct mii_bus *bus) int stmmac_pcs_setup(struct net_device *ndev) { struct stmmac_priv *priv = netdev_priv(ndev); - struct fwnode_handle *devnode, *pcsnode; - struct dw_xpcs *xpcs = NULL; - int addr, ret; - - devnode = dev_fwnode(priv->device); - - if (priv->plat->pcs_init) { - ret = priv->plat->pcs_init(priv); - } else if (fwnode_property_present(devnode, "pcs-handle")) { - pcsnode = fwnode_find_reference(devnode, "pcs-handle", 0); - xpcs = xpcs_create_fwnode(pcsnode); - fwnode_handle_put(pcsnode); - ret = PTR_ERR_OR_ZERO(xpcs); - } else if (priv->plat->mdio_bus_data && - priv->plat->mdio_bus_data->pcs_mask) { - addr = ffs(priv->plat->mdio_bus_data->pcs_mask) - 1; - xpcs = xpcs_create_mdiodev(priv->mii, addr); - ret = PTR_ERR_OR_ZERO(xpcs); - } else { + int ret; + + if (!priv->plat->pcs_init) return 0; - } + ret = priv->plat->pcs_init(priv); if (ret) - return dev_err_probe(priv->device, ret, "No xPCS found\n"); - - if (xpcs) - xpcs_config_eee_mult_fact(xpcs, priv->plat->mult_fact_100ns); - - priv->hw->xpcs = xpcs; + return dev_err_probe(priv->device, ret, "Failed to initialize PCS\n"); return 0; } @@ -463,14 +442,10 @@ void stmmac_pcs_clean(struct net_device *ndev) { struct stmmac_priv *priv = netdev_priv(ndev); - if (priv->plat->pcs_exit) - priv->plat->pcs_exit(priv); - - if (!priv->hw->xpcs) + if (!priv->plat->pcs_exit) return; - xpcs_destroy(priv->hw->xpcs); - priv->hw->xpcs = NULL; + priv->plat->pcs_exit(priv); } struct stmmac_clk_rate { -- 2.47.3 From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 518C5C88E65 for ; Sun, 13 Sep 2026 18:59:30 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: Message-ID:Date:Subject:Cc:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=tnwFdNXGT+m/cqUXYCYJFU+SuwTo0oH//EvKFbSYWtA=; b=AufuNeSgAP15Xu LQ6boQbztvnZS69yMhMIMwJ0eLScUgD72K/mrQFZSq+kOucg2w/zhdee3qWcZGQDKBrIIC9QZCI+W VsQbvIOa3xqXECOnMpHwp4yjU+JcBleYiMbzPf+t6o69nuG49ef39Jslm/WTVrjlS3hx7O1SREfC6 7ffum88gmvdK3vAR5XfIn+AvVj06mmgNs3hJKT4i9s60g5GwsSOKeYFrUHXuJEWunTe5aN7qIa2+V vZwpOp/1kLsG1A1YkV1MPHP7aK3dgC0i+L40L5to45idM4pBNEcGV+FcFfmED34r1oUPA/jedaxNp nc7L6+CmV9cuZmeG4kTw==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.99.1 #2 (Red Hat Linux)) id 1x5pQI-00000001wZG-035i; Sun, 13 Sep 2026 18:59:30 +0000 Received: from mail-pj2-x05.google.com ([2607:f8b0:4864:39::5]) by bombadil.infradead.org with esmtps (Exim 4.99.1 #2 (Red Hat Linux)) id 1x5pQE-00000001wWK-2dT5 for linux-phy@lists.infradead.org; Sun, 13 Sep 2026 18:59:28 +0000 Received: by mail-pj2-x05.google.com with SMTP id d9443c01a7336-2d6fbdc8772so11697425ad.0 for ; Sun, 13 Sep 2026 11:59:26 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1789325966; x=1789930766; darn=lists.infradead.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=qN2MkU81Lz1KMvwh0OIvKliZyK5cNgEHJk5t3+uaHA8=; b=I62/YUVcK/1951fnRsY3rvS+2LO2A4WyEY+cEELiBwLmFAifGvY7aiHXXdQ6bwTmIA IlLCY6am+FfZRyz9MgRbhDDdbhcVzrsh/iWdjFvt/LKOwwqE/wPqHQ6HrjOiYpJeoesS +aJ/mjZjvOm0mzYlIOK+5no1DZczCg8u4USLNTBJmzAM49gXZHV87DUsfzxXm6eqIGrJ Z3jJzfiaYejbdNplrsXFHy1ViQaLJMCXsLVGhRrKhIie8hre1YBWd+ERDOCR6coIV9+M 4Ixj2LnwzMil183D9hCqWbYG+wjX3ecWyoRflBK6VeZcJLHZ7zf/aw3qYuNRqZ/aPnOY fh7Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1789325966; x=1789930766; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to:content-type; bh=qN2MkU81Lz1KMvwh0OIvKliZyK5cNgEHJk5t3+uaHA8=; b=VD/qp75xS/1yCU2W91G6ojLIOGaloOmefa6CMwjEJMEv1qfgZTjGJ98UAiB6lRdlIk CsR0LhnKcntsAqh+MiiLeky6MYwHmLCSm0Z+aG4jNKX1E1uAQvHQot7ODg9n8Jz1Pn0j 1MSca9LkY7m3erkABSs2aPOz10CoPW9cE0Z12YM1R+ePUit2nOJKCYxqxZQQy8D8Ls+7 CZ7r5Yi7ZXfml921TurFrga2h5N6gWm6NYsujAxXAns956+CNpB4imipjHK2RpFXpwoS nuZqLt2Nc4W90UUE00/FpXuHBOI/6A6SUTy/liA8nD/Wx1VohmoIycq7zSFBG5WhbHPF 7/UQ== X-Forwarded-Encrypted: i=1; AKwUvBzr2PhNDSQ7qXR54XtJhFe2SQWxA6Tp4DOTNZC8DutDaV+SDDkyuvTXWjCexCOL29h1h+0Nkqcuhs0=@lists.infradead.org X-Gm-Message-State: AFuF++nG76lUgAiFMoPD1ALTvdFuuFuoX002Wq8avuIbevnG88nELRdQ uwhFlLyjli0BxAjVOy7U/nqhzdkbWBLLJfh1a83prWDxpsgMp/c6IEWK X-Gm-Gg: AYBFou23a++Xugg1a0pjcolqom/650IdD5G3Nptjnf+qzEyDD1BkiNCvLT2nxjpOhZb UbEZkByJ3qObpBVvWJZne84nqhZIHlAt0+doUDQZYfpFtqLow21+5HGxZumO3EJtq7gSfoB4Sxk CFjQRpL8HL/hO24TwXk08oznIkBwrNpTBAcYNTq2ZJ+UzlM8CpYW4Tf+jXJgz7b6LPT+ApS+73W Wtd5GrIuT/mg0wYotZCUkIYZAqtpVcIsgidPZgOOEouuAb87/igflEGqpqZ3K+CyTItRZCTJlq7 eYK/QrSuhW8CaxwL4+GY3SnOsvKVj9uvk7fRTCcb2jDvS90glPymlVv4aptQFtZ67V42y2C4EKR HllfBDhAtKz3e2tB3JbdH7y7+KAnYDhXwLx4Y5sZLoq24W7H73xNV8wkvqAxKdTq4WeHbUym90A wF7UCQOBKdIYmftxVgsObgKs8iqeZdBUppIj5nmL+yCjXNo+ZPVV6uWqRxN63a03d4EqXZnVM= X-Received: by 2002:a17:903:8c5:b0:2da:eb8f:b4e4 with SMTP id d9443c01a7336-2dd2a1dd9e4mr233613235ad.7.1789325965545; Sun, 13 Sep 2026 11:59:25 -0700 (PDT) Received: from server.lan ([168.138.199.194]) by smtp.gmail.com with ESMTPSA id d9443c01a7336-2dd2cca6b7bsm36808655ad.3.2026.09.13.11.59.16 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 13 Sep 2026 11:59:24 -0700 (PDT) From: Coia Prant To: Andrew Lunn , "David S . Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Heiko Stuebner , Vinod Koul , Maxime Chevallier , Maxime Coquelin , Alexandre Torgue , Lad Prabhakar , Romain Gantois , Heiner Kallweit , Coia Prant Cc: Neil Armstrong , Russell King , Shawn Lin , David Heidelberg , netdev@vger.kernel.org, linux-rockchip@lists.infradead.org, devicetree@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, linux-phy@lists.infradead.org, linux-stm32@st-md-mailman.stormreply.com, linux-renesas-soc@vger.kernel.org Subject: [PATCH net-next v5 01/11] net: stmmac: move XPCS lifetime management to platform drivers Date: Mon, 14 Sep 2026 02:58:36 +0800 Message-ID: <20260913185849.907479-2-coiaprant@gmail.com> X-Mailer: git-send-email 2.47.3 In-Reply-To: <20260913185849.907479-1-coiaprant@gmail.com> References: <20260913185849.907479-1-coiaprant@gmail.com> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.9.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20260913_115926_687160_86E12217 X-CRM114-Status: GOOD ( 22.78 ) X-BeenThere: linux-phy@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: Linux Phy Mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Sender: "linux-phy" Errors-To: linux-phy-bounces+linux-phy=archiver.kernel.org@lists.infradead.org The current XPCS creation logic in stmmac_pcs_setup() is problematic for several reasons. First, if a device tree specifies a "pcs-handle" but no select_pcs() callback is provided by the platform driver, the created XPCS is never used. The phylink framework requires select_pcs() to actually return the PCS to the core, so the pcs-handle property becomes effectively useless without the matching callback. This is confusing for developers who expect that specifying a pcs-handle in their device tree should be sufficient to enable the PCS. Second, and more critically, when a platform driver sets pcs_init() and creates an XPCS inside that callback, the common code afterwards still runs unconditionally and overwrites priv->hw->xpcs with the local xpcs variable, which stays NULL. The platform driver has no way to prevent this override because the common code runs after the platform-specific initialization. After commit 93f84152e4ae ("net: stmmac: clean up stmmac_mac_select_pcs()"), the common code no longer falls back to priv->hw->phylink_pcs if select_pcs() is not set. This change reinforces that each platform must manage its own PCS life cycle explicitly, but the XPCS creation code in stmmac_pcs_setup() was not updated to match this new expectation, leaving a gap where platform drivers have no clean way to take control of XPCS creation. Address all of these issues by simplifying the existing pcs_init() and pcs_exit() dispatch in stmmac_pcs_setup() and stmmac_pcs_clean(). The common stmmac_pcs_setup() now calls plat->pcs_init() if present, and stmmac_pcs_clean() calls plat->pcs_exit() if present, removing the confusing and error-prone XPCS creation logic from the common code. Platforms that do not need an XPCS simply leave the callbacks as NULL and no change in behavior occurs. Platforms that do need an XPCS can now create it with the exact configuration they require, including wrapping it with custom phylink_pcs_ops when necessary. The Intel mGbE glue is updated to create its XPCS inside its own pcs_init() implementation, and the renesas-gbeth, rzn1 and socfpga pcs_exit() callbacks now explicitly clear priv->hw->phylink_pcs after destroying the PCS to avoid dangling pointer references. Reviewed-by: Maxime Chevallier Signed-off-by: Coia Prant --- .../net/ethernet/stmicro/stmmac/dwmac-intel.c | 44 +++++++++++++++++-- .../stmicro/stmmac/dwmac-renesas-gbeth.c | 7 ++- .../net/ethernet/stmicro/stmmac/dwmac-rzn1.c | 7 ++- .../ethernet/stmicro/stmmac/dwmac-socfpga.c | 7 ++- .../net/ethernet/stmicro/stmmac/stmmac_mdio.c | 39 +++------------- 5 files changed, 62 insertions(+), 42 deletions(-) diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-intel.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-intel.c index f5f9fa67ecd77..4308dccbf2570 100644 --- a/drivers/net/ethernet/stmicro/stmmac/dwmac-intel.c +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-intel.c @@ -603,13 +603,47 @@ static void common_default_data(struct plat_stmmacenet_data *plat) plat->mdio_bus_data->needs_reset = true; } +static int intel_mgbe_pcs_init(struct stmmac_priv *priv) +{ + struct fwnode_handle *devnode, *pcsnode; + struct dw_xpcs *xpcs; + int addr; + + devnode = dev_fwnode(priv->device); + + if (fwnode_property_present(devnode, "pcs-handle")) { + pcsnode = fwnode_find_reference(devnode, "pcs-handle", 0); + xpcs = xpcs_create_fwnode(pcsnode); + fwnode_handle_put(pcsnode); + } else { + addr = ffs(priv->plat->mdio_bus_data->pcs_mask) - 1; + xpcs = xpcs_create_mdiodev(priv->mii, addr); + } + + if (IS_ERR(xpcs)) + return PTR_ERR(xpcs); + + xpcs_config_eee_mult_fact(xpcs, priv->plat->mult_fact_100ns); + + priv->hw->xpcs = xpcs; + return 0; +} + +static void intel_mgbe_pcs_exit(struct stmmac_priv *priv) +{ + if (!priv->hw->xpcs) + return; + + xpcs_destroy(priv->hw->xpcs); + priv->hw->xpcs = NULL; +} + static struct phylink_pcs *intel_mgbe_select_pcs(struct stmmac_priv *priv, phy_interface_t interface) { - /* plat->mdio_bus_data->has_xpcs has been set true, so there - * should always be an XPCS. The original code would always - * return this if present. - */ + if (!priv->hw->xpcs) + return NULL; + return xpcs_to_phylink_pcs(priv->hw->xpcs); } @@ -733,6 +767,8 @@ static int intel_mgbe_common_data(struct pci_dev *pdev, plat->phy_interface == PHY_INTERFACE_MODE_1000BASEX) { plat->mdio_bus_data->pcs_mask = BIT_U32(INTEL_MGBE_XPCS_ADDR); plat->default_an_inband = true; + plat->pcs_init = intel_mgbe_pcs_init; + plat->pcs_exit = intel_mgbe_pcs_exit; plat->select_pcs = intel_mgbe_select_pcs; } diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-renesas-gbeth.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-renesas-gbeth.c index 19f34e18bfef2..9af32c26f9c14 100644 --- a/drivers/net/ethernet/stmicro/stmmac/dwmac-renesas-gbeth.c +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-renesas-gbeth.c @@ -81,8 +81,11 @@ static int renesas_gmac_pcs_init(struct stmmac_priv *priv) static void renesas_gmac_pcs_exit(struct stmmac_priv *priv) { - if (priv->hw->phylink_pcs) - miic_destroy(priv->hw->phylink_pcs); + if (!priv->hw->phylink_pcs) + return; + + miic_destroy(priv->hw->phylink_pcs); + priv->hw->phylink_pcs = NULL; } static struct phylink_pcs *renesas_gmac_select_pcs(struct stmmac_priv *priv, diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-rzn1.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-rzn1.c index 13634965bc19a..01df4776edb3f 100644 --- a/drivers/net/ethernet/stmicro/stmmac/dwmac-rzn1.c +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-rzn1.c @@ -35,8 +35,11 @@ static int rzn1_dwmac_pcs_init(struct stmmac_priv *priv) static void rzn1_dwmac_pcs_exit(struct stmmac_priv *priv) { - if (priv->hw->phylink_pcs) - miic_destroy(priv->hw->phylink_pcs); + if (!priv->hw->phylink_pcs) + return; + + miic_destroy(priv->hw->phylink_pcs); + priv->hw->phylink_pcs = NULL; } static struct phylink_pcs *rzn1_dwmac_select_pcs(struct stmmac_priv *priv, diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-socfpga.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-socfpga.c index 1d7f0a57d2889..6d4bc1fe8f751 100644 --- a/drivers/net/ethernet/stmicro/stmmac/dwmac-socfpga.c +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-socfpga.c @@ -539,8 +539,11 @@ static int socfpga_dwmac_pcs_init(struct stmmac_priv *priv) static void socfpga_dwmac_pcs_exit(struct stmmac_priv *priv) { - if (priv->hw->phylink_pcs) - lynx_pcs_destroy(priv->hw->phylink_pcs); + if (!priv->hw->phylink_pcs) + return; + + lynx_pcs_destroy(priv->hw->phylink_pcs); + priv->hw->phylink_pcs = NULL; } static struct phylink_pcs *socfpga_dwmac_select_pcs(struct stmmac_priv *priv, diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c index afe98ff5bdcb0..7396b68899c66 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c @@ -426,35 +426,14 @@ int stmmac_mdio_reset(struct mii_bus *bus) int stmmac_pcs_setup(struct net_device *ndev) { struct stmmac_priv *priv = netdev_priv(ndev); - struct fwnode_handle *devnode, *pcsnode; - struct dw_xpcs *xpcs = NULL; - int addr, ret; - - devnode = dev_fwnode(priv->device); - - if (priv->plat->pcs_init) { - ret = priv->plat->pcs_init(priv); - } else if (fwnode_property_present(devnode, "pcs-handle")) { - pcsnode = fwnode_find_reference(devnode, "pcs-handle", 0); - xpcs = xpcs_create_fwnode(pcsnode); - fwnode_handle_put(pcsnode); - ret = PTR_ERR_OR_ZERO(xpcs); - } else if (priv->plat->mdio_bus_data && - priv->plat->mdio_bus_data->pcs_mask) { - addr = ffs(priv->plat->mdio_bus_data->pcs_mask) - 1; - xpcs = xpcs_create_mdiodev(priv->mii, addr); - ret = PTR_ERR_OR_ZERO(xpcs); - } else { + int ret; + + if (!priv->plat->pcs_init) return 0; - } + ret = priv->plat->pcs_init(priv); if (ret) - return dev_err_probe(priv->device, ret, "No xPCS found\n"); - - if (xpcs) - xpcs_config_eee_mult_fact(xpcs, priv->plat->mult_fact_100ns); - - priv->hw->xpcs = xpcs; + return dev_err_probe(priv->device, ret, "Failed to initialize PCS\n"); return 0; } @@ -463,14 +442,10 @@ void stmmac_pcs_clean(struct net_device *ndev) { struct stmmac_priv *priv = netdev_priv(ndev); - if (priv->plat->pcs_exit) - priv->plat->pcs_exit(priv); - - if (!priv->hw->xpcs) + if (!priv->plat->pcs_exit) return; - xpcs_destroy(priv->hw->xpcs); - priv->hw->xpcs = NULL; + priv->plat->pcs_exit(priv); } struct stmmac_clk_rate { -- 2.47.3 -- linux-phy mailing list linux-phy@lists.infradead.org https://lists.infradead.org/mailman/listinfo/linux-phy From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 159B3C88E63 for ; Sun, 13 Sep 2026 18:59:31 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: Message-ID:Date:Subject:Cc:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=aPxtBLp8BHuWw/f3CdZJHj5sLEZvKFSCHJB+Ci84iAQ=; b=bpGtATzMJ7cmh7 9f0gFmO/EStZsveOD4Z/z3PZw5QU8E9hnG34ZkYhcjMPeg9KQMnA3DQI9yGA4s2jWFtt5RlHwPk6L N3VcTdFUrOMDV3BgKbfJ5jQgew4Ol128wwjRfRVHxfmukm/+Nxc2Y7JfMbuM0ffz3px+KV3ZNgXkx 0qOzZCqFXoUsgbD7u2bCZiRpOeIsbSgGAmmhmSGs9AFi6bQiTljqVEbE5FV5p7FdMN7OoRld9jpD3 K7uJICrzY+keq9t9hZuywp2f0hbJrqOB7i4JxIpjVsHbsjKALMWyAOpOwhxZLxhr2UKAWc7kZunLO hZ5SQtnenSdfahTco3Bg==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.99.1 #2 (Red Hat Linux)) id 1x5pQG-00000001wXZ-2Ibm; Sun, 13 Sep 2026 18:59:28 +0000 Received: from mail-pj2-x05.google.com ([2607:f8b0:4864:39::5]) by bombadil.infradead.org with esmtps (Exim 4.99.1 #2 (Red Hat Linux)) id 1x5pQE-00000001wWL-2d8G for linux-rockchip@lists.infradead.org; Sun, 13 Sep 2026 18:59:27 +0000 Received: by mail-pj2-x05.google.com with SMTP id d9443c01a7336-2d6fbdc8772so11697445ad.0 for ; Sun, 13 Sep 2026 11:59:26 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1789325966; x=1789930766; darn=lists.infradead.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=qN2MkU81Lz1KMvwh0OIvKliZyK5cNgEHJk5t3+uaHA8=; b=I62/YUVcK/1951fnRsY3rvS+2LO2A4WyEY+cEELiBwLmFAifGvY7aiHXXdQ6bwTmIA IlLCY6am+FfZRyz9MgRbhDDdbhcVzrsh/iWdjFvt/LKOwwqE/wPqHQ6HrjOiYpJeoesS +aJ/mjZjvOm0mzYlIOK+5no1DZczCg8u4USLNTBJmzAM49gXZHV87DUsfzxXm6eqIGrJ Z3jJzfiaYejbdNplrsXFHy1ViQaLJMCXsLVGhRrKhIie8hre1YBWd+ERDOCR6coIV9+M 4Ixj2LnwzMil183D9hCqWbYG+wjX3ecWyoRflBK6VeZcJLHZ7zf/aw3qYuNRqZ/aPnOY fh7Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1789325966; x=1789930766; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to:content-type; bh=qN2MkU81Lz1KMvwh0OIvKliZyK5cNgEHJk5t3+uaHA8=; b=KsSoZyISN7TePrw4sPWL6BheqTnUPFBSk70Fitby4f4KTrIKKOgUEGHQ7Q8H7NROHq OZvCds8uVugZX6rYXBRkfPyUJ7PXrhbbjHRHOoZNM6DL3yIduWGXFxsaEiYgdzHHWYq1 OI4IrWD3OaGiWpQTXcX/YJ0daYVKuogcZklbjLBHRmX1p6FDOB5eRFnP7gTnjq4acGpq RQnJgcPG91WtpnJH4bFh177gfl3ndpviJhJ/CvbQbrKMPxrVmhYR8d8vMeV/PiTxoO6d ecYl3mOT+rTNO4m3YJ5f8w9nyypa8P6IvGm1Ta3typX1jBVh8pA7FmQ5ucGJNuHWG5jy +POQ== X-Forwarded-Encrypted: i=1; AKwUvBzKKlCLbo8XOEdtI5+HOWy3sPfAuY29r0J2HrpKFNh46F38i7FKj0KAim4vbAJbquQjQSilgsU8QRiUMjB7YA==@lists.infradead.org X-Gm-Message-State: AFuF++kvCPqFEs3r0D1vF0sH19fEbIJpIbZvbYV3f82LvQi8ZYUZ38F5 WXcwtNZ98XLIkmyUdjda+bRf2lsCCHGIBWD4mBi+nOX3au1190nYWkSW X-Gm-Gg: AYBFou1B0SqC7dVbZCwwfa7iFqfpGIyM0ly5PZxMw+u9zehXmB8smbkRI5qAdmmG1lU Ln7FqZflBvPdg7IrnogtkwDohx457CtQnPHlAgLrQoI+qzH2NYCswr6zDZ316u56XMC4G9JElQz Mz62yAOOJankol9uCljgrw5/8BidkjYazIzh2tRgtCSoikBwZxvv93RTyYZCJS6Hb4GU8waO94V JWQnl4ROm2vQp0TTNgMl3GHyHgxX2hgxpee+g7A/PKmtSCO8X9TyOIbFtgLfn4Qs7c8gA4HktOz LJawAFyNjxWT31dPOGW4Sv6LAzTzfQh7Kw+BIpCniZGyItOHJi8XEnc55GsURQzjvbsJkh3dnWK c3y3FpBJa0INwAnkYwjBaZKnoNRZcOHvoc/NdxQRL5piT1ebBHGJthY389QbuBzpd+kVSIf8I6N PKtM6SFoEgfVSvCi1SOkLkuFvxQgAwEhNhADRjMD2nzxaCUa5Q/jXwfCnwRz4uaxBTCmtfqCY= X-Received: by 2002:a17:903:8c5:b0:2da:eb8f:b4e4 with SMTP id d9443c01a7336-2dd2a1dd9e4mr233613235ad.7.1789325965545; Sun, 13 Sep 2026 11:59:25 -0700 (PDT) Received: from server.lan ([168.138.199.194]) by smtp.gmail.com with ESMTPSA id d9443c01a7336-2dd2cca6b7bsm36808655ad.3.2026.09.13.11.59.16 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 13 Sep 2026 11:59:24 -0700 (PDT) From: Coia Prant To: Andrew Lunn , "David S . Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Heiko Stuebner , Vinod Koul , Maxime Chevallier , Maxime Coquelin , Alexandre Torgue , Lad Prabhakar , Romain Gantois , Heiner Kallweit , Coia Prant Cc: Neil Armstrong , Russell King , Shawn Lin , David Heidelberg , netdev@vger.kernel.org, linux-rockchip@lists.infradead.org, devicetree@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, linux-phy@lists.infradead.org, linux-stm32@st-md-mailman.stormreply.com, linux-renesas-soc@vger.kernel.org Subject: [PATCH net-next v5 01/11] net: stmmac: move XPCS lifetime management to platform drivers Date: Mon, 14 Sep 2026 02:58:36 +0800 Message-ID: <20260913185849.907479-2-coiaprant@gmail.com> X-Mailer: git-send-email 2.47.3 In-Reply-To: <20260913185849.907479-1-coiaprant@gmail.com> References: <20260913185849.907479-1-coiaprant@gmail.com> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.9.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20260913_115926_683531_4C689A0F X-CRM114-Status: GOOD ( 23.00 ) X-BeenThere: linux-rockchip@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: Upstream kernel work for Rockchip platforms List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Sender: "Linux-rockchip" Errors-To: linux-rockchip-bounces+linux-rockchip=archiver.kernel.org@lists.infradead.org The current XPCS creation logic in stmmac_pcs_setup() is problematic for several reasons. First, if a device tree specifies a "pcs-handle" but no select_pcs() callback is provided by the platform driver, the created XPCS is never used. The phylink framework requires select_pcs() to actually return the PCS to the core, so the pcs-handle property becomes effectively useless without the matching callback. This is confusing for developers who expect that specifying a pcs-handle in their device tree should be sufficient to enable the PCS. Second, and more critically, when a platform driver sets pcs_init() and creates an XPCS inside that callback, the common code afterwards still runs unconditionally and overwrites priv->hw->xpcs with the local xpcs variable, which stays NULL. The platform driver has no way to prevent this override because the common code runs after the platform-specific initialization. After commit 93f84152e4ae ("net: stmmac: clean up stmmac_mac_select_pcs()"), the common code no longer falls back to priv->hw->phylink_pcs if select_pcs() is not set. This change reinforces that each platform must manage its own PCS life cycle explicitly, but the XPCS creation code in stmmac_pcs_setup() was not updated to match this new expectation, leaving a gap where platform drivers have no clean way to take control of XPCS creation. Address all of these issues by simplifying the existing pcs_init() and pcs_exit() dispatch in stmmac_pcs_setup() and stmmac_pcs_clean(). The common stmmac_pcs_setup() now calls plat->pcs_init() if present, and stmmac_pcs_clean() calls plat->pcs_exit() if present, removing the confusing and error-prone XPCS creation logic from the common code. Platforms that do not need an XPCS simply leave the callbacks as NULL and no change in behavior occurs. Platforms that do need an XPCS can now create it with the exact configuration they require, including wrapping it with custom phylink_pcs_ops when necessary. The Intel mGbE glue is updated to create its XPCS inside its own pcs_init() implementation, and the renesas-gbeth, rzn1 and socfpga pcs_exit() callbacks now explicitly clear priv->hw->phylink_pcs after destroying the PCS to avoid dangling pointer references. Reviewed-by: Maxime Chevallier Signed-off-by: Coia Prant --- .../net/ethernet/stmicro/stmmac/dwmac-intel.c | 44 +++++++++++++++++-- .../stmicro/stmmac/dwmac-renesas-gbeth.c | 7 ++- .../net/ethernet/stmicro/stmmac/dwmac-rzn1.c | 7 ++- .../ethernet/stmicro/stmmac/dwmac-socfpga.c | 7 ++- .../net/ethernet/stmicro/stmmac/stmmac_mdio.c | 39 +++------------- 5 files changed, 62 insertions(+), 42 deletions(-) diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-intel.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-intel.c index f5f9fa67ecd77..4308dccbf2570 100644 --- a/drivers/net/ethernet/stmicro/stmmac/dwmac-intel.c +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-intel.c @@ -603,13 +603,47 @@ static void common_default_data(struct plat_stmmacenet_data *plat) plat->mdio_bus_data->needs_reset = true; } +static int intel_mgbe_pcs_init(struct stmmac_priv *priv) +{ + struct fwnode_handle *devnode, *pcsnode; + struct dw_xpcs *xpcs; + int addr; + + devnode = dev_fwnode(priv->device); + + if (fwnode_property_present(devnode, "pcs-handle")) { + pcsnode = fwnode_find_reference(devnode, "pcs-handle", 0); + xpcs = xpcs_create_fwnode(pcsnode); + fwnode_handle_put(pcsnode); + } else { + addr = ffs(priv->plat->mdio_bus_data->pcs_mask) - 1; + xpcs = xpcs_create_mdiodev(priv->mii, addr); + } + + if (IS_ERR(xpcs)) + return PTR_ERR(xpcs); + + xpcs_config_eee_mult_fact(xpcs, priv->plat->mult_fact_100ns); + + priv->hw->xpcs = xpcs; + return 0; +} + +static void intel_mgbe_pcs_exit(struct stmmac_priv *priv) +{ + if (!priv->hw->xpcs) + return; + + xpcs_destroy(priv->hw->xpcs); + priv->hw->xpcs = NULL; +} + static struct phylink_pcs *intel_mgbe_select_pcs(struct stmmac_priv *priv, phy_interface_t interface) { - /* plat->mdio_bus_data->has_xpcs has been set true, so there - * should always be an XPCS. The original code would always - * return this if present. - */ + if (!priv->hw->xpcs) + return NULL; + return xpcs_to_phylink_pcs(priv->hw->xpcs); } @@ -733,6 +767,8 @@ static int intel_mgbe_common_data(struct pci_dev *pdev, plat->phy_interface == PHY_INTERFACE_MODE_1000BASEX) { plat->mdio_bus_data->pcs_mask = BIT_U32(INTEL_MGBE_XPCS_ADDR); plat->default_an_inband = true; + plat->pcs_init = intel_mgbe_pcs_init; + plat->pcs_exit = intel_mgbe_pcs_exit; plat->select_pcs = intel_mgbe_select_pcs; } diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-renesas-gbeth.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-renesas-gbeth.c index 19f34e18bfef2..9af32c26f9c14 100644 --- a/drivers/net/ethernet/stmicro/stmmac/dwmac-renesas-gbeth.c +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-renesas-gbeth.c @@ -81,8 +81,11 @@ static int renesas_gmac_pcs_init(struct stmmac_priv *priv) static void renesas_gmac_pcs_exit(struct stmmac_priv *priv) { - if (priv->hw->phylink_pcs) - miic_destroy(priv->hw->phylink_pcs); + if (!priv->hw->phylink_pcs) + return; + + miic_destroy(priv->hw->phylink_pcs); + priv->hw->phylink_pcs = NULL; } static struct phylink_pcs *renesas_gmac_select_pcs(struct stmmac_priv *priv, diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-rzn1.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-rzn1.c index 13634965bc19a..01df4776edb3f 100644 --- a/drivers/net/ethernet/stmicro/stmmac/dwmac-rzn1.c +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-rzn1.c @@ -35,8 +35,11 @@ static int rzn1_dwmac_pcs_init(struct stmmac_priv *priv) static void rzn1_dwmac_pcs_exit(struct stmmac_priv *priv) { - if (priv->hw->phylink_pcs) - miic_destroy(priv->hw->phylink_pcs); + if (!priv->hw->phylink_pcs) + return; + + miic_destroy(priv->hw->phylink_pcs); + priv->hw->phylink_pcs = NULL; } static struct phylink_pcs *rzn1_dwmac_select_pcs(struct stmmac_priv *priv, diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-socfpga.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-socfpga.c index 1d7f0a57d2889..6d4bc1fe8f751 100644 --- a/drivers/net/ethernet/stmicro/stmmac/dwmac-socfpga.c +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-socfpga.c @@ -539,8 +539,11 @@ static int socfpga_dwmac_pcs_init(struct stmmac_priv *priv) static void socfpga_dwmac_pcs_exit(struct stmmac_priv *priv) { - if (priv->hw->phylink_pcs) - lynx_pcs_destroy(priv->hw->phylink_pcs); + if (!priv->hw->phylink_pcs) + return; + + lynx_pcs_destroy(priv->hw->phylink_pcs); + priv->hw->phylink_pcs = NULL; } static struct phylink_pcs *socfpga_dwmac_select_pcs(struct stmmac_priv *priv, diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c index afe98ff5bdcb0..7396b68899c66 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c @@ -426,35 +426,14 @@ int stmmac_mdio_reset(struct mii_bus *bus) int stmmac_pcs_setup(struct net_device *ndev) { struct stmmac_priv *priv = netdev_priv(ndev); - struct fwnode_handle *devnode, *pcsnode; - struct dw_xpcs *xpcs = NULL; - int addr, ret; - - devnode = dev_fwnode(priv->device); - - if (priv->plat->pcs_init) { - ret = priv->plat->pcs_init(priv); - } else if (fwnode_property_present(devnode, "pcs-handle")) { - pcsnode = fwnode_find_reference(devnode, "pcs-handle", 0); - xpcs = xpcs_create_fwnode(pcsnode); - fwnode_handle_put(pcsnode); - ret = PTR_ERR_OR_ZERO(xpcs); - } else if (priv->plat->mdio_bus_data && - priv->plat->mdio_bus_data->pcs_mask) { - addr = ffs(priv->plat->mdio_bus_data->pcs_mask) - 1; - xpcs = xpcs_create_mdiodev(priv->mii, addr); - ret = PTR_ERR_OR_ZERO(xpcs); - } else { + int ret; + + if (!priv->plat->pcs_init) return 0; - } + ret = priv->plat->pcs_init(priv); if (ret) - return dev_err_probe(priv->device, ret, "No xPCS found\n"); - - if (xpcs) - xpcs_config_eee_mult_fact(xpcs, priv->plat->mult_fact_100ns); - - priv->hw->xpcs = xpcs; + return dev_err_probe(priv->device, ret, "Failed to initialize PCS\n"); return 0; } @@ -463,14 +442,10 @@ void stmmac_pcs_clean(struct net_device *ndev) { struct stmmac_priv *priv = netdev_priv(ndev); - if (priv->plat->pcs_exit) - priv->plat->pcs_exit(priv); - - if (!priv->hw->xpcs) + if (!priv->plat->pcs_exit) return; - xpcs_destroy(priv->hw->xpcs); - priv->hw->xpcs = NULL; + priv->plat->pcs_exit(priv); } struct stmmac_clk_rate { -- 2.47.3 _______________________________________________ Linux-rockchip mailing list Linux-rockchip@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-rockchip