From patchwork Thu Jul 25 12:44:49 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Daniel Golle X-Patchwork-Id: 13741890 X-Patchwork-Delegate: kuba@kernel.org Received: from pidgin.makrotopia.org (pidgin.makrotopia.org [185.142.180.65]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id BB631219EB; Thu, 25 Jul 2024 12:45:19 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.142.180.65 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1721911522; cv=none; b=lO8Zxi+xnDa6TuBQw8wMo3LnkmJVsu1rZoAtihDF6YoeNBLMSO5FTKBuomO+ONqBmCvecKfVTDNaB9JeoFuEowAQgxiXTFOiKLFb6tAg1Uucgm1CY/oFp1E8a2kXO9RdM/myr2QM8SB6VQNcJL8SOlaVaG59/zTiLpNumd0tU3g= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1721911522; c=relaxed/simple; bh=Kno7oXfRynZA04n185N0SSwq7t3bgmw59672KoymYrc=; h=Date:From:To:Subject:Message-ID:MIME-Version:Content-Type: Content-Disposition; b=Q6IODlmL0O7s0YIQqAxScTqjO3ExBAFDzgRWxRw2JW3jnlf2t6bwIPd5JLXhJ7IG/s08KsVgFcvkSsOHTkGFTas4OTU0H06a6d1j9oXQd6rCJWsmXg3aRCx6wjxcTMBAPU19i9AilSFYVYLRb4BTKc13997zYxBxFS/1Xyc9+DA= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=makrotopia.org; spf=pass smtp.mailfrom=makrotopia.org; arc=none smtp.client-ip=185.142.180.65 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=makrotopia.org Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=makrotopia.org Received: from local by pidgin.makrotopia.org with esmtpsa (TLS1.3:TLS_AES_256_GCM_SHA384:256) (Exim 4.98) (envelope-from ) id 1sWxq9-000000002Yy-3gXn; Thu, 25 Jul 2024 12:45:02 +0000 Date: Thu, 25 Jul 2024 13:44:49 +0100 From: Daniel Golle To: Andrew Lunn , Heiner Kallweit , Russell King , "David S. Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , John Crispin , Felix Fietkau , Lorenzo Bianconi , Sean Wang , Mark Lee , Bc-bocun Chen , Sam Shih , Weijie Gao , Steven Liu , Matthias Brugger , AngeloGioacchino Del Regno , linux-kernel@vger.kernel.org, netdev@vger.kernel.org Subject: [PATCH RFC net-next] net: pcs: add helper module for standalone drivers Message-ID: Precedence: bulk X-Mailing-List: netdev@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Disposition: inline X-Patchwork-Delegate: kuba@kernel.org X-Patchwork-State: RFC Implement helper module for standalone PCS drivers which allows standaline PCS drivers to register and users to get instances of 'struct phylink_pcs' using device tree nodes. At this point only a single instance for each device tree node is supported, once we got devices providing more than one PCS we can extend it and introduce an xlate function as well as '#pcs-cells', similar to how this is done by the PHY framework. Signed-off-by: Daniel Golle --- This is meant to provide the infrastructure suggested by Russell King in an earlier review. It just took me a long while to find the time to implement this. Users are going to be the standalone PCS drivers for 8/10 LynxI as well as 64/66 USXGMII PCS found on MediaTek MT7988 SoC. See also https://patchwork.kernel.org/comment/25636726/ The full tree where this is being used can be found at https://github.com/dangowrt/linux/commits/mt7988-for-next/ drivers/net/pcs/Kconfig | 4 ++ drivers/net/pcs/Makefile | 1 + drivers/net/pcs/pcs-standalone.c | 95 +++++++++++++++++++++++++++++ include/linux/pcs/pcs-standalone.h | 25 ++++++++ 4 files changed, 129 insertions(+) create mode 100644 drivers/net/pcs/pcs-standalone.c create mode 100644 include/linux/pcs/pcs-standalone.h diff --git a/drivers/net/pcs/Kconfig b/drivers/net/pcs/Kconfig index f6aa437473de..2b02b9351fa4 100644 --- a/drivers/net/pcs/Kconfig +++ b/drivers/net/pcs/Kconfig @@ -5,6 +5,10 @@ menu "PCS device drivers" +config PCS_STANDALONE + tristate + select PHYLINK + config PCS_XPCS tristate "Synopsys DesignWare Ethernet XPCS" select PHYLINK diff --git a/drivers/net/pcs/Makefile b/drivers/net/pcs/Makefile index 4f7920618b90..0cb0057f2b8e 100644 --- a/drivers/net/pcs/Makefile +++ b/drivers/net/pcs/Makefile @@ -4,6 +4,7 @@ pcs_xpcs-$(CONFIG_PCS_XPCS) := pcs-xpcs.o pcs-xpcs-plat.o \ pcs-xpcs-nxp.o pcs-xpcs-wx.o +obj-$(CONFIG_PCS_STANDALONE) += pcs-standalone.o obj-$(CONFIG_PCS_XPCS) += pcs_xpcs.o obj-$(CONFIG_PCS_LYNX) += pcs-lynx.o obj-$(CONFIG_PCS_MTK_LYNXI) += pcs-mtk-lynxi.o diff --git a/drivers/net/pcs/pcs-standalone.c b/drivers/net/pcs/pcs-standalone.c new file mode 100644 index 000000000000..1569793328a1 --- /dev/null +++ b/drivers/net/pcs/pcs-standalone.c @@ -0,0 +1,95 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Helpers for standalone PCS drivers + * + * Copyright (C) 2024 Daniel Golle + */ + +#include +#include + +static LIST_HEAD(pcs_list); +static DEFINE_MUTEX(pcs_mutex); + +struct pcs_standalone { + struct device *dev; + struct phylink_pcs *pcs; + struct list_head list; +}; + +static void devm_pcs_provider_release(struct device *dev, void *res) +{ + struct pcs_standalone *pcssa = (struct pcs_standalone *)res; + + mutex_lock(&pcs_mutex); + list_del(&pcssa->list); + mutex_unlock(&pcs_mutex); +} + +int devm_pcs_register(struct device *dev, struct phylink_pcs *pcs) +{ + struct pcs_standalone *pcssa; + + pcssa = devres_alloc(devm_pcs_provider_release, sizeof(*pcssa), + GFP_KERNEL); + if (!pcssa) + return -ENOMEM; + + devres_add(dev, pcssa); + pcssa->pcs = pcs; + pcssa->dev = dev; + + mutex_lock(&pcs_mutex); + list_add_tail(&pcssa->list, &pcs_list); + mutex_unlock(&pcs_mutex); + + return 0; +} +EXPORT_SYMBOL_GPL(devm_pcs_register); + +static struct pcs_standalone *of_pcs_locate(const struct device_node *_np, u32 index) +{ + struct device_node *np; + struct pcs_standalone *iter, *pcssa = NULL; + + if (!_np) + return NULL; + + np = of_parse_phandle(_np, "pcs-handle", index); + if (!np) + return NULL; + + mutex_lock(&pcs_mutex); + list_for_each_entry(iter, &pcs_list, list) { + if (iter->dev->of_node != np) + continue; + + pcssa = iter; + break; + } + mutex_unlock(&pcs_mutex); + + of_node_put(np); + + return pcssa ?: ERR_PTR(-ENODEV); +} + +struct phylink_pcs *devm_of_pcs_get(struct device *dev, + const struct device_node *np, + unsigned int index) +{ + struct pcs_standalone *pcssa; + + pcssa = of_pcs_locate(np ?: dev->of_node, index); + if (IS_ERR_OR_NULL(pcssa)) + return ERR_PTR(PTR_ERR(pcssa)); + + device_link_add(dev, pcssa->dev, DL_FLAG_AUTOREMOVE_CONSUMER); + + return pcssa->pcs; +} +EXPORT_SYMBOL_GPL(devm_of_pcs_get); + +MODULE_DESCRIPTION("Helper for standalone PCS drivers"); +MODULE_AUTHOR("Daniel Golle "); +MODULE_LICENSE("GPL"); diff --git a/include/linux/pcs/pcs-standalone.h b/include/linux/pcs/pcs-standalone.h new file mode 100644 index 000000000000..ad7819f4a2eb --- /dev/null +++ b/include/linux/pcs/pcs-standalone.h @@ -0,0 +1,25 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef __LINUX_PCS_STANDALONE_H +#define __LINUX_PCS_STANDALONE_H + +#include +#include +#include +#include + +#if IS_ENABLED(CONFIG_PCS_STANDALONE) +int devm_pcs_register(struct device *dev, struct phylink_pcs *pcs); +struct phylink_pcs *devm_of_pcs_get(struct device *dev, + const struct device_node *np, unsigned int index); +#else +static inline int devm_pcs_register(struct device *dev, struct phylink_pcs *pcs); + return -EOPNOTSUPP; +} +static inline struct phylink_pcs *devm_of_pcs_get(struct device *dev, + const struct device_node *np, + unsigned int index) +{ + return ERR_PTR(-EOPNOTSUPP); +} +#endif /* CONFIG_PCS_STANDALONE */ +#endif /* __LINUX_PCS_STANDALONE_H */