From patchwork Tue Apr 11 09:27:20 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jiawen Wu X-Patchwork-Id: 673015 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 vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 5FC7EC77B72 for ; Tue, 11 Apr 2023 09:29:24 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229761AbjDKJ2u (ORCPT ); Tue, 11 Apr 2023 05:28:50 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:47680 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229751AbjDKJ2V (ORCPT ); Tue, 11 Apr 2023 05:28:21 -0400 Received: from smtpbgjp3.qq.com (smtpbgjp3.qq.com [54.92.39.34]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 54EB82683; Tue, 11 Apr 2023 02:28:19 -0700 (PDT) X-QQ-mid: bizesmtp91t1681205295t0e3gu1c Received: from wxdbg.localdomain.com ( [183.129.236.74]) by bizesmtp.qq.com (ESMTP) with id ; Tue, 11 Apr 2023 17:28:14 +0800 (CST) X-QQ-SSF: 01400000000000H0Z000000A0000000 X-QQ-FEAT: iBxuBmNAXy1slOmqKzYjXbxjNpuTE/rrMsWViLgpQVLn9YAuADygLyKRpPhjM BCRnRToI5UoCC0LPynNvn4fNUKMeayYGI9gl0RM2q9SGNWV7dYLDh91al1Eu/am0l1qsftS aZgZwmH3he6QO5QRPvk+MHgDTDCqeJj9pNdr7S1dGglbZoIEarmmgLBm6rgPVwioRnjUWVM v4vs842QgRU9jli8vRKq++9WKEim8VrxgceqBI7fImQmGh0xE+9ODqK+tyRkb9Uvj9yRcGS ybwr7laloRHxdOaAo6RjqemjJ0Yl8+pqcE0gb7CrWqiBKZ4nzl6b6Ays3IJ4Ck7sHwbEd+L mbpCObBaAUZ54Z/RSTZp7uRU3o4AHs0LSApZBslmGoA0hP87lKhiGh4h5FeaL/hSMujnrNd Yn2YQELRRzeA9sVJ4dWhRg== X-QQ-GoodBg: 2 X-BIZMAIL-ID: 15386639139174796298 From: Jiawen Wu To: netdev@vger.kernel.org, linux@armlinux.org.uk Cc: linux-i2c@vger.kernel.org, linux-gpio@vger.kernel.org, mengyuanlou@net-swift.com, Jiawen Wu Subject: [PATCH net-next v2 1/6] net: txgbe: Add software nodes to support phylink Date: Tue, 11 Apr 2023 17:27:20 +0800 Message-Id: <20230411092725.104992-2-jiawenwu@trustnetic.com> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20230411092725.104992-1-jiawenwu@trustnetic.com> References: <20230411092725.104992-1-jiawenwu@trustnetic.com> MIME-Version: 1.0 X-QQ-SENDSIZE: 520 Feedback-ID: bizesmtp:trustnetic.com:qybglogicsvr:qybglogicsvr5 Precedence: bulk List-ID: X-Mailing-List: linux-i2c@vger.kernel.org Register software nodes for GPIO, I2C, SFP and PHYLINK. Define the device properties. Signed-off-by: Jiawen Wu --- drivers/net/ethernet/wangxun/libwx/wx_type.h | 1 + drivers/net/ethernet/wangxun/txgbe/Makefile | 1 + .../net/ethernet/wangxun/txgbe/txgbe_main.c | 19 +++- .../net/ethernet/wangxun/txgbe/txgbe_phy.c | 86 +++++++++++++++++++ .../net/ethernet/wangxun/txgbe/txgbe_phy.h | 10 +++ .../net/ethernet/wangxun/txgbe/txgbe_type.h | 42 +++++++++ 6 files changed, 158 insertions(+), 1 deletion(-) create mode 100644 drivers/net/ethernet/wangxun/txgbe/txgbe_phy.c create mode 100644 drivers/net/ethernet/wangxun/txgbe/txgbe_phy.h diff --git a/drivers/net/ethernet/wangxun/libwx/wx_type.h b/drivers/net/ethernet/wangxun/libwx/wx_type.h index 32f952d93009..97bce855bc60 100644 --- a/drivers/net/ethernet/wangxun/libwx/wx_type.h +++ b/drivers/net/ethernet/wangxun/libwx/wx_type.h @@ -611,6 +611,7 @@ enum wx_isb_idx { struct wx { u8 __iomem *hw_addr; + void *priv; struct pci_dev *pdev; struct net_device *netdev; struct wx_bus_info bus; diff --git a/drivers/net/ethernet/wangxun/txgbe/Makefile b/drivers/net/ethernet/wangxun/txgbe/Makefile index 6db14a2cb2d0..7507f762edfe 100644 --- a/drivers/net/ethernet/wangxun/txgbe/Makefile +++ b/drivers/net/ethernet/wangxun/txgbe/Makefile @@ -8,4 +8,5 @@ obj-$(CONFIG_TXGBE) += txgbe.o txgbe-objs := txgbe_main.o \ txgbe_hw.o \ + txgbe_phy.o \ txgbe_ethtool.o diff --git a/drivers/net/ethernet/wangxun/txgbe/txgbe_main.c b/drivers/net/ethernet/wangxun/txgbe/txgbe_main.c index 5b8a121fb496..5a5e7620e9f8 100644 --- a/drivers/net/ethernet/wangxun/txgbe/txgbe_main.c +++ b/drivers/net/ethernet/wangxun/txgbe/txgbe_main.c @@ -15,6 +15,7 @@ #include "../libwx/wx_hw.h" #include "txgbe_type.h" #include "txgbe_hw.h" +#include "txgbe_phy.h" #include "txgbe_ethtool.h" char txgbe_driver_name[] = "txgbe"; @@ -513,6 +514,7 @@ static int txgbe_probe(struct pci_dev *pdev, struct net_device *netdev; int err, expected_gts; struct wx *wx = NULL; + struct txgbe *txgbe; u16 eeprom_verh = 0, eeprom_verl = 0, offset = 0; u16 eeprom_cfg_blkh = 0, eeprom_cfg_blkl = 0; @@ -663,10 +665,21 @@ static int txgbe_probe(struct pci_dev *pdev, "0x%08x", etrack_id); } - err = register_netdev(netdev); + txgbe = devm_kzalloc(&pdev->dev, sizeof(*txgbe), GFP_KERNEL); + if (!txgbe) + return -ENOMEM; + + txgbe->wx = wx; + wx->priv = txgbe; + + err = txgbe_init_phy(txgbe); if (err) goto err_release_hw; + err = register_netdev(netdev); + if (err) + goto err_remove_phy; + pci_set_drvdata(pdev, wx); netif_tx_stop_all_queues(netdev); @@ -694,6 +707,8 @@ static int txgbe_probe(struct pci_dev *pdev, return 0; +err_remove_phy: + txgbe_remove_phy(txgbe); err_release_hw: wx_clear_interrupt_scheme(wx); wx_control_hw(wx, false); @@ -724,6 +739,8 @@ static void txgbe_remove(struct pci_dev *pdev) netdev = wx->netdev; unregister_netdev(netdev); + txgbe_remove_phy((struct txgbe *)wx->priv); + pci_release_selected_regions(pdev, pci_select_bars(pdev, IORESOURCE_MEM)); diff --git a/drivers/net/ethernet/wangxun/txgbe/txgbe_phy.c b/drivers/net/ethernet/wangxun/txgbe/txgbe_phy.c new file mode 100644 index 000000000000..86d5e0647d5e --- /dev/null +++ b/drivers/net/ethernet/wangxun/txgbe/txgbe_phy.c @@ -0,0 +1,86 @@ +// SPDX-License-Identifier: GPL-2.0 +/* Copyright (c) 2015 - 2023 Beijing WangXun Technology Co., Ltd. */ + +#include +#include + +#include "../libwx/wx_type.h" +#include "txgbe_type.h" +#include "txgbe_phy.h" + +static int txgbe_swnodes_register(struct txgbe *txgbe) +{ + struct txgbe_nodes *nodes = &txgbe->nodes; + struct pci_dev *pdev = txgbe->wx->pdev; + struct software_node *swnodes; + u32 id; + + id = (pdev->bus->number << 8) | pdev->devfn; + + snprintf(nodes->gpio_name, sizeof(nodes->gpio_name), "txgbe_gpio-%x", id); + snprintf(nodes->i2c_name, sizeof(nodes->i2c_name), "txgbe_i2c-%x", id); + snprintf(nodes->sfp_name, sizeof(nodes->sfp_name), "txgbe_sfp-%x", id); + snprintf(nodes->phylink_name, sizeof(nodes->phylink_name), "txgbe_phylink-%x", id); + + swnodes = nodes->swnodes; + + /* GPIO 0: tx fault + * GPIO 1: tx disable + * GPIO 2: sfp module absent + * GPIO 3: rx signal lost + * GPIO 4: rate select, 1G(0) 10G(1) + * GPIO 5: rate select, 1G(0) 10G(1) + */ + nodes->gpio_props[0] = PROPERTY_ENTRY_STRING("pinctrl-names", "default"); + swnodes[SWNODE_GPIO] = NODE_PROP(nodes->gpio_name, nodes->gpio_props); + nodes->gpio0_ref[0] = SOFTWARE_NODE_REFERENCE(&swnodes[SWNODE_GPIO], 0, GPIO_ACTIVE_HIGH); + nodes->gpio1_ref[0] = SOFTWARE_NODE_REFERENCE(&swnodes[SWNODE_GPIO], 1, GPIO_ACTIVE_HIGH); + nodes->gpio2_ref[0] = SOFTWARE_NODE_REFERENCE(&swnodes[SWNODE_GPIO], 2, GPIO_ACTIVE_LOW); + nodes->gpio3_ref[0] = SOFTWARE_NODE_REFERENCE(&swnodes[SWNODE_GPIO], 3, GPIO_ACTIVE_HIGH); + nodes->gpio4_ref[0] = SOFTWARE_NODE_REFERENCE(&swnodes[SWNODE_GPIO], 4, GPIO_ACTIVE_HIGH); + nodes->gpio5_ref[0] = SOFTWARE_NODE_REFERENCE(&swnodes[SWNODE_GPIO], 5, GPIO_ACTIVE_HIGH); + + nodes->i2c_props[0] = PROPERTY_ENTRY_STRING("pinctrl-names", "default"); + swnodes[SWNODE_I2C] = NODE_PROP(nodes->i2c_name, nodes->i2c_props); + nodes->i2c_ref[0] = SOFTWARE_NODE_REFERENCE(&swnodes[SWNODE_I2C]); + + nodes->sfp_props[0] = PROPERTY_ENTRY_STRING("compatible", "sff,sfp"); + nodes->sfp_props[1] = PROPERTY_ENTRY_REF_ARRAY("i2c-bus", nodes->i2c_ref); + nodes->sfp_props[2] = PROPERTY_ENTRY_REF_ARRAY("tx-fault-gpios", nodes->gpio0_ref); + nodes->sfp_props[3] = PROPERTY_ENTRY_REF_ARRAY("tx-disable-gpios", nodes->gpio1_ref); + nodes->sfp_props[4] = PROPERTY_ENTRY_REF_ARRAY("mod-def0-gpios", nodes->gpio2_ref); + nodes->sfp_props[5] = PROPERTY_ENTRY_REF_ARRAY("los-gpios", nodes->gpio3_ref); + nodes->sfp_props[6] = PROPERTY_ENTRY_REF_ARRAY("rate-select1-gpios", nodes->gpio4_ref); + nodes->sfp_props[7] = PROPERTY_ENTRY_REF_ARRAY("rate-select0-gpios", nodes->gpio5_ref); + swnodes[SWNODE_SFP] = NODE_PROP(nodes->sfp_name, nodes->sfp_props); + nodes->sfp_ref[0] = SOFTWARE_NODE_REFERENCE(&swnodes[SWNODE_SFP]); + + nodes->phylink_props[0] = PROPERTY_ENTRY_STRING("managed", "in-band-status"); + nodes->phylink_props[1] = PROPERTY_ENTRY_REF_ARRAY("sfp", nodes->sfp_ref); + swnodes[SWNODE_PHYLINK] = NODE_PROP(nodes->phylink_name, nodes->phylink_props); + + nodes->group[SWNODE_GPIO] = &swnodes[SWNODE_GPIO]; + nodes->group[SWNODE_I2C] = &swnodes[SWNODE_I2C]; + nodes->group[SWNODE_SFP] = &swnodes[SWNODE_SFP]; + nodes->group[SWNODE_PHYLINK] = &swnodes[SWNODE_PHYLINK]; + + return software_node_register_node_group(nodes->group); +} + +int txgbe_init_phy(struct txgbe *txgbe) +{ + int ret; + + ret = txgbe_swnodes_register(txgbe); + if (ret) { + wx_err(txgbe->wx, "failed to register software nodes\n"); + return ret; + } + + return 0; +} + +void txgbe_remove_phy(struct txgbe *txgbe) +{ + software_node_unregister_node_group(txgbe->nodes.group); +} diff --git a/drivers/net/ethernet/wangxun/txgbe/txgbe_phy.h b/drivers/net/ethernet/wangxun/txgbe/txgbe_phy.h new file mode 100644 index 000000000000..1ab592124986 --- /dev/null +++ b/drivers/net/ethernet/wangxun/txgbe/txgbe_phy.h @@ -0,0 +1,10 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* Copyright (c) 2015 - 2023 Beijing WangXun Technology Co., Ltd. */ + +#ifndef _TXGBE_PHY_H_ +#define _TXGBE_PHY_H_ + +int txgbe_init_phy(struct txgbe *txgbe); +void txgbe_remove_phy(struct txgbe *txgbe); + +#endif /* _TXGBE_NODE_H_ */ diff --git a/drivers/net/ethernet/wangxun/txgbe/txgbe_type.h b/drivers/net/ethernet/wangxun/txgbe/txgbe_type.h index 63a1c733718d..d30684378f4e 100644 --- a/drivers/net/ethernet/wangxun/txgbe/txgbe_type.h +++ b/drivers/net/ethernet/wangxun/txgbe/txgbe_type.h @@ -4,6 +4,8 @@ #ifndef _TXGBE_TYPE_H_ #define _TXGBE_TYPE_H_ +#include + /* Device IDs */ #define TXGBE_DEV_ID_SP1000 0x1001 #define TXGBE_DEV_ID_WX1820 0x2001 @@ -99,4 +101,44 @@ extern char txgbe_driver_name[]; +#define NODE_PROP(_NAME, _PROP) \ + (const struct software_node) { \ + .name = _NAME, \ + .properties = _PROP, \ + } + +enum txgbe_swnodes { + SWNODE_GPIO = 0, + SWNODE_I2C, + SWNODE_SFP, + SWNODE_PHYLINK, + SWNODE_MAX +}; + +struct txgbe_nodes { + char gpio_name[32]; + char i2c_name[32]; + char sfp_name[32]; + char phylink_name[32]; + struct property_entry gpio_props[1]; + struct property_entry i2c_props[1]; + struct property_entry sfp_props[8]; + struct property_entry phylink_props[2]; + struct software_node_ref_args i2c_ref[1]; + struct software_node_ref_args gpio0_ref[1]; + struct software_node_ref_args gpio1_ref[1]; + struct software_node_ref_args gpio2_ref[1]; + struct software_node_ref_args gpio3_ref[1]; + struct software_node_ref_args gpio4_ref[1]; + struct software_node_ref_args gpio5_ref[1]; + struct software_node_ref_args sfp_ref[1]; + struct software_node swnodes[SWNODE_MAX]; + const struct software_node *group[SWNODE_MAX + 1]; +}; + +struct txgbe { + struct wx *wx; + struct txgbe_nodes nodes; +}; + #endif /* _TXGBE_TYPE_H_ */