From nobody Tue Oct 7 00:22:40 2025 Received: from szxga04-in.huawei.com (szxga04-in.huawei.com [45.249.212.190]) (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 7B1792F2727; Wed, 16 Jul 2025 10:07:48 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=45.249.212.190 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1752660471; cv=none; b=F/xqwHhT9CKrN08b3sfi88RVrufW5XTYUXDzBsMP5jsnrWYZj8j5KmmUHWeW8WiLVwCtQsWmgfrIkeHA1AIvQ1ge/a7eP6wXDkogYv4IXotJ6mD030Ubd0oJ7zgEueJxOCetUbe8zs7Hx++YaN01od0Z4K6A9bvlqxOE/EvU6ZY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1752660471; c=relaxed/simple; bh=7XlPuIRpbg6BDhvE2ZYzUP4ltOm43y0M0k7+AdOguNU=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=Z9VN7i4jNr590BGFD6PrxGiaQShR2b9yt8TRD2HjwLgNfxaum4AbdhrPSDweRdC1O6Tj1o89c9PQMHPj2ShhLlzCng8weuE3JfACgVAUB7p81wyFG1APE7Gbl6IxEKK4p3QPpdFopX+o8mvKz/KIw0zyQOqCUUHDQ1AEcQH7954= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=huawei.com; spf=pass smtp.mailfrom=huawei.com; arc=none smtp.client-ip=45.249.212.190 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=huawei.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=huawei.com Received: from mail.maildlp.com (unknown [172.19.162.112]) by szxga04-in.huawei.com (SkyGuard) with ESMTP id 4bhsBX6ylCz2TT43; Wed, 16 Jul 2025 18:05:40 +0800 (CST) Received: from kwepemk100013.china.huawei.com (unknown [7.202.194.61]) by mail.maildlp.com (Postfix) with ESMTPS id 4BDAD1402DA; Wed, 16 Jul 2025 18:07:45 +0800 (CST) Received: from localhost.localdomain (10.90.31.46) by kwepemk100013.china.huawei.com (7.202.194.61) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.1544.11; Wed, 16 Jul 2025 18:07:44 +0800 From: Jijie Shao To: , , , , , , , , CC: , , , , , , , , Subject: [PATCH net-next 1/2] net: phy: motorcomm: Add support for PHY LEDs on YT8521 Date: Wed, 16 Jul 2025 18:00:40 +0800 Message-ID: <20250716100041.2833168-2-shaojijie@huawei.com> X-Mailer: git-send-email 2.30.0 In-Reply-To: <20250716100041.2833168-1-shaojijie@huawei.com> References: <20250716100041.2833168-1-shaojijie@huawei.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-ClientProxiedBy: kwepems100001.china.huawei.com (7.221.188.238) To kwepemk100013.china.huawei.com (7.202.194.61) Content-Type: text/plain; charset="utf-8" Add minimal LED controller driver supporting the most common uses with the 'netdev' trigger. Signed-off-by: Jijie Shao Tested-by: Heiko Stuebner --- drivers/net/phy/motorcomm.c | 120 ++++++++++++++++++++++++++++++++++++ 1 file changed, 120 insertions(+) diff --git a/drivers/net/phy/motorcomm.c b/drivers/net/phy/motorcomm.c index 0e91f5d1a4fd..e1a1c3a1c9d0 100644 --- a/drivers/net/phy/motorcomm.c +++ b/drivers/net/phy/motorcomm.c @@ -213,6 +213,23 @@ #define YT8521_RC1R_RGMII_2_100_NS 14 #define YT8521_RC1R_RGMII_2_250_NS 15 =20 +/* LED CONFIG */ +#define YT8521_MAX_LEDS 3 +#define YT8521_LED0_CFG_REG 0xA00C +#define YT8521_LED1_CFG_REG 0xA00D +#define YT8521_LED2_CFG_REG 0xA00E +#define YT8521_LED_ACT_BLK_IND BIT(13) +#define YT8521_LED_FDX_ON_EN BIT(12) +#define YT8521_LED_HDX_ON_EN BIT(11) +#define YT8521_LED_TXACT_BLK_EN BIT(10) +#define YT8521_LED_RXACT_BLK_EN BIT(9) +/* 1000Mbps */ +#define YT8521_LED_GT_ON_EN BIT(6) +/* 100Mbps */ +#define YT8521_LED_HT_ON_EN BIT(5) +/* 10Mbps */ +#define YT8521_LED_BT_ON_EN BIT(4) + #define YTPHY_MISC_CONFIG_REG 0xA006 #define YTPHY_MCR_FIBER_SPEED_MASK BIT(0) #define YTPHY_MCR_FIBER_1000BX (0x1 << 0) @@ -1681,6 +1698,106 @@ static int yt8521_config_init(struct phy_device *ph= ydev) return phy_restore_page(phydev, old_page, ret); } =20 +static const unsigned long supported_trgs =3D (BIT(TRIGGER_NETDEV_FULL_DUP= LEX) | + BIT(TRIGGER_NETDEV_HALF_DUPLEX) | + BIT(TRIGGER_NETDEV_LINK) | + BIT(TRIGGER_NETDEV_LINK_10) | + BIT(TRIGGER_NETDEV_LINK_100) | + BIT(TRIGGER_NETDEV_LINK_1000) | + BIT(TRIGGER_NETDEV_RX) | + BIT(TRIGGER_NETDEV_TX)); + +static int yt8521_led_hw_is_supported(struct phy_device *phydev, u8 index, + unsigned long rules) +{ + if (index >=3D YT8521_MAX_LEDS) + return -EINVAL; + + /* All combinations of the supported triggers are allowed */ + if (rules & ~supported_trgs) + return -EOPNOTSUPP; + + return 0; +} + +static int yt8521_led_hw_control_set(struct phy_device *phydev, u8 index, + unsigned long rules) +{ + u16 val =3D 0; + + if (index >=3D YT8521_MAX_LEDS) + return -EINVAL; + + if (test_bit(TRIGGER_NETDEV_LINK, &rules)) { + val |=3D YT8521_LED_BT_ON_EN; + val |=3D YT8521_LED_HT_ON_EN; + val |=3D YT8521_LED_GT_ON_EN; + } + + if (test_bit(TRIGGER_NETDEV_LINK_10, &rules)) + val |=3D YT8521_LED_BT_ON_EN; + + if (test_bit(TRIGGER_NETDEV_LINK_100, &rules)) + val |=3D YT8521_LED_HT_ON_EN; + + if (test_bit(TRIGGER_NETDEV_LINK_1000, &rules)) + val |=3D YT8521_LED_GT_ON_EN; + + if (test_bit(TRIGGER_NETDEV_FULL_DUPLEX, &rules)) + val |=3D YT8521_LED_HDX_ON_EN; + + if (test_bit(TRIGGER_NETDEV_HALF_DUPLEX, &rules)) + val |=3D YT8521_LED_FDX_ON_EN; + + if (test_bit(TRIGGER_NETDEV_TX, &rules) || + test_bit(TRIGGER_NETDEV_RX, &rules)) + val |=3D YT8521_LED_ACT_BLK_IND; + + if (test_bit(TRIGGER_NETDEV_TX, &rules)) + val |=3D YT8521_LED_TXACT_BLK_EN; + + if (test_bit(TRIGGER_NETDEV_RX, &rules)) + val |=3D YT8521_LED_RXACT_BLK_EN; + + return ytphy_write_ext(phydev, YT8521_LED0_CFG_REG + index, val); +} + +static int yt8521_led_hw_control_get(struct phy_device *phydev, u8 index, + unsigned long *rules) +{ + int val; + + if (index >=3D YT8521_MAX_LEDS) + return -EINVAL; + + val =3D ytphy_read_ext(phydev, YT8521_LED0_CFG_REG + index); + if (val < 0) + return val; + + if (val & YT8521_LED_TXACT_BLK_EN) + set_bit(TRIGGER_NETDEV_TX, rules); + + if (val & YT8521_LED_RXACT_BLK_EN) + set_bit(TRIGGER_NETDEV_RX, rules); + + if (val & YT8521_LED_FDX_ON_EN) + set_bit(TRIGGER_NETDEV_FULL_DUPLEX, rules); + + if (val & YT8521_LED_HDX_ON_EN) + set_bit(TRIGGER_NETDEV_HALF_DUPLEX, rules); + + if (val & YT8521_LED_GT_ON_EN) + set_bit(TRIGGER_NETDEV_LINK_1000, rules); + + if (val & YT8521_LED_HT_ON_EN) + set_bit(TRIGGER_NETDEV_LINK_100, rules); + + if (val & YT8521_LED_BT_ON_EN) + set_bit(TRIGGER_NETDEV_LINK_10, rules); + + return 0; +} + static int yt8531_config_init(struct phy_device *phydev) { struct device_node *node =3D phydev->mdio.dev.of_node; @@ -2920,6 +3037,9 @@ static struct phy_driver motorcomm_phy_drvs[] =3D { .soft_reset =3D yt8521_soft_reset, .suspend =3D yt8521_suspend, .resume =3D yt8521_resume, + .led_hw_is_supported =3D yt8521_led_hw_is_supported, + .led_hw_control_set =3D yt8521_led_hw_control_set, + .led_hw_control_get =3D yt8521_led_hw_control_get, }, { PHY_ID_MATCH_EXACT(PHY_ID_YT8531), --=20 2.33.0 From nobody Tue Oct 7 00:22:40 2025 Received: from szxga05-in.huawei.com (szxga05-in.huawei.com [45.249.212.191]) (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 7DFB72F272B; Wed, 16 Jul 2025 10:07:48 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=45.249.212.191 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1752660471; cv=none; b=Weu3+2Jm5B08lwdFXW5XuKQ4JQ2kDXLJZtcmAz5+s/gh/zio6nldBTpxlZDCVwkP+3CnFrDJpQT0PL24RiFBwC8PIRMfxPwStvtr38KSsDQAT6U+QymCMWR6UYRIgsqpWJSX/lf7SXtVlA95eKu5WlpKG5WU5FQLnoFmXKsQwRg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1752660471; c=relaxed/simple; bh=nLDtChB/cR47HVGRGZA8t5xKv5ZD1c2sMJhML42iCEE=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=ukPCEF6NaL5wYU7oO+yMOyF9pDrjb7j0RItCByWg2/c1bBmxjaTZeeF3FkdL4q9yiapZPvVB6LVChgDteBHw1uBSNFUeWSeTRnltDdFYaI+6+I91H4jacU2GSOtYG1MS5XhAoe3/NsEfor70uL4aYB/CCgDnhP6gDk0sdMxkvvk= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=huawei.com; spf=pass smtp.mailfrom=huawei.com; arc=none smtp.client-ip=45.249.212.191 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=huawei.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=huawei.com Received: from mail.maildlp.com (unknown [172.19.88.214]) by szxga05-in.huawei.com (SkyGuard) with ESMTP id 4bhs9w4Tjvz1R7Ys; Wed, 16 Jul 2025 18:05:08 +0800 (CST) Received: from kwepemk100013.china.huawei.com (unknown [7.202.194.61]) by mail.maildlp.com (Postfix) with ESMTPS id EA1161A016C; Wed, 16 Jul 2025 18:07:45 +0800 (CST) Received: from localhost.localdomain (10.90.31.46) by kwepemk100013.china.huawei.com (7.202.194.61) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.1544.11; Wed, 16 Jul 2025 18:07:45 +0800 From: Jijie Shao To: , , , , , , , , CC: , , , , , , , , Subject: [PATCH net-next 2/2] net: hibmcge: Add support for PHY LEDs on YT8521 Date: Wed, 16 Jul 2025 18:00:41 +0800 Message-ID: <20250716100041.2833168-3-shaojijie@huawei.com> X-Mailer: git-send-email 2.30.0 In-Reply-To: <20250716100041.2833168-1-shaojijie@huawei.com> References: <20250716100041.2833168-1-shaojijie@huawei.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-ClientProxiedBy: kwepems100001.china.huawei.com (7.221.188.238) To kwepemk100013.china.huawei.com (7.202.194.61) Content-Type: text/plain; charset="utf-8" hibmcge is a PCIE EP device, and its controller is not on the board. And board uses ACPI not DTS to create the device tree. So, this makes it impossible to add a "reg" property(used in of_phy_led()) for hibmcge. Therefore, the PHY_LED framework cannot be used directly. This patch creates a separate LED device for hibmcge and directly calls the phy->drv->led_hw**() function to operate the related LEDs. Signed-off-by: Jijie Shao --- drivers/net/ethernet/hisilicon/Kconfig | 8 ++ .../net/ethernet/hisilicon/hibmcge/Makefile | 1 + .../net/ethernet/hisilicon/hibmcge/hbg_led.c | 132 ++++++++++++++++++ .../net/ethernet/hisilicon/hibmcge/hbg_led.h | 17 +++ .../net/ethernet/hisilicon/hibmcge/hbg_main.c | 7 + 5 files changed, 165 insertions(+) create mode 100644 drivers/net/ethernet/hisilicon/hibmcge/hbg_led.c create mode 100644 drivers/net/ethernet/hisilicon/hibmcge/hbg_led.h diff --git a/drivers/net/ethernet/hisilicon/Kconfig b/drivers/net/ethernet/= hisilicon/Kconfig index 65302c41bfb1..143b25f329c7 100644 --- a/drivers/net/ethernet/hisilicon/Kconfig +++ b/drivers/net/ethernet/hisilicon/Kconfig @@ -157,4 +157,12 @@ config HIBMCGE =20 If you are unsure, say N. =20 +config HIBMCGE_LEDS + def_bool LEDS_TRIGGER_NETDEV + depends on HIBMCGE && LEDS_CLASS + depends on LEDS_CLASS=3Dy || HIBMCGE=3Dm + help + Optional support for controlling the NIC LED's with the netdev + LED trigger. + endif # NET_VENDOR_HISILICON diff --git a/drivers/net/ethernet/hisilicon/hibmcge/Makefile b/drivers/net/= ethernet/hisilicon/hibmcge/Makefile index 1a9da564b306..a78057208064 100644 --- a/drivers/net/ethernet/hisilicon/hibmcge/Makefile +++ b/drivers/net/ethernet/hisilicon/hibmcge/Makefile @@ -7,3 +7,4 @@ obj-$(CONFIG_HIBMCGE) +=3D hibmcge.o =20 hibmcge-objs =3D hbg_main.o hbg_hw.o hbg_mdio.o hbg_irq.o hbg_txrx.o hbg_e= thtool.o \ hbg_debugfs.o hbg_err.o hbg_diagnose.o +hibmcge-$(CONFIG_HIBMCGE_LEDS) +=3D hbg_led.o diff --git a/drivers/net/ethernet/hisilicon/hibmcge/hbg_led.c b/drivers/net= /ethernet/hisilicon/hibmcge/hbg_led.c new file mode 100644 index 000000000000..013eae1c54f2 --- /dev/null +++ b/drivers/net/ethernet/hisilicon/hibmcge/hbg_led.c @@ -0,0 +1,132 @@ +// SPDX-License-Identifier: GPL-2.0+ +// Copyright (c) 2025 Hisilicon Limited. + +#include +#include +#include +#include "hbg_common.h" +#include "hbg_led.h" + +#define PHY_ID_YT8521 0x0000011a + +#define to_hbg_led(lcdev) container_of(lcdev, struct hbg_led_classdev, led) +#define to_hbg_phy_dev(lcdev) \ + (((struct hbg_led_classdev *)to_hbg_led(lcdev))->priv->mac.phydev) + +static int hbg_led_hw_control_set(struct led_classdev *led_cdev, + unsigned long rules) +{ + struct hbg_led_classdev *hbg_led =3D to_hbg_led(led_cdev); + struct phy_device *phydev =3D to_hbg_phy_dev(led_cdev); + int ret; + + mutex_lock(&phydev->lock); + ret =3D phydev->drv->led_hw_control_set(phydev, hbg_led->index, rules); + mutex_unlock(&phydev->lock); + + return ret; +} + +static int hbg_led_hw_control_get(struct led_classdev *led_cdev, + unsigned long *rules) +{ + struct hbg_led_classdev *hbg_led =3D to_hbg_led(led_cdev); + struct phy_device *phydev =3D to_hbg_phy_dev(led_cdev); + int ret; + + mutex_lock(&phydev->lock); + ret =3D phydev->drv->led_hw_control_get(phydev, hbg_led->index, rules); + mutex_unlock(&phydev->lock); + + return ret; +} + +static int hbg_led_hw_is_supported(struct led_classdev *led_cdev, + unsigned long rules) +{ + struct hbg_led_classdev *hbg_led =3D to_hbg_led(led_cdev); + struct phy_device *phydev =3D to_hbg_phy_dev(led_cdev); + int ret; + + mutex_lock(&phydev->lock); + ret =3D phydev->drv->led_hw_is_supported(phydev, hbg_led->index, rules); + mutex_unlock(&phydev->lock); + + return ret; +} + +static struct device * + hbg_led_hw_control_get_device(struct led_classdev *led_cdev) +{ + struct hbg_led_classdev *hbg_led =3D to_hbg_led(led_cdev); + + return &hbg_led->priv->netdev->dev; +} + +static int hbg_setup_ldev(struct hbg_led_classdev *hbg_led) +{ + struct led_classdev *ldev =3D &hbg_led->led; + struct hbg_priv *priv =3D hbg_led->priv; + struct device *dev =3D &priv->pdev->dev; + + ldev->name =3D devm_kasprintf(dev, GFP_KERNEL, "%s-%s-%d", + dev_driver_string(dev), + pci_name(priv->pdev), hbg_led->index); + if (!ldev->name) + return -ENOMEM; + + ldev->hw_control_trigger =3D "netdev"; + ldev->hw_control_set =3D hbg_led_hw_control_set; + ldev->hw_control_get =3D hbg_led_hw_control_get; + ldev->hw_control_is_supported =3D hbg_led_hw_is_supported; + ldev->hw_control_get_device =3D hbg_led_hw_control_get_device; + + return devm_led_classdev_register(dev, ldev); +} + +static u32 hbg_get_phy_max_led_count(struct hbg_priv *priv) +{ + struct phy_device *phydev =3D priv->mac.phydev; + + if (!phydev->drv->led_hw_is_supported || + !phydev->drv->led_hw_control_set || + !phydev->drv->led_hw_control_get) + return 0; + + /* YT8521, support 3 leds */ + if (phydev->drv->phy_id =3D=3D PHY_ID_YT8521) + return 3; + + return 0; +} + +int hbg_leds_init(struct hbg_priv *priv) +{ + u32 led_count =3D hbg_get_phy_max_led_count(priv); + struct phy_device *phydev =3D priv->mac.phydev; + struct hbg_led_classdev *leds; + int ret; + int i; + + if (!led_count) + return 0; + + leds =3D devm_kcalloc(&priv->pdev->dev, led_count, + sizeof(*leds), GFP_KERNEL); + if (!leds) + return -ENOMEM; + + for (i =3D 0; i < led_count; i++) { + /* for YT8521, we only have two lights, 0 and 2. */ + if (phydev->drv->phy_id =3D=3D PHY_ID_YT8521 && i =3D=3D 1) + continue; + + leds[i].priv =3D priv; + leds[i].index =3D i; + ret =3D hbg_setup_ldev(&leds[i]); + if (ret) + return ret; + } + + return 0; +} diff --git a/drivers/net/ethernet/hisilicon/hibmcge/hbg_led.h b/drivers/net= /ethernet/hisilicon/hibmcge/hbg_led.h new file mode 100644 index 000000000000..463285077c91 --- /dev/null +++ b/drivers/net/ethernet/hisilicon/hibmcge/hbg_led.h @@ -0,0 +1,17 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* Copyright (c) 2025 Hisilicon Limited. */ + +#ifndef __HBG_LED_H +#define __HBG_LED_H + +#include "hbg_common.h" + +struct hbg_led_classdev { + struct hbg_priv *priv; + struct led_classdev led; + u32 index; +}; + +int hbg_leds_init(struct hbg_priv *priv); + +#endif diff --git a/drivers/net/ethernet/hisilicon/hibmcge/hbg_main.c b/drivers/ne= t/ethernet/hisilicon/hibmcge/hbg_main.c index 2e64dc1ab355..f2f8f651f3d2 100644 --- a/drivers/net/ethernet/hisilicon/hibmcge/hbg_main.c +++ b/drivers/net/ethernet/hisilicon/hibmcge/hbg_main.c @@ -12,6 +12,7 @@ #include "hbg_ethtool.h" #include "hbg_hw.h" #include "hbg_irq.h" +#include "hbg_led.h" #include "hbg_mdio.h" #include "hbg_txrx.h" #include "hbg_debugfs.h" @@ -383,6 +384,12 @@ static int hbg_init(struct hbg_priv *priv) if (ret) return ret; =20 + if (IS_ENABLED(CONFIG_HIBMCGE_LEDS)) { + ret =3D hbg_leds_init(priv); + if (ret) + return ret; + } + ret =3D hbg_mac_filter_init(priv); if (ret) return ret; --=20 2.33.0