From 89e7ff5e58b8d18e3c5504d155d3c1f7ed6f3d49 Mon Sep 17 00:00:00 2001 From: baiywt Date: Thu, 18 May 2023 15:55:23 +0800 Subject: [PATCH] net: phy: add sysfs node for reading PHY's registers --- drivers/net/phy/phy_device.c | 58 ++++++++++++++++++++++++++++++++++++ 1 file changed, 58 insertions(+) diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c index 7fbb0904b..a7f6e3a9f 100644 --- a/drivers/net/phy/phy_device.c +++ b/drivers/net/phy/phy_device.c @@ -563,11 +563,69 @@ static ssize_t phy_dev_flags_show(struct device *dev, } static DEVICE_ATTR_RO(phy_dev_flags); +static ssize_t +phy_registers_show(struct device *dev, struct device_attribute *attr, char *buf) +{ + struct phy_device *phydev = to_phy_device(dev); + int index; + + for (index = 0; index < 32; index++) + sprintf(buf, "%s%2d: 0x%x\n", buf, index, + phy_read(phydev, index)); + + return strlen(buf); +} + +static ssize_t +phy_registers_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct phy_device *phydev = to_phy_device(dev); + int index = 0, val = 0; + char tmp[32]; + char *data; + + if (count >= sizeof(tmp)) + goto out; + + memset(tmp, 0, sizeof(tmp)); + memcpy(tmp, buf, count); + + data = tmp; + data = strstr(data, " "); + if (!data) + goto out; + *data = 0; + data++; + + if (kstrtoint(tmp, 0, &index) || index >= 32) + goto out; + + if (kstrtoint(data, 0, &val) || val > 0xffff) + goto out; + + pr_info("Set Ethernet PHY register %d to 0x%x\n", (int)index, (int)val); + + phy_write(phydev, index, val); + + return count; + +out: + pr_err("wrong register value input\n"); + pr_err("usage: \n"); + + return count; +} + +static DEVICE_ATTR_RW(phy_registers); + static struct attribute *phy_dev_attrs[] = { &dev_attr_phy_id.attr, &dev_attr_phy_interface.attr, &dev_attr_phy_has_fixups.attr, &dev_attr_phy_dev_flags.attr, + &dev_attr_phy_registers.attr, NULL, }; ATTRIBUTE_GROUPS(phy_dev);