From nobody Wed Dec 17 06:03:32 2025 Received: from canpmsgout05.his.huawei.com (canpmsgout05.his.huawei.com [113.46.200.220]) (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 26AB728D850; Mon, 15 Dec 2025 12:59:58 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=113.46.200.220 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1765803600; cv=none; b=ISowDzhamX00a8iLtqjSGSszPXsJsfQmcuer+cFkrx4O4kGkYabZ2nluaCI7AOe744aOQwl1vPSILvJ2/aFgLu1HBfwDkrtrqZQW1QgNcL8Yir+mFs/Q7gmbL98d1cx1gHTaYEJtDtcO73CpLPrlkFFKA9/VwSgymUFsjBTcnu0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1765803600; c=relaxed/simple; bh=8sIdV1vSPUwp0OuguQeVcd+qoz7KzJoL8HsTzLVh7EI=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=WyVlhO98pVS+hQWG1TyqON5NSIPos4x66e3z8cvvIzhXs41YM9WQkuPwpHJl8kLubuxtSUlVsXL66O3iIx/S3n9EDEzg80rbZ0jjbUpi1aC6jzGAmfiYdrPABNdlGX1RaegVvCQo/MCzHfaOpe+qfQJwGSntPj1N53GFi4KlkrU= 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; dkim=pass (1024-bit key) header.d=huawei.com header.i=@huawei.com header.b=DxZVX2jl; arc=none smtp.client-ip=113.46.200.220 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 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=huawei.com header.i=@huawei.com header.b="DxZVX2jl" dkim-signature: v=1; a=rsa-sha256; d=huawei.com; s=dkim; c=relaxed/relaxed; q=dns/txt; h=From; bh=5U6BHLA8ULqFPpbl15/Pen372oWN+BOp1QgNe1s7QOQ=; b=DxZVX2jlI92jmiO9UDFckb4GThu0dO3LrPm+6lMGvvbPvUwKBZvDTzY57h+sZ5lN75BZXPF34 zj4f/HD1fw20eS1gTMm5aJXHARvbuv2ydcq4F60/P5B27HqC3rX0mUvYThTXfKtAUiapPIqZ+BF nHz4e1FlstWjlZXeHI+Pp8U= Received: from mail.maildlp.com (unknown [172.19.88.194]) by canpmsgout05.his.huawei.com (SkyGuard) with ESMTPS id 4dVKpl1j5cz12LDf; Mon, 15 Dec 2025 20:57:35 +0800 (CST) Received: from kwepemk100013.china.huawei.com (unknown [7.202.194.61]) by mail.maildlp.com (Postfix) with ESMTPS id 08D6E140133; Mon, 15 Dec 2025 20:59:50 +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; Mon, 15 Dec 2025 20:59:49 +0800 From: Jijie Shao To: , , , , , , , , CC: , , , , , , , , Subject: [PATCH RFC net-next 3/6] net: hibmcge: create a software node for phy_led Date: Mon, 15 Dec 2025 20:57:02 +0800 Message-ID: <20251215125705.1567527-4-shaojijie@huawei.com> X-Mailer: git-send-email 2.30.0 In-Reply-To: <20251215125705.1567527-1-shaojijie@huawei.com> References: <20251215125705.1567527-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" Currently, phy_led supports of node, acpi node, and software node. The hibmcge hardware(including leds) is on the BMC side, while the driver runs on the host side. An apic or of node needs to be created on the host side to support phy_led; otherwise, phy_led will not be supported. Therefore, in order to support phy_led, this patch will create a software node when it detects that the phy device is not bound to any fwnode. Closes: https://lore.kernel.org/all/023a85e4-87e2-4bd3-9727-69a2bfdc4145@lu= nn.ch/ Signed-off-by: Jijie Shao --- .../ethernet/hisilicon/hibmcge/hbg_common.h | 11 ++ .../net/ethernet/hisilicon/hibmcge/hbg_mdio.c | 120 +++++++++++++++++- 2 files changed, 124 insertions(+), 7 deletions(-) diff --git a/drivers/net/ethernet/hisilicon/hibmcge/hbg_common.h b/drivers/= net/ethernet/hisilicon/hibmcge/hbg_common.h index 8e134da3e217..d20dd324e129 100644 --- a/drivers/net/ethernet/hisilicon/hibmcge/hbg_common.h +++ b/drivers/net/ethernet/hisilicon/hibmcge/hbg_common.h @@ -5,8 +5,10 @@ #define __HBG_COMMON_H =20 #include +#include #include #include +#include #include #include "hbg_reg.h" =20 @@ -130,6 +132,9 @@ struct hbg_vector { u32 info_array_len; }; =20 +#define HBG_LED_MAX_NUM (sizeof(u32) / sizeof(u8)) +#define HBG_LED_SOFTWARE_NODE_MAX_NUM (HBG_LED_MAX_NUM + 2) + struct hbg_mac { struct mii_bus *mdio_bus; struct phy_device *phydev; @@ -140,6 +145,12 @@ struct hbg_mac { u32 autoneg; u32 link_status; u32 pause_autoneg; + + struct software_node phy_node; + struct software_node leds_node; + struct software_node led_nodes[HBG_LED_MAX_NUM]; + struct property_entry leds_props[HBG_LED_MAX_NUM][4]; + const struct software_node *nodes[HBG_LED_SOFTWARE_NODE_MAX_NUM + 1]; }; =20 struct hbg_mac_table_entry { diff --git a/drivers/net/ethernet/hisilicon/hibmcge/hbg_mdio.c b/drivers/ne= t/ethernet/hisilicon/hibmcge/hbg_mdio.c index b6f0a2780ea8..edd8ccefbb62 100644 --- a/drivers/net/ethernet/hisilicon/hibmcge/hbg_mdio.c +++ b/drivers/net/ethernet/hisilicon/hibmcge/hbg_mdio.c @@ -263,11 +263,119 @@ static int hbg_fixed_phy_init(struct hbg_priv *priv) return hbg_phy_connect(priv); } =20 -int hbg_mdio_init(struct hbg_priv *priv) +static void hbg_phy_device_free(void *data) +{ + phy_device_free((struct phy_device *)data); +} + +static void hbg_phy_device_remove(void *data) +{ + phy_device_remove((struct phy_device *)data); +} + +static void hbg_software_node_unregister_group(void *data) +{ + const struct software_node **node =3D data; + + software_node_unregister_node_group(node); +} + +static void hbg_device_remove_software_node(void *data) +{ + device_remove_software_node((struct device *)data); +} + +static int hbg_register_phy_leds_software_node(struct hbg_priv *priv, + struct phy_device *phydev) { + struct fwnode_handle *fwnode =3D dev_fwnode(&phydev->mdio.dev); struct device *dev =3D &priv->pdev->dev; struct hbg_mac *mac =3D &priv->mac; + u32 node_index =3D 0, i; + const char *label; + int ret; + + if (fwnode) { + dev_dbg(dev, "phy fwnode is already exists\n"); + return 0; + } + + mac->phy_node.name =3D devm_kasprintf(dev, GFP_KERNEL, "%s-%s-%u", + "mii", dev_name(dev), + mac->phy_addr); + mac->nodes[node_index++] =3D &mac->phy_node; + + mac->leds_node.name =3D devm_kasprintf(dev, GFP_KERNEL, "leds"); + mac->leds_node.parent =3D &mac->phy_node; + mac->nodes[node_index++] =3D &mac->leds_node; + + for (i =3D 0; i < HBG_LED_MAX_NUM; i++) { + mac->leds_props[i][0] =3D PROPERTY_ENTRY_U32("reg", i); + label =3D devm_kasprintf(dev, GFP_KERNEL, "%u", i); + mac->leds_props[i][1] =3D PROPERTY_ENTRY_STRING("label", label); + + mac->led_nodes[i].name =3D devm_kasprintf(dev, GFP_KERNEL, + "led@%u", i); + mac->led_nodes[i].properties =3D mac->leds_props[i]; + mac->led_nodes[i].parent =3D &mac->leds_node; + + mac->nodes[node_index++] =3D &mac->led_nodes[i]; + } + + ret =3D software_node_register_node_group(mac->nodes); + if (ret) + return dev_err_probe(dev, ret, + "failed to register software node\n"); + + ret =3D devm_add_action_or_reset(dev, hbg_software_node_unregister_group, + mac->nodes); + if (ret) + return ret; + + ret =3D device_add_software_node(&phydev->mdio.dev, &mac->phy_node); + if (ret) + return dev_err_probe(dev, ret, "failed to add software node\n"); + + return devm_add_action_or_reset(dev, hbg_device_remove_software_node, + &phydev->mdio.dev); +} + +static int hbg_find_phy_device(struct hbg_priv *priv, struct mii_bus *mdio= _bus) +{ + struct device *dev =3D &priv->pdev->dev; struct phy_device *phydev; + int ret; + + phydev =3D get_phy_device(mdio_bus, priv->mac.phy_addr, false); + if (IS_ERR(phydev)) + return dev_err_probe(dev, -ENODEV, + "failed to get phy device\n"); + + ret =3D devm_add_action_or_reset(dev, hbg_phy_device_free, phydev); + if (ret) + return ret; + + ret =3D hbg_register_phy_leds_software_node(priv, phydev); + if (ret) + return ret; + + ret =3D phy_device_register(phydev); + if (ret) + return dev_err_probe(dev, ret, + "failed to register phy device\n"); + + ret =3D devm_add_action_or_reset(dev, hbg_phy_device_remove, phydev); + if (ret) + return ret; + + priv->mac.phydev =3D phydev; + return 0; +} + +int hbg_mdio_init(struct hbg_priv *priv) +{ + struct device *dev =3D &priv->pdev->dev; + struct hbg_mac *mac =3D &priv->mac; struct mii_bus *mdio_bus; int ret; =20 @@ -281,7 +389,7 @@ int hbg_mdio_init(struct hbg_priv *priv) =20 mdio_bus->parent =3D dev; mdio_bus->priv =3D priv; - mdio_bus->phy_mask =3D ~(1 << mac->phy_addr); + mdio_bus->phy_mask =3D 0xFFFFFFFF; /* not scan phy device */ mdio_bus->name =3D "hibmcge mii bus"; mac->mdio_bus =3D mdio_bus; =20 @@ -293,12 +401,10 @@ int hbg_mdio_init(struct hbg_priv *priv) if (ret) return dev_err_probe(dev, ret, "failed to register MDIO bus\n"); =20 - phydev =3D mdiobus_get_phy(mdio_bus, mac->phy_addr); - if (!phydev) - return dev_err_probe(dev, -ENODEV, - "failed to get phy device\n"); + ret =3D hbg_find_phy_device(priv, mdio_bus); + if (ret) + return ret; =20 - mac->phydev =3D phydev; hbg_mdio_init_hw(priv); return hbg_phy_connect(priv); } --=20 2.33.0