From patchwork Sat Nov 25 00:11:18 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Christian Marangi X-Patchwork-Id: 747293 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="QPqCne8j" Received: from mail-wr1-x42a.google.com (mail-wr1-x42a.google.com [IPv6:2a00:1450:4864:20::42a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id A0E2C173D; Fri, 24 Nov 2023 16:35:21 -0800 (PST) Received: by mail-wr1-x42a.google.com with SMTP id ffacd0b85a97d-332e3ad436cso1232351f8f.3; Fri, 24 Nov 2023 16:35:21 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1700872520; x=1701477320; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:from:to:cc:subject:date:message-id :reply-to; bh=03wonMi6/ThM2gO3QCZn24JsXK7jMYiMUg0Bft7Hcig=; b=QPqCne8jDezXZ7k7Y760MTwPH0y9dgENWHdqMucf/cbM6WyS0ZBZGUdtPLvvTqhapB HonowiaHGmBdE4nYW9RdaV4sINlas0NGpdfhTwbx+T+oE/5xV34nmnIS4SPSmIoykX4O Phek3ytuG+1swrjN3i1/hItieMmhTqYrsDQON7MBmVgb8uBBe0a/L+B4KnZXrXffpA9w VKfGWipRzIfkjpUpf9P46UkjE8VmnbHLzdz70IuROIAJCiN1ef+HbePj+AEZ4TwEmesd ho+ZFj3p4xTUR/l9Q/eFSZygxU1ilozTZKF8hbnVMqpBh47e2WqkqCGHegfewbq7/OwH xV7Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1700872520; x=1701477320; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=03wonMi6/ThM2gO3QCZn24JsXK7jMYiMUg0Bft7Hcig=; b=ZMWgyG99Sv+vLRN4Vm+Dn4UfjVkdg84B8LuZZslz5vFnCI/7I+KoFx/20W1zb19fZG 0IlHF1/9RIuR3HDng6cTRUxk1lQUj6cR3xGsCVfxv2TCxOVV0R9DfKVzImv7YVY2zoni Y5kneEt4rUvM8Cjzh03wfg41KrhsF3qs3SBFB9N8HT51nge3mMWrtLjUzBx3KmVIh1DR AOoMpiGFERjex1yrfRXGr4eaS2Pw/c3xAVvwqGS1s16YjnQLNw13C1Eaok4SNkIRBAYx aQGzsQ3tr63yLmsPooVgVrjYMLyPHDhAZ7fOkyhv7mlnnoj4zS2z62esskSbDNtBL5Ab oqdA== X-Gm-Message-State: AOJu0YwvjNbrhWAIW32z8LdxVsO4BcRWhNh+68/ogLkOJW2QcqZYaP1B 2Y/xfqnMiqOnQSDCCjfuiwY= X-Google-Smtp-Source: AGHT+IHEXCiKhc3oIX7bfHnHDv4+GrDV+EmGNkZQq6BamuJtr7wYxNTmW7a5qF0Rt8heIN6J/MZhxw== X-Received: by 2002:a5d:6605:0:b0:332:e31b:1f3 with SMTP id n5-20020a5d6605000000b00332e31b01f3mr3398583wru.31.1700872519970; Fri, 24 Nov 2023 16:35:19 -0800 (PST) Received: from localhost.localdomain (93-34-89-13.ip49.fastwebnet.it. [93.34.89.13]) by smtp.googlemail.com with ESMTPSA id u13-20020a05600c00cd00b00405718cbeadsm4268005wmm.1.2023.11.24.16.35.18 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 24 Nov 2023 16:35:19 -0800 (PST) From: Christian Marangi To: "David S. Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Andy Gross , Bjorn Andersson , Konrad Dybcio , Andrew Lunn , Heiner Kallweit , Russell King , Florian Fainelli , Broadcom internal kernel review list , Daniel Golle , Qingfang Deng , SkyLake Huang , Matthias Brugger , AngeloGioacchino Del Regno , Vladimir Oltean , David Epping , Harini Katakam , Christian Marangi , "Russell King (Oracle)" , Robert Marko , netdev@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-arm-msm@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-mediatek@lists.infradead.org Subject: [net-next RFC PATCH v2 02/11] dt-bindings: net: document ethernet PHY package nodes Date: Sat, 25 Nov 2023 01:11:18 +0100 Message-Id: <20231125001127.5674-3-ansuelsmth@gmail.com> X-Mailer: git-send-email 2.40.1 In-Reply-To: <20231125001127.5674-1-ansuelsmth@gmail.com> References: <20231125001127.5674-1-ansuelsmth@gmail.com> Precedence: bulk X-Mailing-List: devicetree@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Document ethernet PHY package nodes used to describe PHY shipped in bundle of 4-5 PHY. These particular PHY require specific PHY in the package for global onfiguration of the PHY package. Example are PHY package that have some regs only in one PHY of the package and will affect every other PHY in the package, for example related to PHY interface mode calibration or global PHY mode selection. The PHY package node MUST declare the base address used by the PHY driver for global configuration by calculating the offsets of the global PHY based on the base address of the PHY package. Signed-off-by: Christian Marangi --- .../bindings/net/ethernet-phy-package.yaml | 66 +++++++++++++++++++ 1 file changed, 66 insertions(+) create mode 100644 Documentation/devicetree/bindings/net/ethernet-phy-package.yaml diff --git a/Documentation/devicetree/bindings/net/ethernet-phy-package.yaml b/Documentation/devicetree/bindings/net/ethernet-phy-package.yaml new file mode 100644 index 000000000000..943952749b40 --- /dev/null +++ b/Documentation/devicetree/bindings/net/ethernet-phy-package.yaml @@ -0,0 +1,66 @@ +# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/net/ethernet-phy-package.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Ethernet PHY Package Common Properties + +maintainers: + - Christian Marangi ; + #size-cells = <0>; + + ethernet-phy-package@0 { + #address-cells = <1>; + #size-cells = <0>; + reg = <0>; + + ethernet-phy@0 { + compatible = "ethernet-phy-ieee802.3-c22"; + reg = <0>; + }; + + phy4: ethernet-phy@4 { + compatible = "ethernet-phy-ieee802.3-c22"; + reg = <4>; + }; + }; + }; From patchwork Sat Nov 25 00:11:19 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Christian Marangi X-Patchwork-Id: 747292 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="hKJaLDcd" Received: from mail-wm1-x335.google.com (mail-wm1-x335.google.com [IPv6:2a00:1450:4864:20::335]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 58E7F19A9; Fri, 24 Nov 2023 16:35:23 -0800 (PST) Received: by mail-wm1-x335.google.com with SMTP id 5b1f17b1804b1-40b2fa4ec5eso17076005e9.2; Fri, 24 Nov 2023 16:35:23 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1700872522; x=1701477322; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:from:to:cc:subject:date:message-id :reply-to; bh=gQgR2jfnMMv7W0Th4DaHjvErxX4R3n2xwaVlAKSCuVc=; b=hKJaLDcdC/Hchv7KT15V61pOi0vm2qw6+lyhyh93xtWzv2ouLWSv4OU6rAEGRv1Fvr 2WJSo5sGuf5gH1nRRj9uawzkHS4nX3JszwXOXcNB1DRoj8LAor89eiEetUbGttJOhZdp tiz2RSe7WOoZRROboS6jO4PI8TykeLmEq+BeAKdKz9is/vbcYe0xe/EnfeMYTgfQXGoQ DVpHvNkfe0By89IphLPwhQI4XkLYiFu0qfRuxhrgf1sYxIux3HlToLHM41LUTDnkrQ6C nzSzBQu9B7EEUd8vg6xvv8bvAFrs4cZFSfbEKx+IpAXwbSjCXIZWtx8ulVU/OlYqH1BR zQgw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1700872522; x=1701477322; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=gQgR2jfnMMv7W0Th4DaHjvErxX4R3n2xwaVlAKSCuVc=; b=CjnY7sGL575lN+SLLf/bUgvFmi0zJwcCEI++NQ7WcR/Hys29pTCu1LrjamaFYcWcFd EZVy9dWS3OLglH2pLEeyjB/vosLUMTDNt2c8AEti8TsuHXCpFu7Ywp5TUvLiMCmXWe3z Ln6iqdjZwqCDeXRhpp0Z9BhLGm8vr/3q8Pr5zkxpTHIJQdi8DudXz7xTaQ9qrcx8GtIE hpNO/x7h9EF/bhCHgtdSor4qZEoLo5qoy0treEpAyRw4cKhKeiz6eAoKhU2G4xR5pkCl W3F6ChuyqK4FImoytHscee55J/L/5ZV4X5t/Lu1Gi6iZELL0RXW8tOW7cIPtJj3hcVDC xTkg== X-Gm-Message-State: AOJu0YwKthP4u0QA4d7Kw0umhdhmw+3ZwcZs8GsSU3Bp7ENKgzC8ZR+v YhwSGvLD1jJ3/AqJS1kOzd4= X-Google-Smtp-Source: AGHT+IH3Zuh20XPlulV/zgygp478aT9a7n7dkKQ/OgX1HZ9p0rkGGUQdnV7P6HuGLrzXJMq+ZhH6EA== X-Received: by 2002:a05:600c:1ca5:b0:40b:3e7e:af56 with SMTP id k37-20020a05600c1ca500b0040b3e7eaf56mr901531wms.26.1700872521507; Fri, 24 Nov 2023 16:35:21 -0800 (PST) Received: from localhost.localdomain (93-34-89-13.ip49.fastwebnet.it. [93.34.89.13]) by smtp.googlemail.com with ESMTPSA id u13-20020a05600c00cd00b00405718cbeadsm4268005wmm.1.2023.11.24.16.35.20 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 24 Nov 2023 16:35:21 -0800 (PST) From: Christian Marangi To: "David S. Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Andy Gross , Bjorn Andersson , Konrad Dybcio , Andrew Lunn , Heiner Kallweit , Russell King , Florian Fainelli , Broadcom internal kernel review list , Daniel Golle , Qingfang Deng , SkyLake Huang , Matthias Brugger , AngeloGioacchino Del Regno , Vladimir Oltean , David Epping , Harini Katakam , Christian Marangi , "Russell King (Oracle)" , Robert Marko , netdev@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-arm-msm@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-mediatek@lists.infradead.org Subject: [net-next RFC PATCH v2 03/11] net: phy: add initial support for PHY package in DT Date: Sat, 25 Nov 2023 01:11:19 +0100 Message-Id: <20231125001127.5674-4-ansuelsmth@gmail.com> X-Mailer: git-send-email 2.40.1 In-Reply-To: <20231125001127.5674-1-ansuelsmth@gmail.com> References: <20231125001127.5674-1-ansuelsmth@gmail.com> Precedence: bulk X-Mailing-List: devicetree@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Add initial support for PHY package in DT. Make it easier to define PHY package and describe the global PHY directly in DT by refereincing them by phandles instead of custom functions in each PHY driver. Each PHY in a package needs to be defined in a dedicated node in the mdio node. This dedicated node needs to have the node name with the prefix "ethernet-phy-package". With this defined, the generic PHY probe will join each PHY in this dedicated node to the package. PHY driver MUST set the required global PHY count in .phy_package_global_phy_num and define .phy_package_global_phys_offset as the table of offset of the required global PHYs for PHY package global configuration. mdio_bus.c and of_mdio.c is updated to now support and parse also PHY package subnote by checking if the node name have the prefix "ethernet-phy-package". Signed-off-by: Christian Marangi --- drivers/net/mdio/of_mdio.c | 68 +++++++++++++++++++++++++----------- drivers/net/phy/mdio_bus.c | 35 ++++++++++++++----- drivers/net/phy/phy_device.c | 61 ++++++++++++++++++++++++++++++++ include/linux/phy.h | 9 +++++ 4 files changed, 144 insertions(+), 29 deletions(-) diff --git a/drivers/net/mdio/of_mdio.c b/drivers/net/mdio/of_mdio.c index 64ebcb6d235c..de2ebb59d2d2 100644 --- a/drivers/net/mdio/of_mdio.c +++ b/drivers/net/mdio/of_mdio.c @@ -139,6 +139,47 @@ bool of_mdiobus_child_is_phy(struct device_node *child) } EXPORT_SYMBOL(of_mdiobus_child_is_phy); +static int __of_mdiobus_parse_phys(struct mii_bus *mdio, struct device_node *np, + bool *scanphys) +{ + struct device_node *child; + int addr, rc = 0; + + /* Loop over the child nodes and register a phy_device for each phy */ + for_each_available_child_of_node(np, child) { + if (of_node_name_prefix(child, "ethernet-phy-package")) { + rc = __of_mdiobus_parse_phys(mdio, child, scanphys); + if (rc && rc != -ENODEV) + goto exit; + + continue; + } + + addr = of_mdio_parse_addr(&mdio->dev, child); + if (addr < 0) { + *scanphys = true; + continue; + } + + if (of_mdiobus_child_is_phy(child)) + rc = of_mdiobus_register_phy(mdio, child, addr); + else + rc = of_mdiobus_register_device(mdio, child, addr); + + if (rc == -ENODEV) + dev_err(&mdio->dev, + "MDIO device at address %d is missing.\n", + addr); + else if (rc) + goto exit; + } + + return 0; +exit: + of_node_put(child); + return rc; +} + /** * __of_mdiobus_register - Register mii_bus and create PHYs from the device tree * @mdio: pointer to mii_bus structure @@ -180,25 +221,9 @@ int __of_mdiobus_register(struct mii_bus *mdio, struct device_node *np, return rc; /* Loop over the child nodes and register a phy_device for each phy */ - for_each_available_child_of_node(np, child) { - addr = of_mdio_parse_addr(&mdio->dev, child); - if (addr < 0) { - scanphys = true; - continue; - } - - if (of_mdiobus_child_is_phy(child)) - rc = of_mdiobus_register_phy(mdio, child, addr); - else - rc = of_mdiobus_register_device(mdio, child, addr); - - if (rc == -ENODEV) - dev_err(&mdio->dev, - "MDIO device at address %d is missing.\n", - addr); - else if (rc) - goto unregister; - } + rc = __of_mdiobus_parse_phys(mdio, np, &scanphys); + if (rc) + goto unregister; if (!scanphys) return 0; @@ -227,15 +252,16 @@ int __of_mdiobus_register(struct mii_bus *mdio, struct device_node *np, if (!rc) break; if (rc != -ENODEV) - goto unregister; + goto put_unregister; } } } return 0; -unregister: +put_unregister: of_node_put(child); +unregister: mdiobus_unregister(mdio); return rc; } diff --git a/drivers/net/phy/mdio_bus.c b/drivers/net/phy/mdio_bus.c index 25dcaa49ab8b..5ba43d593c6b 100644 --- a/drivers/net/phy/mdio_bus.c +++ b/drivers/net/phy/mdio_bus.c @@ -455,19 +455,25 @@ EXPORT_SYMBOL(of_mdio_find_bus); * found, set the of_node pointer for the mdio device. This allows * auto-probed phy devices to be supplied with information passed in * via DT. + * If a PHY package is found, PHY is searched also there. */ -static void of_mdiobus_link_mdiodev(struct mii_bus *bus, - struct mdio_device *mdiodev) +static int of_mdiobus_find_phy(struct device *dev, struct mdio_device *mdiodev, + struct device_node *np) { - struct device *dev = &mdiodev->dev; struct device_node *child; - if (dev->of_node || !bus->dev.of_node) - return; - - for_each_available_child_of_node(bus->dev.of_node, child) { + for_each_available_child_of_node(np, child) { int addr; + if (of_node_name_prefix(child, "ethernet-phy-package")) { + if (!of_mdiobus_find_phy(dev, mdiodev, child)) { + of_node_put(child); + return 0; + } + + continue; + } + addr = of_mdio_parse_addr(dev, child); if (addr < 0) continue; @@ -477,9 +483,22 @@ static void of_mdiobus_link_mdiodev(struct mii_bus *bus, /* The refcount on "child" is passed to the mdio * device. Do _not_ use of_node_put(child) here. */ - return; + return 0; } } + + return -ENODEV; +} + +static void of_mdiobus_link_mdiodev(struct mii_bus *bus, + struct mdio_device *mdiodev) +{ + struct device *dev = &mdiodev->dev; + + if (dev->of_node || !bus->dev.of_node) + return; + + of_mdiobus_find_phy(dev, mdiodev, bus->dev.of_node); } #else /* !IS_ENABLED(CONFIG_OF_MDIO) */ static inline void of_mdiobus_link_mdiodev(struct mii_bus *mdio, diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c index e016dbfb0d27..f25bedb69b90 100644 --- a/drivers/net/phy/phy_device.c +++ b/drivers/net/phy/phy_device.c @@ -3193,6 +3193,62 @@ static int of_phy_leds(struct phy_device *phydev) return 0; } +static int of_phy_package(struct phy_device *phydev) +{ + struct device_node *node = phydev->mdio.dev.of_node; + struct device_node *package_node; + const u8 *global_phys_offset; + int *global_phys_addr; + u8 global_phys_num; + u32 base_addr; + int i, ret; + + if (!node) + return 0; + + package_node = of_get_parent(node); + if (!package_node) + return 0; + + if (!of_node_name_prefix(package_node, "ethernet-phy-package")) + return 0; + + if (of_property_read_u32(package_node, "reg", &base_addr)) + return -EINVAL; + + global_phys_num = phydev->drv->phy_package_global_phys_num; + global_phys_offset = phydev->drv->phy_package_global_phys_offset; + if (!global_phys_num || !global_phys_offset) + return -EINVAL; + + global_phys_addr = kmalloc_array(global_phys_num, sizeof(*global_phys_addr), + GFP_KERNEL); + if (!global_phys_addr) + return -ENOMEM; + + for (i = 0; i < global_phys_num; i++) { + int addr = base_addr + global_phys_offset[i]; + + /* Make sure the calculated address is valid */ + if (unlikely(addr >= PHY_MAX_ADDR)) + return -EINVAL; + + global_phys_addr[i] = addr; + } + + ret = devm_phy_package_join(&phydev->mdio.dev, phydev, global_phys_addr, + global_phys_num, 0); + if (ret) + goto exit; + + phydev->shared->np = package_node; + +exit: + kfree(global_phys_addr); + + return ret; +} + /** * fwnode_mdio_find_device - Given a fwnode, find the mdio_device * @fwnode: pointer to the mdio_device's fwnode @@ -3301,6 +3357,11 @@ static int phy_probe(struct device *dev) if (phydrv->flags & PHY_IS_INTERNAL) phydev->is_internal = true; + /* Parse DT to detect PHY package and join them */ + err = of_phy_package(phydev); + if (err) + goto out; + /* Deassert the reset signal */ phy_device_reset(phydev, 0); diff --git a/include/linux/phy.h b/include/linux/phy.h index c2bb3f0b9dda..3f75ae85b740 100644 --- a/include/linux/phy.h +++ b/include/linux/phy.h @@ -327,6 +327,7 @@ struct mdio_bus_stats { /** * struct phy_package_shared - Shared information in PHY packages + * @np: Pointer to the Device Node if PHY package defined in DT * @addrs: List of common PHY addresses used to combine PHYs in one package * @addrs_num: Number of common PHY addresses in addrs list * @refcnt: Number of PHYs connected to this shared data @@ -339,6 +340,8 @@ struct mdio_bus_stats { * phy_package_leave(). */ struct phy_package_shared { + /* With PHY package defined in DT this points to the PHY package node */ + struct device_node *np; /* addrs list pointer */ /* note that this pointer is shared between different phydevs. * It is allocated and freed automatically by phy_package_join() and @@ -888,6 +891,10 @@ struct phy_led { * @flags: A bitfield defining certain other features this PHY * supports (like interrupts) * @driver_data: Static driver data + * @phy_package_global_phys_offset: Table of offset of the required + * global PHYs for PHY package global configuration. + * @phy_package_global_phys_num: Num of the required global PHYs + * for PHY package global configuration. * * All functions are optional. If config_aneg or read_status * are not implemented, the phy core uses the genphy versions. @@ -905,6 +912,8 @@ struct phy_driver { const unsigned long * const features; u32 flags; const void *driver_data; + const u8 *phy_package_global_phys_offset; + const u8 phy_package_global_phys_num; /** * @soft_reset: Called to issue a PHY software reset From patchwork Sat Nov 25 00:11:22 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Christian Marangi X-Patchwork-Id: 747291 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="STS20KIn" Received: from mail-wm1-x329.google.com (mail-wm1-x329.google.com [IPv6:2a00:1450:4864:20::329]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 155CC19B7; Fri, 24 Nov 2023 16:35:28 -0800 (PST) Received: by mail-wm1-x329.google.com with SMTP id 5b1f17b1804b1-40b2c8e91afso18143695e9.3; Fri, 24 Nov 2023 16:35:28 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1700872526; x=1701477326; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:from:to:cc:subject:date:message-id :reply-to; bh=vcMwiWHz9qYe+Y9Zq1AR8weNzBMQy4Mg6NfLIwNy3q4=; b=STS20KInglK4T9aWAyYP67hUY3l26ecE5JPqDcazThMB4rEFMe2DhZNdgm7vBJ1S+K Cw0i6SAakB+wZeloCB2EFOTJkCC0i0xQarAJDsEAYQi/FLRiAPoTTfOEu2sNx334pd2y htMP6DjeBsISLZyGKr34xdtz7itI0PDC6+8FfzGcok+V7vDlcFL0YXWaBjU0zB9mA/iV r7/X3Tq52/VIFX5C2sigE4LW6vRw8U4il5hva9roAs+QozGmZyK8NxSAelKLorGk5RyC RI6Go0Tj+vytNKK9ndWyeuqW95NKARhjOjaZs2X/aOiA0i2PBhrXPrmPM6QX7GTPIaB5 Bv0w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1700872526; x=1701477326; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=vcMwiWHz9qYe+Y9Zq1AR8weNzBMQy4Mg6NfLIwNy3q4=; b=tMNmagI+fWhccbr0AcJVXFmiBkKdR61ubLXZxR+uO2MuAjDIKRPyT7QFIAXsnfAmSc 1AAylVLzFE6QtBuZneeFyAa3uuQBkcdBA1/mTzwGLRkJqaSFl/PC3xs/npt+QVe156on nPTRosw2hIdi+KVsSq24RHrTKAE1g3ch7OyGiU5AVvcTHRHfkC2SUt9faFB0Bl68ocqA mvLlgqYBdiPejFWgYw2ebd+Zrqbi3Ae9fzr6KXxwllxODX8rjgm0Hny4yvTHVTmTYlaZ pbSrCJzlgtMLuFQgQeEGfY4GgU30fQD1oAx7ERud0L1yyuLP3LuyTToWyibIjws++oug 7mTA== X-Gm-Message-State: AOJu0YwxtbEgEVKX0KUCZm5XJgF8KhRDlUbww1GRcLmBMZIgmiKXQfo1 Q8q4pvjo+HqRWffC65DTofY= X-Google-Smtp-Source: AGHT+IFXmHhNEQUs3v0Z74fnQ+w5I7liDT133TiEHE1H6er7Lzi3dwTa6E8rghUZEgwLREoIIGNEZw== X-Received: by 2002:a05:600c:314c:b0:405:95ae:4a94 with SMTP id h12-20020a05600c314c00b0040595ae4a94mr3259912wmo.5.1700872526488; Fri, 24 Nov 2023 16:35:26 -0800 (PST) Received: from localhost.localdomain (93-34-89-13.ip49.fastwebnet.it. [93.34.89.13]) by smtp.googlemail.com with ESMTPSA id u13-20020a05600c00cd00b00405718cbeadsm4268005wmm.1.2023.11.24.16.35.24 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 24 Nov 2023 16:35:26 -0800 (PST) From: Christian Marangi To: "David S. Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Andy Gross , Bjorn Andersson , Konrad Dybcio , Andrew Lunn , Heiner Kallweit , Russell King , Florian Fainelli , Broadcom internal kernel review list , Daniel Golle , Qingfang Deng , SkyLake Huang , Matthias Brugger , AngeloGioacchino Del Regno , Vladimir Oltean , David Epping , Harini Katakam , Christian Marangi , "Russell King (Oracle)" , Robert Marko , netdev@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-arm-msm@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-mediatek@lists.infradead.org Subject: [net-next RFC PATCH v2 06/11] net: phy: move mmd_phy_indirect to generic header Date: Sat, 25 Nov 2023 01:11:22 +0100 Message-Id: <20231125001127.5674-7-ansuelsmth@gmail.com> X-Mailer: git-send-email 2.40.1 In-Reply-To: <20231125001127.5674-1-ansuelsmth@gmail.com> References: <20231125001127.5674-1-ansuelsmth@gmail.com> Precedence: bulk X-Mailing-List: devicetree@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Move mmd_phy_indirect function from phy-core to generic phy.h to permit future usage for PHY package read/write_mmd. Signed-off-by: Christian Marangi --- drivers/net/phy/phy-core.c | 14 -------------- include/linux/phy.h | 14 ++++++++++++++ 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/drivers/net/phy/phy-core.c b/drivers/net/phy/phy-core.c index 966c93cbe616..b4f80847eefd 100644 --- a/drivers/net/phy/phy-core.c +++ b/drivers/net/phy/phy-core.c @@ -526,20 +526,6 @@ int phy_speed_down_core(struct phy_device *phydev) return 0; } -static void mmd_phy_indirect(struct mii_bus *bus, int phy_addr, int devad, - u16 regnum) -{ - /* Write the desired MMD Devad */ - __mdiobus_write(bus, phy_addr, MII_MMD_CTRL, devad); - - /* Write the desired MMD register address */ - __mdiobus_write(bus, phy_addr, MII_MMD_DATA, regnum); - - /* Select the Function : DATA with no post increment */ - __mdiobus_write(bus, phy_addr, MII_MMD_CTRL, - devad | MII_MMD_CTRL_NOINCR); -} - /** * __phy_read_mmd - Convenience function for reading a register * from an MMD on a given PHY. diff --git a/include/linux/phy.h b/include/linux/phy.h index 677b5bceac45..0f3b21c90583 100644 --- a/include/linux/phy.h +++ b/include/linux/phy.h @@ -1356,6 +1356,20 @@ static inline int __phy_modify_changed(struct phy_device *phydev, u32 regnum, regnum, mask, set); } +static inline void mmd_phy_indirect(struct mii_bus *bus, int phy_addr, int devad, + u16 regnum) +{ + /* Write the desired MMD Devad */ + __mdiobus_write(bus, phy_addr, MII_MMD_CTRL, devad); + + /* Write the desired MMD register address */ + __mdiobus_write(bus, phy_addr, MII_MMD_DATA, regnum); + + /* Select the Function : DATA with no post increment */ + __mdiobus_write(bus, phy_addr, MII_MMD_CTRL, + devad | MII_MMD_CTRL_NOINCR); +} + /* * phy_read_mmd - Convenience function for reading a register * from an MMD on a given PHY. From patchwork Sat Nov 25 00:11:23 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Christian Marangi X-Patchwork-Id: 747290 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="LUsvjnkm" Received: from mail-wm1-x332.google.com (mail-wm1-x332.google.com [IPv6:2a00:1450:4864:20::332]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 8BA7D1BC1; Fri, 24 Nov 2023 16:35:29 -0800 (PST) Received: by mail-wm1-x332.google.com with SMTP id 5b1f17b1804b1-40b27726369so17263385e9.0; Fri, 24 Nov 2023 16:35:29 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1700872528; x=1701477328; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:from:to:cc:subject:date:message-id :reply-to; bh=s7OVOcGHUcPnU+8BUU2tjf4Y7gvtOJAy7pXlV7RvF1I=; b=LUsvjnkmu78VqrV5G5vv9wqZBp8i1oOkR0zd9XjcmO5PsWVzK7n7NPb8D8DR+D2X4T yv7Oz6LjoyFYxkS9N5uNJVu9Xft6tUsvxZzXNouB2T1Sr8d2ee+H9o6V75HitxYj8a0a T17LOHwQjGrQr3qF1jSUzlpyahaYDg7ephknuyK/lUmo10jcGhSW6CzyPMb4xugsRk8d x3AawqgqbsBzghjTrwpAUDRargf5vq3xf1b3IoelqOSbty8ulh8VHNZPy1OEH2YXC4BE Jm3MoJfZOlFIMJUBT7LcMjSj3lFjurcC2Y2jCHCHbQkrWejcBi2jinrRVsiOfk/Z9XWI CVvQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1700872528; x=1701477328; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=s7OVOcGHUcPnU+8BUU2tjf4Y7gvtOJAy7pXlV7RvF1I=; b=gao/7ZSK7eP7zMjoJOt9sjkuhFeS/IQDjibomW3v/uai1bHqaFbxcjVpSSTRP+/ii+ qWUMMqZBpu6Zk+BpquZNB4nF+zAH1xX1JB6Ytupq6SL8G/s+DILxirKFpsC5SIdxytXr aW4vso4QJw+yPJGJ+m0fRp6FoZOgy+4Imkw9DuEGsklr0a4DjQwwHCV0VWVQaW4vf2Gz 2rcQB07wSNCDGnYCfJeAb/zAljZvVmBuCT1iK4t2EPJWLMsNmW/ta5GjCBjamulPsSvm CSwcq5Q7zJ0mv8ZRiRWO2b2mxG0ZRnW14eMUYA0j9VVVfwPp+RpN/46ehc/EkgF3TRWu jVCQ== X-Gm-Message-State: AOJu0YyMhsPemQH4PRjJFyU0nyb0JB4JZe8a0WL8dx/ioUWHYjukmH8I AeE5ICoAPH0b2aWq9HwlaCk= X-Google-Smtp-Source: AGHT+IGcE1dOF2/4XmII3D8k9pAOirkX3JthCM23UGSAVeigejq1ME7yX5mhXBajq2F60t3CrBZvGg== X-Received: by 2002:a05:600c:3b16:b0:3fe:ba7:f200 with SMTP id m22-20020a05600c3b1600b003fe0ba7f200mr3564351wms.20.1700872527977; Fri, 24 Nov 2023 16:35:27 -0800 (PST) Received: from localhost.localdomain (93-34-89-13.ip49.fastwebnet.it. [93.34.89.13]) by smtp.googlemail.com with ESMTPSA id u13-20020a05600c00cd00b00405718cbeadsm4268005wmm.1.2023.11.24.16.35.26 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 24 Nov 2023 16:35:27 -0800 (PST) From: Christian Marangi To: "David S. Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Andy Gross , Bjorn Andersson , Konrad Dybcio , Andrew Lunn , Heiner Kallweit , Russell King , Florian Fainelli , Broadcom internal kernel review list , Daniel Golle , Qingfang Deng , SkyLake Huang , Matthias Brugger , AngeloGioacchino Del Regno , Vladimir Oltean , David Epping , Harini Katakam , Christian Marangi , "Russell King (Oracle)" , Robert Marko , netdev@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-arm-msm@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-mediatek@lists.infradead.org Subject: [net-next RFC PATCH v2 07/11] net: phy: add support for PHY package MMD read/write Date: Sat, 25 Nov 2023 01:11:23 +0100 Message-Id: <20231125001127.5674-8-ansuelsmth@gmail.com> X-Mailer: git-send-email 2.40.1 In-Reply-To: <20231125001127.5674-1-ansuelsmth@gmail.com> References: <20231125001127.5674-1-ansuelsmth@gmail.com> Precedence: bulk X-Mailing-List: devicetree@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Some PHY in PHY package may require to read/write MMD regs to correctly configure the PHY package. Add support for these additional required function in both lock and no lock variant. Signed-off-by: Christian Marangi --- include/linux/phy.h | 72 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 72 insertions(+) diff --git a/include/linux/phy.h b/include/linux/phy.h index 0f3b21c90583..4c5856d9865d 100644 --- a/include/linux/phy.h +++ b/include/linux/phy.h @@ -2104,6 +2104,78 @@ static inline int __phy_package_write(struct phy_device *phydev, return __mdiobus_write(phydev->mdio.bus, addr, regnum, val); } +static inline int phy_package_read_mmd(struct phy_device *phydev, + int global_phy_index, int devad, u32 regnum) +{ + struct phy_package_shared *shared = phydev->shared; + struct mii_bus *bus = phydev->mdio.bus; + int addr, val; + + if (!shared || global_phy_index > shared->addrs_num - 1) + return -EIO; + + addr = shared->addrs[global_phy_index]; + + phy_lock_mdio_bus(phydev); + mmd_phy_indirect(bus, addr, devad, regnum); + val = __mdiobus_read(bus, addr, MII_MMD_DATA); + phy_unlock_mdio_bus(phydev); + + return val; +} + +static inline int __phy_package_read_mmd(struct phy_device *phydev, + int global_phy_index, int devad, u32 regnum) +{ + struct phy_package_shared *shared = phydev->shared; + struct mii_bus *bus = phydev->mdio.bus; + int addr; + + if (!shared || global_phy_index > shared->addrs_num - 1) + return -EIO; + + addr = shared->addrs[global_phy_index]; + mmd_phy_indirect(bus, addr, devad, regnum); + return __mdiobus_read(bus, addr, MII_MMD_DATA); +} + +static inline int phy_package_write_mmd(struct phy_device *phydev, + int global_phy_index, int devad, + u32 regnum, u16 val) +{ + struct phy_package_shared *shared = phydev->shared; + struct mii_bus *bus = phydev->mdio.bus; + int addr, ret; + + if (!shared || global_phy_index > shared->addrs_num - 1) + return -EIO; + + addr = shared->addrs[global_phy_index]; + + phy_lock_mdio_bus(phydev); + mmd_phy_indirect(bus, addr, devad, regnum); + ret = __mdiobus_write(bus, addr, MII_MMD_DATA, val); + phy_unlock_mdio_bus(phydev); + + return ret; +} + +static inline int __phy_package_write_mmd(struct phy_device *phydev, + int global_phy_index, int devad, + u32 regnum, u16 val) +{ + struct phy_package_shared *shared = phydev->shared; + struct mii_bus *bus = phydev->mdio.bus; + int addr; + + if (!shared || global_phy_index > shared->addrs_num - 1) + return -EIO; + + addr = shared->addrs[global_phy_index]; + mmd_phy_indirect(bus, addr, devad, regnum); + return __mdiobus_write(bus, addr, MII_MMD_DATA, val); +} + static inline bool __phy_package_set_once(struct phy_device *phydev, unsigned int b) { From patchwork Sat Nov 25 00:11:25 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Christian Marangi X-Patchwork-Id: 747289 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="MYNoJ++W" Received: from mail-wm1-x335.google.com (mail-wm1-x335.google.com [IPv6:2a00:1450:4864:20::335]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id E253F1BD6; Fri, 24 Nov 2023 16:35:32 -0800 (PST) Received: by mail-wm1-x335.google.com with SMTP id 5b1f17b1804b1-40b27726369so17263825e9.0; Fri, 24 Nov 2023 16:35:32 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1700872531; x=1701477331; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:from:to:cc:subject:date:message-id :reply-to; bh=MHiLFw1bIGohpGtROyp7CqLCgHPbQhHjoTE9dyN6vFM=; b=MYNoJ++WjyUQR7oZbprPpd/W1kjoOypyR9uH45lgCFTzi8SQn8ORZEswL+5aXmm0YU HYgj1rAMAVESk06onBC66hcftf4FzUAfYa1Wn5t0DT3Q8Ahs5qIR0uHPGMWo5M0tk18+ gcoGszax6yWD5xsegyn9jd3F835O4D1T71iDh4woahYsrxadYdRp7RdN4P6FpX2Xl+zH 9kJQ32xjrqoEeUzYpa4Wr7oLnadKyk7mbJaxmJls0H2vdTO6OI/jsjuLlF+tfHblXozN BT2+Xpn/bEwt1PXbOAzN4roL/372ceqQvgPHkysLmigGuy3ZwrqdHqdnMQPlGfYnrrxF KRaQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1700872531; x=1701477331; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=MHiLFw1bIGohpGtROyp7CqLCgHPbQhHjoTE9dyN6vFM=; b=GqCbhCC3OYeKSRmbu6RWKsfev7ffNkNqc+CJ8sMoo9OE89697BovB540sZ/lPJeDyl kUgG5ybSK+VAgfBWckzBJYMzqhg1sgchWAqHV3EFCvWflvNmzwDnTCngGAhyf3Nke/og TsaY919vRP9tk8XLo2ZTH4IJFVO4lxOlgR4qNhP7UcVBijJZtkTIQ/i3hs+9fP2GHOwA 2JnudrjQBP6jSDwykWzR8Sg1Q0v/GSYu49gW98vmyeacwXUCuKYEoNSdMStJvuQ487QH oqs2SsN6ZVt399VOVKlO9Q5NqdIV1+841UWob5sXX5JG9pIoALMzIkAyr2MjtJjKNMOX fQKg== X-Gm-Message-State: AOJu0YyieQ+9hMfPNbaTTiNw0GRts3VB2DYqpeqFpC7l6HxpfmL/89AG yxtKf+CpsW74QjIniNTsrs4= X-Google-Smtp-Source: AGHT+IGLc1mlt385WXqXvC6FEasxlmbyfmfpQzHK0GhuUqCYjrLEyySLW33U0gTDlILd7OygLIsynA== X-Received: by 2002:a05:600c:5252:b0:40b:36e7:1edf with SMTP id fc18-20020a05600c525200b0040b36e71edfmr3919226wmb.26.1700872531054; Fri, 24 Nov 2023 16:35:31 -0800 (PST) Received: from localhost.localdomain (93-34-89-13.ip49.fastwebnet.it. [93.34.89.13]) by smtp.googlemail.com with ESMTPSA id u13-20020a05600c00cd00b00405718cbeadsm4268005wmm.1.2023.11.24.16.35.29 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 24 Nov 2023 16:35:30 -0800 (PST) From: Christian Marangi To: "David S. Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Andy Gross , Bjorn Andersson , Konrad Dybcio , Andrew Lunn , Heiner Kallweit , Russell King , Florian Fainelli , Broadcom internal kernel review list , Daniel Golle , Qingfang Deng , SkyLake Huang , Matthias Brugger , AngeloGioacchino Del Regno , Vladimir Oltean , David Epping , Harini Katakam , Christian Marangi , "Russell King (Oracle)" , Robert Marko , netdev@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-arm-msm@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-mediatek@lists.infradead.org Subject: [net-next RFC PATCH v2 09/11] dt-bindings: net: Document Qcom QCA807x PHY package Date: Sat, 25 Nov 2023 01:11:25 +0100 Message-Id: <20231125001127.5674-10-ansuelsmth@gmail.com> X-Mailer: git-send-email 2.40.1 In-Reply-To: <20231125001127.5674-1-ansuelsmth@gmail.com> References: <20231125001127.5674-1-ansuelsmth@gmail.com> Precedence: bulk X-Mailing-List: devicetree@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Document Qcom QCA807x PHY package. Qualcomm QCA807X Ethernet PHY is PHY package of 2 or 5 IEEE 802.3 clause 22 compliant 10BASE-Te, 100BASE-TX and 1000BASE-T PHY-s. Document the required property to make the PHY package correctly configure and work. Signed-off-by: Christian Marangi --- .../devicetree/bindings/net/qcom,qca807x.yaml | 148 ++++++++++++++++++ 1 file changed, 148 insertions(+) create mode 100644 Documentation/devicetree/bindings/net/qcom,qca807x.yaml diff --git a/Documentation/devicetree/bindings/net/qcom,qca807x.yaml b/Documentation/devicetree/bindings/net/qcom,qca807x.yaml new file mode 100644 index 000000000000..f6f07c77a639 --- /dev/null +++ b/Documentation/devicetree/bindings/net/qcom,qca807x.yaml @@ -0,0 +1,148 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/net/qcom,qca807x.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Qualcomm QCA807X Ethernet PHY + +maintainers: + - Christian Marangi + - Robert Marko + +description: | + Qualcomm QCA807X Ethernet PHY is PHY package of 2 or 5 + IEEE 802.3 clause 22 compliant 10BASE-Te, 100BASE-TX and + 1000BASE-T PHY-s. + + They feature 2 SerDes, one for PSGMII or QSGMII connection with + MAC, while second one is SGMII for connection to MAC or fiber. + + Both models have a combo port that supports 1000BASE-X and + 100BASE-FX fiber. + + Each PHY inside of QCA807x series has 4 digitally controlled + output only pins that natively drive LED-s for up to 2 attached + LEDs. Some vendor also use these 4 output for GPIO usage without + attaching LEDs. + + Note that output pins can be set to drive LEDs OR GPIO, mixed + definition are not accepted. + +allOf: + - $ref: ethernet-phy-package.yaml# + +select: + properties: + $nodename: + pattern: "^ethernet-phy-package(@[a-f0-9]+)?$" + + patternProperties: + ^ethernet-phy(@[a-f0-9]+)?$: + properties: + compatible: + contains: + enum: + - ethernet-phy-id004d.d0b2 + - ethernet-phy-id004d.d0b1 + + required: + - compatible + + required: + - $nodename + +properties: + qcom,package-mode: + enum: + - qsgmii + - psgmii + + qcom,tx-driver-strength: + enum: [140, 160, 180, 200, 220 + 240, 260, 280, 300, 320 + 400, 500, 600] + +patternProperties: + ^ethernet-phy(@[a-f0-9]+)?$: + $ref: /schemas/net/ethernet-phy.yaml# + + properties: + gpio-controller: + description: set the output lines as GPIO instead of LEDs + type: boolean + + '#gpio-cells': + description: number of GPIO cells for the PHY + const: 2 + + dependencies: + gpio-controller: ['#gpio-cells'] + + if: + required: + - gpio-controller + then: + properties: + leds: false + + unevaluatedProperties: false + +unevaluatedProperties: false + +examples: + - | + #include + + mdio { + #address-cells = <1>; + #size-cells = <0>; + + ethernet-phy-package@0 { + #address-cells = <1>; + #size-cells = <0>; + reg = <0>; + + qcom,package-mode = "qsgmii"; + + ethernet-phy@0 { + compatible = "ethernet-phy-id004d.d0b2"; + reg = <0>; + + leds { + #address-cells = <1>; + #size-cells = <0>; + + led@0 { + reg = <0>; + color = ; + function = LED_FUNCTION_LAN; + default-state = "keep"; + }; + }; + }; + + ethernet-phy@1 { + compatible = "ethernet-phy-id004d.d0b2"; + reg = <1>; + }; + + ethernet-phy@2 { + compatible = "ethernet-phy-id004d.d0b2"; + reg = <2>; + + gpio-controller; + #gpio-cells = <2>; + }; + + ethernet-phy@3 { + compatible = "ethernet-phy-id004d.d0b2"; + reg = <3>; + }; + + ethernet-phy@4 { + compatible = "ethernet-phy-id004d.d0b2"; + reg = <4>; + }; + }; + }; From patchwork Sat Nov 25 00:11:27 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Christian Marangi X-Patchwork-Id: 747288 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="W5slt0zm" Received: from mail-wm1-x334.google.com (mail-wm1-x334.google.com [IPv6:2a00:1450:4864:20::334]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 92A361BFD; Fri, 24 Nov 2023 16:35:36 -0800 (PST) Received: by mail-wm1-x334.google.com with SMTP id 5b1f17b1804b1-40b38a1351fso13698855e9.2; Fri, 24 Nov 2023 16:35:36 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1700872534; x=1701477334; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:from:to:cc:subject:date:message-id :reply-to; bh=CTazJ/w9K8X3w9qAb9l5X8/8R+7Ak4yLgq8b+fWLdDU=; b=W5slt0zmGi0fR4X6Fk77218VWJY1gwkN+tCbclC6slWbfneMd960vflHUtyo5lJZWd 8C7puKgoE9UVb8O2hoPKMsyCidSVXFEG5OLRV/4/Kuw5Od/rVnybE9jNYSYbZhoTSLDS ecw2kxTC5J0ENmw4++MaETk04BLtjjriZdqAUCkNOOWtxemfdvo3egd6D5SY6hTExsJO pdX7oi7iRuL0vx1re/PvVgwvCcFqcfbS21DrxJj2o1feYnFk/mwM4IPfeWAdy25DufJ+ o21HT1e3PN8x8F3SsaoJ/3G1FTMWUSyR+SjGo9OCkMVX1P3LHpdFg1ezXbr/UIXdEIta Xvjg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1700872534; x=1701477334; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=CTazJ/w9K8X3w9qAb9l5X8/8R+7Ak4yLgq8b+fWLdDU=; b=cVjQU1J0TYeUvJs2Cf+TqnBeKjFkpISQNbZwcYMBljVtk/IOwOX+UvVdJIIyAnRt7M sPTOXuq4CQkyxF6Q6EKaEbsGaXy8FJqREAFgq8ZyUk/K8/EPtKbcgMwEaewXNrN92S5c TuQF/pI0AmrtSJWQMWqIHTaEiXoVa8nxt+ZjjMXYTM4RJEQ0N1g2vcSs5oVtYQnyRsxa 18aT2qAiS44fqm9TPY4p6zxNjdwBzINUA7CrrUu66foniH8Q6ltnGvE2TY2rGf3+TUiL QYtddsZXCA1MeaTIdwE0+xxLiOII/wD2iK+LFf/P8HEYJXIPYLrNIC3EKpCEiXfpWWbY t9TA== X-Gm-Message-State: AOJu0YyRBHkfDOU9YiLO5pNTCBj5e6quFealoSQ4kjPEuSoszmlLlm0J SKSPGyjQwdprH9iuO7h8IcU= X-Google-Smtp-Source: AGHT+IHj1mBhj0yFQ1GkFw1sMHVrcbyqcUYZJTWYoTVUD3SDqWByru/762b9bYkEeomMfJ8SyTwoqg== X-Received: by 2002:a05:600c:4f16:b0:40b:3633:9380 with SMTP id l22-20020a05600c4f1600b0040b36339380mr3452926wmq.33.1700872534247; Fri, 24 Nov 2023 16:35:34 -0800 (PST) Received: from localhost.localdomain (93-34-89-13.ip49.fastwebnet.it. [93.34.89.13]) by smtp.googlemail.com with ESMTPSA id u13-20020a05600c00cd00b00405718cbeadsm4268005wmm.1.2023.11.24.16.35.32 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 24 Nov 2023 16:35:33 -0800 (PST) From: Christian Marangi To: "David S. Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Andy Gross , Bjorn Andersson , Konrad Dybcio , Andrew Lunn , Heiner Kallweit , Russell King , Florian Fainelli , Broadcom internal kernel review list , Daniel Golle , Qingfang Deng , SkyLake Huang , Matthias Brugger , AngeloGioacchino Del Regno , Vladimir Oltean , David Epping , Harini Katakam , Christian Marangi , "Russell King (Oracle)" , Robert Marko , netdev@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-arm-msm@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-mediatek@lists.infradead.org Subject: [net-next RFC PATCH v2 11/11] net: phy: qca807x: Add support for configurable LED Date: Sat, 25 Nov 2023 01:11:27 +0100 Message-Id: <20231125001127.5674-12-ansuelsmth@gmail.com> X-Mailer: git-send-email 2.40.1 In-Reply-To: <20231125001127.5674-1-ansuelsmth@gmail.com> References: <20231125001127.5674-1-ansuelsmth@gmail.com> Precedence: bulk X-Mailing-List: devicetree@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 QCA8072/5 have up to 2 LEDs attached for PHY. LEDs can be configured to be ON/hw blink or be set to HW control. Hw blink mode is set to blink at 4Hz or 250ms. PHY can support both copper (TP) or fiber (FIBRE) kind and supports different HW control modes based on the port type. HW control modes supported for netdev trigger for copper ports are: - LINK_10 - LINK_100 - LINK_1000 - TX - RX - FULL_DUPLEX - HALF_DUPLEX HW control modes supported for netdev trigger for fiber ports are: - LINK_100 - LINK_1000 - TX - RX - FULL_DUPLEX - HALF_DUPLEX LED support conflicts with GPIO controller feature and must be disabled if gpio-controller is used for the PHY. Signed-off-by: Christian Marangi --- drivers/net/phy/qca807x.c | 382 +++++++++++++++++++++++++++++++++++++- 1 file changed, 375 insertions(+), 7 deletions(-) diff --git a/drivers/net/phy/qca807x.c b/drivers/net/phy/qca807x.c index 6a1bad1b95c3..d1648f801ff3 100644 --- a/drivers/net/phy/qca807x.c +++ b/drivers/net/phy/qca807x.c @@ -79,17 +79,60 @@ #define QCA807X_MMD7_1000BASE_T_POWER_SAVE_PER_CABLE_LENGTH 0x801a #define QCA807X_CONTROL_DAC_MASK GENMASK(2, 0) +#define QCA807X_MMD7_LED_GLOBAL 0x8073 +#define QCA807X_LED_BLINK_1 GENMASK(11, 6) +#define QCA807X_LED_BLINK_2 GENMASK(5, 0) +/* Values are the same for both BLINK_1 and BLINK_2 */ +#define QCA807X_LED_BLINK_FREQ_MASK GENMASK(5, 3) +#define QCA807X_LED_BLINK_FREQ_2HZ FIELD_PREP(QCA807X_LED_BLINK_FREQ_MASK, 0x0) +#define QCA807X_LED_BLINK_FREQ_4HZ FIELD_PREP(QCA807X_LED_BLINK_FREQ_MASK, 0x1) +#define QCA807X_LED_BLINK_FREQ_8HZ FIELD_PREP(QCA807X_LED_BLINK_FREQ_MASK, 0x2) +#define QCA807X_LED_BLINK_FREQ_16HZ FIELD_PREP(QCA807X_LED_BLINK_FREQ_MASK, 0x3) +#define QCA807X_LED_BLINK_FREQ_32HZ FIELD_PREP(QCA807X_LED_BLINK_FREQ_MASK, 0x4) +#define QCA807X_LED_BLINK_FREQ_64HZ FIELD_PREP(QCA807X_LED_BLINK_FREQ_MASK, 0x5) +#define QCA807X_LED_BLINK_FREQ_128HZ FIELD_PREP(QCA807X_LED_BLINK_FREQ_MASK, 0x6) +#define QCA807X_LED_BLINK_FREQ_256HZ FIELD_PREP(QCA807X_LED_BLINK_FREQ_MASK, 0x7) +#define QCA807X_LED_BLINK_DUTY_MASK GENMASK(2, 0) +#define QCA807X_LED_BLINK_DUTY_50_50 FIELD_PREP(QCA807X_LED_BLINK_DUTY_MASK, 0x0) +#define QCA807X_LED_BLINK_DUTY_75_25 FIELD_PREP(QCA807X_LED_BLINK_DUTY_MASK, 0x1) +#define QCA807X_LED_BLINK_DUTY_25_75 FIELD_PREP(QCA807X_LED_BLINK_DUTY_MASK, 0x2) +#define QCA807X_LED_BLINK_DUTY_33_67 FIELD_PREP(QCA807X_LED_BLINK_DUTY_MASK, 0x3) +#define QCA807X_LED_BLINK_DUTY_67_33 FIELD_PREP(QCA807X_LED_BLINK_DUTY_MASK, 0x4) +#define QCA807X_LED_BLINK_DUTY_17_83 FIELD_PREP(QCA807X_LED_BLINK_DUTY_MASK, 0x5) +#define QCA807X_LED_BLINK_DUTY_83_17 FIELD_PREP(QCA807X_LED_BLINK_DUTY_MASK, 0x6) +#define QCA807X_LED_BLINK_DUTY_8_92 FIELD_PREP(QCA807X_LED_BLINK_DUTY_MASK, 0x7) #define QCA807X_MMD7_LED_100N_1 0x8074 #define QCA807X_MMD7_LED_100N_2 0x8075 #define QCA807X_MMD7_LED_1000N_1 0x8076 #define QCA807X_MMD7_LED_1000N_2 0x8077 -#define QCA807X_LED_TXACT_BLK_EN_2 BIT(10) -#define QCA807X_LED_RXACT_BLK_EN_2 BIT(9) -#define QCA807X_LED_GT_ON_EN_2 BIT(6) -#define QCA807X_LED_HT_ON_EN_2 BIT(5) -#define QCA807X_LED_BT_ON_EN_2 BIT(4) -#define QCA807X_GPIO_FORCE_EN BIT(15) -#define QCA807X_GPIO_FORCE_MODE_MASK GENMASK(14, 13) +/* Values are the same for LED1 and LED2 */ +/* Values for control 1 */ +#define QCA807X_LED_COPPER_ON_BLINK_MASK GENMASK(12, 0) +#define QCA807X_LED_FDX_ON_EN BIT(12) +#define QCA807X_LED_HDX_ON_EN BIT(11) +#define QCA807X_LED_TXACT_BLK_EN BIT(10) +#define QCA807X_LED_RXACT_BLK_EN BIT(9) +#define QCA807X_LED_GT_ON_EN BIT(6) +#define QCA807X_LED_HT_ON_EN BIT(5) +#define QCA807X_LED_BT_ON_EN BIT(4) +/* Values for control 2 */ +#define QCA807X_LED_FORCE_EN BIT(15) +#define QCA807X_LED_FORCE_MODE_MASK GENMASK(14, 13) +#define QCA807X_LED_FORCE_BLINK_1 FIELD_PREP(QCA807X_LED_FORCE_MODE_MASK, 0x3) +#define QCA807X_LED_FORCE_BLINK_2 FIELD_PREP(QCA807X_LED_FORCE_MODE_MASK, 0x2) +#define QCA807X_LED_FORCE_ON FIELD_PREP(QCA807X_LED_FORCE_MODE_MASK, 0x1) +#define QCA807X_LED_FORCE_OFF FIELD_PREP(QCA807X_LED_FORCE_MODE_MASK, 0x0) +#define QCA807X_LED_FIBER_ON_BLINK_MASK GENMASK(11, 1) +#define QCA807X_LED_FIBER_TXACT_BLK_EN BIT(10) +#define QCA807X_LED_FIBER_RXACT_BLK_EN BIT(9) +#define QCA807X_LED_FIBER_FDX_ON_EN BIT(6) +#define QCA807X_LED_FIBER_HDX_ON_EN BIT(5) +#define QCA807X_LED_FIBER_1000BX_ON_EN BIT(2) +#define QCA807X_LED_FIBER_100FX_ON_EN BIT(1) + +/* Some device repurpose the LED as GPIO out */ +#define QCA807X_GPIO_FORCE_EN QCA807X_LED_FORCE_EN +#define QCA807X_GPIO_FORCE_MODE_MASK QCA807X_LED_FORCE_MODE_MASK #define QCA807X_INTR_ENABLE 0x12 #define QCA807X_INTR_STATUS 0x13 @@ -357,6 +400,320 @@ static int qca807x_cable_test_start(struct phy_device *phydev) return ret; } +static int qca807x_led_parse_netdev(struct phy_device *phydev, unsigned long rules, + u16 *offload_trigger) +{ + /* Parsing specific to netdev trigger */ + switch (phydev->port) { + case PORT_TP: + if (test_bit(TRIGGER_NETDEV_TX, &rules)) + *offload_trigger |= QCA807X_LED_TXACT_BLK_EN; + if (test_bit(TRIGGER_NETDEV_RX, &rules)) + *offload_trigger |= QCA807X_LED_RXACT_BLK_EN; + if (test_bit(TRIGGER_NETDEV_LINK_10, &rules)) + *offload_trigger |= QCA807X_LED_BT_ON_EN; + if (test_bit(TRIGGER_NETDEV_LINK_100, &rules)) + *offload_trigger |= QCA807X_LED_HT_ON_EN; + if (test_bit(TRIGGER_NETDEV_LINK_1000, &rules)) + *offload_trigger |= QCA807X_LED_GT_ON_EN; + if (test_bit(TRIGGER_NETDEV_HALF_DUPLEX, &rules)) + *offload_trigger |= QCA807X_LED_HDX_ON_EN; + if (test_bit(TRIGGER_NETDEV_FULL_DUPLEX, &rules)) + *offload_trigger |= QCA807X_LED_FDX_ON_EN; + break; + case PORT_FIBRE: + if (test_bit(TRIGGER_NETDEV_TX, &rules)) + *offload_trigger |= QCA807X_LED_FIBER_TXACT_BLK_EN; + if (test_bit(TRIGGER_NETDEV_RX, &rules)) + *offload_trigger |= QCA807X_LED_FIBER_RXACT_BLK_EN; + if (test_bit(TRIGGER_NETDEV_LINK_100, &rules)) + *offload_trigger |= QCA807X_LED_FIBER_100FX_ON_EN; + if (test_bit(TRIGGER_NETDEV_LINK_1000, &rules)) + *offload_trigger |= QCA807X_LED_FIBER_1000BX_ON_EN; + if (test_bit(TRIGGER_NETDEV_HALF_DUPLEX, &rules)) + *offload_trigger |= QCA807X_LED_FIBER_HDX_ON_EN; + if (test_bit(TRIGGER_NETDEV_FULL_DUPLEX, &rules)) + *offload_trigger |= QCA807X_LED_FIBER_FDX_ON_EN; + break; + default: + return -EOPNOTSUPP; + } + + if (rules && !*offload_trigger) + return -EOPNOTSUPP; + + return 0; +} + +static int qca807x_led_hw_control_enable(struct phy_device *phydev, u8 index) +{ + int val, reg, ret; + + switch (index) { + case 0: + reg = QCA807X_MMD7_LED_100N_2; + break; + case 1: + reg = QCA807X_MMD7_LED_1000N_2; + break; + default: + return -EINVAL; + } + + val = phy_read_mmd(phydev, MDIO_MMD_AN, reg); + val &= ~QCA807X_LED_FORCE_EN; + ret = phy_write_mmd(phydev, MDIO_MMD_AN, reg, val); + + return ret; +} + +static int qca807x_led_hw_is_supported(struct phy_device *phydev, u8 index, + unsigned long rules) +{ + u16 offload_trigger = 0; + + if (index > 1) + return -EINVAL; + + return qca807x_led_parse_netdev(phydev, rules, &offload_trigger); +} + +static int qca807x_led_hw_control_set(struct phy_device *phydev, u8 index, + unsigned long rules) +{ + int val, ret, copper_reg, fibre_reg; + u16 offload_trigger = 0; + + switch (index) { + case 0: + copper_reg = QCA807X_MMD7_LED_100N_1; + fibre_reg = QCA807X_MMD7_LED_100N_2; + break; + case 1: + copper_reg = QCA807X_MMD7_LED_1000N_1; + fibre_reg = QCA807X_MMD7_LED_1000N_2; + break; + default: + return -EINVAL; + } + + ret = qca807x_led_parse_netdev(phydev, rules, &offload_trigger); + if (ret) + return ret; + + ret = qca807x_led_hw_control_enable(phydev, index); + if (ret) + return ret; + + switch (phydev->port) { + case PORT_TP: + val = phy_read_mmd(phydev, MDIO_MMD_AN, copper_reg); + val &= ~QCA807X_LED_COPPER_ON_BLINK_MASK; + val |= offload_trigger; + ret = phy_write_mmd(phydev, MDIO_MMD_AN, copper_reg, val); + break; + case PORT_FIBRE: + val = phy_read_mmd(phydev, MDIO_MMD_AN, fibre_reg); + val &= ~QCA807X_LED_FIBER_ON_BLINK_MASK; + val |= offload_trigger; + ret = phy_write_mmd(phydev, MDIO_MMD_AN, fibre_reg, val); + break; + default: + return -EINVAL; + } + + return ret; +} + +static bool qca807x_led_hw_control_status(struct phy_device *phydev, u8 index) +{ + int val, reg; + + switch (index) { + case 0: + reg = QCA807X_MMD7_LED_100N_2; + break; + case 1: + reg = QCA807X_MMD7_LED_1000N_2; + break; + default: + return false; + } + + val = phy_read_mmd(phydev, MDIO_MMD_AN, reg); + + return !(val & QCA807X_LED_FORCE_EN); +} + +static int qca807x_led_hw_control_get(struct phy_device *phydev, u8 index, + unsigned long *rules) +{ + int val, copper_reg, fibre_reg; + + switch (index) { + case 0: + copper_reg = QCA807X_MMD7_LED_100N_1; + fibre_reg = QCA807X_MMD7_LED_100N_2; + break; + case 1: + copper_reg = QCA807X_MMD7_LED_1000N_1; + fibre_reg = QCA807X_MMD7_LED_100N_2; + break; + default: + return -EINVAL; + } + + /* Check if we have hw control enabled */ + if (qca807x_led_hw_control_status(phydev, index)) + return -EINVAL; + + /* Parsing specific to netdev trigger */ + switch (phydev->port) { + case PORT_TP: + val = phy_read_mmd(phydev, MDIO_MMD_AN, copper_reg); + if (val & QCA807X_LED_TXACT_BLK_EN) + set_bit(TRIGGER_NETDEV_TX, rules); + if (val & QCA807X_LED_RXACT_BLK_EN) + set_bit(TRIGGER_NETDEV_RX, rules); + if (val & QCA807X_LED_BT_ON_EN) + set_bit(TRIGGER_NETDEV_LINK_10, rules); + if (val & QCA807X_LED_HT_ON_EN) + set_bit(TRIGGER_NETDEV_LINK_100, rules); + if (val & QCA807X_LED_GT_ON_EN) + set_bit(TRIGGER_NETDEV_LINK_1000, rules); + if (val & QCA807X_LED_HDX_ON_EN) + set_bit(TRIGGER_NETDEV_HALF_DUPLEX, rules); + if (val & QCA807X_LED_FDX_ON_EN) + set_bit(TRIGGER_NETDEV_FULL_DUPLEX, rules); + break; + case PORT_FIBRE: + val = phy_read_mmd(phydev, MDIO_MMD_AN, fibre_reg); + if (val & QCA807X_LED_FIBER_TXACT_BLK_EN) + set_bit(TRIGGER_NETDEV_TX, rules); + if (val & QCA807X_LED_FIBER_RXACT_BLK_EN) + set_bit(TRIGGER_NETDEV_RX, rules); + if (val & QCA807X_LED_FIBER_100FX_ON_EN) + set_bit(TRIGGER_NETDEV_LINK_100, rules); + if (val & QCA807X_LED_FIBER_1000BX_ON_EN) + set_bit(TRIGGER_NETDEV_LINK_1000, rules); + if (val & QCA807X_LED_FIBER_HDX_ON_EN) + set_bit(TRIGGER_NETDEV_HALF_DUPLEX, rules); + if (val & QCA807X_LED_FIBER_FDX_ON_EN) + set_bit(TRIGGER_NETDEV_FULL_DUPLEX, rules); + break; + default: + return -EINVAL; + } + + return 0; +} + +static int qca807x_led_hw_control_reset(struct phy_device *phydev, u8 index) +{ + int val, copper_reg, fibre_reg, ret; + + switch (index) { + case 0: + copper_reg = QCA807X_MMD7_LED_100N_1; + fibre_reg = QCA807X_MMD7_LED_100N_2; + break; + case 1: + copper_reg = QCA807X_MMD7_LED_1000N_1; + fibre_reg = QCA807X_MMD7_LED_100N_2; + break; + default: + return -EINVAL; + } + + switch (phydev->port) { + case PORT_TP: + val = phy_read_mmd(phydev, MDIO_MMD_AN, copper_reg); + val &= ~QCA807X_LED_COPPER_ON_BLINK_MASK; + ret = phy_write_mmd(phydev, MDIO_MMD_AN, copper_reg, val); + break; + case PORT_FIBRE: + val = phy_read_mmd(phydev, MDIO_MMD_AN, fibre_reg); + val &= ~QCA807X_LED_FIBER_ON_BLINK_MASK; + ret = phy_write_mmd(phydev, MDIO_MMD_AN, fibre_reg, val); + break; + default: + return -EINVAL; + } + + return ret; +} + +static int qca807x_led_brightness_set(struct phy_device *phydev, + u8 index, enum led_brightness value) +{ + int val, ret; + u16 reg; + + switch (index) { + case 0: + reg = QCA807X_MMD7_LED_100N_2; + break; + case 1: + reg = QCA807X_MMD7_LED_1000N_2; + break; + default: + return -EINVAL; + } + + /* If we are setting off the LED reset any hw control rule */ + if (!value) { + ret = qca807x_led_hw_control_reset(phydev, index); + if (ret) + return ret; + } + + val = phy_read_mmd(phydev, MDIO_MMD_AN, reg); + val &= ~(QCA807X_LED_FORCE_EN | QCA807X_LED_FORCE_MODE_MASK); + val |= QCA807X_LED_FORCE_EN; + if (value) + val |= QCA807X_LED_FORCE_ON; + ret = phy_write_mmd(phydev, MDIO_MMD_AN, reg, val); + + return ret; +} + +static int qca807x_led_blink_set(struct phy_device *phydev, u8 index, + unsigned long *delay_on, + unsigned long *delay_off) +{ + int val, ret; + u16 reg; + + switch (index) { + case 0: + reg = QCA807X_MMD7_LED_100N_2; + break; + case 1: + reg = QCA807X_MMD7_LED_1000N_2; + break; + default: + return -EINVAL; + } + + /* Set blink to 50% off, 50% on at 4Hz by default */ + val = phy_read_mmd(phydev, MDIO_MMD_AN, QCA807X_MMD7_LED_GLOBAL); + val &= ~(QCA807X_LED_BLINK_FREQ_MASK | QCA807X_LED_BLINK_DUTY_MASK); + val |= QCA807X_LED_BLINK_FREQ_4HZ | QCA807X_LED_BLINK_DUTY_50_50; + ret = phy_write_mmd(phydev, MDIO_MMD_AN, QCA807X_MMD7_LED_GLOBAL, val); + + /* We use BLINK_1 for normal blinking */ + val = phy_read_mmd(phydev, MDIO_MMD_AN, reg); + val &= ~(QCA807X_LED_FORCE_EN | QCA807X_LED_FORCE_MODE_MASK); + val |= QCA807X_LED_FORCE_EN | QCA807X_LED_FORCE_BLINK_1; + ret = phy_write_mmd(phydev, MDIO_MMD_AN, reg, val); + + /* We set blink to 4Hz, aka 250ms */ + *delay_on = 250 / 2; + *delay_off = 250 / 2; + + return ret; +} + #ifdef CONFIG_GPIOLIB static int qca807x_gpio_get_direction(struct gpio_chip *gc, unsigned int offset) { @@ -746,6 +1103,12 @@ static int qca807x_probe(struct phy_device *phydev) ret = qca807x_gpio(phydev); if (ret) return ret; + + phydev->drv->led_brightness_set = NULL; + phydev->drv->led_blink_set = NULL; + phydev->drv->led_hw_is_supported = NULL; + phydev->drv->led_hw_control_set = NULL; + phydev->drv->led_hw_control_get = NULL; } } @@ -933,6 +1296,11 @@ static struct phy_driver qca807x_drivers[] = { .suspend = genphy_suspend, .cable_test_start = qca807x_cable_test_start, .cable_test_get_status = qca807x_cable_test_get_status, + .led_brightness_set = qca807x_led_brightness_set, + .led_blink_set = qca807x_led_blink_set, + .led_hw_is_supported = qca807x_led_hw_is_supported, + .led_hw_control_set = qca807x_led_hw_control_set, + .led_hw_control_get = qca807x_led_hw_control_get, /* PHY package define */ .phy_package_global_phys_offset = qca807x_global_phys_offset, .phy_package_global_phys_num = ARRAY_SIZE(qca807x_global_phys_offset),