From patchwork Thu Dec 14 20:14:39 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tobias Waldekranz X-Patchwork-Id: 13493589 X-Patchwork-Delegate: kuba@kernel.org Received: from mail-lf1-f48.google.com (mail-lf1-f48.google.com [209.85.167.48]) (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 E8A1E6A32A for ; Thu, 14 Dec 2023 20:15:03 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=waldekranz.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=waldekranz.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=waldekranz-com.20230601.gappssmtp.com header.i=@waldekranz-com.20230601.gappssmtp.com header.b="QYCwS8ih" Received: by mail-lf1-f48.google.com with SMTP id 2adb3069b0e04-50bce78f145so9907508e87.0 for ; Thu, 14 Dec 2023 12:15:03 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=waldekranz-com.20230601.gappssmtp.com; s=20230601; t=1702584902; x=1703189702; darn=vger.kernel.org; h=content-transfer-encoding:organization:mime-version:references :in-reply-to:message-id:date:subject:cc:to:from:from:to:cc:subject :date:message-id:reply-to; bh=NQpFYsK8/obVkITErfPH3Tq20K9RS8oXAAq1YZCGghE=; b=QYCwS8ihkbZW81xJbA5cQOfR+IMGyYTZ/JAlD8siheJ02wCfASC48CJgIBKdrrKed6 Nw6IpjOwa2mFgQ0kgT+ZW7FDWopfO465F5e8haDSjav7R+LM1yuOOxoNt9qq2oYNhmp/ mRlvmZwINisuxDnMQ5YUB+rUYE6sCCdGqGNf+t1CP9I9ZJ9lIE0cA2lvH5F/VEa0yzGE Ls6F2y5mCjRUQOg3MoRyEp3YKxmCL5v10W78Md7Y6Ku6UWJqW5uR130ClT9mW43MaV9f OzIdryc4ZTxIexBCN5XVPgP1rEMUtsuCoBJcL5LX6lUpY21R5ClGEEl5EpsatcY0oFyD WeXg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1702584902; x=1703189702; h=content-transfer-encoding:organization:mime-version:references :in-reply-to:message-id:date:subject:cc:to:from:x-gm-message-state :from:to:cc:subject:date:message-id:reply-to; bh=NQpFYsK8/obVkITErfPH3Tq20K9RS8oXAAq1YZCGghE=; b=Y6tK36ncag8nJTfXgwSv+U32GbZcj9478DFGLhJ5PRQo2ICSyaLESQc2HzEDHFyq9v 6R9wqpVtwr255Uq0IHw5sp1zkuw1JRUvwWSjyqpwpkQ4qbmbHn1wl20lGWxppxqqAK5e 2OKfLT00LjEfzQpS2cB3GPG/n+U8ODS+Vy//fvd+FGYwDPyDdrti3bV9dLGhj2cFw6d2 3lKPon8wNC5ir63jQ7LNSXD4EoMA0dYo4UqT89Cw98/7OXOqR9wZbY8IXp6NuImXa4g9 0OtzH2Nkt88iuR4R3rsX7jaISuyjhI1EJQZuwYhEini+p/3wag4RZBC85r3f8egc8dht k5Ww== X-Gm-Message-State: AOJu0YxwPUc15wSox/tI5DXbgTkvAq6P6JsA4WprTyi1X9aWjyJsMxQH GDSzBmveI6N5DAkRbfqi+3FPCA== X-Google-Smtp-Source: AGHT+IF6xtDoWaYsQc+IvKQpfiDqtrfNeO8TXvb1Wd9mnsmgg1F4nRGOdE94WyGFWpC5VAvlRvfEgA== X-Received: by 2002:ac2:5610:0:b0:50c:ff6c:64ae with SMTP id v16-20020ac25610000000b0050cff6c64aemr2078270lfd.196.1702584901823; Thu, 14 Dec 2023 12:15:01 -0800 (PST) Received: from wkz-x13.addiva.ad (h-158-174-187-194.NA.cust.bahnhof.se. [158.174.187.194]) by smtp.gmail.com with ESMTPSA id dw11-20020a0565122c8b00b0050e140f84besm369519lfb.164.2023.12.14.12.15.00 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 14 Dec 2023 12:15:00 -0800 (PST) From: Tobias Waldekranz To: davem@davemloft.net, kuba@kernel.org Cc: linux@armlinux.org.uk, kabel@kernel.org, andrew@lunn.ch, hkallweit1@gmail.com, robh+dt@kernel.org, krzysztof.kozlowski+dt@linaro.org, conor+dt@kernel.org, netdev@vger.kernel.org, devicetree@vger.kernel.org Subject: [PATCH net-next 1/4] net: phy: marvell10g: Support firmware loading on 88X3310 Date: Thu, 14 Dec 2023 21:14:39 +0100 Message-Id: <20231214201442.660447-2-tobias@waldekranz.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20231214201442.660447-1-tobias@waldekranz.com> References: <20231214201442.660447-1-tobias@waldekranz.com> Precedence: bulk X-Mailing-List: netdev@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Organization: Addiva Elektronik X-Patchwork-Delegate: kuba@kernel.org When probing, if a device is waiting for firmware to be loaded into its RAM, ask userspace for the binary and load it over XMDIO. We have no choice but to bail out of the probe if firmware is not available, as the device does not have any built-in image on which to fall back. Signed-off-by: Tobias Waldekranz --- drivers/net/phy/marvell10g.c | 149 +++++++++++++++++++++++++++++++++++ 1 file changed, 149 insertions(+) diff --git a/drivers/net/phy/marvell10g.c b/drivers/net/phy/marvell10g.c index ad43e280930c..83233b30d7b0 100644 --- a/drivers/net/phy/marvell10g.c +++ b/drivers/net/phy/marvell10g.c @@ -25,6 +25,7 @@ #include #include #include +#include #include #include #include @@ -50,6 +51,13 @@ enum { MV_PMA_21X0_PORT_CTRL_MACTYPE_10GBASER_RATE_MATCH = 0x6, MV_PMA_BOOT = 0xc050, MV_PMA_BOOT_FATAL = BIT(0), + MV_PMA_BOOT_PRGS_MASK = 0x0006, + MV_PMA_BOOT_PRGS_INIT = 0x0000, + MV_PMA_BOOT_PRGS_WAIT = 0x0002, + MV_PMA_BOOT_PRGS_CSUM = 0x0004, + MV_PMA_BOOT_PRGS_JRAM = 0x0006, + MV_PMA_BOOT_APP_STARTED = BIT(4), + MV_PMA_BOOT_APP_LOADED = BIT(6), MV_PCS_BASE_T = 0x0000, MV_PCS_BASE_R = 0x1000, @@ -96,6 +104,12 @@ enum { MV_PCS_PORT_INFO_NPORTS_MASK = 0x0380, MV_PCS_PORT_INFO_NPORTS_SHIFT = 7, + /* Firmware downloading */ + MV_PCS_FW_ADDR_LOW = 0xd0f0, + MV_PCS_FW_ADDR_HIGH = 0xd0f1, + MV_PCS_FW_DATA = 0xd0f2, + MV_PCS_FW_CSUM = 0xd0f3, + /* SerDes reinitialization 88E21X0 */ MV_AN_21X0_SERDES_CTRL2 = 0x800f, MV_AN_21X0_SERDES_CTRL2_AUTO_INIT_DIS = BIT(13), @@ -156,6 +170,7 @@ struct mv3310_chip { const struct mv3310_mactype *mactypes; size_t n_mactypes; + const char *firmware_path; #ifdef CONFIG_HWMON int (*hwmon_read_temp_reg)(struct phy_device *phydev); @@ -506,6 +521,132 @@ static const struct sfp_upstream_ops mv3310_sfp_ops = { .module_insert = mv3310_sfp_insert, }; +struct mv3310_fw_hdr { + struct { + u32 size; + u32 addr; + u16 csum; + } __packed data; + + u8 flags; +#define MV3310_FW_HDR_DATA_ONLY BIT(6) + + u8 port_skip; + u32 next_hdr; + u16 csum; + + u8 pad[14]; +} __packed; + +static int mv3310_load_fw_sect(struct phy_device *phydev, + const struct mv3310_fw_hdr *hdr, const u8 *data) +{ + int err = 0; + size_t i; + u16 csum; + + dev_dbg(&phydev->mdio.dev, "Loading %u byte %s section at 0x%08x\n", + hdr->data.size, + (hdr->flags & MV3310_FW_HDR_DATA_ONLY) ? "data" : "executable", + hdr->data.addr); + + for (i = 0, csum = 0; i < hdr->data.size; i++) + csum += data[i]; + + if ((u16)~csum != hdr->data.csum) { + dev_err(&phydev->mdio.dev, "Corrupt section data\n"); + return -EINVAL; + } + + phy_lock_mdio_bus(phydev); + + /* Any existing checksum is cleared by a read */ + __phy_read_mmd(phydev, MDIO_MMD_PCS, MV_PCS_FW_CSUM); + + __phy_write_mmd(phydev, MDIO_MMD_PCS, MV_PCS_FW_ADDR_LOW, hdr->data.addr & 0xffff); + __phy_write_mmd(phydev, MDIO_MMD_PCS, MV_PCS_FW_ADDR_HIGH, hdr->data.addr >> 16); + + for (i = 0; i < hdr->data.size; i += 2) { + __phy_write_mmd(phydev, MDIO_MMD_PCS, MV_PCS_FW_DATA, + (data[i + 1] << 8) | data[i]); + } + + csum = __phy_read_mmd(phydev, MDIO_MMD_PCS, MV_PCS_FW_CSUM); + if ((u16)~csum != hdr->data.csum) { + dev_err(&phydev->mdio.dev, "Download failed\n"); + err = -EIO; + goto unlock; + } + + if (hdr->flags & MV3310_FW_HDR_DATA_ONLY) + goto unlock; + + __phy_modify_mmd(phydev, MDIO_MMD_PMAPMD, MV_PMA_BOOT, 0, MV_PMA_BOOT_APP_LOADED); + mdelay(200); + if (!(__phy_read_mmd(phydev, MDIO_MMD_PMAPMD, MV_PMA_BOOT) & MV_PMA_BOOT_APP_STARTED)) { + dev_err(&phydev->mdio.dev, "Application did not startup\n"); + err = -ENODEV; + } + +unlock: + phy_unlock_mdio_bus(phydev); + return err; +} + +static int mv3310_load_fw(struct phy_device *phydev) +{ + const struct mv3310_chip *chip = to_mv3310_chip(phydev); + const struct firmware *fw; + struct mv3310_fw_hdr hdr; + const u8 *sect; + size_t i; + u16 csum; + int err; + + if (!chip->firmware_path) + return -EOPNOTSUPP; + + err = request_firmware(&fw, chip->firmware_path, &phydev->mdio.dev); + if (err) + return err; + + if (fw->size & 1) { + err = -EINVAL; + goto release; + } + + for (sect = fw->data; (sect + sizeof(hdr)) < (fw->data + fw->size);) { + memcpy(&hdr, sect, sizeof(hdr)); + hdr.data.size = cpu_to_le32(hdr.data.size); + hdr.data.addr = cpu_to_le32(hdr.data.addr); + hdr.data.csum = cpu_to_le16(hdr.data.csum); + hdr.next_hdr = cpu_to_le32(hdr.next_hdr); + hdr.csum = cpu_to_le16(hdr.csum); + + for (i = 0, csum = 0; i < offsetof(struct mv3310_fw_hdr, csum); i++) + csum += sect[i]; + + if ((u16)~csum != hdr.csum) { + dev_err(&phydev->mdio.dev, "Corrupt section header\n"); + err = -EINVAL; + break; + } + + err = mv3310_load_fw_sect(phydev, &hdr, sect + sizeof(hdr)); + if (err) + break; + + if (!hdr.next_hdr) + break; + + sect = fw->data + hdr.next_hdr; + } + +release: + release_firmware(fw); + return err; +} + static int mv3310_probe(struct phy_device *phydev) { const struct mv3310_chip *chip = to_mv3310_chip(phydev); @@ -527,6 +668,12 @@ static int mv3310_probe(struct phy_device *phydev) return -ENODEV; } + if ((ret & MV_PMA_BOOT_PRGS_MASK) == MV_PMA_BOOT_PRGS_WAIT) { + ret = mv3310_load_fw(phydev); + if (ret) + return ret; + } + priv = devm_kzalloc(&phydev->mdio.dev, sizeof(*priv), GFP_KERNEL); if (!priv) return -ENOMEM; @@ -1219,6 +1366,7 @@ static const struct mv3310_chip mv3310_type = { .mactypes = mv3310_mactypes, .n_mactypes = ARRAY_SIZE(mv3310_mactypes), + .firmware_path = "mrvl/x3310fw.hdr", #ifdef CONFIG_HWMON .hwmon_read_temp_reg = mv3310_hwmon_read_temp_reg, @@ -1489,4 +1637,5 @@ static struct mdio_device_id __maybe_unused mv3310_tbl[] = { }; MODULE_DEVICE_TABLE(mdio, mv3310_tbl); MODULE_DESCRIPTION("Marvell Alaska X/M multi-gigabit Ethernet PHY driver"); +MODULE_FIRMWARE("mrvl/x3310fw.hdr"); MODULE_LICENSE("GPL"); From patchwork Thu Dec 14 20:14:40 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tobias Waldekranz X-Patchwork-Id: 13493588 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 6571D6A327 for ; Thu, 14 Dec 2023 20:15:05 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=waldekranz.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=waldekranz.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=waldekranz-com.20230601.gappssmtp.com header.i=@waldekranz-com.20230601.gappssmtp.com header.b="ZBmR5SJH" Received: by mail-lf1-f53.google.com with SMTP id 2adb3069b0e04-50bf8843a6fso1051484e87.0 for ; Thu, 14 Dec 2023 12:15:04 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=waldekranz-com.20230601.gappssmtp.com; s=20230601; t=1702584903; x=1703189703; darn=vger.kernel.org; h=content-transfer-encoding:organization:mime-version:references :in-reply-to:message-id:date:subject:cc:to:from:from:to:cc:subject :date:message-id:reply-to; bh=MMoRpkfRW6a85kKrBsEgEyVwIQWfuSkyqetOVceBkAM=; b=ZBmR5SJH2V/IB6J9ho9pcCHCMgGsNrrORUGiO6ENqDp6qrfQlOwwr7jT8Zhxm3g4ae Q7u9IKl1aUBtFZB8UA8lM90fenTUhJYgxaZhaK/j/0T9wt609nNeYSCqliI4GYn/U78J fH9AZKjzFADU56Imysn8DgLhoO0s/eK54Ugpm2I2j9vXFV7IVurR1q7mzzCa8VpVXdkN 9L2zeq5IIkj8PNmLn2fitnOJeRZQCFRCh6uvkEiaxQ5kMM7jozuDTJdadRZhNf/pAsQa JtLcXlybm+BmXicI9PIsuygCEUndj8+z0qh5rQduCXCBQ6e3P6oHwNC1mWP1mSHv515y MiCQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1702584903; x=1703189703; h=content-transfer-encoding:organization:mime-version:references :in-reply-to:message-id:date:subject:cc:to:from:x-gm-message-state :from:to:cc:subject:date:message-id:reply-to; bh=MMoRpkfRW6a85kKrBsEgEyVwIQWfuSkyqetOVceBkAM=; b=nKgETt+rhvhRazC35Lfu5Q3gOr0EQbqcNB9WGUuySp0NzmvsISz1uCqGWlVFjFjSPW pnngBl7vPD6naxsOX6w7rH4wchpdYaGVlJQ2YvqhhYuj2CS5gioD1PqhCRzAAWcaIi3O u0JiKJOdYflnZlqjcULvpa5Xc/lgs0wjWnM8jVvx0zy4JwpDUXd7tLvIWzC/PTQ9bVZZ S/i/za4chHTC56fmjaJ0AFy7Jd0OxlF47wpvZSYxH3g0EBTPGOOMe0C+iOi/XEM5HOdV aEhXxEeY9zeIhtVsMRqtu0dfjVcDD4rc7L22tkCx/cS0iyrOn6sOSkSQI1Rxy2CyprlY yEJw== X-Gm-Message-State: AOJu0Yzx2MHtWWY4TV+Vc9n5wKEMht+sluyN02y8Ba8YTeZ0krKYKZ/j XHp1nKA8MPBTkchcHfXZyCayoQ== X-Google-Smtp-Source: AGHT+IGCgjN4xx8n7yHMZRIWO7Q0Ci61+v1Uhi/DZfbACzbOj9dRF7ZoDgfmwasRYgNxlH9vAJucbw== X-Received: by 2002:a05:6512:a8d:b0:50b:fc8e:a531 with SMTP id m13-20020a0565120a8d00b0050bfc8ea531mr6380708lfu.12.1702584903154; Thu, 14 Dec 2023 12:15:03 -0800 (PST) Received: from wkz-x13.addiva.ad (h-158-174-187-194.NA.cust.bahnhof.se. [158.174.187.194]) by smtp.gmail.com with ESMTPSA id dw11-20020a0565122c8b00b0050e140f84besm369519lfb.164.2023.12.14.12.15.01 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 14 Dec 2023 12:15:02 -0800 (PST) From: Tobias Waldekranz To: davem@davemloft.net, kuba@kernel.org Cc: linux@armlinux.org.uk, kabel@kernel.org, andrew@lunn.ch, hkallweit1@gmail.com, robh+dt@kernel.org, krzysztof.kozlowski+dt@linaro.org, conor+dt@kernel.org, netdev@vger.kernel.org, devicetree@vger.kernel.org Subject: [PATCH net-next 2/4] net: phy: marvell10g: Fix power-up when strapped to start powered down Date: Thu, 14 Dec 2023 21:14:40 +0100 Message-Id: <20231214201442.660447-3-tobias@waldekranz.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20231214201442.660447-1-tobias@waldekranz.com> References: <20231214201442.660447-1-tobias@waldekranz.com> Precedence: bulk X-Mailing-List: netdev@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Organization: Addiva Elektronik X-Patchwork-Delegate: kuba@kernel.org On devices which are hardware strapped to start powered down (PDSTATE == 1), make sure that we clear the power-down bit on all units affected by this setting. Signed-off-by: Tobias Waldekranz --- drivers/net/phy/marvell10g.c | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/drivers/net/phy/marvell10g.c b/drivers/net/phy/marvell10g.c index 83233b30d7b0..1c1333d867fb 100644 --- a/drivers/net/phy/marvell10g.c +++ b/drivers/net/phy/marvell10g.c @@ -344,11 +344,22 @@ static int mv3310_power_down(struct phy_device *phydev) static int mv3310_power_up(struct phy_device *phydev) { + static const u16 resets[][2] = { + { MDIO_MMD_PCS, MV_PCS_BASE_R + MDIO_CTRL1 }, + { MDIO_MMD_PCS, MV_PCS_1000BASEX + MDIO_CTRL1 }, + { MDIO_MMD_PCS, MV_PCS_BASE_T + MDIO_CTRL1 }, + { MDIO_MMD_PMAPMD, MDIO_CTRL1 }, + { MDIO_MMD_VEND2, MV_V2_PORT_CTRL }, + }; struct mv3310_priv *priv = dev_get_drvdata(&phydev->mdio.dev); - int ret; + int i, ret; - ret = phy_clear_bits_mmd(phydev, MDIO_MMD_VEND2, MV_V2_PORT_CTRL, - MV_V2_PORT_CTRL_PWRDOWN); + for (i = 0; i < ARRAY_SIZE(resets); i++) { + ret = phy_clear_bits_mmd(phydev, resets[i][0], resets[i][1], + MV_V2_PORT_CTRL_PWRDOWN); + if (ret) + break; + } /* Sometimes, the power down bit doesn't clear immediately, and * a read of this register causes the bit not to clear. Delay From patchwork Thu Dec 14 20:14:41 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tobias Waldekranz X-Patchwork-Id: 13493591 X-Patchwork-Delegate: kuba@kernel.org Received: from mail-lf1-f50.google.com (mail-lf1-f50.google.com [209.85.167.50]) (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 F3E0F6A33A for ; Thu, 14 Dec 2023 20:15:06 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=waldekranz.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=waldekranz.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=waldekranz-com.20230601.gappssmtp.com header.i=@waldekranz-com.20230601.gappssmtp.com header.b="YCmLJDkV" Received: by mail-lf1-f50.google.com with SMTP id 2adb3069b0e04-50bffb64178so10076777e87.2 for ; Thu, 14 Dec 2023 12:15:06 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=waldekranz-com.20230601.gappssmtp.com; s=20230601; t=1702584904; x=1703189704; darn=vger.kernel.org; h=content-transfer-encoding:organization:mime-version:references :in-reply-to:message-id:date:subject:cc:to:from:from:to:cc:subject :date:message-id:reply-to; bh=I7HLv62IYJdHMlDeZU7GmB5aQgHlfet899NoGCtHGJY=; b=YCmLJDkVEKfwItjDjpiFeqnUBUm9kXbIjf3JzFiib7a9JgKbCZVyxO8e+ReRyUjYJ9 OV+YP6ks9i7pvv3hWv/ZOhf83oJDcIOLPtf5A339jJ/iBrkfL1XF/F96OhdjT1w+1FmM PTSlwX6SsYr05UVG5znTn1pShbNBcrlVFTW24O9cJRjOkNY9Md8rawnfEp9cdQzox9p9 tTe38Zrj7Dz7Vnc8y5sHETpSK7AUCKNPiBan+aE3tSe+rMUcCtdt+EE0Ou5oZgBRQj9U vyVski7Yrg4UPaDtqr5JdLtbcX1vHGqe3cQY3ybXuGbObMio5ZlVNveXCOZXpD4l+yKQ VAEg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1702584904; x=1703189704; h=content-transfer-encoding:organization:mime-version:references :in-reply-to:message-id:date:subject:cc:to:from:x-gm-message-state :from:to:cc:subject:date:message-id:reply-to; bh=I7HLv62IYJdHMlDeZU7GmB5aQgHlfet899NoGCtHGJY=; b=E/xFd7HyFOnOq5qGWuuq+FLdOdCy/9fzM5DYdlmGIoZOIP5spbLIGsjdFQ8eedJ6QH JV6S1+zWzQKahJkAMlvB9hqydBI30q0wAAgtDzZ3SPXThKXwsMYvSbtyIlkhnQdilnoU kOVyPaak2YI4t8/Re26c5Ovlh/p2XheefwmGnv1bqBwq7UZb0naLREL78/YzHwdRri0r SHu5vC2pRfA2YoT/Yf7dzLlOtiaGdELDaXhB2/3948dQjG0gXhKddYBAgQwzgBEBd6Kq 31LNbBqPAzw/7l2fHwYEPDEl4bfB+hHvmejiEVOwSfu9iR8sXKo4sQ1hltKXsXCMTBhf b76Q== X-Gm-Message-State: AOJu0Yz413/YPvySNKszp5gjQnUwB57QoWmV++n9tv3MKIByB5oOrR3c CG8jArBwCz20uEPMk+ubi/LWaM4hgZ5IWVNPtuM= X-Google-Smtp-Source: AGHT+IFaGXXOf4tADTBM1Ga8Rxetf5wJRLNmDeDq6xqhSzPRs/O2pCk2oOTdTkZRu6MBzbEn+HvzNQ== X-Received: by 2002:ac2:4251:0:b0:50e:1b4e:cbdd with SMTP id m17-20020ac24251000000b0050e1b4ecbddmr505780lfl.114.1702584904312; Thu, 14 Dec 2023 12:15:04 -0800 (PST) Received: from wkz-x13.addiva.ad (h-158-174-187-194.NA.cust.bahnhof.se. [158.174.187.194]) by smtp.gmail.com with ESMTPSA id dw11-20020a0565122c8b00b0050e140f84besm369519lfb.164.2023.12.14.12.15.03 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 14 Dec 2023 12:15:03 -0800 (PST) From: Tobias Waldekranz To: davem@davemloft.net, kuba@kernel.org Cc: linux@armlinux.org.uk, kabel@kernel.org, andrew@lunn.ch, hkallweit1@gmail.com, robh+dt@kernel.org, krzysztof.kozlowski+dt@linaro.org, conor+dt@kernel.org, netdev@vger.kernel.org, devicetree@vger.kernel.org Subject: [PATCH net-next 3/4] net: phy: marvell10g: Add LED support for 88X3310 Date: Thu, 14 Dec 2023 21:14:41 +0100 Message-Id: <20231214201442.660447-4-tobias@waldekranz.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20231214201442.660447-1-tobias@waldekranz.com> References: <20231214201442.660447-1-tobias@waldekranz.com> Precedence: bulk X-Mailing-List: netdev@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Organization: Addiva Elektronik X-Patchwork-Delegate: kuba@kernel.org Pickup the LEDs from the state in which the hardware reset or bootloader left them, but also support further configuration via device tree. This is primarily needed because the electrical polarity and drive behavior is software controlled and not possible to set via hardware strapping. Trigger support: - "none" - "timer": Map 60-100 ms periods to the fast rate (81ms) and 1000-1600 ms periods to the slow rate (1300ms). Defer everything else to software blinking - "netdev": Offload link or duplex information to the solid behavior; tx and/or rx activity to blink behavior. Signed-off-by: Tobias Waldekranz --- drivers/net/phy/marvell10g.c | 436 +++++++++++++++++++++++++++++++++++ 1 file changed, 436 insertions(+) diff --git a/drivers/net/phy/marvell10g.c b/drivers/net/phy/marvell10g.c index 1c1333d867fb..73d74977dd05 100644 --- a/drivers/net/phy/marvell10g.c +++ b/drivers/net/phy/marvell10g.c @@ -28,6 +28,7 @@ #include #include #include +#include #include #include #include @@ -136,6 +137,14 @@ enum { MV_V2_33X0_PORT_CTRL_MACTYPE_10GBASER_NO_SGMII_AN = 0x5, MV_V2_33X0_PORT_CTRL_MACTYPE_10GBASER_RATE_MATCH = 0x6, MV_V2_33X0_PORT_CTRL_MACTYPE_USXGMII = 0x7, + MV_V2_LED0_CONTROL = 0xf020, + MV_V2_LED_CONTROL_POLARITY_MASK = 0x0003, + MV_V2_LED_CONTROL_POLARITY_SHIFT = 0, + MV_V2_LED_CONTROL_BLINK_RATE = BIT(2), + MV_V2_LED_CONTROL_SOLID_FUNC_MASK = 0x00f8, + MV_V2_LED_CONTROL_SOLID_FUNC_SHIFT = 3, + MV_V2_LED_CONTROL_BLINK_FUNC_MASK = 0x1f00, + MV_V2_LED_CONTROL_BLINK_FUNC_SHIFT = 8, MV_V2_PORT_INTR_STS = 0xf040, MV_V2_PORT_INTR_MASK = 0xf043, MV_V2_PORT_INTR_STS_WOL_EN = BIT(8), @@ -164,6 +173,7 @@ struct mv3310_mactype { struct mv3310_chip { bool (*has_downshift)(struct phy_device *phydev); void (*init_supported_interfaces)(unsigned long *mask); + int (*leds_probe)(struct phy_device *phydev); int (*get_mactype)(struct phy_device *phydev); int (*set_mactype)(struct phy_device *phydev, int mactype); int (*select_mactype)(unsigned long *interfaces); @@ -177,6 +187,13 @@ struct mv3310_chip { #endif }; +#define MV3310_N_LEDS 4 + +struct mv3310_led { + u8 index; + u16 fw_ctrl; +}; + struct mv3310_priv { DECLARE_BITMAP(supported_interfaces, PHY_INTERFACE_MODE_MAX); const struct mv3310_mactype *mactype; @@ -186,6 +203,8 @@ struct mv3310_priv { struct device *hwmon_dev; char *hwmon_name; + + struct mv3310_led led[MV3310_N_LEDS]; }; static const struct mv3310_chip *to_mv3310_chip(struct phy_device *phydev) @@ -193,6 +212,413 @@ static const struct mv3310_chip *to_mv3310_chip(struct phy_device *phydev) return phydev->drv->driver_data; } +enum mv3310_led_func { + MV3310_LED_FUNC_OFF = 0x00, + MV3310_LED_FUNC_TX_RX = 0x01, + MV3310_LED_FUNC_TX = 0x02, + MV3310_LED_FUNC_RX = 0x03, + MV3310_LED_FUNC_COLLISION = 0x04, + MV3310_LED_FUNC_LINK_COPPER = 0x05, + MV3310_LED_FUNC_LINK_FIBER = 0x06, + MV3310_LED_FUNC_LINK = 0x07, + MV3310_LED_FUNC_10M_LINK = 0x08, + MV3310_LED_FUNC_100M_LINK = 0x09, + MV3310_LED_FUNC_1G_LINK = 0x0a, + MV3310_LED_FUNC_10G_LINK = 0x0b, + MV3310_LED_FUNC_10M_100M_LINK = 0x0c, + MV3310_LED_FUNC_10M_100M_1G_LINK = 0x0d, + MV3310_LED_FUNC_100M_10G_LINK = 0x0e, + MV3310_LED_FUNC_1G_10G_LINK = 0x0f, + MV3310_LED_FUNC_1G_10G_SLAVE = 0x10, + MV3310_LED_FUNC_1G_10G_MASTER = 0x11, + MV3310_LED_FUNC_HALF_DUPLEX = 0x12, + MV3310_LED_FUNC_FULL_DUPLEX = 0x13, + MV3310_LED_FUNC_LINK_EEE = 0x14, + MV3310_LED_FUNC_2G5_LINK = 0x15, + MV3310_LED_FUNC_5G_LINK = 0x16, + MV3310_LED_FUNC_ON = 0x17, + MV3310_LED_FUNC_2G5_5G_SLAVE = 0x18, + MV3310_LED_FUNC_2G5_5G_MASTER = 0x19, + + MV3310_LED_FUNC_SPEED_BLINK = 0x1f +}; + +static int mv3310_led_flags_from_funcs(struct mv3310_led *led, + enum mv3310_led_func solid, + enum mv3310_led_func blink, + unsigned long *flagsp) +{ + unsigned long flags = 0; + + switch (solid) { + case MV3310_LED_FUNC_OFF: + break; + case MV3310_LED_FUNC_LINK_COPPER: + case MV3310_LED_FUNC_LINK_FIBER: + case MV3310_LED_FUNC_LINK: + flags |= TRIGGER_NETDEV_LINK; + break; + case MV3310_LED_FUNC_HALF_DUPLEX: + flags |= TRIGGER_NETDEV_HALF_DUPLEX; + break; + case MV3310_LED_FUNC_FULL_DUPLEX: + flags |= TRIGGER_NETDEV_FULL_DUPLEX; + break; + default: + return -EINVAL; + } + + switch (blink) { + case MV3310_LED_FUNC_OFF: + break; + case MV3310_LED_FUNC_TX: + flags |= TRIGGER_NETDEV_TX; + break; + case MV3310_LED_FUNC_RX: + flags |= TRIGGER_NETDEV_RX; + break; + case MV3310_LED_FUNC_TX_RX: + flags |= TRIGGER_NETDEV_TX | TRIGGER_NETDEV_RX; + break; + default: + return -EINVAL; + } + + *flagsp = flags; + return 0; +} + +static int mv3310_led_funcs_from_flags(struct mv3310_led *led, + unsigned long flags, + enum mv3310_led_func *solid, + enum mv3310_led_func *blink) +{ + unsigned long activity, duplex, link; + + if (flags & ~(BIT(TRIGGER_NETDEV_LINK) | + BIT(TRIGGER_NETDEV_HALF_DUPLEX) | + BIT(TRIGGER_NETDEV_FULL_DUPLEX) | + BIT(TRIGGER_NETDEV_TX) | + BIT(TRIGGER_NETDEV_RX))) + return -EINVAL; + + link = flags & BIT(TRIGGER_NETDEV_LINK); + + duplex = flags & (BIT(TRIGGER_NETDEV_HALF_DUPLEX) | + BIT(TRIGGER_NETDEV_FULL_DUPLEX)); + + activity = flags & (BIT(TRIGGER_NETDEV_TX) | + BIT(TRIGGER_NETDEV_RX)); + + if (link && duplex) + return -EINVAL; + + if (solid) { + if (link) { + *solid = MV3310_LED_FUNC_LINK; + } else if (duplex) { + switch (duplex) { + case BIT(TRIGGER_NETDEV_HALF_DUPLEX): + *solid = MV3310_LED_FUNC_HALF_DUPLEX; + break; + case BIT(TRIGGER_NETDEV_FULL_DUPLEX): + *solid = MV3310_LED_FUNC_FULL_DUPLEX; + break; + default: + break; + } + } else { + *solid = MV3310_LED_FUNC_OFF; + } + } + + if (blink) { + switch (activity) { + case 0: + *blink = MV3310_LED_FUNC_OFF; + break; + case BIT(TRIGGER_NETDEV_TX): + *blink = MV3310_LED_FUNC_TX; + break; + case BIT(TRIGGER_NETDEV_RX): + *blink = MV3310_LED_FUNC_RX; + break; + default: + *blink = MV3310_LED_FUNC_TX_RX; + break; + } + } + + return 0; +} + +static int mv3310_led_get(struct phy_device *phydev, + struct mv3310_led *led, + enum mv3310_led_func *solid, + enum mv3310_led_func *blink, + bool *slow_blink) +{ + int ctrl; + + ctrl = phy_read_mmd(phydev, MDIO_MMD_VEND2, + MV_V2_LED0_CONTROL + led->index); + if (ctrl < 0) + return ctrl; + + *solid = (ctrl & MV_V2_LED_CONTROL_SOLID_FUNC_MASK) >> + MV_V2_LED_CONTROL_SOLID_FUNC_SHIFT; + *blink = (ctrl & MV_V2_LED_CONTROL_BLINK_FUNC_MASK) >> + MV_V2_LED_CONTROL_BLINK_FUNC_SHIFT; + + *slow_blink = !!(ctrl & MV_V2_LED_CONTROL_BLINK_RATE); + return 0; +} + +static int mv3310_led_set(struct phy_device *phydev, + struct mv3310_led *led, + enum mv3310_led_func solid, + enum mv3310_led_func blink, + bool slow_blink) +{ + u16 ctrl = led->fw_ctrl; + + ctrl &= ~MV_V2_LED_CONTROL_SOLID_FUNC_MASK; + ctrl &= ~MV_V2_LED_CONTROL_BLINK_FUNC_MASK; + ctrl &= ~MV_V2_LED_CONTROL_BLINK_RATE; + + ctrl |= solid << MV_V2_LED_CONTROL_SOLID_FUNC_SHIFT; + ctrl |= blink << MV_V2_LED_CONTROL_BLINK_FUNC_SHIFT; + + if (slow_blink) + ctrl |= MV_V2_LED_CONTROL_BLINK_RATE; + + return phy_write_mmd(phydev, MDIO_MMD_VEND2, + MV_V2_LED0_CONTROL + led->index, ctrl); +} + +enum mv3310_led_polarity { + MV3310_LED_POLARITY_ACTIVE_LOW = 0x0, + MV3310_LED_POLARITY_ACTIVE_HIGH = 0x1, + MV3310_LED_POLARITY_ACTIVE_LOW_TRISTATE = 0x2, + MV3310_LED_POLARITY_ACTIVE_HIGH_TRISTATE = 0x3, +}; + +static const char * const mv3310_led_polarity_name[] = { + [MV3310_LED_POLARITY_ACTIVE_LOW] = "active-low", + [MV3310_LED_POLARITY_ACTIVE_HIGH] = "active-high", + [MV3310_LED_POLARITY_ACTIVE_LOW_TRISTATE] = "active-low-tristate", + [MV3310_LED_POLARITY_ACTIVE_HIGH_TRISTATE] = "active-high-tristate", +}; + +static int mv3310_led_polarity_from_str(const char *str, + enum mv3310_led_polarity *polarity) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(mv3310_led_polarity_name); i++) { + if (!mv3310_led_polarity_name[i]) + continue; + + if (!strcmp(mv3310_led_polarity_name[i], str)) { + *polarity = i; + return 0; + } + } + + return -ENOENT; +} + +static int mv3310_led_probe_of(struct phy_device *phydev, + struct device_node *np) +{ + struct mv3310_priv *priv = dev_get_drvdata(&phydev->mdio.dev); + enum mv3310_led_polarity polarity; + struct mv3310_led *led; + const char *str; + u32 index; + u16 ctrl; + int err; + + err = of_property_read_u32(np, "reg", &index); + if (err) + return err; + + if (index >= MV3310_N_LEDS) + return -EINVAL; + + led = &priv->led[index]; + ctrl = led->fw_ctrl; + + err = of_property_read_string(np, "marvell,polarity", &str); + err = err ? : mv3310_led_polarity_from_str(str, &polarity); + if (!err) { + ctrl &= ~MV_V2_LED_CONTROL_POLARITY_MASK; + ctrl |= polarity << MV_V2_LED_CONTROL_POLARITY_SHIFT; + } + + if (ctrl != led->fw_ctrl) { + led->fw_ctrl = ctrl; + + return phy_write_mmd(phydev, MDIO_MMD_VEND2, + MV_V2_LED0_CONTROL + index, ctrl); + } + + return 0; +} + +static int mv3310_leds_probe(struct phy_device *phydev) +{ + struct mv3310_priv *priv = dev_get_drvdata(&phydev->mdio.dev); + struct device_node *node = phydev->mdio.dev.of_node; + struct device_node *pnp, *np; + int err, val, index; + + /* Save the config left by HW reset or bootloader, to make + * sure that we do not loose any polarity config made by + * firmware. This will be overridden by info from DT, if + * available. + */ + for (index = 0; index < MV3310_N_LEDS; index++) { + val = phy_read_mmd(phydev, MDIO_MMD_VEND2, + MV_V2_LED0_CONTROL + index); + if (val < 0) + return val; + + priv->led[index] = (struct mv3310_led) { + .index = index, + .fw_ctrl = val, + }; + } + + if (!node) + return 0; + + pnp = of_get_child_by_name(node, "leds"); + if (!pnp) + return 0; + + for_each_available_child_of_node(pnp, np) { + err = mv3310_led_probe_of(phydev, np); + if (err) + return err; + } + + return 0; +} + +static int mv3310_led_brightness_set(struct phy_device *phydev, + u8 index, enum led_brightness value) +{ + struct mv3310_priv *priv = dev_get_drvdata(&phydev->mdio.dev); + enum mv3310_led_func solid; + struct mv3310_led *led; + + if (index >= MV3310_N_LEDS) + return -ENODEV; + + led = &priv->led[index]; + + if (value == LED_OFF) + solid = MV3310_LED_FUNC_OFF; + else + solid = MV3310_LED_FUNC_ON; + + return mv3310_led_set(phydev, led, solid, MV3310_LED_FUNC_OFF, false); +} + +static int mv3310_led_blink_set(struct phy_device *phydev, u8 index, + unsigned long *delay_on, + unsigned long *delay_off) +{ + struct mv3310_priv *priv = dev_get_drvdata(&phydev->mdio.dev); + struct mv3310_led *led; + bool slow_blink; + int err; + + if (index >= MV3310_N_LEDS) + return -ENODEV; + + led = &priv->led[index]; + + if (*delay_on != *delay_off) + /* Defer anything other than 50% duty cycles to + * software. + */ + return -EINVAL; + + /* Accept values within ~20% of our supported rates (80ms or + * 1300ms periods). + */ + if ((*delay_on >= 30) && (*delay_on <= 50)) + slow_blink = false; + else if (((*delay_on >= 500) && (*delay_on <= 800)) || (*delay_on == 0)) + slow_blink = true; + else + return -EINVAL; + + err = mv3310_led_set(phydev, led, MV3310_LED_FUNC_OFF, + MV3310_LED_FUNC_ON, slow_blink); + if (!err) + *delay_on = *delay_off = slow_blink ? 650 : 40; + + return err; +} + +static int mv3310_led_hw_is_supported(struct phy_device *phydev, u8 index, + unsigned long flags) +{ + struct mv3310_priv *priv = dev_get_drvdata(&phydev->mdio.dev); + struct mv3310_led *led; + + if (index >= MV3310_N_LEDS) + return -ENODEV; + + led = &priv->led[index]; + + return mv3310_led_funcs_from_flags(led, flags, NULL, NULL); +} + +static int mv3310_led_hw_control_set(struct phy_device *phydev, u8 index, + unsigned long flags) +{ + struct mv3310_priv *priv = dev_get_drvdata(&phydev->mdio.dev); + enum mv3310_led_func solid, blink; + struct mv3310_led *led; + int err; + + if (index >= MV3310_N_LEDS) + return -ENODEV; + + led = &priv->led[index]; + + err = mv3310_led_funcs_from_flags(led, flags, &solid, &blink); + if (err) + return err; + + return mv3310_led_set(phydev, led, solid, blink, false); +} + +static int mv3310_led_hw_control_get(struct phy_device *phydev, u8 index, + unsigned long *flags) +{ + struct mv3310_priv *priv = dev_get_drvdata(&phydev->mdio.dev); + enum mv3310_led_func solid, blink; + struct mv3310_led *led; + bool slow_blink; + int err; + + if (index >= MV3310_N_LEDS) + return -ENODEV; + + led = &priv->led[index]; + + err = mv3310_led_get(phydev, led, &solid, &blink, &slow_blink); + if (err) + return err; + + return mv3310_led_flags_from_funcs(led, solid, blink, flags); +} + #ifdef CONFIG_HWMON static umode_t mv3310_hwmon_is_visible(const void *data, enum hwmon_sensor_types type, @@ -719,6 +1145,10 @@ static int mv3310_probe(struct phy_device *phydev) if (ret) return ret; + ret = chip->leds_probe ? chip->leds_probe(phydev) : 0; + if (ret) + return ret; + chip->init_supported_interfaces(priv->supported_interfaces); return phy_sfp_probe(phydev, &mv3310_sfp_ops); @@ -1371,6 +1801,7 @@ static void mv2111_init_supported_interfaces(unsigned long *mask) static const struct mv3310_chip mv3310_type = { .has_downshift = mv3310_has_downshift, .init_supported_interfaces = mv3310_init_supported_interfaces, + .leds_probe = mv3310_leds_probe, .get_mactype = mv3310_get_mactype, .set_mactype = mv3310_set_mactype, .select_mactype = mv3310_select_mactype, @@ -1579,6 +2010,11 @@ static struct phy_driver mv3310_drivers[] = { .set_loopback = genphy_c45_loopback, .get_wol = mv3110_get_wol, .set_wol = mv3110_set_wol, + .led_brightness_set = mv3310_led_brightness_set, + .led_blink_set = mv3310_led_blink_set, + .led_hw_is_supported = mv3310_led_hw_is_supported, + .led_hw_control_set = mv3310_led_hw_control_set, + .led_hw_control_get = mv3310_led_hw_control_get, }, { .phy_id = MARVELL_PHY_ID_88X3310, From patchwork Thu Dec 14 20:14:42 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Tobias Waldekranz X-Patchwork-Id: 13493590 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 E016C6A33B for ; Thu, 14 Dec 2023 20:15:07 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=waldekranz.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=waldekranz.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=waldekranz-com.20230601.gappssmtp.com header.i=@waldekranz-com.20230601.gappssmtp.com header.b="3T5YzupG" Received: by mail-lf1-f49.google.com with SMTP id 2adb3069b0e04-50e18689828so1093562e87.2 for ; Thu, 14 Dec 2023 12:15:07 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=waldekranz-com.20230601.gappssmtp.com; s=20230601; t=1702584906; x=1703189706; darn=vger.kernel.org; h=content-transfer-encoding:organization:mime-version:references :in-reply-to:message-id:date:subject:cc:to:from:from:to:cc:subject :date:message-id:reply-to; bh=+yM7zmNbZ3NMKlj22szdncYUAuggJTnUNqcTouIT5Qs=; b=3T5YzupGDwDsFAtlSa/rbnO769F100DajDkQIjejKwUW6QsJqWwK8rHITDMU8knofk aibr1B0+x/7fcNGPutuXoNs4ZZtO9W/U9suZUJ7n2sHcOMohjaxhS1w8CZ0Zo95COd8H mgpZvuYpNHjhDfA1YY4W52BycvZnIRUK69XgbQL3MSFKAPJjDrdne4iQ032cTobr8OIi UgUJZsO2IvYfb9q3q2ifus128VSxa0Kl7xem5wTYqCFxO4EAaDdeGfQ9UAGllccqK1SD Zc2PYOQoMjdRtiTL5GRACMwdJO3nSqC4IZX+mcUPdv/cOTlNfMXupNDeR27fpHQr3OoE EzhQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1702584906; x=1703189706; h=content-transfer-encoding:organization:mime-version:references :in-reply-to:message-id:date:subject:cc:to:from:x-gm-message-state :from:to:cc:subject:date:message-id:reply-to; bh=+yM7zmNbZ3NMKlj22szdncYUAuggJTnUNqcTouIT5Qs=; b=TV42/ycpanFCf+/4MnkON/Unj61OLohTgn2k4oMMVcE7YJY/fJXpNxdiKmUwO+dd8w yl+rfchKYd0lJcqu2mjLwjIGJxZBhQXjFyjqRgYLkm64RxssSLMhLPZ1VZkMIiQoYHQz DXghoS4Fpw5dMsXezXuu4T6WW/9Cy/nHNelNcdY0sE+EhIHzSJtiZl2hv6c7iCXzTecx A4Mkxej7jMBH5Y221+eSSkbTSphOTXAJrwxs8gYg/iHzgqGcFVgdTmVfIuFkWyPmqcl2 IziNFPdTn5YTunNC/ywF29MWkauIbDWdYMfHnPJzz11W79PSC0geMQ0paYzwDJgpJ4gf wjyQ== X-Gm-Message-State: AOJu0Yx0AL9lFGpo/yY6w6fX/9wR3zDavL2XhhUwjxSwzw2qTYKIcv0O 9S9f7MHv87xndEjd+mtsHWbPHw== X-Google-Smtp-Source: AGHT+IGlxWLTei4ZhkkCQO5kN+blstnu3fm/QzjY3Gm3mbAab7sIaqeIXNBqxpx6zULCUy0YYjdlPw== X-Received: by 2002:a05:6512:31d2:b0:50e:154e:d7ad with SMTP id j18-20020a05651231d200b0050e154ed7admr1325381lfe.79.1702584905748; Thu, 14 Dec 2023 12:15:05 -0800 (PST) Received: from wkz-x13.addiva.ad (h-158-174-187-194.NA.cust.bahnhof.se. [158.174.187.194]) by smtp.gmail.com with ESMTPSA id dw11-20020a0565122c8b00b0050e140f84besm369519lfb.164.2023.12.14.12.15.04 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 14 Dec 2023 12:15:04 -0800 (PST) From: Tobias Waldekranz To: davem@davemloft.net, kuba@kernel.org Cc: linux@armlinux.org.uk, kabel@kernel.org, andrew@lunn.ch, hkallweit1@gmail.com, robh+dt@kernel.org, krzysztof.kozlowski+dt@linaro.org, conor+dt@kernel.org, netdev@vger.kernel.org, devicetree@vger.kernel.org Subject: [PATCH net-next 4/4] dt-bindings: net: marvell10g: Document LED polarity Date: Thu, 14 Dec 2023 21:14:42 +0100 Message-Id: <20231214201442.660447-5-tobias@waldekranz.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20231214201442.660447-1-tobias@waldekranz.com> References: <20231214201442.660447-1-tobias@waldekranz.com> Precedence: bulk X-Mailing-List: netdev@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Organization: Addiva Elektronik X-Patchwork-Delegate: kuba@kernel.org Hardware supports multiple ways of driving attached LEDs, but this is not configurable via any sample-at-reset pins - rather it must be set via software. Signed-off-by: Tobias Waldekranz --- .../bindings/net/marvell,marvell10g.yaml | 60 +++++++++++++++++++ MAINTAINERS | 1 + 2 files changed, 61 insertions(+) create mode 100644 Documentation/devicetree/bindings/net/marvell,marvell10g.yaml diff --git a/Documentation/devicetree/bindings/net/marvell,marvell10g.yaml b/Documentation/devicetree/bindings/net/marvell,marvell10g.yaml new file mode 100644 index 000000000000..37ff7fdfdd3d --- /dev/null +++ b/Documentation/devicetree/bindings/net/marvell,marvell10g.yaml @@ -0,0 +1,60 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/net/marvell,marvell10g.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Marvell Alaska X 10G Ethernet PHY + +maintainers: + - Tobias Waldekranz + +description: | + Bindings for Marvell Alaska X 10G Ethernet PHYs + +allOf: + - $ref: ethernet-phy.yaml# + +properties: + leds: + type: object + + properties: + '#address-cells': + const: 1 + + '#size-cells': + const: 0 + + patternProperties: + '^led@[a-f0-9]+$': + $ref: /schemas/leds/common.yaml# + + properties: + marvell,polarity: + description: | + Electrical polarity and drive type for this LED. In the + active state, hardware may drive the pin either low or + high. In the inactive state, the pin can either be + driven to the opposite logic level, or be tristated. + $ref: /schemas/types.yaml#/definitions/string + enum: + - active-low + - active-high + - active-low-tristate + - active-high-tristate + +unevaluatedProperties: false + +examples: + - | + mdio { + #address-cells = <1>; + #size-cells = <0>; + + ethernet-phy@0 { + reg = <0>; + + marvell,polarity = "active-low-tristate"; + }; + }; diff --git a/MAINTAINERS b/MAINTAINERS index a151988646fe..2def66789f9d 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -12849,6 +12849,7 @@ M: Russell King M: Marek BehĂșn L: netdev@vger.kernel.org S: Maintained +F: Documentation/devicetree/bindings/net/marvell,marvell10g.yaml F: drivers/net/phy/marvell10g.c MARVELL MVEBU THERMAL DRIVER