Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

net: phy: Add c45_phy_ids sysfs directory entry

The phy_id field only shows the PHY ID of the C22 device, and the C45
device did not store its PHY ID in this field.

Add a new phy_mmd_group, and export the mmd<n>_device_id for the C45
device. These files are invisible to the C22 device.

Signed-off-by: Yajun Deng <yajun.deng@linux.dev>
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
Link: https://patch.msgid.link/20250613131903.2961-1-yajun.deng@linux.dev
Signed-off-by: Paolo Abeni <pabeni@redhat.com>

authored by

Yajun Deng and committed by
Paolo Abeni
170e4e39 9149a632

+120 -2
+10
Documentation/ABI/testing/sysfs-class-net-phydev
··· 26 26 This ID is used to match the device with the appropriate 27 27 driver. 28 28 29 + What: /sys/class/mdio_bus/<bus>/<device>/c45_phy_ids/mmd<n>_device_id 30 + Date: June 2025 31 + KernelVersion: 6.17 32 + Contact: netdev@vger.kernel.org 33 + Description: 34 + This attribute contains the 32-bit PHY Identifier as reported 35 + by the device during bus enumeration, encoded in hexadecimal. 36 + These C45 IDs are used to match the device with the appropriate 37 + driver. These files are invisible to the C22 device. 38 + 29 39 What: /sys/class/mdio_bus/<bus>/<device>/phy_interface 30 40 Date: February 2014 31 41 KernelVersion: 3.15
+110 -2
drivers/net/phy/phy_device.c
··· 652 652 &dev_attr_phy_dev_flags.attr, 653 653 NULL, 654 654 }; 655 - ATTRIBUTE_GROUPS(phy_dev); 655 + 656 + static const struct attribute_group phy_dev_group = { 657 + .attrs = phy_dev_attrs, 658 + }; 659 + 660 + #define MMD_DEVICE_ID_ATTR(n) \ 661 + static ssize_t mmd##n##_device_id_show(struct device *dev, \ 662 + struct device_attribute *attr, char *buf) \ 663 + { \ 664 + struct phy_device *phydev = to_phy_device(dev); \ 665 + return sysfs_emit(buf, "0x%.8lx\n", \ 666 + (unsigned long)phydev->c45_ids.device_ids[n]); \ 667 + } \ 668 + static DEVICE_ATTR_RO(mmd##n##_device_id) 669 + 670 + MMD_DEVICE_ID_ATTR(1); 671 + MMD_DEVICE_ID_ATTR(2); 672 + MMD_DEVICE_ID_ATTR(3); 673 + MMD_DEVICE_ID_ATTR(4); 674 + MMD_DEVICE_ID_ATTR(5); 675 + MMD_DEVICE_ID_ATTR(6); 676 + MMD_DEVICE_ID_ATTR(7); 677 + MMD_DEVICE_ID_ATTR(8); 678 + MMD_DEVICE_ID_ATTR(9); 679 + MMD_DEVICE_ID_ATTR(10); 680 + MMD_DEVICE_ID_ATTR(11); 681 + MMD_DEVICE_ID_ATTR(12); 682 + MMD_DEVICE_ID_ATTR(13); 683 + MMD_DEVICE_ID_ATTR(14); 684 + MMD_DEVICE_ID_ATTR(15); 685 + MMD_DEVICE_ID_ATTR(16); 686 + MMD_DEVICE_ID_ATTR(17); 687 + MMD_DEVICE_ID_ATTR(18); 688 + MMD_DEVICE_ID_ATTR(19); 689 + MMD_DEVICE_ID_ATTR(20); 690 + MMD_DEVICE_ID_ATTR(21); 691 + MMD_DEVICE_ID_ATTR(22); 692 + MMD_DEVICE_ID_ATTR(23); 693 + MMD_DEVICE_ID_ATTR(24); 694 + MMD_DEVICE_ID_ATTR(25); 695 + MMD_DEVICE_ID_ATTR(26); 696 + MMD_DEVICE_ID_ATTR(27); 697 + MMD_DEVICE_ID_ATTR(28); 698 + MMD_DEVICE_ID_ATTR(29); 699 + MMD_DEVICE_ID_ATTR(30); 700 + MMD_DEVICE_ID_ATTR(31); 701 + 702 + static struct attribute *phy_mmd_attrs[] = { 703 + &dev_attr_mmd1_device_id.attr, 704 + &dev_attr_mmd2_device_id.attr, 705 + &dev_attr_mmd3_device_id.attr, 706 + &dev_attr_mmd4_device_id.attr, 707 + &dev_attr_mmd5_device_id.attr, 708 + &dev_attr_mmd6_device_id.attr, 709 + &dev_attr_mmd7_device_id.attr, 710 + &dev_attr_mmd8_device_id.attr, 711 + &dev_attr_mmd9_device_id.attr, 712 + &dev_attr_mmd10_device_id.attr, 713 + &dev_attr_mmd11_device_id.attr, 714 + &dev_attr_mmd12_device_id.attr, 715 + &dev_attr_mmd13_device_id.attr, 716 + &dev_attr_mmd14_device_id.attr, 717 + &dev_attr_mmd15_device_id.attr, 718 + &dev_attr_mmd16_device_id.attr, 719 + &dev_attr_mmd17_device_id.attr, 720 + &dev_attr_mmd18_device_id.attr, 721 + &dev_attr_mmd19_device_id.attr, 722 + &dev_attr_mmd20_device_id.attr, 723 + &dev_attr_mmd21_device_id.attr, 724 + &dev_attr_mmd22_device_id.attr, 725 + &dev_attr_mmd23_device_id.attr, 726 + &dev_attr_mmd24_device_id.attr, 727 + &dev_attr_mmd25_device_id.attr, 728 + &dev_attr_mmd26_device_id.attr, 729 + &dev_attr_mmd27_device_id.attr, 730 + &dev_attr_mmd28_device_id.attr, 731 + &dev_attr_mmd29_device_id.attr, 732 + &dev_attr_mmd30_device_id.attr, 733 + &dev_attr_mmd31_device_id.attr, 734 + NULL 735 + }; 736 + 737 + static umode_t phy_mmd_is_visible(struct kobject *kobj, 738 + struct attribute *attr, int index) 739 + { 740 + struct device *dev = kobj_to_dev(kobj); 741 + struct phy_device *phydev = to_phy_device(dev); 742 + const int i = index + 1; 743 + 744 + if (!phydev->is_c45) 745 + return 0; 746 + if (i >= ARRAY_SIZE(phydev->c45_ids.device_ids) || 747 + phydev->c45_ids.device_ids[i] == 0xffffffff) 748 + return 0; 749 + 750 + return attr->mode; 751 + } 752 + 753 + static const struct attribute_group phy_mmd_group = { 754 + .name = "c45_phy_ids", 755 + .attrs = phy_mmd_attrs, 756 + .is_visible = phy_mmd_is_visible, 757 + }; 758 + 759 + static const struct attribute_group *phy_device_groups[] = { 760 + &phy_dev_group, 761 + &phy_mmd_group, 762 + NULL, 763 + }; 656 764 657 765 static const struct device_type mdio_bus_phy_type = { 658 766 .name = "PHY", 659 - .groups = phy_dev_groups, 767 + .groups = phy_device_groups, 660 768 .release = phy_device_release, 661 769 .pm = pm_ptr(&mdio_bus_phy_pm_ops), 662 770 };