From patchwork Mon Feb 5 16:48:33 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Christian Marangi X-Patchwork-Id: 13545863 X-Patchwork-Delegate: kuba@kernel.org Received: from mail-lf1-f49.google.com (mail-lf1-f49.google.com [209.85.167.49]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 5993D3FE46; Mon, 5 Feb 2024 16:49:06 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.167.49 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1707151748; cv=none; b=C6emLdxVhwfg+2CEMIFS4p5ArSZfuPJuDXv6w0fFEB82AARS7/+ZkUSYILQH0yGoINQ3ztj5LHQyrofIBaiOsWfRfNCC1SOxEQXx2GlScw0m2xSYpP0Jp0LHH+M6NnqFQRovNSK5kpFBV5wJ1qRHFR33VuSYmFkpGrMVJWstX8w= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1707151748; c=relaxed/simple; bh=ilTj5VWnzbXDnAmzljy5yyfGbnvyZnNPzs2eb6s2nj8=; h=From:To:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=LWmHF3QqTdmg7qpFLB4TRfzi/tMOchqtxsIBb2N3NVg6Usdvr9A6lZ3VGdlGV1HMPEck0ffCVFzlL4fJR3yVIMj0QYVtqEygnTO4mJle8cHorca/rzf1LsRcIbSyfKY4IJ9dlk7/sYEmdso+RL+b4G1JYC9/D/2ggaB37EPOA5I= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=K+a9wNmJ; arc=none smtp.client-ip=209.85.167.49 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="K+a9wNmJ" Received: by mail-lf1-f49.google.com with SMTP id 2adb3069b0e04-51025cafb51so6954032e87.2; Mon, 05 Feb 2024 08:49:05 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1707151744; x=1707756544; 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=9hloNsWsZXa6Vf2TLiftzXJ4XARi6FJ1Kn6mZNuM3PA=; b=K+a9wNmJDEBDKvFcLkgsGKk94M39xZJKRmwSqplO9LoAyRDqF6tEUXDyiMeN82z4JG FuI6Ed0SsJuCBd9N73s3gu69NARRH0wqs7HjwrnWktpoJeqLp4XoKD7GkAeoKk5YMhXu 8SL4aGqz35mCxhbb9z7X8aTx28TRSaC7ba+cbefigrJ6/O0EmsNglGmZ6G5nr9wrkfht +hqp1pS9o1B7Qfp1dhpDHaKYOhfjPM0oatC18WOOc1AZI9hd9iW+rVErbbH6GxDeQHVT Pk5qEGeJosI0ghmLL96BQ91pRuo3OPjQ+4oiiJzUe0DT6U1xQ9hoevhk53JuZnMOXwnh lmrw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1707151744; x=1707756544; 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=9hloNsWsZXa6Vf2TLiftzXJ4XARi6FJ1Kn6mZNuM3PA=; b=A9yMpKUrqjslZN/xxm4HEcd6ccQ7QhKnNt6GYZKe7MeYRXlb+H1dSDv3j2JAO3Wme3 F3aQeag5tPPcYpMa3aM35/vkIsgfd1pzL+lrn7kCxpGIyhKsWtrk90eQzZNpEa9dukrL vsXLD65s38FiVYpAvQuYc1yOspgor5W/t4p3EHOlK9JGeC1IJ3aEzPeN9lAjSSTx0y3W rpZatpZRcWh6xmXhtqEfv1TYiKUbVSc56sTH9e9MnsfF+c3zAE6413xWf0r1SeWMboUO v50sfx215/1FkYj7gVltbBEWwKdXVyAfkZsrVkhlcjXkRAjhXq5Tsi/kiCRx07b2gktj RMIw== X-Gm-Message-State: AOJu0Yyva1qcCENb9IXRd1nqfs/wRhe0DLmfrxsqVrN2JGhbxUCu8l5L NxEAiIypT/WqDH1b41XJxA8P2gmgpX8MLft0i4nfJqReycCz+yaY X-Google-Smtp-Source: AGHT+IGKL4S/NbUdFlbh/K8uszUH1kWAVsBWWqkO40Q/829DjsnfSp4xNi0RfcgWVWVjLwHZQWKglA== X-Received: by 2002:a19:6717:0:b0:511:475b:7079 with SMTP id b23-20020a196717000000b00511475b7079mr114167lfc.43.1707151743947; Mon, 05 Feb 2024 08:49:03 -0800 (PST) X-Forwarded-Encrypted: i=0; AJvYcCW7fo8RmTk93QVMmXH9b9xNfXo/Y6u0mwzN0bO8Wc+3ASzGhhEg9iWBADgb611Wbtb1fEztVq0HxdJq4wqf6kNWF6NOqEwoq1w/befzV/Z+3M6/smTRqyvkxBKKVD05cMjRW86p0egExti2ehZalMblBRh4FiksZ5KfDC1vqD3dxaOgN7287VcJX18S6GXo6nZNK8Y/U0mHqqYl2HrlYjj4/cTWu2D23kfuBQ8fUAEBPJcWiKt9EgDLgsHDZCNx1wvFKPtesPP9P7IV7L9f1hgFiqdppvKfNOW87wfoLGB8twsQlPMYc/RvXowtDRVgwbVmAORMVkaWczHDpDB3Qn1qreZfYXwryZ+A/i1tDV2AWeeM5H6ac5EklYDNgSAGiwHo+qTKxVRpHzU3EDofw4oL9W3dhbKrUsq524mept9tefMddLCsf9fRa58dg3u6F+YylhlUaCHmDjgB33yPKDM/gXIs9+crIxVlqa4WjfKhQcghAo6Torpu7xpPTgDSkWq3eHTsIWKCYXEvXr7SQ5lojYWtXn0L5lTT5H2XmLaGVxiImVDQBE75laMPA7ardePe8UP5ELRMiaOD7zRUe+/3yDi9hDhz6c2zsM9fDQOoUdYlRlHsCkYCOf9wyDFn3gDi65Ccrh0QJCIoQN4YpavZ+enBd6uuIOkLBPghBGww8AUcointXA== Received: from localhost.localdomain (93-34-89-13.ip49.fastwebnet.it. [93.34.89.13]) by smtp.googlemail.com with ESMTPSA id k2-20020a05600c1c8200b0040fafd84095sm9140567wms.41.2024.02.05.08.49.02 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 05 Feb 2024 08:49:03 -0800 (PST) From: Christian Marangi To: "David S. Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Bjorn Andersson , Konrad Dybcio , Andrew Lunn , Heiner Kallweit , Russell King , Florian Fainelli , Broadcom internal kernel review list , Christian Marangi , Robert Marko , netdev@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-arm-msm@vger.kernel.org Subject: [net-next PATCH v6 01/10] dt-bindings: net: document ethernet PHY package nodes Date: Mon, 5 Feb 2024 17:48:33 +0100 Message-ID: <20240205164851.1351-2-ansuelsmth@gmail.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20240205164851.1351-1-ansuelsmth@gmail.com> References: <20240205164851.1351-1-ansuelsmth@gmail.com> Precedence: bulk X-Mailing-List: netdev@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Patchwork-Delegate: kuba@kernel.org Document ethernet PHY package nodes used to describe PHY shipped in bundle of 2-5 PHY. The special node describe a container of PHY that share common properties. This is a generic schema and PHY package should create specialized version with the required additional shared properties. Example are PHY packages 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. Each reg of the PHYs defined in the PHY package node is absolute and describe the real address of the Ethernet PHY on the bus. Signed-off-by: Christian Marangi --- .../bindings/net/ethernet-phy-package.yaml | 52 +++++++++++++++++++ 1 file changed, 52 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..e567101e6f38 --- /dev/null +++ b/Documentation/devicetree/bindings/net/ethernet-phy-package.yaml @@ -0,0 +1,52 @@ +# 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 + +description: + PHY packages are multi-port Ethernet PHY of the same family + and each Ethernet PHY is affected by the global configuration + of the PHY package. + + Each reg of the PHYs defined in the PHY package node is + absolute and describe the real address of the Ethernet PHY on + the MDIO bus. + +properties: + $nodename: + pattern: "^ethernet-phy-package@[a-f0-9]+$" + + reg: + minimum: 0 + maximum: 31 + description: + The base ID number for the PHY package. + Commonly the ID of the first PHY in the PHY package. + + Some PHY in the PHY package might be not defined but + still occupy ID on the device (just not attached to + anything) hence the PHY package reg might correspond + to a not attached PHY (offset 0). + + '#address-cells': + const: 1 + + '#size-cells': + const: 0 + +patternProperties: + ^ethernet-phy@[a-f0-9]+$: + $ref: ethernet-phy.yaml# + +required: + - reg + - '#address-cells' + - '#size-cells' + +additionalProperties: true From patchwork Mon Feb 5 16:48:34 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Christian Marangi X-Patchwork-Id: 13545864 X-Patchwork-Delegate: kuba@kernel.org Received: from mail-lf1-f43.google.com (mail-lf1-f43.google.com [209.85.167.43]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 729B73D99E; Mon, 5 Feb 2024 16:49:07 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.167.43 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1707151749; cv=none; b=m4mnjPnI8kP5j15G+BgnA6kDCFKXCI+oDkjU4k1OIYYKoKKw2hjkshrxG7+KRbAN/obv4977vFzvSVrI44weIATsndTaUaCf5GIwuI+FdbreZnKCYqhvzX35WCUejiAZmbatn4eHETMWVQnLDqAWPKcXU4NN+tIexo7MEm4xGSE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1707151749; c=relaxed/simple; bh=QUMd/pymTNWROMEPvOP0tST5nIvBnoIZpBFhJ64dhxw=; h=From:To:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=In3vxFC9KZLPw50dEHTHcy288lSJebBPCu9pJqxzhPrzOk8/KoDV/gTEkmijnet8Qf/OOnOAzL8A24PjOgOr+XjTdPpt92FXk9s7etHaw0rcSxutv/avRHPyG6O3T/ot922BoRm0z5XlL2kBQd6JibFllwMUqxkdnGNQlxlDhHE= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=Vd1VHMQs; arc=none smtp.client-ip=209.85.167.43 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="Vd1VHMQs" Received: by mail-lf1-f43.google.com with SMTP id 2adb3069b0e04-511538be947so954846e87.3; Mon, 05 Feb 2024 08:49:07 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1707151745; x=1707756545; 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=ozVMLwHgKVfJzWQo5tW7oNNWQr0MV/j4f/0n469yn4M=; b=Vd1VHMQs9c3r3r+ysu2zpPPGpmm5Hd7eqG19wc3Ea2hrbZEYtW6nk44T9NSeQBZMiS CnceKXI7pIC91hw4BrYfkqRyIgPrx9Z8zPWv6//qtuUWKOo6QCdCChdrGpuQFHccmwnK NRCCfUbiurE+Dkh0EQV2yzIBSC2pYk+dW/oGD445FfZ/p26el3R0JPhN306uU4XEjFul XMDUKi4croPMqjPNGIdhAUXS2nRfHYHR3D6YjyYXPE4CpAiKcGTODVDcjhcZcVOeYNEP aZAFordVImTlDcAJBj4UuRhfj5HT+i0G601ybOYf9E4fzOUrXjPFmCVpHh54PL/ireC4 QLOw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1707151745; x=1707756545; 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=ozVMLwHgKVfJzWQo5tW7oNNWQr0MV/j4f/0n469yn4M=; b=Of0KqOC0xpwAUc6JvVNKxrHc7ECc39CQZ1qBd+7bnP/d+Kf6uFL25iRlcl41bdaGqm 8yVhFlwchG19XoEHuLna5z4uSqcwhMOVwlPfxRGNF5PIPIPbwt/JB9lr+g12Cuw1ozFI TW7JvP01bfq3+zgE4dKTgbiOw6woIrZ2CXJC1aKzo4AvLXZzYsGOea54SUYgHqSl5ELh 84wusPHT4paGlaLWeuP9W+lDO2f4sqZwqPxV36iquCqrmFRV9xvwMQGsTF76KHJWs5Kd hhkPxXKj1Hvaz7BgurbRG7M7hNclnVOlDAIgiP+AzNMc7jkBLPqV3RgibGLzAJ2hTJVN txfw== X-Gm-Message-State: AOJu0Yxt+FYSyx935zu0zd4kTnsHf0klJB/8ag/EipDUoYEBRkztsqeh 3nGADBU1bhY4rPmB0dGcAL/opiMbCa7mioWJv/Y5QQdbiiMlRZIamyev9ROu X-Google-Smtp-Source: AGHT+IEiBJAxu5f7/MXQ00yym5c3Q53XmYm2ChwEJlzsaXM9KEbeAV2yLQLeo6FAUsJpu/VdTryeTA== X-Received: by 2002:a19:8c19:0:b0:511:297f:2732 with SMTP id o25-20020a198c19000000b00511297f2732mr122812lfd.31.1707151745386; Mon, 05 Feb 2024 08:49:05 -0800 (PST) X-Forwarded-Encrypted: i=0; AJvYcCUS+2aX1gUn1eBXcvBG1RDeE6hlA+QE0aGi3kidpjPYVsE2gAh1X/9dM7bboBH19pbuZ45ndzo9BVB8uX87ueeQXzAEzoObEItsmaUqhA71e+aY3BOvItwLtXf4GOHMfRbUswwZBiQHgkiA4v2TCh8SbU6s9G9LeZYXHa/1Wvnanugxc8AIZL0KXheyOMj8buAm42wdUCgKeAIv6A+97bDFWjyM6sB/73pG0X+01Ywr1i69RN57Xm+J1StqjWor2ylI4qq1DSZL4R6sA+ov6UCcC1scIugU/10qTnXguJ3HKF3jDPIcOFx2UZfwt52SSP3gJXJjYQ/lQQjxJ0CNTxFShg5zE5qx3lzLkhZHGU3mrU7teoF0YFXv9PTJQZhQ4g/AV70BhgVC8al9HFT8SvS/oJBXcVXCjrUSLkSD4MNF7vjhp1NDt2yt/3buETBJRpB2BVIImnqDQiismudmCUEVUh22yW7IQhLDFmMoslt01uxnlZ5rcs63bICdypZ5MgK0bUxsfd28ADTNAde427DDYz6XIfyXgVdPkzXzUDLmRMxyt7Y1+g1f1w0aULQfnPpcu556F5qX7Ll6MpwtJFt4qgntBit4lB9I7o2ChAeqk8/Oxi3rI+CpAco2BBQS9MMNnghrkEazD+CdhS0zpzQetLCfMSjawp5juvemgasNJQkD5C+fmQ== Received: from localhost.localdomain (93-34-89-13.ip49.fastwebnet.it. [93.34.89.13]) by smtp.googlemail.com with ESMTPSA id k2-20020a05600c1c8200b0040fafd84095sm9140567wms.41.2024.02.05.08.49.04 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 05 Feb 2024 08:49:04 -0800 (PST) From: Christian Marangi To: "David S. Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Bjorn Andersson , Konrad Dybcio , Andrew Lunn , Heiner Kallweit , Russell King , Florian Fainelli , Broadcom internal kernel review list , Christian Marangi , Robert Marko , netdev@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-arm-msm@vger.kernel.org Subject: [net-next PATCH v6 02/10] net: phy: add support for scanning PHY in PHY packages nodes Date: Mon, 5 Feb 2024 17:48:34 +0100 Message-ID: <20240205164851.1351-3-ansuelsmth@gmail.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20240205164851.1351-1-ansuelsmth@gmail.com> References: <20240205164851.1351-1-ansuelsmth@gmail.com> Precedence: bulk X-Mailing-List: netdev@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Patchwork-Delegate: kuba@kernel.org Add support for scanning PHY in PHY package nodes. PHY packages nodes are just container for actual PHY on the MDIO bus. Their PHY address defined in the PHY package node are absolute and reflect the address on the MDIO bus. mdio_bus.c and of_mdio.c is updated to now support and parse also PHY package subnode by checking if the node name match "ethernet-phy-package". As PHY package reg is mandatory and each PHY in the PHY package must have a reg, every invalid PHY Package node is ignored and will be skipped by the autoscan fallback. Signed-off-by: Christian Marangi --- drivers/net/mdio/of_mdio.c | 79 +++++++++++++++++++++++++++----------- drivers/net/phy/mdio_bus.c | 44 +++++++++++++++++---- 2 files changed, 92 insertions(+), 31 deletions(-) diff --git a/drivers/net/mdio/of_mdio.c b/drivers/net/mdio/of_mdio.c index 64ebcb6d235c..08e607f62e10 100644 --- a/drivers/net/mdio/of_mdio.c +++ b/drivers/net/mdio/of_mdio.c @@ -139,6 +139,53 @@ 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_eq(child, "ethernet-phy-package")) { + /* Ignore invalid ethernet-phy-package node */ + if (!of_property_present(child, "reg")) + continue; + + rc = __of_mdiobus_parse_phys(mdio, child, NULL); + if (rc && rc != -ENODEV) + goto exit; + + continue; + } + + addr = of_mdio_parse_addr(&mdio->dev, child); + if (addr < 0) { + /* Skip scanning for invalid ethernet-phy-package node */ + if (scanphys) + *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,33 +227,18 @@ 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; /* auto scan for PHYs with empty reg property */ for_each_available_child_of_node(np, child) { - /* Skip PHYs with reg property set */ - if (of_property_present(child, "reg")) + /* Skip PHYs with reg property set or ethernet-phy-package node */ + if (of_property_present(child, "reg") || + of_node_name_eq(child, "ethernet-phy-package")) continue; for (addr = 0; addr < PHY_MAX_ADDR; addr++) { @@ -227,15 +259,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 afbad1ad8683..08624f073014 100644 --- a/drivers/net/phy/mdio_bus.c +++ b/drivers/net/phy/mdio_bus.c @@ -459,19 +459,34 @@ 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_eq(child, "ethernet-phy-package")) { + /* Validate PHY package reg presence */ + if (!of_property_present(child, "reg")) { + of_node_put(child); + return -EINVAL; + } + + if (!of_mdiobus_find_phy(dev, mdiodev, child)) { + /* The refcount for the PHY package will be + * incremented later when PHY join the Package. + */ + of_node_put(child); + return 0; + } + + continue; + } + addr = of_mdio_parse_addr(dev, child); if (addr < 0) continue; @@ -481,9 +496,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, From patchwork Mon Feb 5 16:48:35 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Christian Marangi X-Patchwork-Id: 13545865 X-Patchwork-Delegate: kuba@kernel.org Received: from mail-lf1-f53.google.com (mail-lf1-f53.google.com [209.85.167.53]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id CA5FE40BE7; Mon, 5 Feb 2024 16:49:08 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.167.53 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1707151750; cv=none; b=MwkERUCJgMyqxSOgWlf+rtik7Fyg3a57C8cWmRHIaNZ99h8/atgt6WuktTV/182R+YOYpe5eJfRz1nCpXSTZCtuyTP8T7S2l2dzN3V6sk8fhiUP7BMpIfrEFY79FbaU3s9zrVZrWPXyhHQXIG32b9YDOxblx/0FfqUuA15+NrCc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1707151750; c=relaxed/simple; bh=Og5Cxg2unNdb74R5cOmUSglesmMWnLWZ6HhHgIx2ia8=; h=From:To:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=GB1BYVpqaxMXwsQU373yy+Uqda/WCEslQN8dTrsgzKNpWdkAuM0Jh9Y6mrJJMcR0IUo/jcB2/bnKqXTTp3MVbCLW8V/Nve8csR0VQ8WLOOjDTfAoucS9xY5EJFN1n5sJGpBlRRCymsW2I7yfZ89tqpIJjdj5YJdAquF1C+mvxis= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=BEh7YN0P; arc=none smtp.client-ip=209.85.167.53 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="BEh7YN0P" Received: by mail-lf1-f53.google.com with SMTP id 2adb3069b0e04-5112a04c7acso7437600e87.3; Mon, 05 Feb 2024 08:49:08 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1707151747; x=1707756547; 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=QOdvH1bIIsmqoTot3Fl0cDk3IRpxfG68ITGLhwsu3rw=; b=BEh7YN0PO1uPHbZbCC13KGKz9lGbLcTWqK57Vezlf9BmZpen4rnwhZUrqXHpZWK9V2 VtbwE9QbaqzIghTJuOIjad9QAoaKu2rOH3Uu0e9DPbRrGvd/biuGJt8AeU2V82ZADsTZ Kod8wkv1YFFfEvc2HSpEDyXzypUp9UkcL2pxZ1eEznY8EmIHFiJ1zslNp5T1ENulTeNG /oIp0F2wJnLyBAELXvu1fQQOMXA52XeR1pD7EupsliPh6ow7hjMxFUXafsG981xlknEp P5A/gHYcVcnp/onTBVuZxXHwLRDZesMO+Qw04qS0UF+TL5qAy+Ib9yYiwm0NZfwNBbhm xlLA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1707151747; x=1707756547; 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=QOdvH1bIIsmqoTot3Fl0cDk3IRpxfG68ITGLhwsu3rw=; b=j6JUVqCGnB1HKnUvs9TeL4N5F+8qNBiYKrDFzXdOan5+UFJLT2mN3VSyn/mbocjGEz /wgyNvHlfw43YgJ6ParfSdwI6jBw7eFHrG+QlgK4DjxOBXDEXfbnHzYBmzzdc50VnaNt 4Aa5kfy2BxXkXqsA9Cb7iroY4VVp4+WeD6uZtsrNxKxaDI7Cfnuc5zFDO6mA1Uu9uWax 9ydVmjtOvizWwM7j9Tq+XZraJk4dYXeb3OUDYSjsvYYek+raJ238y63JZdi2K0vwZp1E i6nYGsW4WEcWZy9XAcjXgc2/tlctl4Uet+c4xdWM4sCaawCe8DuD0dLwuA3yvn8a4RTB LDyg== X-Gm-Message-State: AOJu0Ywy4kN0lYn53gdQaQz8DhOZQJ/m3Yo4Fk06b7gValn0claShiAh ewXI1cNncfXazePktbz2L2ERp9TvXNvd8lx0doT/sVNK2kbdaokg X-Google-Smtp-Source: AGHT+IEMD06ygfXVcu9qumaDiOb5730gV1sMXVwFlTtwSaAjXb6/utNw1v9vr3cW+LES0GLzTNwVeg== X-Received: by 2002:a05:6512:3b20:b0:511:4dfb:17d8 with SMTP id f32-20020a0565123b2000b005114dfb17d8mr132377lfv.40.1707151746614; Mon, 05 Feb 2024 08:49:06 -0800 (PST) X-Forwarded-Encrypted: i=0; AJvYcCXm2T+gGul4pDsD/F3CnTbKDW3yrsyAl6RfkK3AMmUpDuv9BQLTd3lW340Zjbncr+SAgQ2AHBQkQ8XfknrH6QcUJWEfWvgMUWZVSe7Et6M/ihHSdx/Zy2HmveFVKcsinsX8kh5p7e5HWtNRhhiNaPNk0EDPl7ocjl1rmXLp9/Q324ZFDaP0TQXml5MTn4hP3O5xOrpN/kFAH53xIcTq8ukrYiLbQqF3UaugIHEEg0BiozJWoQg1KD0D1KpkT3dCpM8XnkN9G5VYlJYn5RJG1KehNLlOHA3/iQm20uHjvmkWQ7K+Ac6ISsF9kgFZplU8JoAswjf5NayNRiZmA9Igw6yMXcm+SJYbEu7eegWqz//cGSlVRcfGDG1LDcA9RTlPRmYlvrORLS1MXHcVYecEatH+zrn7zMxTU51DkV04PQ8ANgTKorpaGrZljZ698qZW539HErMNiNb7lfHk+qPVyMfyQcptDtAeAd44E1LFVhJmXw63iTl4ykjKjGEyT+POLLUS+BQEle6wEWCS5NIkx707heiBkBsCv5VWpwcRcUi9GGbU/WWe8RXfZsdzZuloCubznpXb6a+e+ukmC66sxjq5su50eu+Y2VvdbcgoibzF793QHA5UaBtLgnW1fmDg5llWjxFMlZMda/ioIln8HgsUb5QJ2M6c6WPK+kAEsm0PUmPJCcSndw== Received: from localhost.localdomain (93-34-89-13.ip49.fastwebnet.it. [93.34.89.13]) by smtp.googlemail.com with ESMTPSA id k2-20020a05600c1c8200b0040fafd84095sm9140567wms.41.2024.02.05.08.49.05 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 05 Feb 2024 08:49:06 -0800 (PST) From: Christian Marangi To: "David S. Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Bjorn Andersson , Konrad Dybcio , Andrew Lunn , Heiner Kallweit , Russell King , Florian Fainelli , Broadcom internal kernel review list , Christian Marangi , Robert Marko , netdev@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-arm-msm@vger.kernel.org Subject: [net-next PATCH v6 03/10] net: phy: add devm/of_phy_package_join helper Date: Mon, 5 Feb 2024 17:48:35 +0100 Message-ID: <20240205164851.1351-4-ansuelsmth@gmail.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20240205164851.1351-1-ansuelsmth@gmail.com> References: <20240205164851.1351-1-ansuelsmth@gmail.com> Precedence: bulk X-Mailing-List: netdev@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Patchwork-Delegate: kuba@kernel.org Add devm/of_phy_package_join helper to join PHYs in a PHY package. These are variant of the manual phy_package_join with the difference that these will use DT nodes to derive the base_addr instead of manually passing an hardcoded value. An additional value is added in phy_package_shared, "np" to reference the PHY package node pointer in specific PHY driver probe_once and config_init_once functions to make use of additional specific properties defined in the PHY package node in DT. The np value is filled only with of_phy_package_join if a valid PHY package node is found. A valid PHY package node must have the node name set to "ethernet-phy-package". Signed-off-by: Christian Marangi --- drivers/net/phy/phy_device.c | 96 ++++++++++++++++++++++++++++++++++++ include/linux/phy.h | 6 +++ 2 files changed, 102 insertions(+) diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c index 52828d1c64f7..c30907dc9fb7 100644 --- a/drivers/net/phy/phy_device.c +++ b/drivers/net/phy/phy_device.c @@ -1708,6 +1708,7 @@ int phy_package_join(struct phy_device *phydev, int base_addr, size_t priv_size) shared->priv_size = priv_size; } shared->base_addr = base_addr; + shared->np = NULL; refcount_set(&shared->refcnt, 1); bus->shared[base_addr] = shared; } else { @@ -1730,6 +1731,63 @@ int phy_package_join(struct phy_device *phydev, int base_addr, size_t priv_size) } EXPORT_SYMBOL_GPL(phy_package_join); +/** + * of_phy_package_join - join a common PHY group in PHY package + * @phydev: target phy_device struct + * @priv_size: if non-zero allocate this amount of bytes for private data + * + * This is a variant of phy_package_join for PHY package defined in DT. + * + * The parent node of the @phydev is checked as a valid PHY package node + * structure (by matching the node name "ethernet-phy-package") and the + * base_addr for the PHY package is passed to phy_package_join. + * + * With this configuration the shared struct will also have the np value + * filled to use additional DT defined properties in PHY specific + * probe_once and config_init_once PHY package OPs. + * + * Returns < 0 on error, 0 on success. Esp. calling phy_package_join() + * with the same cookie but a different priv_size is an error. Or a parent + * node is not detected or is not valid or doesn't match the expected node + * name for PHY package. + */ +int of_phy_package_join(struct phy_device *phydev, size_t priv_size) +{ + struct device_node *node = phydev->mdio.dev.of_node; + struct device_node *package_node; + u32 base_addr; + int ret; + + if (!node) + return -EINVAL; + + package_node = of_get_parent(node); + if (!package_node) + return -EINVAL; + + if (!of_node_name_eq(package_node, "ethernet-phy-package")) { + ret = -EINVAL; + goto exit; + } + + if (of_property_read_u32(package_node, "reg", &base_addr)) { + ret = -EINVAL; + goto exit; + } + + ret = phy_package_join(phydev, base_addr, priv_size); + if (ret) + goto exit; + + phydev->shared->np = package_node; + + return 0; +exit: + of_node_put(package_node); + return ret; +} +EXPORT_SYMBOL_GPL(of_phy_package_join); + /** * phy_package_leave - leave a common PHY group * @phydev: target phy_device struct @@ -1746,6 +1804,10 @@ void phy_package_leave(struct phy_device *phydev) if (!shared) return; + /* Decrease the node refcount on leave if present */ + if (shared->np) + of_node_put(shared->np); + if (refcount_dec_and_mutex_lock(&shared->refcnt, &bus->shared_lock)) { bus->shared[shared->base_addr] = NULL; mutex_unlock(&bus->shared_lock); @@ -1798,6 +1860,40 @@ int devm_phy_package_join(struct device *dev, struct phy_device *phydev, } EXPORT_SYMBOL_GPL(devm_phy_package_join); +/** + * devm_of_phy_package_join - resource managed of_phy_package_join() + * @dev: device that is registering this PHY package + * @phydev: target phy_device struct + * @priv_size: if non-zero allocate this amount of bytes for private data + * + * Managed of_phy_package_join(). Shared storage fetched by this function, + * phy_package_leave() is automatically called on driver detach. See + * of_phy_package_join() for more information. + */ +int devm_of_phy_package_join(struct device *dev, struct phy_device *phydev, + size_t priv_size) +{ + struct phy_device **ptr; + int ret; + + ptr = devres_alloc(devm_phy_package_leave, sizeof(*ptr), + GFP_KERNEL); + if (!ptr) + return -ENOMEM; + + ret = of_phy_package_join(phydev, priv_size); + + if (!ret) { + *ptr = phydev; + devres_add(dev, ptr); + } else { + devres_free(ptr); + } + + return ret; +} +EXPORT_SYMBOL_GPL(devm_of_phy_package_join); + /** * phy_detach - detach a PHY device from its network device * @phydev: target phy_device struct diff --git a/include/linux/phy.h b/include/linux/phy.h index a66f07d3f5f4..2aed925e6c23 100644 --- a/include/linux/phy.h +++ b/include/linux/phy.h @@ -329,6 +329,7 @@ struct mdio_bus_stats { * struct phy_package_shared - Shared information in PHY packages * @base_addr: Base PHY address of PHY package used to combine PHYs * in one package and for offset calculation of phy_package_read/write + * @np: Pointer to the Device Node if PHY package defined in DT * @refcnt: Number of PHYs connected to this shared data * @flags: Initialization of PHY package * @priv_size: Size of the shared private data @priv @@ -340,6 +341,8 @@ struct mdio_bus_stats { */ struct phy_package_shared { u8 base_addr; + /* With PHY package defined in DT this points to the PHY package node */ + struct device_node *np; refcount_t refcnt; unsigned long flags; size_t priv_size; @@ -1999,9 +2002,12 @@ int phy_ethtool_set_link_ksettings(struct net_device *ndev, const struct ethtool_link_ksettings *cmd); int phy_ethtool_nway_reset(struct net_device *ndev); int phy_package_join(struct phy_device *phydev, int base_addr, size_t priv_size); +int of_phy_package_join(struct phy_device *phydev, size_t priv_size); void phy_package_leave(struct phy_device *phydev); int devm_phy_package_join(struct device *dev, struct phy_device *phydev, int base_addr, size_t priv_size); +int devm_of_phy_package_join(struct device *dev, struct phy_device *phydev, + size_t priv_size); int __init mdio_bus_init(void); void mdio_bus_exit(void); From patchwork Mon Feb 5 16:48:36 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Christian Marangi X-Patchwork-Id: 13545866 X-Patchwork-Delegate: kuba@kernel.org Received: from mail-wm1-f43.google.com (mail-wm1-f43.google.com [209.85.128.43]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id BA24E3EA86; Mon, 5 Feb 2024 16:49:09 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.43 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1707151752; cv=none; b=kZdFUcOw/6Hu5Alffp5dlq8+cfJ3zTkzhuL+U98kfSijnS4lp9F+BC1KeMCS4jXK5XSfXBmWDu9Wo9rDD7WjzC3DcTCh8ERy8N9pbKhuYxh5UvkoPRQ4iyl2Vw82aPZ2fNFwGiMnZzrn9F6enQlVgUAlXdrmzvfeaLeapgfS3p8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1707151752; c=relaxed/simple; bh=bdGHFT01GXpmJAQStvsRsVbmYpKcKYK9cB/9/B8I5YA=; h=From:To:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=N+ha+BHjU2cLAhK918ggAcy5cZsjy2eN0G+XLP2tCHDJea0dDS0vnAAht8uDUDEqccdfgtpdowV3pa/ym4RYHERdE5o8fKDSGGiRvXJx53Jld+JwU6FVyc3mCB7VwetPCKXK0ZEI5Qr/9MeL4/Jx6olrgq8wLn9+D8xM1JFRDjE= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=bAELeNmG; arc=none smtp.client-ip=209.85.128.43 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="bAELeNmG" Received: by mail-wm1-f43.google.com with SMTP id 5b1f17b1804b1-40fdf17fa89so2086365e9.0; Mon, 05 Feb 2024 08:49:09 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1707151748; x=1707756548; 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=7QAcRaCEqZ94Pf+SfvUe08GyZuxBTp3ojtTnlOyieSA=; b=bAELeNmGWi9DVENr742f+WiEtC9kr5U3m0GX28FAthCEGJB6uNOOEL/9pn+/Auv7r/ bTq8QSDjCpYaSvf4b4tjhIyLeuW9tfC610fUIP2l1A/9SkjYFQecssBZsKsdkTkOKGx2 cM2+0T2bCQKaMtqV3Iu5kUcwtct9Iemo66E8CxnJIKevPCBtfyEbBkQCJIafsZCyyMw2 NVWJYa+GDC+dgnDpSXlPyKtfcyBE+A7oLxvQ/u4lwvzQpOo8xV+a7C3Wuu5vDOsNX0AO cXtN6+d7OppJBh/e9E80FKaBsAF//WTj6pR/UREiasK4UnsAFIYHHj5EuYTURWjMr06S Qgcg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1707151748; x=1707756548; 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=7QAcRaCEqZ94Pf+SfvUe08GyZuxBTp3ojtTnlOyieSA=; b=hS/vlHJe4G86mGIonWVTkMjsMhU6945/KWCpSCHIihYeAgCDeQYRww6McXbprR2Syv nBHJryiqD5f2IA/trGct1JUY4zSwuBRIf5EbazVVL3SrCx8s9ECjHsolSBE9uVCGNVnp fKX1bK/u/epKtN+KyVaiJS3S227j8FxuLNUZTf5QChO/3W2JOj3dF5ZvM0ut7Ihdjy5z l9W/82i1QpAV1cTmG74UEq2EmpzK5Ruw4cdIJ80P6MHqH0TWcDFj+lYXB9xlwK/WGvw4 42M7+QzrZ1gP38u/M7Uk1WaLN8bGyvfAkp2oENmg31mywPsX/1w5oRt4j2CiM30RVL+z tUaw== X-Gm-Message-State: AOJu0YywZnh0m2Kj3YaiGW5+kj6n8iC72sQ0nHPXQ20K0OuLpOQHImON HqHywBIrdbGvNDo30UEtmIvKb+WKGcm5D4z6ugOkBB1cZKRSbpXd X-Google-Smtp-Source: AGHT+IG2gULhDU3nCYWCLxtI6WfSusENKORohcqM7kphczKlU5s+0oO1NBbQD2PobJc5TofeOj7Piw== X-Received: by 2002:a05:600c:4fc6:b0:40f:bbdb:4f2b with SMTP id o6-20020a05600c4fc600b0040fbbdb4f2bmr4482359wmq.19.1707151747809; Mon, 05 Feb 2024 08:49:07 -0800 (PST) X-Forwarded-Encrypted: i=0; AJvYcCUr6sP26m9lWQLj+mVy2hEI8IXJexNrk3ELknMBHdf4epazno6fCfxP06o7D6IRRvV5Vu2kSvoGY4NYeMrX6MQwpxEFTtd6AmAdRY557/NK3UA72pTB0ltXAUdiyuXZ5/nAsCd3/2hvMj8yyT5qOVQAUNqCGgjKxkGleyl4mmgPsXMaboG/awac0rRxfGdWRGdrQAhmVXx3rqQE09sswXZbLlvbL8xKFNSM26VI1p5nsCCCtCGgcvPKEHbvuIbBObLRmp++aYLpLt4quHfbeWQB8ura2E40JsiIJyebzF7TQbJGLWVlce4r6OHHtkdmsKTJDG/cPWbD1Zbfbr3WfgS+d/Aj9Vun8d5sKSync+P0OVEkBYBI6xLlft8PBWx1L4KFvQTEJHvhGt+qBoIuGENx7vBJOEiyU8VG+A2ODchwBrrQ9Z0rCp+HNfj8/+H6AKAFTNZ8pXALegZW0ys4QTnUQTsx+KRevt2DWfvkzB1O1Zu/K2XBIcNtYXL+Kd5MqPDHEIkHj6mDhpaPurQArg3zymTrED3NujiRiRmFVvF8fHQPCd5BLmbZ6XbKLBR+2ZMWX5e64V8xqd8OOXnmkZwkGAdh676oQAkgOg09eUAjTeHivmtmTZ2IdXyD95LtzhM4bV4vjxXmwNlenelNcncjVliUccPQcV/4BdesA/PF9KdF2zHBdA== Received: from localhost.localdomain (93-34-89-13.ip49.fastwebnet.it. [93.34.89.13]) by smtp.googlemail.com with ESMTPSA id k2-20020a05600c1c8200b0040fafd84095sm9140567wms.41.2024.02.05.08.49.06 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 05 Feb 2024 08:49:07 -0800 (PST) From: Christian Marangi To: "David S. Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Bjorn Andersson , Konrad Dybcio , Andrew Lunn , Heiner Kallweit , Russell King , Florian Fainelli , Broadcom internal kernel review list , Christian Marangi , Robert Marko , netdev@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-arm-msm@vger.kernel.org Subject: [net-next PATCH v6 04/10] net: phy: qcom: move more function to shared library Date: Mon, 5 Feb 2024 17:48:36 +0100 Message-ID: <20240205164851.1351-5-ansuelsmth@gmail.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20240205164851.1351-1-ansuelsmth@gmail.com> References: <20240205164851.1351-1-ansuelsmth@gmail.com> Precedence: bulk X-Mailing-List: netdev@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Patchwork-Delegate: kuba@kernel.org Move more function to shared library in preparation for introduction of new PHY Family qca807x that will make use of both functions from at803x and qca808x as it's a transition PHY with some implementation of at803x and some from the new qca808x. Signed-off-by: Christian Marangi --- drivers/net/phy/qcom/at803x.c | 35 ----- drivers/net/phy/qcom/qca808x.c | 205 ---------------------------- drivers/net/phy/qcom/qcom-phy-lib.c | 193 ++++++++++++++++++++++++++ drivers/net/phy/qcom/qcom.h | 51 +++++++ 4 files changed, 244 insertions(+), 240 deletions(-) diff --git a/drivers/net/phy/qcom/at803x.c b/drivers/net/phy/qcom/at803x.c index 36b70e88394e..3e3ee4c1d4bc 100644 --- a/drivers/net/phy/qcom/at803x.c +++ b/drivers/net/phy/qcom/at803x.c @@ -504,41 +504,6 @@ static void at803x_link_change_notify(struct phy_device *phydev) } } -static int at803x_read_status(struct phy_device *phydev) -{ - struct at803x_ss_mask ss_mask = { 0 }; - int err, old_link = phydev->link; - - /* Update the link, but return if there was an error */ - err = genphy_update_link(phydev); - if (err) - return err; - - /* why bother the PHY if nothing can have changed */ - if (phydev->autoneg == AUTONEG_ENABLE && old_link && phydev->link) - return 0; - - phydev->speed = SPEED_UNKNOWN; - phydev->duplex = DUPLEX_UNKNOWN; - phydev->pause = 0; - phydev->asym_pause = 0; - - err = genphy_read_lpa(phydev); - if (err < 0) - return err; - - ss_mask.speed_mask = AT803X_SS_SPEED_MASK; - ss_mask.speed_shift = __bf_shf(AT803X_SS_SPEED_MASK); - err = at803x_read_specific_status(phydev, ss_mask); - if (err < 0) - return err; - - if (phydev->autoneg == AUTONEG_ENABLE && phydev->autoneg_complete) - phy_resolve_aneg_pause(phydev); - - return 0; -} - static int at803x_config_aneg(struct phy_device *phydev) { struct at803x_priv *priv = phydev->priv; diff --git a/drivers/net/phy/qcom/qca808x.c b/drivers/net/phy/qcom/qca808x.c index 0f549027d899..8124bc2d5e5f 100644 --- a/drivers/net/phy/qcom/qca808x.c +++ b/drivers/net/phy/qcom/qca808x.c @@ -2,7 +2,6 @@ #include #include -#include #include "qcom.h" @@ -63,55 +62,6 @@ #define QCA808X_DBG_AN_TEST 0xb #define QCA808X_HIBERNATION_EN BIT(15) -#define QCA808X_CDT_ENABLE_TEST BIT(15) -#define QCA808X_CDT_INTER_CHECK_DIS BIT(13) -#define QCA808X_CDT_STATUS BIT(11) -#define QCA808X_CDT_LENGTH_UNIT BIT(10) - -#define QCA808X_MMD3_CDT_STATUS 0x8064 -#define QCA808X_MMD3_CDT_DIAG_PAIR_A 0x8065 -#define QCA808X_MMD3_CDT_DIAG_PAIR_B 0x8066 -#define QCA808X_MMD3_CDT_DIAG_PAIR_C 0x8067 -#define QCA808X_MMD3_CDT_DIAG_PAIR_D 0x8068 -#define QCA808X_CDT_DIAG_LENGTH_SAME_SHORT GENMASK(15, 8) -#define QCA808X_CDT_DIAG_LENGTH_CROSS_SHORT GENMASK(7, 0) - -#define QCA808X_CDT_CODE_PAIR_A GENMASK(15, 12) -#define QCA808X_CDT_CODE_PAIR_B GENMASK(11, 8) -#define QCA808X_CDT_CODE_PAIR_C GENMASK(7, 4) -#define QCA808X_CDT_CODE_PAIR_D GENMASK(3, 0) - -#define QCA808X_CDT_STATUS_STAT_TYPE GENMASK(1, 0) -#define QCA808X_CDT_STATUS_STAT_FAIL FIELD_PREP_CONST(QCA808X_CDT_STATUS_STAT_TYPE, 0) -#define QCA808X_CDT_STATUS_STAT_NORMAL FIELD_PREP_CONST(QCA808X_CDT_STATUS_STAT_TYPE, 1) -#define QCA808X_CDT_STATUS_STAT_SAME_OPEN FIELD_PREP_CONST(QCA808X_CDT_STATUS_STAT_TYPE, 2) -#define QCA808X_CDT_STATUS_STAT_SAME_SHORT FIELD_PREP_CONST(QCA808X_CDT_STATUS_STAT_TYPE, 3) - -#define QCA808X_CDT_STATUS_STAT_MDI GENMASK(3, 2) -#define QCA808X_CDT_STATUS_STAT_MDI1 FIELD_PREP_CONST(QCA808X_CDT_STATUS_STAT_MDI, 1) -#define QCA808X_CDT_STATUS_STAT_MDI2 FIELD_PREP_CONST(QCA808X_CDT_STATUS_STAT_MDI, 2) -#define QCA808X_CDT_STATUS_STAT_MDI3 FIELD_PREP_CONST(QCA808X_CDT_STATUS_STAT_MDI, 3) - -/* NORMAL are MDI with type set to 0 */ -#define QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI1_SAME_NORMAL QCA808X_CDT_STATUS_STAT_MDI1 -#define QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI1_SAME_OPEN (QCA808X_CDT_STATUS_STAT_SAME_OPEN |\ - QCA808X_CDT_STATUS_STAT_MDI1) -#define QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI1_SAME_SHORT (QCA808X_CDT_STATUS_STAT_SAME_SHORT |\ - QCA808X_CDT_STATUS_STAT_MDI1) -#define QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI2_SAME_NORMAL QCA808X_CDT_STATUS_STAT_MDI2 -#define QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI2_SAME_OPEN (QCA808X_CDT_STATUS_STAT_SAME_OPEN |\ - QCA808X_CDT_STATUS_STAT_MDI2) -#define QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI2_SAME_SHORT (QCA808X_CDT_STATUS_STAT_SAME_SHORT |\ - QCA808X_CDT_STATUS_STAT_MDI2) -#define QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI3_SAME_NORMAL QCA808X_CDT_STATUS_STAT_MDI3 -#define QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI3_SAME_OPEN (QCA808X_CDT_STATUS_STAT_SAME_OPEN |\ - QCA808X_CDT_STATUS_STAT_MDI3) -#define QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI3_SAME_SHORT (QCA808X_CDT_STATUS_STAT_SAME_SHORT |\ - QCA808X_CDT_STATUS_STAT_MDI3) - -/* Added for reference of existence but should be handled by wait_for_completion already */ -#define QCA808X_CDT_STATUS_STAT_BUSY (BIT(1) | BIT(3)) - #define QCA808X_MMD7_LED_GLOBAL 0x8073 #define QCA808X_LED_BLINK_1 GENMASK(11, 6) #define QCA808X_LED_BLINK_2 GENMASK(5, 0) @@ -396,86 +346,6 @@ static int qca808x_soft_reset(struct phy_device *phydev) return ret; } -static bool qca808x_cdt_fault_length_valid(int cdt_code) -{ - switch (cdt_code) { - case QCA808X_CDT_STATUS_STAT_SAME_SHORT: - case QCA808X_CDT_STATUS_STAT_SAME_OPEN: - case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI1_SAME_NORMAL: - case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI1_SAME_OPEN: - case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI1_SAME_SHORT: - case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI2_SAME_NORMAL: - case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI2_SAME_OPEN: - case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI2_SAME_SHORT: - case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI3_SAME_NORMAL: - case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI3_SAME_OPEN: - case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI3_SAME_SHORT: - return true; - default: - return false; - } -} - -static int qca808x_cable_test_result_trans(int cdt_code) -{ - switch (cdt_code) { - case QCA808X_CDT_STATUS_STAT_NORMAL: - return ETHTOOL_A_CABLE_RESULT_CODE_OK; - case QCA808X_CDT_STATUS_STAT_SAME_SHORT: - return ETHTOOL_A_CABLE_RESULT_CODE_SAME_SHORT; - case QCA808X_CDT_STATUS_STAT_SAME_OPEN: - return ETHTOOL_A_CABLE_RESULT_CODE_OPEN; - case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI1_SAME_NORMAL: - case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI1_SAME_OPEN: - case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI1_SAME_SHORT: - case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI2_SAME_NORMAL: - case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI2_SAME_OPEN: - case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI2_SAME_SHORT: - case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI3_SAME_NORMAL: - case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI3_SAME_OPEN: - case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI3_SAME_SHORT: - return ETHTOOL_A_CABLE_RESULT_CODE_CROSS_SHORT; - case QCA808X_CDT_STATUS_STAT_FAIL: - default: - return ETHTOOL_A_CABLE_RESULT_CODE_UNSPEC; - } -} - -static int qca808x_cdt_fault_length(struct phy_device *phydev, int pair, - int result) -{ - int val; - u32 cdt_length_reg = 0; - - switch (pair) { - case ETHTOOL_A_CABLE_PAIR_A: - cdt_length_reg = QCA808X_MMD3_CDT_DIAG_PAIR_A; - break; - case ETHTOOL_A_CABLE_PAIR_B: - cdt_length_reg = QCA808X_MMD3_CDT_DIAG_PAIR_B; - break; - case ETHTOOL_A_CABLE_PAIR_C: - cdt_length_reg = QCA808X_MMD3_CDT_DIAG_PAIR_C; - break; - case ETHTOOL_A_CABLE_PAIR_D: - cdt_length_reg = QCA808X_MMD3_CDT_DIAG_PAIR_D; - break; - default: - return -EINVAL; - } - - val = phy_read_mmd(phydev, MDIO_MMD_PCS, cdt_length_reg); - if (val < 0) - return val; - - if (result == ETHTOOL_A_CABLE_RESULT_CODE_SAME_SHORT) - val = FIELD_GET(QCA808X_CDT_DIAG_LENGTH_SAME_SHORT, val); - else - val = FIELD_GET(QCA808X_CDT_DIAG_LENGTH_CROSS_SHORT, val); - - return at803x_cdt_fault_length(val); -} - static int qca808x_cable_test_start(struct phy_device *phydev) { int ret; @@ -517,81 +387,6 @@ static int qca808x_cable_test_start(struct phy_device *phydev) return 0; } -static int qca808x_cable_test_get_pair_status(struct phy_device *phydev, u8 pair, - u16 status) -{ - int length, result; - u16 pair_code; - - switch (pair) { - case ETHTOOL_A_CABLE_PAIR_A: - pair_code = FIELD_GET(QCA808X_CDT_CODE_PAIR_A, status); - break; - case ETHTOOL_A_CABLE_PAIR_B: - pair_code = FIELD_GET(QCA808X_CDT_CODE_PAIR_B, status); - break; - case ETHTOOL_A_CABLE_PAIR_C: - pair_code = FIELD_GET(QCA808X_CDT_CODE_PAIR_C, status); - break; - case ETHTOOL_A_CABLE_PAIR_D: - pair_code = FIELD_GET(QCA808X_CDT_CODE_PAIR_D, status); - break; - default: - return -EINVAL; - } - - result = qca808x_cable_test_result_trans(pair_code); - ethnl_cable_test_result(phydev, pair, result); - - if (qca808x_cdt_fault_length_valid(pair_code)) { - length = qca808x_cdt_fault_length(phydev, pair, result); - ethnl_cable_test_fault_length(phydev, pair, length); - } - - return 0; -} - -static int qca808x_cable_test_get_status(struct phy_device *phydev, bool *finished) -{ - int ret, val; - - *finished = false; - - val = QCA808X_CDT_ENABLE_TEST | - QCA808X_CDT_LENGTH_UNIT; - ret = at803x_cdt_start(phydev, val); - if (ret) - return ret; - - ret = at803x_cdt_wait_for_completion(phydev, QCA808X_CDT_ENABLE_TEST); - if (ret) - return ret; - - val = phy_read_mmd(phydev, MDIO_MMD_PCS, QCA808X_MMD3_CDT_STATUS); - if (val < 0) - return val; - - ret = qca808x_cable_test_get_pair_status(phydev, ETHTOOL_A_CABLE_PAIR_A, val); - if (ret) - return ret; - - ret = qca808x_cable_test_get_pair_status(phydev, ETHTOOL_A_CABLE_PAIR_B, val); - if (ret) - return ret; - - ret = qca808x_cable_test_get_pair_status(phydev, ETHTOOL_A_CABLE_PAIR_C, val); - if (ret) - return ret; - - ret = qca808x_cable_test_get_pair_status(phydev, ETHTOOL_A_CABLE_PAIR_D, val); - if (ret) - return ret; - - *finished = true; - - return 0; -} - static int qca808x_get_features(struct phy_device *phydev) { int ret; diff --git a/drivers/net/phy/qcom/qcom-phy-lib.c b/drivers/net/phy/qcom/qcom-phy-lib.c index e0295d4b4a51..786bfc39912c 100644 --- a/drivers/net/phy/qcom/qcom-phy-lib.c +++ b/drivers/net/phy/qcom/qcom-phy-lib.c @@ -5,6 +5,7 @@ #include #include +#include #include "qcom.h" @@ -311,6 +312,42 @@ int at803x_prepare_config_aneg(struct phy_device *phydev) } EXPORT_SYMBOL_GPL(at803x_prepare_config_aneg); +int at803x_read_status(struct phy_device *phydev) +{ + struct at803x_ss_mask ss_mask = { 0 }; + int err, old_link = phydev->link; + + /* Update the link, but return if there was an error */ + err = genphy_update_link(phydev); + if (err) + return err; + + /* why bother the PHY if nothing can have changed */ + if (phydev->autoneg == AUTONEG_ENABLE && old_link && phydev->link) + return 0; + + phydev->speed = SPEED_UNKNOWN; + phydev->duplex = DUPLEX_UNKNOWN; + phydev->pause = 0; + phydev->asym_pause = 0; + + err = genphy_read_lpa(phydev); + if (err < 0) + return err; + + ss_mask.speed_mask = AT803X_SS_SPEED_MASK; + ss_mask.speed_shift = __bf_shf(AT803X_SS_SPEED_MASK); + err = at803x_read_specific_status(phydev, ss_mask); + if (err < 0) + return err; + + if (phydev->autoneg == AUTONEG_ENABLE && phydev->autoneg_complete) + phy_resolve_aneg_pause(phydev); + + return 0; +} +EXPORT_SYMBOL_GPL(at803x_read_status); + static int at803x_get_downshift(struct phy_device *phydev, u8 *d) { int val; @@ -427,3 +464,159 @@ int at803x_cdt_wait_for_completion(struct phy_device *phydev, return ret < 0 ? ret : 0; } EXPORT_SYMBOL_GPL(at803x_cdt_wait_for_completion); + +static bool qca808x_cdt_fault_length_valid(int cdt_code) +{ + switch (cdt_code) { + case QCA808X_CDT_STATUS_STAT_SAME_SHORT: + case QCA808X_CDT_STATUS_STAT_SAME_OPEN: + case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI1_SAME_NORMAL: + case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI1_SAME_OPEN: + case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI1_SAME_SHORT: + case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI2_SAME_NORMAL: + case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI2_SAME_OPEN: + case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI2_SAME_SHORT: + case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI3_SAME_NORMAL: + case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI3_SAME_OPEN: + case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI3_SAME_SHORT: + return true; + default: + return false; + } +} + +static int qca808x_cable_test_result_trans(int cdt_code) +{ + switch (cdt_code) { + case QCA808X_CDT_STATUS_STAT_NORMAL: + return ETHTOOL_A_CABLE_RESULT_CODE_OK; + case QCA808X_CDT_STATUS_STAT_SAME_SHORT: + return ETHTOOL_A_CABLE_RESULT_CODE_SAME_SHORT; + case QCA808X_CDT_STATUS_STAT_SAME_OPEN: + return ETHTOOL_A_CABLE_RESULT_CODE_OPEN; + case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI1_SAME_NORMAL: + case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI1_SAME_OPEN: + case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI1_SAME_SHORT: + case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI2_SAME_NORMAL: + case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI2_SAME_OPEN: + case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI2_SAME_SHORT: + case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI3_SAME_NORMAL: + case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI3_SAME_OPEN: + case QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI3_SAME_SHORT: + return ETHTOOL_A_CABLE_RESULT_CODE_CROSS_SHORT; + case QCA808X_CDT_STATUS_STAT_FAIL: + default: + return ETHTOOL_A_CABLE_RESULT_CODE_UNSPEC; + } +} + +static int qca808x_cdt_fault_length(struct phy_device *phydev, int pair, + int result) +{ + int val; + u32 cdt_length_reg = 0; + + switch (pair) { + case ETHTOOL_A_CABLE_PAIR_A: + cdt_length_reg = QCA808X_MMD3_CDT_DIAG_PAIR_A; + break; + case ETHTOOL_A_CABLE_PAIR_B: + cdt_length_reg = QCA808X_MMD3_CDT_DIAG_PAIR_B; + break; + case ETHTOOL_A_CABLE_PAIR_C: + cdt_length_reg = QCA808X_MMD3_CDT_DIAG_PAIR_C; + break; + case ETHTOOL_A_CABLE_PAIR_D: + cdt_length_reg = QCA808X_MMD3_CDT_DIAG_PAIR_D; + break; + default: + return -EINVAL; + } + + val = phy_read_mmd(phydev, MDIO_MMD_PCS, cdt_length_reg); + if (val < 0) + return val; + + if (result == ETHTOOL_A_CABLE_RESULT_CODE_SAME_SHORT) + val = FIELD_GET(QCA808X_CDT_DIAG_LENGTH_SAME_SHORT, val); + else + val = FIELD_GET(QCA808X_CDT_DIAG_LENGTH_CROSS_SHORT, val); + + return at803x_cdt_fault_length(val); +} + +static int qca808x_cable_test_get_pair_status(struct phy_device *phydev, u8 pair, + u16 status) +{ + int length, result; + u16 pair_code; + + switch (pair) { + case ETHTOOL_A_CABLE_PAIR_A: + pair_code = FIELD_GET(QCA808X_CDT_CODE_PAIR_A, status); + break; + case ETHTOOL_A_CABLE_PAIR_B: + pair_code = FIELD_GET(QCA808X_CDT_CODE_PAIR_B, status); + break; + case ETHTOOL_A_CABLE_PAIR_C: + pair_code = FIELD_GET(QCA808X_CDT_CODE_PAIR_C, status); + break; + case ETHTOOL_A_CABLE_PAIR_D: + pair_code = FIELD_GET(QCA808X_CDT_CODE_PAIR_D, status); + break; + default: + return -EINVAL; + } + + result = qca808x_cable_test_result_trans(pair_code); + ethnl_cable_test_result(phydev, pair, result); + + if (qca808x_cdt_fault_length_valid(pair_code)) { + length = qca808x_cdt_fault_length(phydev, pair, result); + ethnl_cable_test_fault_length(phydev, pair, length); + } + + return 0; +} + +int qca808x_cable_test_get_status(struct phy_device *phydev, bool *finished) +{ + int ret, val; + + *finished = false; + + val = QCA808X_CDT_ENABLE_TEST | + QCA808X_CDT_LENGTH_UNIT; + ret = at803x_cdt_start(phydev, val); + if (ret) + return ret; + + ret = at803x_cdt_wait_for_completion(phydev, QCA808X_CDT_ENABLE_TEST); + if (ret) + return ret; + + val = phy_read_mmd(phydev, MDIO_MMD_PCS, QCA808X_MMD3_CDT_STATUS); + if (val < 0) + return val; + + ret = qca808x_cable_test_get_pair_status(phydev, ETHTOOL_A_CABLE_PAIR_A, val); + if (ret) + return ret; + + ret = qca808x_cable_test_get_pair_status(phydev, ETHTOOL_A_CABLE_PAIR_B, val); + if (ret) + return ret; + + ret = qca808x_cable_test_get_pair_status(phydev, ETHTOOL_A_CABLE_PAIR_C, val); + if (ret) + return ret; + + ret = qca808x_cable_test_get_pair_status(phydev, ETHTOOL_A_CABLE_PAIR_D, val); + if (ret) + return ret; + + *finished = true; + + return 0; +} +EXPORT_SYMBOL_GPL(qca808x_cable_test_get_status); diff --git a/drivers/net/phy/qcom/qcom.h b/drivers/net/phy/qcom/qcom.h index c127d8f50f0f..dc259bbf0678 100644 --- a/drivers/net/phy/qcom/qcom.h +++ b/drivers/net/phy/qcom/qcom.h @@ -54,6 +54,55 @@ #define AT803X_CDT_STATUS_STAT_MASK GENMASK(9, 8) #define AT803X_CDT_STATUS_DELTA_TIME_MASK GENMASK(7, 0) +#define QCA808X_CDT_ENABLE_TEST BIT(15) +#define QCA808X_CDT_INTER_CHECK_DIS BIT(13) +#define QCA808X_CDT_STATUS BIT(11) +#define QCA808X_CDT_LENGTH_UNIT BIT(10) + +#define QCA808X_MMD3_CDT_STATUS 0x8064 +#define QCA808X_MMD3_CDT_DIAG_PAIR_A 0x8065 +#define QCA808X_MMD3_CDT_DIAG_PAIR_B 0x8066 +#define QCA808X_MMD3_CDT_DIAG_PAIR_C 0x8067 +#define QCA808X_MMD3_CDT_DIAG_PAIR_D 0x8068 +#define QCA808X_CDT_DIAG_LENGTH_SAME_SHORT GENMASK(15, 8) +#define QCA808X_CDT_DIAG_LENGTH_CROSS_SHORT GENMASK(7, 0) + +#define QCA808X_CDT_CODE_PAIR_A GENMASK(15, 12) +#define QCA808X_CDT_CODE_PAIR_B GENMASK(11, 8) +#define QCA808X_CDT_CODE_PAIR_C GENMASK(7, 4) +#define QCA808X_CDT_CODE_PAIR_D GENMASK(3, 0) + +#define QCA808X_CDT_STATUS_STAT_TYPE GENMASK(1, 0) +#define QCA808X_CDT_STATUS_STAT_FAIL FIELD_PREP_CONST(QCA808X_CDT_STATUS_STAT_TYPE, 0) +#define QCA808X_CDT_STATUS_STAT_NORMAL FIELD_PREP_CONST(QCA808X_CDT_STATUS_STAT_TYPE, 1) +#define QCA808X_CDT_STATUS_STAT_SAME_OPEN FIELD_PREP_CONST(QCA808X_CDT_STATUS_STAT_TYPE, 2) +#define QCA808X_CDT_STATUS_STAT_SAME_SHORT FIELD_PREP_CONST(QCA808X_CDT_STATUS_STAT_TYPE, 3) + +#define QCA808X_CDT_STATUS_STAT_MDI GENMASK(3, 2) +#define QCA808X_CDT_STATUS_STAT_MDI1 FIELD_PREP_CONST(QCA808X_CDT_STATUS_STAT_MDI, 1) +#define QCA808X_CDT_STATUS_STAT_MDI2 FIELD_PREP_CONST(QCA808X_CDT_STATUS_STAT_MDI, 2) +#define QCA808X_CDT_STATUS_STAT_MDI3 FIELD_PREP_CONST(QCA808X_CDT_STATUS_STAT_MDI, 3) + +/* NORMAL are MDI with type set to 0 */ +#define QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI1_SAME_NORMAL QCA808X_CDT_STATUS_STAT_MDI1 +#define QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI1_SAME_OPEN (QCA808X_CDT_STATUS_STAT_SAME_OPEN |\ + QCA808X_CDT_STATUS_STAT_MDI1) +#define QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI1_SAME_SHORT (QCA808X_CDT_STATUS_STAT_SAME_SHORT |\ + QCA808X_CDT_STATUS_STAT_MDI1) +#define QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI2_SAME_NORMAL QCA808X_CDT_STATUS_STAT_MDI2 +#define QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI2_SAME_OPEN (QCA808X_CDT_STATUS_STAT_SAME_OPEN |\ + QCA808X_CDT_STATUS_STAT_MDI2) +#define QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI2_SAME_SHORT (QCA808X_CDT_STATUS_STAT_SAME_SHORT |\ + QCA808X_CDT_STATUS_STAT_MDI2) +#define QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI3_SAME_NORMAL QCA808X_CDT_STATUS_STAT_MDI3 +#define QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI3_SAME_OPEN (QCA808X_CDT_STATUS_STAT_SAME_OPEN |\ + QCA808X_CDT_STATUS_STAT_MDI3) +#define QCA808X_CDT_STATUS_STAT_CROSS_SHORT_WITH_MDI3_SAME_SHORT (QCA808X_CDT_STATUS_STAT_SAME_SHORT |\ + QCA808X_CDT_STATUS_STAT_MDI3) + +/* Added for reference of existence but should be handled by wait_for_completion already */ +#define QCA808X_CDT_STATUS_STAT_BUSY (BIT(1) | BIT(3)) + #define AT803X_LOC_MAC_ADDR_0_15_OFFSET 0x804C #define AT803X_LOC_MAC_ADDR_16_31_OFFSET 0x804B #define AT803X_LOC_MAC_ADDR_32_47_OFFSET 0x804A @@ -110,6 +159,7 @@ int at803x_read_specific_status(struct phy_device *phydev, struct at803x_ss_mask ss_mask); int at803x_config_mdix(struct phy_device *phydev, u8 ctrl); int at803x_prepare_config_aneg(struct phy_device *phydev); +int at803x_read_status(struct phy_device *phydev); int at803x_get_tunable(struct phy_device *phydev, struct ethtool_tunable *tuna, void *data); int at803x_set_tunable(struct phy_device *phydev, @@ -118,3 +168,4 @@ int at803x_cdt_fault_length(int dt); int at803x_cdt_start(struct phy_device *phydev, u32 cdt_start); int at803x_cdt_wait_for_completion(struct phy_device *phydev, u32 cdt_en); +int qca808x_cable_test_get_status(struct phy_device *phydev, bool *finished); From patchwork Mon Feb 5 16:48:37 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Christian Marangi X-Patchwork-Id: 13545867 X-Patchwork-Delegate: kuba@kernel.org Received: from mail-lf1-f44.google.com (mail-lf1-f44.google.com [209.85.167.44]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 61DB245952; Mon, 5 Feb 2024 16:49:11 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.167.44 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1707151753; cv=none; b=TrriwhVKZz7K6heChCv5/f4bKwqlEbIitf5p5MXW8LljZSp4h8tJzkUaiqWXjX/acxmEfTiPNHtlybu3WZqCNANMQZx5wS/XteRLj8EtLA3aslitijCPzNp2v/N2JfEjVqPIsENEg48zv0jtUj0ensQEpzXKCeHRrz7f6G8BvNs= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1707151753; c=relaxed/simple; bh=Wg5jJEedhsGjN5i61zC/V7MyghdP2OFcHkRYafvEIEk=; h=From:To:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=SP5NxCziGNRoj9fZ5W3TYg3+5ls8gyln7Mpt8wiObPo0eD3BvYW6p07F59F3PVWN7JUqHcRAtTO1S6c6gZv7w6ccDn/CTQChFTfGSp9BABs97adKD7gjPmvmE7UUW9FTMF+0A56OIINCLoW5IHCezb1RekzB4d9rXBaGtMOcQYk= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=Tk9/mvlK; arc=none smtp.client-ip=209.85.167.44 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="Tk9/mvlK" Received: by mail-lf1-f44.google.com with SMTP id 2adb3069b0e04-51137c8088dso4606426e87.1; Mon, 05 Feb 2024 08:49:11 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1707151749; x=1707756549; 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=ik0kKiOnA2UFtkx7hoizPBGiM4n98hhnoOpxjfv8+/Q=; b=Tk9/mvlKzD35K7pp8jN3qA+R6922dSPcsysx3p/t4pqFXiAmvqZkt/9z6r5XAwGMq5 kRi5tyTIUH9FPYI4MCjVjKm7BHmLYFLetegqguYO/pYpIUXhpq8EpCrOIuFWU0AUB7+7 HeT11UbD4qb2nWHc05w7rJWrKL8/8MtMdgMabgptbuvafTwgqi4g9iS6pdYWOwD7uroN h2BcdWDSShusw5iorRB56l+03AzHFRnLzPZI4D6+GrStZ5YYwbASmbglj+pFeMdLN7Mc BIzOu2+WXucrfSwXwtExikiyPqJrQqq5XQ9x+SvMyXTioeeitu8Jh1ZEp8VO3obtsDR9 9EIw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1707151749; x=1707756549; 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=ik0kKiOnA2UFtkx7hoizPBGiM4n98hhnoOpxjfv8+/Q=; b=RYkOp4yF31e3mTKj13Em4q9ASCr/ACx31+NwlcET9ZDMLmt5fwnMDjC3BeuMTOvfJV IND2bxW+ei0/TEIJuoc4ASWxSvwMsAv/me1xKoi08nSXFmCZ1M6zJyyPn/ic/cXW35b1 i9tCOD8p/ckvm9jR9rOlH9iFObIQ9g5MoXgUl5Nl/sSGlDVjU80CoK8JwH9fHaQYnVN4 4IIxqAljKA9RBeIYo49kG/h0n7+0DozCtNktC1IUjh9um18EUD4kOpwxbUZHzO1/BujC pOZWyWztFZ8I072GRiDDQtJwx7x9NE4YFuTuQ/0y14KpsIvzSS/diI2SfgJzamQEg7xU M7WQ== X-Gm-Message-State: AOJu0YzZb88rNxZIoxwi8CeTsCUW4+3vxqxWLSi8oNVaSU1FkXi6FHcW wSQ3rw+IA8yzvXtMhC5hfMZBdDsR3YlLPElaV79r0UnSuKDxLjDF X-Google-Smtp-Source: AGHT+IHVM2lzBYD3zxtZEFsJBnV9ARYndrSilWtLhxFGRvJSsQwO+J5QwCtgEgJawGvE3w/2LEse7w== X-Received: by 2002:ac2:410a:0:b0:511:4f21:4517 with SMTP id b10-20020ac2410a000000b005114f214517mr127917lfi.33.1707151749006; Mon, 05 Feb 2024 08:49:09 -0800 (PST) X-Forwarded-Encrypted: i=0; AJvYcCWVEugsGv/mOoWaB+lGOcd/WTHd4xopt3wV8dg/L7c1WXRbSj4gM6e1DnN8XemxWC9RV1Ixe9ZKxqm8HDXKw+lKXlk+07p5Ha4SOxPesoE4CYBWqlC08r5hr/zflxjLDEB+MxqmIhL+Gbe07Fk4r1XpJ/Wh8DZU5gV6Pby7V2Tq0neLXrTubnEZ9O3e5fCMBW07LZLlk6hpAh7B3aDvXB2JOHNQXdEH4RHovkBUGK6v4TpH7VtDGNeA1jM8U73m+A+ujskEbA+qv7d5pr9cb8HZMsejHKr4h86lOyg47Z9+ADxl5bvUP9/OdE+l0dWItymsGy3w3Eu3KbkCXrI8qXAm9J7eBtuxoHuF43nHksF82cGmtj/5ly6Z66bmQongnPpZJlLO3tn8Mli7s1jPBiBHcVM5gVy9Fs5+mb0oSBKsJTpUR0oNtLl3c9XVdBc3MM0ctOEYi83B5f35zEDH1dhVOTSgLN4lHmtF5JzY8czcLkuD04tq7A2hRPj+mNFSofD2NFSpRsD34nuO1sVnuTuuoEIktTKmLU7fiSjHwFxW1rT0jSMpdWV1Os7gJ2dStdtdyBVJglBI2NY3HiQcbNPZ4ESkdV2DOKWW29DNRBSvPCcLH0t1aoifGRhRB15lRoRk40lQUgo7DMRZ0h38OJB9cKuV6Uc25fq4x1hdr3JCe8XGrJkMog== Received: from localhost.localdomain (93-34-89-13.ip49.fastwebnet.it. [93.34.89.13]) by smtp.googlemail.com with ESMTPSA id k2-20020a05600c1c8200b0040fafd84095sm9140567wms.41.2024.02.05.08.49.07 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 05 Feb 2024 08:49:08 -0800 (PST) From: Christian Marangi To: "David S. Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Bjorn Andersson , Konrad Dybcio , Andrew Lunn , Heiner Kallweit , Russell King , Florian Fainelli , Broadcom internal kernel review list , Christian Marangi , Robert Marko , netdev@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-arm-msm@vger.kernel.org Subject: [net-next PATCH v6 05/10] dt-bindings: net: Document Qcom QCA807x PHY package Date: Mon, 5 Feb 2024 17:48:37 +0100 Message-ID: <20240205164851.1351-6-ansuelsmth@gmail.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20240205164851.1351-1-ansuelsmth@gmail.com> References: <20240205164851.1351-1-ansuelsmth@gmail.com> Precedence: bulk X-Mailing-List: netdev@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Patchwork-Delegate: kuba@kernel.org 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 Reviewed-by: Conor Dooley --- .../devicetree/bindings/net/qcom,qca807x.yaml | 184 ++++++++++++++++++ 1 file changed, 184 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..021246cd7b3a --- /dev/null +++ b/Documentation/devicetree/bindings/net/qcom,qca807x.yaml @@ -0,0 +1,184 @@ +# 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 QCA8072/5 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. + +$ref: ethernet-phy-package.yaml# + +properties: + compatible: + enum: + - qcom,qca8072-package + - qcom,qca8075-package + + qcom,package-mode: + description: | + PHY package can be configured in 3 mode following this table: + + First Serdes mode Second Serdes mode + Option 1 PSGMII for copper Disabled + ports 0-4 + Option 2 PSGMII for copper 1000BASE-X / 100BASE-FX + ports 0-4 + Option 3 QSGMII for copper SGMII for + ports 0-3 copper port 4 + + PSGMII mode (option 1 or 2) is configured dynamically by the driver + based on the presence of a connected SFP device. + $ref: /schemas/types.yaml#/definitions/string + enum: + - qsgmii + - psgmii + default: psgmii + + qcom,tx-driver-strength-milliwatt: + description: set the TX Amplifier value in mv. + $ref: /schemas/types.yaml#/definitions/uint32 + enum: [140, 160, 180, 200, 220, + 240, 260, 280, 300, 320, + 400, 500, 600] + default: 600 + +patternProperties: + ^ethernet-phy@[a-f0-9]+$: + $ref: ethernet-phy.yaml# + + properties: + qcom,dac-full-amplitude: + description: + Set Analog MDI driver amplitude to FULL. + + With this not defined, amplitude is set to DSP. + (amplitude is adjusted based on cable length) + + With this enabled and qcom,dac-full-bias-current + and qcom,dac-disable-bias-current-tweak disabled, + bias current is half. + type: boolean + + qcom,dac-full-bias-current: + description: + Set Analog MDI driver bias current to FULL. + + With this not defined, bias current is set to DSP. + (bias current is adjusted based on cable length) + + Actual bias current might be different with + qcom,dac-disable-bias-current-tweak disabled. + type: boolean + + qcom,dac-disable-bias-current-tweak: + description: | + Set Analog MDI driver bias current to disable tweak + to bias current. + + With this not defined, bias current tweak are enabled + by default. + + With this enabled the following tweak are NOT applied: + - With both FULL amplitude and FULL bias current: bias current + is set to half. + - With only DSP amplitude: bias current is set to half and + is set to 1/4 with cable < 10m. + - With DSP bias current (included both DSP amplitude and + DSP bias current): bias current is half the detected current + with cable < 10m. + type: boolean + + gpio-controller: true + + '#gpio-cells': + const: 2 + + if: + required: + - gpio-controller + then: + properties: + leds: false + + unevaluatedProperties: false + +required: + - compatible + +unevaluatedProperties: false + +examples: + - | + #include + + mdio { + #address-cells = <1>; + #size-cells = <0>; + + ethernet-phy-package@0 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "qcom,qca8075-package"; + reg = <0>; + + qcom,package-mode = "qsgmii"; + + ethernet-phy@0 { + reg = <0>; + + leds { + #address-cells = <1>; + #size-cells = <0>; + + led@0 { + reg = <0>; + color = ; + function = LED_FUNCTION_LAN; + default-state = "keep"; + }; + }; + }; + + ethernet-phy@1 { + reg = <1>; + }; + + ethernet-phy@2 { + reg = <2>; + + gpio-controller; + #gpio-cells = <2>; + }; + + ethernet-phy@3 { + reg = <3>; + }; + + ethernet-phy@4 { + reg = <4>; + }; + }; + }; From patchwork Mon Feb 5 16:48:38 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Christian Marangi X-Patchwork-Id: 13545868 X-Patchwork-Delegate: kuba@kernel.org Received: from mail-wm1-f51.google.com (mail-wm1-f51.google.com [209.85.128.51]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 3A68B47796; Mon, 5 Feb 2024 16:49:12 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.51 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1707151754; cv=none; b=HK/Y06IemDTbmCIsW5nRCrVYuFosP9zVpj0+QMM6DKDBzCsKhRNcSM6odlzw6xSrRZbY3a+dZiVIetimLvQ4EDS3kLSvBdnT4JNVItLtVAahFlkFbpcMFst+JLdFVPvbhRSNmj3soHPq+XQmB7Maxy0rnpdns1n7zYg+DptnHa8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1707151754; c=relaxed/simple; bh=mG+KMNv/A3mLJpuaFQD/GBoSpPY4XzSaY9y3kPO1C5A=; h=From:To:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=YmRDehx8u236e4NCnZA/2gHjdl3t2l0fwzfjk7CCnG4n/0mmqfo+jPUt/lmeUUDrMS6Bhf4iJ170/sl4iq6iVxz8ohOJjj1httPcBIfPLdMPwMNEStVM3DqTPttJM4FdGBQ9wtkS55jrUdZEeildlUwlxoB0pV4Zz3cVoi5Jv6o= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=Xg64uf4B; arc=none smtp.client-ip=209.85.128.51 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="Xg64uf4B" Received: by mail-wm1-f51.google.com with SMTP id 5b1f17b1804b1-40fb3b5893eso38065025e9.0; Mon, 05 Feb 2024 08:49:11 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1707151750; x=1707756550; 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=MCJZjdTnS6Uq1X+PLH0vDHoWwK/834bPA12yZFCUGH4=; b=Xg64uf4B7iqs9vzSCnAVB7P6ckktfC9TkGc4J4Wzt2zcSkEwsVXgXlp3KPj3iNdwoN sc4khUzX7n6dT4j7yC6vciRTyNAoQGUUJNP1NSbZCdppiRHEmKq4XO5KHsBEVeU+/0xN CndH6th8MRQuTEXEwq0zuMWF4ui0o7gA7SvlAQ3RSxs7nLhrgZ/IRdh+AxacfYcfh/AS jXUmoeGK0M/y+MryYIF7C2m7Ej1JqbJ7PH4wnAFcrueY5ExUmc6G7Wc6rNgdcpl8IrL5 V4qhgKJU+B6x/CU1c6ko1rseTq2mZ8YWifOA4gVCKAVaX8UqTpEPNkDV2QriXMEexk+N /I6w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1707151750; x=1707756550; 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=MCJZjdTnS6Uq1X+PLH0vDHoWwK/834bPA12yZFCUGH4=; b=tYh4zpY6wm2FFrYVKYA9hFcw80uQacdjkqNAUIi0I1b+8WJnS6XShK/CUfyDialyW+ xoSzR+WUvzseOueRb4mhuVTyz9wfpJMFQ0D0BMa30ZOSrhMI86N+Q8woCgKJ2Lmy4HlX zbOZolFOzUGRY2gdUBUH1LucvynoTe7DkdVCusHz12jeAPDx1vfy6kznVZh3uX/Y1PvK JGSXvAY8xGNq8WVMLSZLefogOaH4JjUvPxG5RNjKofrLVVArUsZkmwAeunRfzuQljLK0 elnn1CCJsfJeZ3z+iw84SwFNUOQiNK3F/vIf/GhkC8AM+i8qGppoEqB4gT4CdMpupYgF OrOg== X-Gm-Message-State: AOJu0Yx815ekoIsl2YnlOlvsC9hn2K/M70XnQCDU0WyVaH+DilM0wG+9 1bv3RzM7K6BJtksBscs70srwrFbbKxoeryyW2tF0AjnqG8ocKk78 X-Google-Smtp-Source: AGHT+IEDEPzgMRIb7uIB+twc14/N29RzHH+LkwnK/Nt6G+0n+6ccjSFmOowkYPV2YdLZ1FjBeuzp5g== X-Received: by 2002:a05:600c:1c02:b0:40e:46b6:bc48 with SMTP id j2-20020a05600c1c0200b0040e46b6bc48mr230699wms.41.1707151750255; Mon, 05 Feb 2024 08:49:10 -0800 (PST) X-Forwarded-Encrypted: i=0; AJvYcCXYbMPE+KrWwopIcUqLHL16J9m6BrOCevgdpd2u1GVnbEiPmgZjMoN85aoaPGSanbLLOrnRdBQl8GeWH8dRPmXZWfx1irZM+1N4VtIOCOR9cwDSj0+o52pJxbHrk+zqKeAvk2qH6TVBTfE4E3FHo0mCd2QTFNX01UOf64BNM4Ciqmpzl5BjUIobL4RyMnJN4Rk7Gikwk266UOaAiMtrJv09ZmSbGmzoa5jRkic4cn6mGu7wupM/fxfvrG/V2hrtZ7kxi8qsVThlEuNyhHzFEWT8Re+m6AhtJJXlCHC7Bmpajg3EkbMgso+hrMvHd637o+G2WEbEns+LY0XcujdimL7ShEajJxOzt6yU/8IYZeGxha/Ea1u4vTZWKxrIq5TJoJdDVS4FP3Wu2L5mHR4b49C3XebXKc6IrXPZLdaVEtac/e0lAdZ59H4rAsSvS2agQfGvK+DcD0rQD2ROgLhKzeMgv4I4NZMOakd7UpQrpEGTQBLAfyge0DjDijckp7jWflw5Q7PyXJZv0yWDpJPRtorDWvm6/OCspzGQ8UEnPcMstHyDs5qm/W6hRZryEEjKoxUbd1LQpXT9FXnl2NS9UnhNbevgtrAWHlDOnkaYy93+U+DQYJTDkbFku5h9oDgyVjiXyTUfHcswaupC7bfDjWR1oEN8tQS9G7NReVpcPx+ReT0fpNgRbA== Received: from localhost.localdomain (93-34-89-13.ip49.fastwebnet.it. [93.34.89.13]) by smtp.googlemail.com with ESMTPSA id k2-20020a05600c1c8200b0040fafd84095sm9140567wms.41.2024.02.05.08.49.09 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 05 Feb 2024 08:49:09 -0800 (PST) From: Christian Marangi To: "David S. Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Bjorn Andersson , Konrad Dybcio , Andrew Lunn , Heiner Kallweit , Russell King , Florian Fainelli , Broadcom internal kernel review list , Christian Marangi , Robert Marko , netdev@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-arm-msm@vger.kernel.org Subject: [net-next PATCH v6 06/10] net: phy: provide whether link has changed in c37_read_status Date: Mon, 5 Feb 2024 17:48:38 +0100 Message-ID: <20240205164851.1351-7-ansuelsmth@gmail.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20240205164851.1351-1-ansuelsmth@gmail.com> References: <20240205164851.1351-1-ansuelsmth@gmail.com> Precedence: bulk X-Mailing-List: netdev@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Patchwork-Delegate: kuba@kernel.org Some PHY driver might require additional regs call after genphy_c37_read_status() is called. Expand genphy_c37_read_status to provide a bool wheather the link has changed or not to permit PHY driver to skip additional regs call if nothing has changed. Every user of genphy_c37_read_status() is updated with the new additional bool. Signed-off-by: Christian Marangi --- drivers/net/phy/broadcom.c | 3 ++- drivers/net/phy/phy_device.c | 11 +++++++++-- drivers/net/phy/qcom/at803x.c | 3 ++- include/linux/phy.h | 2 +- 4 files changed, 14 insertions(+), 5 deletions(-) diff --git a/drivers/net/phy/broadcom.c b/drivers/net/phy/broadcom.c index 312a8bb35d78..370e4ed45098 100644 --- a/drivers/net/phy/broadcom.c +++ b/drivers/net/phy/broadcom.c @@ -665,10 +665,11 @@ static int bcm54616s_config_aneg(struct phy_device *phydev) static int bcm54616s_read_status(struct phy_device *phydev) { struct bcm54616s_phy_priv *priv = phydev->priv; + bool changed; int err; if (priv->mode_1000bx_en) - err = genphy_c37_read_status(phydev); + err = genphy_c37_read_status(phydev, &changed); else err = genphy_read_status(phydev); diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c index c30907dc9fb7..b36839414dfc 100644 --- a/drivers/net/phy/phy_device.c +++ b/drivers/net/phy/phy_device.c @@ -2617,12 +2617,15 @@ EXPORT_SYMBOL(genphy_read_status); /** * genphy_c37_read_status - check the link status and update current link state * @phydev: target phy_device struct + * @changed: pointer where to store if link changed * * Description: Check the link, then figure out the current state * by comparing what we advertise with what the link partner * advertises. This function is for Clause 37 1000Base-X mode. + * + * If link has changed, @changed is set to true, false otherwise. */ -int genphy_c37_read_status(struct phy_device *phydev) +int genphy_c37_read_status(struct phy_device *phydev, bool *changed) { int lpa, err, old_link = phydev->link; @@ -2632,9 +2635,13 @@ int genphy_c37_read_status(struct phy_device *phydev) return err; /* why bother the PHY if nothing can have changed */ - if (phydev->autoneg == AUTONEG_ENABLE && old_link && phydev->link) + if (phydev->autoneg == AUTONEG_ENABLE && old_link && phydev->link) { + *changed = false; return 0; + } + /* Signal link has changed */ + *changed = true; phydev->duplex = DUPLEX_UNKNOWN; phydev->pause = 0; phydev->asym_pause = 0; diff --git a/drivers/net/phy/qcom/at803x.c b/drivers/net/phy/qcom/at803x.c index 3e3ee4c1d4bc..4717c59d51d0 100644 --- a/drivers/net/phy/qcom/at803x.c +++ b/drivers/net/phy/qcom/at803x.c @@ -912,9 +912,10 @@ static int at8031_config_intr(struct phy_device *phydev) static int at8031_read_status(struct phy_device *phydev) { struct at803x_priv *priv = phydev->priv; + bool changed; if (priv->is_1000basex) - return genphy_c37_read_status(phydev); + return genphy_c37_read_status(phydev, &changed); return at803x_read_status(phydev); } diff --git a/include/linux/phy.h b/include/linux/phy.h index 2aed925e6c23..8f7f0101de13 100644 --- a/include/linux/phy.h +++ b/include/linux/phy.h @@ -1876,7 +1876,7 @@ int genphy_write_mmd_unsupported(struct phy_device *phdev, int devnum, /* Clause 37 */ int genphy_c37_config_aneg(struct phy_device *phydev); -int genphy_c37_read_status(struct phy_device *phydev); +int genphy_c37_read_status(struct phy_device *phydev, bool *changed); /* Clause 45 PHY */ int genphy_c45_restart_aneg(struct phy_device *phydev); From patchwork Mon Feb 5 16:48:39 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Christian Marangi X-Patchwork-Id: 13545869 X-Patchwork-Delegate: kuba@kernel.org Received: from mail-wr1-f51.google.com (mail-wr1-f51.google.com [209.85.221.51]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 32970481CD; Mon, 5 Feb 2024 16:49:13 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.221.51 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1707151756; cv=none; b=QUqEJ0yp1bJFdfYCyMxUPhdFoDCeCEUJGyzGPwk1CrfWIOnE9tsuLmOPhdefqaJ3Q+WUoY0LJ5Sobiq+68voV46oUEKfZp526LIlpcupz1Rfk7+jVA1Cof6zY3Mek5orKoi6146+flYgvOfNi7UmqvN23fTZyCb1/6k+jW5+G7I= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1707151756; c=relaxed/simple; bh=JIO5Q4NToHkijFOhkOpq9I2oLqDJ+nKW/XBDN6UzhxM=; h=From:To:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=TzN1GZNfb/G+q8I0o0R8LS3It/AVAeH7Y6N6l2EEro2BuZW74RvCKLH5MA8qK1j+I3NeUzQ36Dx6PFSrHxt7FDb2DKfCjM4VAJ/BuYJev15VSm+TqG/7jx1Ih1qx2AYHP66E8U7hKt9gFa4XEje74tgDfCkxVMH3h1uWemDX25Y= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=S59dRWNg; arc=none smtp.client-ip=209.85.221.51 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="S59dRWNg" Received: by mail-wr1-f51.google.com with SMTP id ffacd0b85a97d-33b401fd72bso654999f8f.3; Mon, 05 Feb 2024 08:49:13 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1707151752; x=1707756552; 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=eAth+Hbw6otxJl0OVFFt9caHiuF+8y5+p+yMYDw15mw=; b=S59dRWNg0XEFJRs2F97TiJVRnGfTWZrixaOh+zMtc+GXz0C9lB6JMG4pg3dfG6OvNZ hOGWqV52XVWxApjCOYWdx6vCKA4xfpnJ3YiVVkvgZVDnBdp2/AKhhqaKo8uVHZN7zs5L unTjZYmyqjnQ1JG+5AWWC5fvs9JJdMgAb7givbcZmeNGDnAFOgb1P6WZYXif+dzagp4X 9sh2T7P2t/WeuEgzcgG89Kcq8MmJZs1f+MuJ3YN2j1joPg9PMQe9MRqKZEjLD6+t6oJ8 KemMGEmAu+lvqj6z9YqQ9QpQc1s9Ev/cPb0U3CXT9+v1/RkXHXOiulQB29PmJJipt7rU /OYQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1707151752; x=1707756552; 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=eAth+Hbw6otxJl0OVFFt9caHiuF+8y5+p+yMYDw15mw=; b=ZK3a8PAZYESrlEzw2Ecrkbn+YCaCQFkNAa6+EcSTsbddSB/NQdpybfXUHO+e8YQ9wR QQ8pI7qbOXt/Geei+8FCf4h4ztkUV40RzhX+Rud24nOM9ETBCgGhCC3HqBN35klQPJhP 2ZIYRVjWQNSrBx+coxHOx98c+c+u6RBRPxizfjwkmbNttYrZ3peaYCA1LpNfITlp39vS gP0H/vYK5QU9BFH+YSnL+UYQcT5CSXF2kCgXOQ6ATYBEfxRwiWk9mF3IVLGMpuYsDPXH ZyABsOVmStF+05TKbYPFu8Nlppbx1dmWh+9tyfyksLM7ZQcN2jpH5RG0E9avowWWbTTH 8x3g== X-Gm-Message-State: AOJu0YzGRlSRtl1auH7ylQiQEzVd0z/dScHAoXcR45tQW+E5UsAYrLLm 83pq2DjJDlDajWuAdp6yBCXGcyaoh69zf6T7sKDSOEUO0VWYPgzq X-Google-Smtp-Source: AGHT+IEa+p2Gu3O5bNF6ARkfDwpkLLOBQjyg3JMGyXPkKBr75Lm6RSe5tzvvKANw/AITvYDtKwGQMA== X-Received: by 2002:a5d:4205:0:b0:336:76de:c171 with SMTP id n5-20020a5d4205000000b0033676dec171mr42537wrq.62.1707151751831; Mon, 05 Feb 2024 08:49:11 -0800 (PST) X-Forwarded-Encrypted: i=0; AJvYcCVBN/rP392aBR4AXOCqzMP23rdDrN6W6799C0gDsxFNocBEFSu4AdE5wQirtKorD+E5RFuemy96KKYvE/mUvWaAesJchsysyZaIrY0ckFiVjJrz5q7dLV6xKQu2rEXaIuEnVh1tRLGLi/uE742EzBF8yw7jnWqGQafdmE7/eLEz7+l2QM240DntucRPkFLUAeJTMHxOhiGPTubZXv90lJImWeOFe8ab15w3omZg7Fs+aZyH36P92X3tPz9c5eRD9cCpTusjxWoGZ3FUg53cWRqaV4PSdWoz8tL2YlNU+WjhxZTbFVaSpqEdqED12X0vKqMorn1/8nLiWCUn2hOftZMdzCX+Ctkqm6UvNHDMlCwKvggkkYBlQHdPm3Sb5kakE6Uh5wOZoI4q64+h+ndLN+ROe+NI78MLqN1Btp53lPMLAdMvQGi9+6RGkeNwut+9eU2lHPttJQ+528b91wHkR7VXJcCbNolqpGAz+yJdRsrLYmdfGjwbouva+r/ATDUOiEqCBF1l9bIzxnqsW5SxouUoUuyDWO8NQZsFt4uZzBGH1sO2I945zEbuJ1m7L2ETSWheGJnhPl4hoJroo3MZwKDtJ9PXAb4yF4W1KnJCKezGYOHe9YxY6yA2xyJXJ0PzizxF/bm7+u8l03c/6fdAZ2MPPA+RtXCETmCWvICGLMBSVQQ62SyCdA== Received: from localhost.localdomain (93-34-89-13.ip49.fastwebnet.it. [93.34.89.13]) by smtp.googlemail.com with ESMTPSA id k2-20020a05600c1c8200b0040fafd84095sm9140567wms.41.2024.02.05.08.49.10 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 05 Feb 2024 08:49:11 -0800 (PST) From: Christian Marangi To: "David S. Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Bjorn Andersson , Konrad Dybcio , Andrew Lunn , Heiner Kallweit , Russell King , Florian Fainelli , Broadcom internal kernel review list , Christian Marangi , Robert Marko , netdev@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-arm-msm@vger.kernel.org Subject: [net-next PATCH v6 07/10] net: phy: qcom: add support for QCA807x PHY Family Date: Mon, 5 Feb 2024 17:48:39 +0100 Message-ID: <20240205164851.1351-8-ansuelsmth@gmail.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20240205164851.1351-1-ansuelsmth@gmail.com> References: <20240205164851.1351-1-ansuelsmth@gmail.com> Precedence: bulk X-Mailing-List: netdev@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Patchwork-Delegate: kuba@kernel.org From: Robert Marko This adds driver for the Qualcomm QCA8072 and QCA8075 PHY-s. They are 2 or 5 port 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. PHY package can be configured in 3 mode following this table: First Serdes mode Second Serdes mode Option 1 PSGMII for copper Disabled ports 0-4 Option 2 PSGMII for copper 1000BASE-X / 100BASE-FX ports 0-4 Option 3 QSGMII for copper SGMII for ports 0-3 copper port 4 Each PHY inside of QCA807x series has 4 digitally controlled output only pins that natively drive LED-s. But some vendors used these to driver generic LED-s controlled by userspace, so lets enable registering each PHY as GPIO controller and add driver for it. These are commonly used in Qualcomm IPQ40xx, IPQ60xx and IPQ807x boards. Co-developed-by: Christian Marangi Signed-off-by: Robert Marko Signed-off-by: Christian Marangi --- drivers/net/phy/qcom/Kconfig | 8 + drivers/net/phy/qcom/Makefile | 1 + drivers/net/phy/qcom/qca807x.c | 597 +++++++++++++++++++++++++++++++++ 3 files changed, 606 insertions(+) create mode 100644 drivers/net/phy/qcom/qca807x.c diff --git a/drivers/net/phy/qcom/Kconfig b/drivers/net/phy/qcom/Kconfig index 80db24deb689..570626cc8e14 100644 --- a/drivers/net/phy/qcom/Kconfig +++ b/drivers/net/phy/qcom/Kconfig @@ -20,3 +20,11 @@ config QCA808X_PHY select QCOM_NET_PHYLIB help Currently supports the QCA8081 model + +config QCA807X_PHY + tristate "Qualcomm QCA807x PHYs" + select QCOM_NET_PHYLIB + depends on OF_MDIO + help + Currently supports the Qualcomm QCA8072, QCA8075 and the PSGMII + control PHY. diff --git a/drivers/net/phy/qcom/Makefile b/drivers/net/phy/qcom/Makefile index 0362d7ed47be..f24fb550babd 100644 --- a/drivers/net/phy/qcom/Makefile +++ b/drivers/net/phy/qcom/Makefile @@ -3,3 +3,4 @@ obj-$(CONFIG_QCOM_NET_PHYLIB) += qcom-phy-lib.o obj-$(CONFIG_AT803X_PHY) += at803x.o obj-$(CONFIG_QCA83XX_PHY) += qca83xx.o obj-$(CONFIG_QCA808X_PHY) += qca808x.o +obj-$(CONFIG_QCA807X_PHY) += qca807x.o diff --git a/drivers/net/phy/qcom/qca807x.c b/drivers/net/phy/qcom/qca807x.c new file mode 100644 index 000000000000..de8ea94c15f7 --- /dev/null +++ b/drivers/net/phy/qcom/qca807x.c @@ -0,0 +1,597 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Copyright (c) 2023 Sartura Ltd. + * + * Author: Robert Marko + * Christian Marangi + * + * Qualcomm QCA8072 and QCA8075 PHY driver + */ + +#include +#include +#include +#include +#include +#include + +#include "qcom.h" + +#define QCA807X_CHIP_CONFIGURATION 0x1f +#define QCA807X_BT_BX_REG_SEL BIT(15) +#define QCA807X_BT_BX_REG_SEL_FIBER 0 +#define QCA807X_BT_BX_REG_SEL_COPPER 1 +#define QCA807X_CHIP_CONFIGURATION_MODE_CFG_MASK GENMASK(3, 0) +#define QCA807X_CHIP_CONFIGURATION_MODE_QSGMII_SGMII 4 +#define QCA807X_CHIP_CONFIGURATION_MODE_PSGMII_FIBER 3 +#define QCA807X_CHIP_CONFIGURATION_MODE_PSGMII_ALL_COPPER 0 + +#define QCA807X_MEDIA_SELECT_STATUS 0x1a +#define QCA807X_MEDIA_DETECTED_COPPER BIT(5) +#define QCA807X_MEDIA_DETECTED_1000_BASE_X BIT(4) +#define QCA807X_MEDIA_DETECTED_100_BASE_FX BIT(3) + +#define QCA807X_MMD7_FIBER_MODE_AUTO_DETECTION 0x807e +#define QCA807X_MMD7_FIBER_MODE_AUTO_DETECTION_EN BIT(0) + +#define QCA807X_MMD7_1000BASE_T_POWER_SAVE_PER_CABLE_LENGTH 0x801a +#define QCA807X_CONTROL_DAC_MASK GENMASK(2, 0) +/* List of tweaks enabled by this bit: + * - With both FULL amplitude and FULL bias current: bias current + * is set to half. + * - With only DSP amplitude: bias current is set to half and + * is set to 1/4 with cable < 10m. + * - With DSP bias current (included both DSP amplitude and + * DSP bias current): bias current is half the detected current + * with cable < 10m. + */ +#define QCA807X_CONTROL_DAC_BIAS_CURRENT_TWEAK BIT(2) +#define QCA807X_CONTROL_DAC_DSP_BIAS_CURRENT BIT(1) +#define QCA807X_CONTROL_DAC_DSP_AMPLITUDE BIT(0) + +#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_MMD7_LED_CTRL(x) (0x8074 + ((x) * 2)) +#define QCA807X_MMD7_LED_FORCE_CTRL(x) (0x8075 + ((x) * 2)) + +#define QCA807X_GPIO_FORCE_EN BIT(15) +#define QCA807X_GPIO_FORCE_MODE_MASK GENMASK(14, 13) + +#define QCA807X_FUNCTION_CONTROL 0x10 +#define QCA807X_FC_MDI_CROSSOVER_MODE_MASK GENMASK(6, 5) +#define QCA807X_FC_MDI_CROSSOVER_AUTO 3 +#define QCA807X_FC_MDI_CROSSOVER_MANUAL_MDIX 1 +#define QCA807X_FC_MDI_CROSSOVER_MANUAL_MDI 0 + +/* PQSGMII Analog PHY specific */ +#define PQSGMII_CTRL_REG 0x0 +#define PQSGMII_ANALOG_SW_RESET BIT(6) +#define PQSGMII_DRIVE_CONTROL_1 0xb +#define PQSGMII_TX_DRIVER_MASK GENMASK(7, 4) +#define PQSGMII_TX_DRIVER_140MV FIELD_PREP(PQSGMII_TX_DRIVER_MASK, 0x0) +#define PQSGMII_TX_DRIVER_160MV FIELD_PREP(PQSGMII_TX_DRIVER_MASK, 0x1) +#define PQSGMII_TX_DRIVER_180MV FIELD_PREP(PQSGMII_TX_DRIVER_MASK, 0x2) +#define PQSGMII_TX_DRIVER_200MV FIELD_PREP(PQSGMII_TX_DRIVER_MASK, 0x3) +#define PQSGMII_TX_DRIVER_220MV FIELD_PREP(PQSGMII_TX_DRIVER_MASK, 0x4) +#define PQSGMII_TX_DRIVER_240MV FIELD_PREP(PQSGMII_TX_DRIVER_MASK, 0x5) +#define PQSGMII_TX_DRIVER_260MV FIELD_PREP(PQSGMII_TX_DRIVER_MASK, 0x6) +#define PQSGMII_TX_DRIVER_280MV FIELD_PREP(PQSGMII_TX_DRIVER_MASK, 0x7) +#define PQSGMII_TX_DRIVER_300MV FIELD_PREP(PQSGMII_TX_DRIVER_MASK, 0x8) +#define PQSGMII_TX_DRIVER_320MV FIELD_PREP(PQSGMII_TX_DRIVER_MASK, 0x9) +#define PQSGMII_TX_DRIVER_400MV FIELD_PREP(PQSGMII_TX_DRIVER_MASK, 0xa) +#define PQSGMII_TX_DRIVER_500MV FIELD_PREP(PQSGMII_TX_DRIVER_MASK, 0xb) +#define PQSGMII_TX_DRIVER_600MV FIELD_PREP(PQSGMII_TX_DRIVER_MASK, 0xc) +#define PQSGMII_MODE_CTRL 0x6d +#define PQSGMII_MODE_CTRL_AZ_WORKAROUND_MASK BIT(0) +#define PQSGMII_MMD3_SERDES_CONTROL 0x805a + +#define PHY_ID_QCA8072 0x004dd0b2 +#define PHY_ID_QCA8075 0x004dd0b1 + +#define QCA807X_COMBO_ADDR_OFFSET 4 +#define QCA807X_PQSGMII_ADDR_OFFSET 5 +#define SERDES_RESET_SLEEP 100 + +enum qca807x_global_phy { + QCA807X_COMBO_ADDR = 4, + QCA807X_PQSGMII_ADDR = 5, +}; + +struct qca807x_shared_priv { + unsigned int package_mode; + u32 tx_driver_strength; +}; + +struct qca807x_gpio_priv { + struct phy_device *phy; +}; + +struct qca807x_priv { + bool dac_full_amplitude; + bool dac_full_bias_current; + bool dac_disable_bias_current_tweak; +}; + +static int qca807x_cable_test_start(struct phy_device *phydev) +{ + /* we do all the (time consuming) work later */ + return 0; +} + +#ifdef CONFIG_GPIOLIB +static int qca807x_gpio_get_direction(struct gpio_chip *gc, unsigned int offset) +{ + return GPIO_LINE_DIRECTION_OUT; +} + +static int qca807x_gpio_get(struct gpio_chip *gc, unsigned int offset) +{ + struct qca807x_gpio_priv *priv = gpiochip_get_data(gc); + u16 reg; + int val; + + reg = QCA807X_MMD7_LED_FORCE_CTRL(offset); + val = phy_read_mmd(priv->phy, MDIO_MMD_AN, reg); + + return FIELD_GET(QCA807X_GPIO_FORCE_MODE_MASK, val); +} + +static void qca807x_gpio_set(struct gpio_chip *gc, unsigned int offset, int value) +{ + struct qca807x_gpio_priv *priv = gpiochip_get_data(gc); + u16 reg; + int val; + + reg = QCA807X_MMD7_LED_FORCE_CTRL(offset); + + val = phy_read_mmd(priv->phy, MDIO_MMD_AN, reg); + val &= ~QCA807X_GPIO_FORCE_MODE_MASK; + val |= QCA807X_GPIO_FORCE_EN; + val |= FIELD_PREP(QCA807X_GPIO_FORCE_MODE_MASK, value); + + phy_write_mmd(priv->phy, MDIO_MMD_AN, reg, val); +} + +static int qca807x_gpio_dir_out(struct gpio_chip *gc, unsigned int offset, int value) +{ + qca807x_gpio_set(gc, offset, value); + + return 0; +} + +static int qca807x_gpio(struct phy_device *phydev) +{ + struct device *dev = &phydev->mdio.dev; + struct qca807x_gpio_priv *priv; + struct gpio_chip *gc; + + priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); + if (!priv) + return -ENOMEM; + + priv->phy = phydev; + + gc = devm_kzalloc(dev, sizeof(*gc), GFP_KERNEL); + if (!gc) + return -ENOMEM; + + gc->label = dev_name(dev); + gc->base = -1; + gc->ngpio = 2; + gc->parent = dev; + gc->owner = THIS_MODULE; + gc->can_sleep = true; + gc->get_direction = qca807x_gpio_get_direction; + gc->direction_output = qca807x_gpio_dir_out; + gc->get = qca807x_gpio_get; + gc->set = qca807x_gpio_set; + + return devm_gpiochip_add_data(dev, gc, priv); +} +#endif + +static int qca807x_read_fiber_status(struct phy_device *phydev) +{ + bool changed; + int ss, err; + + err = genphy_c37_read_status(phydev, &changed); + if (err || !changed) + return err; + + /* Read the QCA807x PHY-Specific Status register fiber page, + * which indicates the speed and duplex that the PHY is actually + * using, irrespective of whether we are in autoneg mode or not. + */ + ss = phy_read(phydev, AT803X_SPECIFIC_STATUS); + if (ss < 0) + return ss; + + phydev->speed = SPEED_UNKNOWN; + phydev->duplex = DUPLEX_UNKNOWN; + if (ss & AT803X_SS_SPEED_DUPLEX_RESOLVED) { + switch (FIELD_GET(AT803X_SS_SPEED_MASK, ss)) { + case AT803X_SS_SPEED_100: + phydev->speed = SPEED_100; + break; + case AT803X_SS_SPEED_1000: + phydev->speed = SPEED_1000; + break; + } + + if (ss & AT803X_SS_DUPLEX) + phydev->duplex = DUPLEX_FULL; + else + phydev->duplex = DUPLEX_HALF; + } + + return 0; +} + +static int qca807x_read_status(struct phy_device *phydev) +{ + if (linkmode_test_bit(ETHTOOL_LINK_MODE_FIBRE_BIT, phydev->supported)) { + switch (phydev->port) { + case PORT_FIBRE: + return qca807x_read_fiber_status(phydev); + case PORT_TP: + return at803x_read_status(phydev); + default: + return -EINVAL; + } + } + + return at803x_read_status(phydev); +} + +static int qca807x_phy_package_probe_once(struct phy_device *phydev) +{ + struct phy_package_shared *shared = phydev->shared; + struct qca807x_shared_priv *priv = shared->priv; + unsigned int tx_driver_strength; + const char *package_mode_name; + + /* Default to 600mw if not defined */ + if (of_property_read_u32(shared->np, "qcom,tx-driver-strength", + &tx_driver_strength)) + tx_driver_strength = 600; + + switch (tx_driver_strength) { + case 140: + priv->tx_driver_strength = PQSGMII_TX_DRIVER_140MV; + break; + case 160: + priv->tx_driver_strength = PQSGMII_TX_DRIVER_160MV; + break; + case 180: + priv->tx_driver_strength = PQSGMII_TX_DRIVER_180MV; + break; + case 200: + priv->tx_driver_strength = PQSGMII_TX_DRIVER_200MV; + break; + case 220: + priv->tx_driver_strength = PQSGMII_TX_DRIVER_220MV; + break; + case 240: + priv->tx_driver_strength = PQSGMII_TX_DRIVER_240MV; + break; + case 260: + priv->tx_driver_strength = PQSGMII_TX_DRIVER_260MV; + break; + case 280: + priv->tx_driver_strength = PQSGMII_TX_DRIVER_280MV; + break; + case 300: + priv->tx_driver_strength = PQSGMII_TX_DRIVER_300MV; + break; + case 320: + priv->tx_driver_strength = PQSGMII_TX_DRIVER_320MV; + break; + case 400: + priv->tx_driver_strength = PQSGMII_TX_DRIVER_400MV; + break; + case 500: + priv->tx_driver_strength = PQSGMII_TX_DRIVER_500MV; + break; + case 600: + priv->tx_driver_strength = PQSGMII_TX_DRIVER_600MV; + break; + default: + return -EINVAL; + } + + priv->package_mode = PHY_INTERFACE_MODE_NA; + if (!of_property_read_string(shared->np, "qcom,package-mode", + &package_mode_name)) { + if (!strcasecmp(package_mode_name, + phy_modes(PHY_INTERFACE_MODE_PSGMII))) + priv->package_mode = PHY_INTERFACE_MODE_PSGMII; + else if (!strcasecmp(package_mode_name, + phy_modes(PHY_INTERFACE_MODE_QSGMII))) + priv->package_mode = PHY_INTERFACE_MODE_QSGMII; + else + return -EINVAL; + } + + return 0; +} + +static int qca807x_phy_package_config_init_once(struct phy_device *phydev) +{ + struct phy_package_shared *shared = phydev->shared; + struct qca807x_shared_priv *priv = shared->priv; + int val, ret; + + phy_lock_mdio_bus(phydev); + + /* Set correct PHY package mode */ + val = __phy_package_read(phydev, QCA807X_COMBO_ADDR, + QCA807X_CHIP_CONFIGURATION); + val &= ~QCA807X_CHIP_CONFIGURATION_MODE_CFG_MASK; + /* package_mode can be QSGMII or PSGMII and we validate + * this in probe_once. + * With package_mode to NA, we default to PSGMII. + */ + switch (priv->package_mode) { + case PHY_INTERFACE_MODE_QSGMII: + val |= QCA807X_CHIP_CONFIGURATION_MODE_QSGMII_SGMII; + break; + case PHY_INTERFACE_MODE_PSGMII: + default: + val |= QCA807X_CHIP_CONFIGURATION_MODE_PSGMII_ALL_COPPER; + } + ret = __phy_package_write(phydev, QCA807X_COMBO_ADDR, + QCA807X_CHIP_CONFIGURATION, val); + if (ret) + goto exit; + + /* After mode change Serdes reset is required */ + val = __phy_package_read(phydev, QCA807X_PQSGMII_ADDR, + PQSGMII_CTRL_REG); + val &= ~PQSGMII_ANALOG_SW_RESET; + ret = __phy_package_write(phydev, QCA807X_PQSGMII_ADDR, + PQSGMII_CTRL_REG, val); + if (ret) + goto exit; + + msleep(SERDES_RESET_SLEEP); + + val = __phy_package_read(phydev, QCA807X_PQSGMII_ADDR, + PQSGMII_CTRL_REG); + val |= PQSGMII_ANALOG_SW_RESET; + ret = __phy_package_write(phydev, QCA807X_PQSGMII_ADDR, + PQSGMII_CTRL_REG, val); + if (ret) + goto exit; + + /* Workaround to enable AZ transmitting ability */ + val = __phy_package_read_mmd(phydev, QCA807X_PQSGMII_ADDR, + MDIO_MMD_PMAPMD, PQSGMII_MODE_CTRL); + val &= ~PQSGMII_MODE_CTRL_AZ_WORKAROUND_MASK; + ret = __phy_package_write_mmd(phydev, QCA807X_PQSGMII_ADDR, + MDIO_MMD_PMAPMD, PQSGMII_MODE_CTRL, val); + if (ret) + goto exit; + + /* Set PQSGMII TX AMP strength */ + val = __phy_package_read(phydev, QCA807X_PQSGMII_ADDR, + PQSGMII_DRIVE_CONTROL_1); + val &= ~PQSGMII_TX_DRIVER_MASK; + val |= FIELD_PREP(PQSGMII_TX_DRIVER_MASK, priv->tx_driver_strength); + ret = __phy_package_write(phydev, QCA807X_PQSGMII_ADDR, + PQSGMII_DRIVE_CONTROL_1, val); + if (ret) + goto exit; + + /* Prevent PSGMII going into hibernation via PSGMII self test */ + val = __phy_package_read_mmd(phydev, QCA807X_COMBO_ADDR, + MDIO_MMD_PCS, PQSGMII_MMD3_SERDES_CONTROL); + val &= ~BIT(1); + ret = __phy_package_write_mmd(phydev, QCA807X_COMBO_ADDR, + MDIO_MMD_PCS, PQSGMII_MMD3_SERDES_CONTROL, val); + +exit: + phy_unlock_mdio_bus(phydev); + + return ret; +} + +static int qca807x_sfp_insert(void *upstream, const struct sfp_eeprom_id *id) +{ + struct phy_device *phydev = upstream; + __ETHTOOL_DECLARE_LINK_MODE_MASK(support) = { 0, }; + phy_interface_t iface; + int ret; + DECLARE_PHY_INTERFACE_MASK(interfaces); + + sfp_parse_support(phydev->sfp_bus, id, support, interfaces); + iface = sfp_select_interface(phydev->sfp_bus, support); + + dev_info(&phydev->mdio.dev, "%s SFP module inserted\n", phy_modes(iface)); + + switch (iface) { + case PHY_INTERFACE_MODE_1000BASEX: + case PHY_INTERFACE_MODE_100BASEX: + /* Set PHY mode to PSGMII combo (1/4 copper + combo ports) mode */ + ret = phy_modify(phydev, + QCA807X_CHIP_CONFIGURATION, + QCA807X_CHIP_CONFIGURATION_MODE_CFG_MASK, + QCA807X_CHIP_CONFIGURATION_MODE_PSGMII_FIBER); + /* Enable fiber mode autodection (1000Base-X or 100Base-FX) */ + ret = phy_set_bits_mmd(phydev, + MDIO_MMD_AN, + QCA807X_MMD7_FIBER_MODE_AUTO_DETECTION, + QCA807X_MMD7_FIBER_MODE_AUTO_DETECTION_EN); + /* Select fiber page */ + ret = phy_clear_bits(phydev, + QCA807X_CHIP_CONFIGURATION, + QCA807X_BT_BX_REG_SEL); + + phydev->port = PORT_FIBRE; + break; + default: + dev_err(&phydev->mdio.dev, "Incompatible SFP module inserted\n"); + return -EINVAL; + } + + return ret; +} + +static void qca807x_sfp_remove(void *upstream) +{ + struct phy_device *phydev = upstream; + + /* Select copper page */ + phy_set_bits(phydev, + QCA807X_CHIP_CONFIGURATION, + QCA807X_BT_BX_REG_SEL); + + phydev->port = PORT_TP; +} + +static const struct sfp_upstream_ops qca807x_sfp_ops = { + .attach = phy_sfp_attach, + .detach = phy_sfp_detach, + .module_insert = qca807x_sfp_insert, + .module_remove = qca807x_sfp_remove, +}; + +static int qca807x_probe(struct phy_device *phydev) +{ + struct device_node *node = phydev->mdio.dev.of_node; + struct qca807x_shared_priv *shared_priv; + struct device *dev = &phydev->mdio.dev; + struct phy_package_shared *shared; + struct qca807x_priv *priv; + int ret; + + ret = devm_of_phy_package_join(dev, phydev, sizeof(*shared_priv)); + if (ret) + return ret; + + if (phy_package_probe_once(phydev)) { + ret = qca807x_phy_package_probe_once(phydev); + if (ret) + return ret; + } + + shared = phydev->shared; + shared_priv = shared->priv; + + /* Make sure PHY follow PHY package mode if enforced */ + if (shared_priv->package_mode != PHY_INTERFACE_MODE_NA && + phydev->interface != shared_priv->package_mode) + return -EINVAL; + + priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); + if (!priv) + return -ENOMEM; + + priv->dac_full_amplitude = of_property_read_bool(node, "qcom,dac-full-amplitude"); + priv->dac_full_bias_current = of_property_read_bool(node, "qcom,dac-full-bias-current"); + priv->dac_disable_bias_current_tweak = of_property_read_bool(node, + "qcom,dac-disable-bias-current-tweak"); + + if (IS_ENABLED(CONFIG_GPIOLIB)) { + /* Do not register a GPIO controller unless flagged for it */ + if (of_property_read_bool(node, "gpio-controller")) { + ret = qca807x_gpio(phydev); + if (ret) + return ret; + } + } + + /* Attach SFP bus on combo port*/ + if (phy_read(phydev, QCA807X_CHIP_CONFIGURATION)) { + ret = phy_sfp_probe(phydev, &qca807x_sfp_ops); + if (ret) + return ret; + linkmode_set_bit(ETHTOOL_LINK_MODE_FIBRE_BIT, phydev->supported); + linkmode_set_bit(ETHTOOL_LINK_MODE_FIBRE_BIT, phydev->advertising); + } + + phydev->priv = priv; + + return 0; +} + +static int qca807x_config_init(struct phy_device *phydev) +{ + struct qca807x_priv *priv = phydev->priv; + u16 control_dac; + int ret; + + if (phy_package_init_once(phydev)) { + ret = qca807x_phy_package_config_init_once(phydev); + if (ret) + return ret; + } + + control_dac = phy_read_mmd(phydev, MDIO_MMD_AN, + QCA807X_MMD7_1000BASE_T_POWER_SAVE_PER_CABLE_LENGTH); + control_dac &= ~QCA807X_CONTROL_DAC_MASK; + if (!priv->dac_full_amplitude) + control_dac |= QCA807X_CONTROL_DAC_DSP_AMPLITUDE; + if (!priv->dac_full_amplitude) + control_dac |= QCA807X_CONTROL_DAC_DSP_BIAS_CURRENT; + if (!priv->dac_disable_bias_current_tweak) + control_dac |= QCA807X_CONTROL_DAC_BIAS_CURRENT_TWEAK; + return phy_write_mmd(phydev, MDIO_MMD_AN, + QCA807X_MMD7_1000BASE_T_POWER_SAVE_PER_CABLE_LENGTH, + control_dac); +} + +static struct phy_driver qca807x_drivers[] = { + { + PHY_ID_MATCH_EXACT(PHY_ID_QCA8072), + .name = "Qualcomm QCA8072", + .flags = PHY_POLL_CABLE_TEST, + /* PHY_GBIT_FEATURES */ + .probe = qca807x_probe, + .config_init = qca807x_config_init, + .read_status = qca807x_read_status, + .config_intr = at803x_config_intr, + .handle_interrupt = at803x_handle_interrupt, + .soft_reset = genphy_soft_reset, + .get_tunable = at803x_get_tunable, + .set_tunable = at803x_set_tunable, + .resume = genphy_resume, + .suspend = genphy_suspend, + .cable_test_start = qca807x_cable_test_start, + .cable_test_get_status = qca808x_cable_test_get_status, + }, + { + PHY_ID_MATCH_EXACT(PHY_ID_QCA8075), + .name = "Qualcomm QCA8075", + .flags = PHY_POLL_CABLE_TEST, + /* PHY_GBIT_FEATURES */ + .probe = qca807x_probe, + .config_init = qca807x_config_init, + .read_status = qca807x_read_status, + .config_intr = at803x_config_intr, + .handle_interrupt = at803x_handle_interrupt, + .soft_reset = genphy_soft_reset, + .get_tunable = at803x_get_tunable, + .set_tunable = at803x_set_tunable, + .resume = genphy_resume, + .suspend = genphy_suspend, + .cable_test_start = qca807x_cable_test_start, + .cable_test_get_status = qca808x_cable_test_get_status, + }, +}; +module_phy_driver(qca807x_drivers); + +static struct mdio_device_id __maybe_unused qca807x_tbl[] = { + { PHY_ID_MATCH_EXACT(PHY_ID_QCA8072) }, + { PHY_ID_MATCH_EXACT(PHY_ID_QCA8075) }, + { } +}; + +MODULE_AUTHOR("Robert Marko "); +MODULE_AUTHOR("Christian Marangi "); +MODULE_DESCRIPTION("Qualcomm QCA807x PHY driver"); +MODULE_DEVICE_TABLE(mdio, qca807x_tbl); +MODULE_LICENSE("GPL"); From patchwork Mon Feb 5 16:48:40 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Christian Marangi X-Patchwork-Id: 13545870 X-Patchwork-Delegate: kuba@kernel.org Received: from mail-wm1-f46.google.com (mail-wm1-f46.google.com [209.85.128.46]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 09C66482EC; Mon, 5 Feb 2024 16:49:14 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.46 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1707151757; cv=none; b=G9f26890Ofg98zgw7FwqEd1r1BfYD5UWNbOqZ3Y2t2aSjv1jQSG+mnbvbOYbXj1ghbPuLNMkTazCItdtESO1PqqvSg8KaOlMKTek14Dr04LWup/50TWr3S+ymREZaMny3+UMW/cMRoElFovP5gj23hL/0GEAxQpTZyZUiJ1pG5E= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1707151757; c=relaxed/simple; bh=DJnY8mF3yKbImXawZIGUIbNxFavZeCJ4NbAohXySnMo=; h=From:To:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=Q1iXsb3XDSY563pIKKkn5f9R9Mah/oJF83pWFBvjzrRxI8CG2/RQMhFD9zn1kWXKMhvkHWqTlT6C9+vvHxHC4bSvaFdnCfJv7dvewCZSYai/je2AqQUO6WTYc/3veRksYdU+rSTk8nZDjM1cFMsSY6LUPCRKUya2rjOmYYeWjp4= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=RI/le5uO; arc=none smtp.client-ip=209.85.128.46 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="RI/le5uO" Received: by mail-wm1-f46.google.com with SMTP id 5b1f17b1804b1-40fc6343bd2so29101715e9.1; Mon, 05 Feb 2024 08:49:14 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1707151753; x=1707756553; 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=JCMP/fDewkGgGWnH4cfQZYvy8INkiAOziFa+q+/zteg=; b=RI/le5uOfGyXZgbxLmODf7Of6DNk8+aWGimtU9Vs3fw6HJE6xevQl62ExrFTkIi9Uo JWY8rTOqtxXMvp7nt0fjHobZpgkepo/i+nWIcc9hnav4EMmuG2iDSkuRC8JFCyhfmn4o XrabiZUCusNo+6BcAdN8UgH4BLTRjgXu9kZiHdpvhSKWM9hnN/fQQALQaQ1oItb0XXDe 13iHjyb8yoaINUwIlbxf3wagIOMfIL5eH7NO6ycKzuyayM/F5M6E+U3CtwKVHcDrazG8 o/O30eD8p4+m8hZDl3sLIpTeH0FqqeP45oxftnWtGkbia3XIRPXdXHIsaURe9uHvEl+I oqQQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1707151753; x=1707756553; 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=JCMP/fDewkGgGWnH4cfQZYvy8INkiAOziFa+q+/zteg=; b=w5nWybACaTOfOQ3xmWvjlQ4VZCo8wWWUz7WGcJMC2JB8TrToQaen4B2syrfG2XXJLs 50rV/hRyBzchbwOfjDmJL08Yo2dADd6+1DvLrgek65mji59DyfwDoEb2XNzV0sTJrlg9 fh05hboaTdRZ1ZYB0s36T++PVEI+ExMyxhNU+Y7wj9WekuIbN0KQZNlSJnOruHSkFJx6 EcxY8vWhHqKl3BY0VNdpazfrCC0TOXQhpeJTo5L+QsvbMKlNMM1xbZhjxfBl5MD16qHS JlXP154Ib8hgXieosf3A5mqvq/wqGkvlk+p8NsNbyxPapwW4Rg4akPxLm4nFDyXScy10 bgGA== X-Gm-Message-State: AOJu0Yytx+MW5E87tK1tPmTupLoC5+vsVjfvQal2yJZoTh+OVnu9zU5T wwOcQI/1DoyU3KAwqyBTmUvRWFQv3CRYpNuKU0ou2vydclEtZixu X-Google-Smtp-Source: AGHT+IG215POtBLQSBQwa3yTnhi9BZiMKsS0BbyxD1ll4LM1I/2biR4IdTys7nCoSgq0zzm6a8nV9A== X-Received: by 2002:a05:600c:450c:b0:40f:c234:1fd5 with SMTP id t12-20020a05600c450c00b0040fc2341fd5mr279165wmo.11.1707151753052; Mon, 05 Feb 2024 08:49:13 -0800 (PST) X-Forwarded-Encrypted: i=0; AJvYcCWqJAEv33qKKL54gkHxCeYKV57Wfq2DmrwVvkbZ2MlQUA2v8Id7yDhDjVSXWM0tcKDdMbFrWlnHw0uqrTNL2aG/kkgpZVTZlbsV7xeNMfg5/hig7PqG0nhepX9fz6w1VzH6rh+385WFajgT4ootPaeTwUt0mNksG37yX+KHDr/qVbfIUXm2D2M+tzVAj2otm4lnkR2WJW7ScqinIoGggu2Iz4dmGEfUa333d2y9BQa58HcSaC/EgTzb2JFHrF8/frMEV5V1Bzx6RZJf3uZiG3VufQA/YSjPhaUkINs7q1bFaBx7vSMJYNU127dl7ZC53us7lGNY7QocY/YISaxFNlyotZdWRRCa2lH6J5+DCrywyYfVsTz8dCUesT8G40GaWJrNhHP4pCvZUSlsn8mWKkqGRDsotseVW2+O9Hj2DvXt0uG0nl5IH4W1h9dJ4i2myM8y23IqUJrn7CUqbnA/WIV6gGcIs66WbXl9SaaLQBkEBfrP8m5QcVqoa+DXgDp+S/CZ/hivJIsDA1pNMQYBgxSnAN3LfVyFJZ7cKmOKGR+VKItI/eaUEURXnZuGIJE88DzYu2/wXNfOT2LVgS7+v3etJRvyYJQIbaA54fPbN2FWdzK6KIiKPOlIPhIeeOfoFy+0Blh3SWJ8EIl7xeMOLcMS4DET+yycvJp2WnvbhZwZ24SEwR3/QQ== Received: from localhost.localdomain (93-34-89-13.ip49.fastwebnet.it. [93.34.89.13]) by smtp.googlemail.com with ESMTPSA id k2-20020a05600c1c8200b0040fafd84095sm9140567wms.41.2024.02.05.08.49.11 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 05 Feb 2024 08:49:12 -0800 (PST) From: Christian Marangi To: "David S. Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Bjorn Andersson , Konrad Dybcio , Andrew Lunn , Heiner Kallweit , Russell King , Florian Fainelli , Broadcom internal kernel review list , Christian Marangi , Robert Marko , netdev@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-arm-msm@vger.kernel.org Subject: [net-next PATCH v6 08/10] net: phy: qcom: move common qca808x LED define to shared header Date: Mon, 5 Feb 2024 17:48:40 +0100 Message-ID: <20240205164851.1351-9-ansuelsmth@gmail.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20240205164851.1351-1-ansuelsmth@gmail.com> References: <20240205164851.1351-1-ansuelsmth@gmail.com> Precedence: bulk X-Mailing-List: netdev@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Patchwork-Delegate: kuba@kernel.org The LED implementation of qca808x and qca807x is the same but qca807x supports also Fiber port and have different hw control bits for Fiber port. In preparation for qca807x introduction, move all the common define to shared header. Signed-off-by: Christian Marangi --- drivers/net/phy/qcom/qca808x.c | 65 ---------------------------------- drivers/net/phy/qcom/qcom.h | 65 ++++++++++++++++++++++++++++++++++ 2 files changed, 65 insertions(+), 65 deletions(-) diff --git a/drivers/net/phy/qcom/qca808x.c b/drivers/net/phy/qcom/qca808x.c index 8124bc2d5e5f..b6ff2676d921 100644 --- a/drivers/net/phy/qcom/qca808x.c +++ b/drivers/net/phy/qcom/qca808x.c @@ -62,29 +62,6 @@ #define QCA808X_DBG_AN_TEST 0xb #define QCA808X_HIBERNATION_EN BIT(15) -#define QCA808X_MMD7_LED_GLOBAL 0x8073 -#define QCA808X_LED_BLINK_1 GENMASK(11, 6) -#define QCA808X_LED_BLINK_2 GENMASK(5, 0) -/* Values are the same for both BLINK_1 and BLINK_2 */ -#define QCA808X_LED_BLINK_FREQ_MASK GENMASK(5, 3) -#define QCA808X_LED_BLINK_FREQ_2HZ FIELD_PREP(QCA808X_LED_BLINK_FREQ_MASK, 0x0) -#define QCA808X_LED_BLINK_FREQ_4HZ FIELD_PREP(QCA808X_LED_BLINK_FREQ_MASK, 0x1) -#define QCA808X_LED_BLINK_FREQ_8HZ FIELD_PREP(QCA808X_LED_BLINK_FREQ_MASK, 0x2) -#define QCA808X_LED_BLINK_FREQ_16HZ FIELD_PREP(QCA808X_LED_BLINK_FREQ_MASK, 0x3) -#define QCA808X_LED_BLINK_FREQ_32HZ FIELD_PREP(QCA808X_LED_BLINK_FREQ_MASK, 0x4) -#define QCA808X_LED_BLINK_FREQ_64HZ FIELD_PREP(QCA808X_LED_BLINK_FREQ_MASK, 0x5) -#define QCA808X_LED_BLINK_FREQ_128HZ FIELD_PREP(QCA808X_LED_BLINK_FREQ_MASK, 0x6) -#define QCA808X_LED_BLINK_FREQ_256HZ FIELD_PREP(QCA808X_LED_BLINK_FREQ_MASK, 0x7) -#define QCA808X_LED_BLINK_DUTY_MASK GENMASK(2, 0) -#define QCA808X_LED_BLINK_DUTY_50_50 FIELD_PREP(QCA808X_LED_BLINK_DUTY_MASK, 0x0) -#define QCA808X_LED_BLINK_DUTY_75_25 FIELD_PREP(QCA808X_LED_BLINK_DUTY_MASK, 0x1) -#define QCA808X_LED_BLINK_DUTY_25_75 FIELD_PREP(QCA808X_LED_BLINK_DUTY_MASK, 0x2) -#define QCA808X_LED_BLINK_DUTY_33_67 FIELD_PREP(QCA808X_LED_BLINK_DUTY_MASK, 0x3) -#define QCA808X_LED_BLINK_DUTY_67_33 FIELD_PREP(QCA808X_LED_BLINK_DUTY_MASK, 0x4) -#define QCA808X_LED_BLINK_DUTY_17_83 FIELD_PREP(QCA808X_LED_BLINK_DUTY_MASK, 0x5) -#define QCA808X_LED_BLINK_DUTY_83_17 FIELD_PREP(QCA808X_LED_BLINK_DUTY_MASK, 0x6) -#define QCA808X_LED_BLINK_DUTY_8_92 FIELD_PREP(QCA808X_LED_BLINK_DUTY_MASK, 0x7) - #define QCA808X_MMD7_LED2_CTRL 0x8074 #define QCA808X_MMD7_LED2_FORCE_CTRL 0x8075 #define QCA808X_MMD7_LED1_CTRL 0x8076 @@ -92,51 +69,9 @@ #define QCA808X_MMD7_LED0_CTRL 0x8078 #define QCA808X_MMD7_LED_CTRL(x) (0x8078 - ((x) * 2)) -/* LED hw control pattern is the same for every LED */ -#define QCA808X_LED_PATTERN_MASK GENMASK(15, 0) -#define QCA808X_LED_SPEED2500_ON BIT(15) -#define QCA808X_LED_SPEED2500_BLINK BIT(14) -/* Follow blink trigger even if duplex or speed condition doesn't match */ -#define QCA808X_LED_BLINK_CHECK_BYPASS BIT(13) -#define QCA808X_LED_FULL_DUPLEX_ON BIT(12) -#define QCA808X_LED_HALF_DUPLEX_ON BIT(11) -#define QCA808X_LED_TX_BLINK BIT(10) -#define QCA808X_LED_RX_BLINK BIT(9) -#define QCA808X_LED_TX_ON_10MS BIT(8) -#define QCA808X_LED_RX_ON_10MS BIT(7) -#define QCA808X_LED_SPEED1000_ON BIT(6) -#define QCA808X_LED_SPEED100_ON BIT(5) -#define QCA808X_LED_SPEED10_ON BIT(4) -#define QCA808X_LED_COLLISION_BLINK BIT(3) -#define QCA808X_LED_SPEED1000_BLINK BIT(2) -#define QCA808X_LED_SPEED100_BLINK BIT(1) -#define QCA808X_LED_SPEED10_BLINK BIT(0) - #define QCA808X_MMD7_LED0_FORCE_CTRL 0x8079 #define QCA808X_MMD7_LED_FORCE_CTRL(x) (0x8079 - ((x) * 2)) -/* LED force ctrl is the same for every LED - * No documentation exist for this, not even internal one - * with NDA as QCOM gives only info about configuring - * hw control pattern rules and doesn't indicate any way - * to force the LED to specific mode. - * These define comes from reverse and testing and maybe - * lack of some info or some info are not entirely correct. - * For the basic LED control and hw control these finding - * are enough to support LED control in all the required APIs. - * - * On doing some comparison with implementation with qca807x, - * it was found that it's 1:1 equal to it and confirms all the - * reverse done. It was also found further specification with the - * force mode and the blink modes. - */ -#define QCA808X_LED_FORCE_EN BIT(15) -#define QCA808X_LED_FORCE_MODE_MASK GENMASK(14, 13) -#define QCA808X_LED_FORCE_BLINK_1 FIELD_PREP(QCA808X_LED_FORCE_MODE_MASK, 0x3) -#define QCA808X_LED_FORCE_BLINK_2 FIELD_PREP(QCA808X_LED_FORCE_MODE_MASK, 0x2) -#define QCA808X_LED_FORCE_ON FIELD_PREP(QCA808X_LED_FORCE_MODE_MASK, 0x1) -#define QCA808X_LED_FORCE_OFF FIELD_PREP(QCA808X_LED_FORCE_MODE_MASK, 0x0) - #define QCA808X_MMD7_LED_POLARITY_CTRL 0x901a /* QSDK sets by default 0x46 to this reg that sets BIT 6 for * LED to active high. It's not clear what BIT 3 and BIT 4 does. diff --git a/drivers/net/phy/qcom/qcom.h b/drivers/net/phy/qcom/qcom.h index dc259bbf0678..9e24997c355f 100644 --- a/drivers/net/phy/qcom/qcom.h +++ b/drivers/net/phy/qcom/qcom.h @@ -103,6 +103,71 @@ /* Added for reference of existence but should be handled by wait_for_completion already */ #define QCA808X_CDT_STATUS_STAT_BUSY (BIT(1) | BIT(3)) +#define QCA808X_MMD7_LED_GLOBAL 0x8073 +#define QCA808X_LED_BLINK_1 GENMASK(11, 6) +#define QCA808X_LED_BLINK_2 GENMASK(5, 0) +/* Values are the same for both BLINK_1 and BLINK_2 */ +#define QCA808X_LED_BLINK_FREQ_MASK GENMASK(5, 3) +#define QCA808X_LED_BLINK_FREQ_2HZ FIELD_PREP(QCA808X_LED_BLINK_FREQ_MASK, 0x0) +#define QCA808X_LED_BLINK_FREQ_4HZ FIELD_PREP(QCA808X_LED_BLINK_FREQ_MASK, 0x1) +#define QCA808X_LED_BLINK_FREQ_8HZ FIELD_PREP(QCA808X_LED_BLINK_FREQ_MASK, 0x2) +#define QCA808X_LED_BLINK_FREQ_16HZ FIELD_PREP(QCA808X_LED_BLINK_FREQ_MASK, 0x3) +#define QCA808X_LED_BLINK_FREQ_32HZ FIELD_PREP(QCA808X_LED_BLINK_FREQ_MASK, 0x4) +#define QCA808X_LED_BLINK_FREQ_64HZ FIELD_PREP(QCA808X_LED_BLINK_FREQ_MASK, 0x5) +#define QCA808X_LED_BLINK_FREQ_128HZ FIELD_PREP(QCA808X_LED_BLINK_FREQ_MASK, 0x6) +#define QCA808X_LED_BLINK_FREQ_256HZ FIELD_PREP(QCA808X_LED_BLINK_FREQ_MASK, 0x7) +#define QCA808X_LED_BLINK_DUTY_MASK GENMASK(2, 0) +#define QCA808X_LED_BLINK_DUTY_50_50 FIELD_PREP(QCA808X_LED_BLINK_DUTY_MASK, 0x0) +#define QCA808X_LED_BLINK_DUTY_75_25 FIELD_PREP(QCA808X_LED_BLINK_DUTY_MASK, 0x1) +#define QCA808X_LED_BLINK_DUTY_25_75 FIELD_PREP(QCA808X_LED_BLINK_DUTY_MASK, 0x2) +#define QCA808X_LED_BLINK_DUTY_33_67 FIELD_PREP(QCA808X_LED_BLINK_DUTY_MASK, 0x3) +#define QCA808X_LED_BLINK_DUTY_67_33 FIELD_PREP(QCA808X_LED_BLINK_DUTY_MASK, 0x4) +#define QCA808X_LED_BLINK_DUTY_17_83 FIELD_PREP(QCA808X_LED_BLINK_DUTY_MASK, 0x5) +#define QCA808X_LED_BLINK_DUTY_83_17 FIELD_PREP(QCA808X_LED_BLINK_DUTY_MASK, 0x6) +#define QCA808X_LED_BLINK_DUTY_8_92 FIELD_PREP(QCA808X_LED_BLINK_DUTY_MASK, 0x7) + +/* LED hw control pattern is the same for every LED */ +#define QCA808X_LED_PATTERN_MASK GENMASK(15, 0) +#define QCA808X_LED_SPEED2500_ON BIT(15) +#define QCA808X_LED_SPEED2500_BLINK BIT(14) +/* Follow blink trigger even if duplex or speed condition doesn't match */ +#define QCA808X_LED_BLINK_CHECK_BYPASS BIT(13) +#define QCA808X_LED_FULL_DUPLEX_ON BIT(12) +#define QCA808X_LED_HALF_DUPLEX_ON BIT(11) +#define QCA808X_LED_TX_BLINK BIT(10) +#define QCA808X_LED_RX_BLINK BIT(9) +#define QCA808X_LED_TX_ON_10MS BIT(8) +#define QCA808X_LED_RX_ON_10MS BIT(7) +#define QCA808X_LED_SPEED1000_ON BIT(6) +#define QCA808X_LED_SPEED100_ON BIT(5) +#define QCA808X_LED_SPEED10_ON BIT(4) +#define QCA808X_LED_COLLISION_BLINK BIT(3) +#define QCA808X_LED_SPEED1000_BLINK BIT(2) +#define QCA808X_LED_SPEED100_BLINK BIT(1) +#define QCA808X_LED_SPEED10_BLINK BIT(0) + +/* LED force ctrl is the same for every LED + * No documentation exist for this, not even internal one + * with NDA as QCOM gives only info about configuring + * hw control pattern rules and doesn't indicate any way + * to force the LED to specific mode. + * These define comes from reverse and testing and maybe + * lack of some info or some info are not entirely correct. + * For the basic LED control and hw control these finding + * are enough to support LED control in all the required APIs. + * + * On doing some comparison with implementation with qca807x, + * it was found that it's 1:1 equal to it and confirms all the + * reverse done. It was also found further specification with the + * force mode and the blink modes. + */ +#define QCA808X_LED_FORCE_EN BIT(15) +#define QCA808X_LED_FORCE_MODE_MASK GENMASK(14, 13) +#define QCA808X_LED_FORCE_BLINK_1 FIELD_PREP(QCA808X_LED_FORCE_MODE_MASK, 0x3) +#define QCA808X_LED_FORCE_BLINK_2 FIELD_PREP(QCA808X_LED_FORCE_MODE_MASK, 0x2) +#define QCA808X_LED_FORCE_ON FIELD_PREP(QCA808X_LED_FORCE_MODE_MASK, 0x1) +#define QCA808X_LED_FORCE_OFF FIELD_PREP(QCA808X_LED_FORCE_MODE_MASK, 0x0) + #define AT803X_LOC_MAC_ADDR_0_15_OFFSET 0x804C #define AT803X_LOC_MAC_ADDR_16_31_OFFSET 0x804B #define AT803X_LOC_MAC_ADDR_32_47_OFFSET 0x804A From patchwork Mon Feb 5 16:48:41 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Christian Marangi X-Patchwork-Id: 13545871 X-Patchwork-Delegate: kuba@kernel.org Received: from mail-wm1-f47.google.com (mail-wm1-f47.google.com [209.85.128.47]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 198414879C; Mon, 5 Feb 2024 16:49:15 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.47 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1707151758; cv=none; b=njvkVzZSSeY8smagVWWxVnE6uLBeZMCJTzqK/iMjJDqMu0eV1xpPKtSgSKfj4tsBiO1nMEFqq8SsntKyUv4oSMmr6HSksBTagnjPExc8LFd5zj26M71E5lvxWBLqSgyP20k1PsKcUel5F2lwIfmGF83OkEI1hbXZlCHWdCXaUYQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1707151758; c=relaxed/simple; bh=0dGPT223KlpSppcb4Q5nKzooandtEzP9beu2JwjbgUA=; h=From:To:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=YlMGf0XtLdZ5W/Fh5TjKRtulLAZsotOc2MtwJ4/bw9aqGo6ivDHccib/gWSN8SU1ZAS/ZnLh6cI1dzFcuIYQ3rhHNtRI04auACdyb7oP/ovNhMGKqPKjro7RWzvzUlAkmhuCarx/DltU0e9r2RpWQHEnd1cmtOfwFINH0yK4kxg= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=njNzfEvm; arc=none smtp.client-ip=209.85.128.47 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="njNzfEvm" Received: by mail-wm1-f47.google.com with SMTP id 5b1f17b1804b1-40ef3f351d2so32318225e9.1; Mon, 05 Feb 2024 08:49:15 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1707151754; x=1707756554; 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=60K7HYoyD/okN2s+2wGpw5kK4uYop3FwQq/xBHnBh9I=; b=njNzfEvmoLHoNplsGuSjfwBYGhKPlBhdkhYI6eRxGbTB/JMBAViSZazu7pJivPC1YY 5F0a7Q6WVVudoRGEB0ltnVYG5AxoOUBfT8CCZ2yTXmJ+o58mpZA6A81Evf0rqAL3FQhj gkb7J34HvzeM3cFZ9DsabIaBgh/4byLtkaHcB0ByCNSlz7R/6tLf99PRChszE8l3w227 Kdtyskrd0dvrD47yiTHBCbncbfEUgzUxHW9S2Jh5Q24MIjy7yP36D5gXXKvWqxE4BTk0 hJW7hz9uhP2NznL9iquav6Dc8kZYMxaaq6JRKYxi6TVBAgzohp5SFcJhfIfHyJI8UCny iPHA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1707151754; x=1707756554; 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=60K7HYoyD/okN2s+2wGpw5kK4uYop3FwQq/xBHnBh9I=; b=w7YVFIq64kFIwRaYM+FJCqbop4bSFMo/BY/lk7FjPXUz8TdinXe/IyH5nGYuPHGrt2 AOZzveHRhp9yPvkNKdyaie8WZ292BpZfZaNqKULaAgTeB31kge3ih8EVo4Xh/MmWVraZ kGGGhI9p7NeHBnB/TcWeXU5Rb19kFBfk3QxIpZP7uIahkcRjXn5+1VQVX0HYGh80ya4X k7JLTcIXtivJ+sGWGL8NiIwZYfhktCDCp88CZADUvszB1vVNE5pSq0SueN2JzcJEuRNp ZDw0zD5nESRU3aLRgRBbeA0r9JkW9MjM/lNfddqcHQ6OZcUOdKSC2pFIntdaeP5HSSGr wspQ== X-Gm-Message-State: AOJu0YxrnHe13fVtpoZJKb5nPcE5K8gjriMZtUBmbFdgqS0QBbcIrcfW zD1jjhAK/8XCgVKIGJ1IzDihne0TL/vDP4wgZrUuaUnnDEMcET5f X-Google-Smtp-Source: AGHT+IGKE/SEPEwmoF/vNiHMxf9+pidXmvr8rjb/gm1p8KvsZYrl8Wmu2XvQuXiRv5Q0Jk5xvIqUNQ== X-Received: by 2002:a05:6000:4023:b0:33b:39cb:a83c with SMTP id cp35-20020a056000402300b0033b39cba83cmr3461914wrb.13.1707151754191; Mon, 05 Feb 2024 08:49:14 -0800 (PST) X-Forwarded-Encrypted: i=0; AJvYcCWV+k4V5nnGJpOX/+Cm5V49MEkEns0GMUpTAJOm2Xytj2NZmqyAwSCxUpeXvUd9IE+wmHlCNv3USbAIfUFDTs4nkQbPR4UayHjH1xbT+2M1e+a78QmHEjjhy59BF6FisTK7z7uLWL2WGl2TSAvw2NF/IhmrIqZ+BD00WqxlV2ratZc0h8RC+S0x3ijR0wae8aSj9Vx/CIaDfrPDC2tbJlKcOQoFMjGbivbVKdswOubn+t0GNJrRzuEl70FwZSMvkiNY8kHtxgOgFC5CQx7G9iL2tsQOMH0o1RwHzm4YMnx0Gpep/cNtcCDLdE5qrkWUa2MqyDRDzlWTrrxbl5ICRtQHOcjkivntzjesbPAdKO8agyS6qFyk/9iFEdor4Crx2LX8+1kHk2QG4Y58wqX/ucoOJuZcErkm4CQMA/Pe7rYrw7Cj23JMToQGjCga3G7/+OdvJFJq2+mcgwo/U8Ra467fS1DSdfw9EqjaAuT94ka/jbbwfgHCcKqLnh2K5OBdrKFjMxtsXAmcY7Ko9FZEJpDQDnqYjjCx6/qUHmT8DKx/QCBnu2ABNqqxZep0v8QQGLQ2QpD+QvnoY7ZjccWTO+okaczhc06Ltt3iYy+Ycp9FgH2mjLlHBMpTdGOLBHA5z4X3Mehd2omvpncp8CQ8GIahlx5wpuMnkgwtJtkDRLNl7vDGGKCesA== Received: from localhost.localdomain (93-34-89-13.ip49.fastwebnet.it. [93.34.89.13]) by smtp.googlemail.com with ESMTPSA id k2-20020a05600c1c8200b0040fafd84095sm9140567wms.41.2024.02.05.08.49.13 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 05 Feb 2024 08:49:13 -0800 (PST) From: Christian Marangi To: "David S. Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Bjorn Andersson , Konrad Dybcio , Andrew Lunn , Heiner Kallweit , Russell King , Florian Fainelli , Broadcom internal kernel review list , Christian Marangi , Robert Marko , netdev@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-arm-msm@vger.kernel.org Subject: [net-next PATCH v6 09/10] net: phy: qcom: generalize some qca808x LED functions Date: Mon, 5 Feb 2024 17:48:41 +0100 Message-ID: <20240205164851.1351-10-ansuelsmth@gmail.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20240205164851.1351-1-ansuelsmth@gmail.com> References: <20240205164851.1351-1-ansuelsmth@gmail.com> Precedence: bulk X-Mailing-List: netdev@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Patchwork-Delegate: kuba@kernel.org Generalize some qca808x LED functions in preparation for qca807x LED support. The LED implementation of qca808x and qca807x is the same but qca807x supports also Fiber port and have different hw control bits for Fiber port. To limit code duplication introduce micro functions that takes reg instead of LED index to tweak all the supported LED modes. Signed-off-by: Christian Marangi --- drivers/net/phy/qcom/qca808x.c | 38 +++----------------- drivers/net/phy/qcom/qcom-phy-lib.c | 54 +++++++++++++++++++++++++++++ drivers/net/phy/qcom/qcom.h | 7 ++++ 3 files changed, 65 insertions(+), 34 deletions(-) diff --git a/drivers/net/phy/qcom/qca808x.c b/drivers/net/phy/qcom/qca808x.c index b6ff2676d921..325e22ce8972 100644 --- a/drivers/net/phy/qcom/qca808x.c +++ b/drivers/net/phy/qcom/qca808x.c @@ -427,9 +427,7 @@ static int qca808x_led_hw_control_enable(struct phy_device *phydev, u8 index) return -EINVAL; reg = QCA808X_MMD7_LED_FORCE_CTRL(index); - - return phy_clear_bits_mmd(phydev, MDIO_MMD_AN, reg, - QCA808X_LED_FORCE_EN); + return qca808x_led_reg_hw_control_enable(phydev, reg); } static int qca808x_led_hw_is_supported(struct phy_device *phydev, u8 index, @@ -470,16 +468,12 @@ static int qca808x_led_hw_control_set(struct phy_device *phydev, u8 index, static bool qca808x_led_hw_control_status(struct phy_device *phydev, u8 index) { u16 reg; - int val; if (index > 2) return false; reg = QCA808X_MMD7_LED_FORCE_CTRL(index); - - val = phy_read_mmd(phydev, MDIO_MMD_AN, reg); - - return !(val & QCA808X_LED_FORCE_EN); + return qca808x_led_reg_hw_control_status(phydev, reg); } static int qca808x_led_hw_control_get(struct phy_device *phydev, u8 index, @@ -547,44 +541,20 @@ static int qca808x_led_brightness_set(struct phy_device *phydev, } reg = QCA808X_MMD7_LED_FORCE_CTRL(index); - - return phy_modify_mmd(phydev, MDIO_MMD_AN, reg, - QCA808X_LED_FORCE_EN | QCA808X_LED_FORCE_MODE_MASK, - QCA808X_LED_FORCE_EN | value ? QCA808X_LED_FORCE_ON : - QCA808X_LED_FORCE_OFF); + return qca808x_led_reg_brightness_set(phydev, reg, value); } static int qca808x_led_blink_set(struct phy_device *phydev, u8 index, unsigned long *delay_on, unsigned long *delay_off) { - int ret; u16 reg; if (index > 2) return -EINVAL; reg = QCA808X_MMD7_LED_FORCE_CTRL(index); - - /* Set blink to 50% off, 50% on at 4Hz by default */ - ret = phy_modify_mmd(phydev, MDIO_MMD_AN, QCA808X_MMD7_LED_GLOBAL, - QCA808X_LED_BLINK_FREQ_MASK | QCA808X_LED_BLINK_DUTY_MASK, - QCA808X_LED_BLINK_FREQ_4HZ | QCA808X_LED_BLINK_DUTY_50_50); - if (ret) - return ret; - - /* We use BLINK_1 for normal blinking */ - ret = phy_modify_mmd(phydev, MDIO_MMD_AN, reg, - QCA808X_LED_FORCE_EN | QCA808X_LED_FORCE_MODE_MASK, - QCA808X_LED_FORCE_EN | QCA808X_LED_FORCE_BLINK_1); - if (ret) - return ret; - - /* We set blink to 4Hz, aka 250ms */ - *delay_on = 250 / 2; - *delay_off = 250 / 2; - - return 0; + return qca808x_led_reg_blink_set(phydev, reg, delay_on, delay_off); } static int qca808x_led_polarity_set(struct phy_device *phydev, int index, diff --git a/drivers/net/phy/qcom/qcom-phy-lib.c b/drivers/net/phy/qcom/qcom-phy-lib.c index 786bfc39912c..d28815ef56bb 100644 --- a/drivers/net/phy/qcom/qcom-phy-lib.c +++ b/drivers/net/phy/qcom/qcom-phy-lib.c @@ -620,3 +620,57 @@ int qca808x_cable_test_get_status(struct phy_device *phydev, bool *finished) return 0; } EXPORT_SYMBOL_GPL(qca808x_cable_test_get_status); + +int qca808x_led_reg_hw_control_enable(struct phy_device *phydev, u16 reg) +{ + return phy_clear_bits_mmd(phydev, MDIO_MMD_AN, reg, + QCA808X_LED_FORCE_EN); +} +EXPORT_SYMBOL_GPL(qca808x_led_reg_hw_control_enable); + +bool qca808x_led_reg_hw_control_status(struct phy_device *phydev, u16 reg) +{ + int val; + + val = phy_read_mmd(phydev, MDIO_MMD_AN, reg); + return !(val & QCA808X_LED_FORCE_EN); +} +EXPORT_SYMBOL_GPL(qca808x_led_reg_hw_control_status); + +int qca808x_led_reg_brightness_set(struct phy_device *phydev, + u16 reg, enum led_brightness value) +{ + return phy_modify_mmd(phydev, MDIO_MMD_AN, reg, + QCA808X_LED_FORCE_EN | QCA808X_LED_FORCE_MODE_MASK, + QCA808X_LED_FORCE_EN | (value ? QCA808X_LED_FORCE_ON : + QCA808X_LED_FORCE_OFF)); +} +EXPORT_SYMBOL_GPL(qca808x_led_reg_brightness_set); + +int qca808x_led_reg_blink_set(struct phy_device *phydev, u16 reg, + unsigned long *delay_on, + unsigned long *delay_off) +{ + int ret; + + /* Set blink to 50% off, 50% on at 4Hz by default */ + ret = phy_modify_mmd(phydev, MDIO_MMD_AN, QCA808X_MMD7_LED_GLOBAL, + QCA808X_LED_BLINK_FREQ_MASK | QCA808X_LED_BLINK_DUTY_MASK, + QCA808X_LED_BLINK_FREQ_4HZ | QCA808X_LED_BLINK_DUTY_50_50); + if (ret) + return ret; + + /* We use BLINK_1 for normal blinking */ + ret = phy_modify_mmd(phydev, MDIO_MMD_AN, reg, + QCA808X_LED_FORCE_EN | QCA808X_LED_FORCE_MODE_MASK, + QCA808X_LED_FORCE_EN | QCA808X_LED_FORCE_BLINK_1); + if (ret) + return ret; + + /* We set blink to 4Hz, aka 250ms */ + *delay_on = 250 / 2; + *delay_off = 250 / 2; + + return 0; +} +EXPORT_SYMBOL_GPL(qca808x_led_reg_blink_set); diff --git a/drivers/net/phy/qcom/qcom.h b/drivers/net/phy/qcom/qcom.h index 9e24997c355f..4bb541728846 100644 --- a/drivers/net/phy/qcom/qcom.h +++ b/drivers/net/phy/qcom/qcom.h @@ -234,3 +234,10 @@ int at803x_cdt_start(struct phy_device *phydev, u32 cdt_start); int at803x_cdt_wait_for_completion(struct phy_device *phydev, u32 cdt_en); int qca808x_cable_test_get_status(struct phy_device *phydev, bool *finished); +int qca808x_led_reg_hw_control_enable(struct phy_device *phydev, u16 reg); +bool qca808x_led_reg_hw_control_status(struct phy_device *phydev, u16 reg); +int qca808x_led_reg_brightness_set(struct phy_device *phydev, + u16 reg, enum led_brightness value); +int qca808x_led_reg_blink_set(struct phy_device *phydev, u16 reg, + unsigned long *delay_on, + unsigned long *delay_off); From patchwork Mon Feb 5 16:48:42 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Christian Marangi X-Patchwork-Id: 13545872 X-Patchwork-Delegate: kuba@kernel.org Received: from mail-wm1-f42.google.com (mail-wm1-f42.google.com [209.85.128.42]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 4DB3A48CC6; Mon, 5 Feb 2024 16:49:17 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.42 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1707151759; cv=none; b=kDV3jYbd8WbOony1FYgzNs443brE9A1RbOT9f7CrH1eBjXLo4yLuNxOa9fzLxOrQXUbQLJb2nCn6rS80Ac5o3+qj65V8CmuQv8w8DqkfwpF3O72Os8WtrD+dqmfFFkQKslYHu8wjCObvgHftIr+gSzTL0LzkjH4JPhND9JIfkd0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1707151759; c=relaxed/simple; bh=CpFiKt9arcAd/DdvTfXA++kS54iSLovvRvO3R5Xb+n0=; h=From:To:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=FONmCxTOhvz/lGsDboIkN03IPpSejAHHmQsR++C7MYoG1GXFskVttKhxJzc1XxQ7fWhNwLazR2OUao7BHZyATLRpgPk3YLFANsPGROc12262MSRqj/tz/ixbMHUI08TVypc0zEDj8s9RSGroAtBWopLD+JFx3pSjIau0j3zaY7o= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=dulMkqUV; arc=none smtp.client-ip=209.85.128.42 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="dulMkqUV" Received: by mail-wm1-f42.google.com with SMTP id 5b1f17b1804b1-40ef3f351d2so32318365e9.1; Mon, 05 Feb 2024 08:49:16 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1707151755; x=1707756555; 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=bYMtIg24uuXRIsgSP6U1ynvtwWf0bDfr47PWEVug3DI=; b=dulMkqUVKhjak1U9MiqknnEk24hi34gEIH2n3HDK0hzv4NkhdmY5oZOmsBT2M3KoGy yhghr+ROc1HX7g9FKT5qDDiBgnkuGkIly9TX348TLUCJfdDttA5y8C7nDI6ujuTidGNv OwjXenArg/sBpEXu9cCyaGEfLx6/yRoAEwbQQUwIwNUhXU+aVDpV2LdQNAYE9rt+08JC 6xijSIt2FaJ/SF0pIcuaAGJNbiQgDxePBklKmwJDBSvgsCheJ7/KENLd96cuegt3BDzi Xja9CpeEnNlM1WCe1ZePGhnzUrF1+NUuWEeWCDjze/2S3V2DkwG7BpDIpbzIDAOOjM6k Eb8A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1707151755; x=1707756555; 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=bYMtIg24uuXRIsgSP6U1ynvtwWf0bDfr47PWEVug3DI=; b=FpcP14YxD4xpHRbimp3tG7+2+gNNKTNtVE/ESkKljbUXhAIaSzp1QHMrcZ2dW1w/xH 2cFr9moZnGo6f/6IRN4cMFsmskOt/yVaxJcBXJZrVAeNTWY00LRSbWoH+yWwh2ZWceQs AEIMOG+fBFRDV5uphgPEWbL6uIldckDncAKjfSaP6IZ5NHBkEhCG0oXo+U1Wg9a+90jd IhV0+cI/ayTYkxoUoBWYWifa9nyFquhwsK4qySGxB7tXmMWElGXEAnDoPklD8HHBU0uB WvWkygADiNAfeYRXo1C8osd9QTXXhVB/sjtKapblRMA/1Pdrfx3GJkPDkcWdYqlNuz74 NfEw== X-Gm-Message-State: AOJu0YxwS0mtKw72ezXuGVTm2tYjQFrBXyZ1A66P479WEZx1Sad5YV5b fQ+XszqccsVE4eSoDDDmM8nIi0KDYhDKJpx/BQNE8/mlywQplBDJ X-Google-Smtp-Source: AGHT+IEi8QATNYyOI1Fy4+ITBi+5rJSUtOAAKFklc4IbmDszrmnMRXUZKvO7SLJkh2anNw3N/gB6Hg== X-Received: by 2002:a05:600c:35cf:b0:40f:dc7e:e286 with SMTP id r15-20020a05600c35cf00b0040fdc7ee286mr177541wmq.13.1707151755398; Mon, 05 Feb 2024 08:49:15 -0800 (PST) X-Forwarded-Encrypted: i=0; AJvYcCW/3uOUeZhpHZvSDxp4PR2FAfP70ve3t1SpGhfGkEOb3LU5Xilm2HOcMbTQGdsrji1efEw0amW1O7ZqoNFRrpe8zLZErYie2reMvwxQigfLh14m8q40Yw4qffaqdwj6P+ea1vLNhcsEzZX6QFdovi7k9cod4R8Y44jofeB0HknIFmL9rk4zMM1mSBpYcsNcY5PiIszlIZXYQDmSyA4yU7yWXxkVL5fMFUx2rm0DmOP2NKtMgO7GEyrMVjxPixaehdkEO9jkK+48zOes0XmPkD5WAwPncLi2MJryaFY/hd8scT6mlu3OVex278r3v3+vVcueT/7XcQCuYPJWTaUmK/CdC6NB+wNEVPBtVFJnxqWbKsV8iKEviZWfoo2w2sIbgPJj+NdyO9sJLM1A90j/IYl3Dlb8+dTybkYztz+eEwEYI0vIxJZ5+38CHURfc6S1dxaQgkjyC7MPAYsD/Fx5gHPLctPiYAVDptyC1/TQtMuV34Wcrqv1fM2aL94CpN75ABxKVXksI/9BI/p1vZ36jdDa9GHezu4PszG7hfD1uspnbljopQ9gSFurzChW4JEZNwJ7d0Ml7vfZCZElKsXYQovjiYKnW9ZRpDdzr6fzV/rHQoi55TKSff1Z6P0CMIjyaHP1trQpQfzi8Jt3qD0W4sc+cxaCaf8taP5ZXgJGnx3vZ3Sf7rjitg== Received: from localhost.localdomain (93-34-89-13.ip49.fastwebnet.it. [93.34.89.13]) by smtp.googlemail.com with ESMTPSA id k2-20020a05600c1c8200b0040fafd84095sm9140567wms.41.2024.02.05.08.49.14 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 05 Feb 2024 08:49:15 -0800 (PST) From: Christian Marangi To: "David S. Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Bjorn Andersson , Konrad Dybcio , Andrew Lunn , Heiner Kallweit , Russell King , Florian Fainelli , Broadcom internal kernel review list , Christian Marangi , Robert Marko , netdev@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-arm-msm@vger.kernel.org Subject: [net-next PATCH v6 10/10] net: phy: qca807x: add support for configurable LED Date: Mon, 5 Feb 2024 17:48:42 +0100 Message-ID: <20240205164851.1351-11-ansuelsmth@gmail.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20240205164851.1351-1-ansuelsmth@gmail.com> References: <20240205164851.1351-1-ansuelsmth@gmail.com> Precedence: bulk X-Mailing-List: netdev@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Patchwork-Delegate: kuba@kernel.org 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/qcom/qca807x.c | 256 ++++++++++++++++++++++++++++++++- 1 file changed, 254 insertions(+), 2 deletions(-) diff --git a/drivers/net/phy/qcom/qca807x.c b/drivers/net/phy/qcom/qca807x.c index de8ea94c15f7..1ec60eeca3c3 100644 --- a/drivers/net/phy/qcom/qca807x.c +++ b/drivers/net/phy/qcom/qca807x.c @@ -57,8 +57,18 @@ #define QCA807X_MMD7_LED_CTRL(x) (0x8074 + ((x) * 2)) #define QCA807X_MMD7_LED_FORCE_CTRL(x) (0x8075 + ((x) * 2)) -#define QCA807X_GPIO_FORCE_EN BIT(15) -#define QCA807X_GPIO_FORCE_MODE_MASK GENMASK(14, 13) +/* LED hw control pattern for fiber port */ +#define QCA807X_LED_FIBER_PATTERN_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 QCA808X_LED_FORCE_EN +#define QCA807X_GPIO_FORCE_MODE_MASK QCA808X_LED_FORCE_MODE_MASK #define QCA807X_FUNCTION_CONTROL 0x10 #define QCA807X_FC_MDI_CROSSOVER_MODE_MASK GENMASK(6, 5) @@ -121,6 +131,233 @@ static int qca807x_cable_test_start(struct phy_device *phydev) return 0; } +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 |= QCA808X_LED_TX_BLINK; + if (test_bit(TRIGGER_NETDEV_RX, &rules)) + *offload_trigger |= QCA808X_LED_RX_BLINK; + if (test_bit(TRIGGER_NETDEV_LINK_10, &rules)) + *offload_trigger |= QCA808X_LED_SPEED10_ON; + if (test_bit(TRIGGER_NETDEV_LINK_100, &rules)) + *offload_trigger |= QCA808X_LED_SPEED100_ON; + if (test_bit(TRIGGER_NETDEV_LINK_1000, &rules)) + *offload_trigger |= QCA808X_LED_SPEED1000_ON; + if (test_bit(TRIGGER_NETDEV_HALF_DUPLEX, &rules)) + *offload_trigger |= QCA808X_LED_HALF_DUPLEX_ON; + if (test_bit(TRIGGER_NETDEV_FULL_DUPLEX, &rules)) + *offload_trigger |= QCA808X_LED_FULL_DUPLEX_ON; + 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) +{ + u16 reg; + + if (index > 1) + return -EINVAL; + + reg = QCA807X_MMD7_LED_FORCE_CTRL(index); + return qca808x_led_reg_hw_control_enable(phydev, reg); +} + +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) +{ + u16 reg, mask, offload_trigger = 0; + int ret; + + if (index > 1) + 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: + reg = QCA807X_MMD7_LED_CTRL(index); + mask = QCA808X_LED_PATTERN_MASK; + break; + case PORT_FIBRE: + /* HW control pattern bits are in LED FORCE reg */ + reg = QCA807X_MMD7_LED_FORCE_CTRL(index); + mask = QCA807X_LED_FIBER_PATTERN_MASK; + break; + default: + return -EINVAL; + } + + return phy_modify_mmd(phydev, MDIO_MMD_AN, reg, mask, + offload_trigger); +} + +static bool qca807x_led_hw_control_status(struct phy_device *phydev, u8 index) +{ + u16 reg; + + if (index > 1) + return false; + + reg = QCA807X_MMD7_LED_FORCE_CTRL(index); + return qca808x_led_reg_hw_control_status(phydev, reg); +} + +static int qca807x_led_hw_control_get(struct phy_device *phydev, u8 index, + unsigned long *rules) +{ + u16 reg; + int val; + + if (index > 1) + 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: + reg = QCA807X_MMD7_LED_CTRL(index); + val = phy_read_mmd(phydev, MDIO_MMD_AN, reg); + if (val & QCA808X_LED_TX_BLINK) + set_bit(TRIGGER_NETDEV_TX, rules); + if (val & QCA808X_LED_RX_BLINK) + set_bit(TRIGGER_NETDEV_RX, rules); + if (val & QCA808X_LED_SPEED10_ON) + set_bit(TRIGGER_NETDEV_LINK_10, rules); + if (val & QCA808X_LED_SPEED100_ON) + set_bit(TRIGGER_NETDEV_LINK_100, rules); + if (val & QCA808X_LED_SPEED1000_ON) + set_bit(TRIGGER_NETDEV_LINK_1000, rules); + if (val & QCA808X_LED_HALF_DUPLEX_ON) + set_bit(TRIGGER_NETDEV_HALF_DUPLEX, rules); + if (val & QCA808X_LED_FULL_DUPLEX_ON) + set_bit(TRIGGER_NETDEV_FULL_DUPLEX, rules); + break; + case PORT_FIBRE: + /* HW control pattern bits are in LED FORCE reg */ + reg = QCA807X_MMD7_LED_FORCE_CTRL(index); + val = phy_read_mmd(phydev, MDIO_MMD_AN, 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) +{ + u16 reg, mask; + + if (index > 1) + return -EINVAL; + + switch (phydev->port) { + case PORT_TP: + reg = QCA807X_MMD7_LED_CTRL(index); + mask = QCA808X_LED_PATTERN_MASK; + break; + case PORT_FIBRE: + /* HW control pattern bits are in LED FORCE reg */ + reg = QCA807X_MMD7_LED_FORCE_CTRL(index); + mask = QCA807X_LED_FIBER_PATTERN_MASK; + break; + default: + return -EINVAL; + } + + return phy_clear_bits_mmd(phydev, MDIO_MMD_AN, reg, mask); +} + +static int qca807x_led_brightness_set(struct phy_device *phydev, + u8 index, enum led_brightness value) +{ + u16 reg; + int ret; + + if (index > 1) + 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; + } + + reg = QCA807X_MMD7_LED_FORCE_CTRL(index); + return qca808x_led_reg_brightness_set(phydev, reg, value); +} + +static int qca807x_led_blink_set(struct phy_device *phydev, u8 index, + unsigned long *delay_on, + unsigned long *delay_off) +{ + u16 reg; + + if (index > 1) + return -EINVAL; + + reg = QCA807X_MMD7_LED_FORCE_CTRL(index); + return qca808x_led_reg_blink_set(phydev, reg, delay_on, delay_off); +} + #ifdef CONFIG_GPIOLIB static int qca807x_gpio_get_direction(struct gpio_chip *gc, unsigned int offset) { @@ -496,6 +733,16 @@ static int qca807x_probe(struct phy_device *phydev) "qcom,dac-disable-bias-current-tweak"); if (IS_ENABLED(CONFIG_GPIOLIB)) { + /* Make sure we don't have mixed leds node and gpio-controller + * to prevent registering leds and having gpio-controller usage + * conflicting with them. + */ + if (of_find_property(node, "leds", NULL) && + of_find_property(node, "gpio-controller", NULL)) { + phydev_err(phydev, "Invalid property detected. LEDs and gpio-controller are mutually exclusive."); + return -EINVAL; + } + /* Do not register a GPIO controller unless flagged for it */ if (of_property_read_bool(node, "gpio-controller")) { ret = qca807x_gpio(phydev); @@ -580,6 +827,11 @@ static struct phy_driver qca807x_drivers[] = { .suspend = genphy_suspend, .cable_test_start = qca807x_cable_test_start, .cable_test_get_status = qca808x_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, }, }; module_phy_driver(qca807x_drivers);