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

net: phy: add support for PHY package MMD read/write

Some PHY in PHY package may require to read/write MMD regs to correctly
configure the PHY package.

Add support for these additional required function in both lock and no
lock variant.

It's assumed that the entire PHY package is either C22 or C45. We use
C22 or C45 way of writing/reading to mmd regs based on the passed phydev
whether it's C22 or C45.

Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>

authored by

Christian Marangi and committed by
David S. Miller
d63710fc 028672bd

+156
+140
drivers/net/phy/phy-core.c
··· 651 651 EXPORT_SYMBOL(phy_write_mmd); 652 652 653 653 /** 654 + * __phy_package_read_mmd - read MMD reg relative to PHY package base addr 655 + * @phydev: The phy_device struct 656 + * @addr_offset: The offset to be added to PHY package base_addr 657 + * @devad: The MMD to read from 658 + * @regnum: The register on the MMD to read 659 + * 660 + * Convenience helper for reading a register of an MMD on a given PHY 661 + * using the PHY package base address. The base address is added to 662 + * the addr_offset value. 663 + * 664 + * Same calling rules as for __phy_read(); 665 + * 666 + * NOTE: It's assumed that the entire PHY package is either C22 or C45. 667 + */ 668 + int __phy_package_read_mmd(struct phy_device *phydev, 669 + unsigned int addr_offset, int devad, 670 + u32 regnum) 671 + { 672 + int addr = phy_package_address(phydev, addr_offset); 673 + 674 + if (addr < 0) 675 + return addr; 676 + 677 + if (regnum > (u16)~0 || devad > 32) 678 + return -EINVAL; 679 + 680 + return mmd_phy_read(phydev->mdio.bus, addr, phydev->is_c45, devad, 681 + regnum); 682 + } 683 + EXPORT_SYMBOL(__phy_package_read_mmd); 684 + 685 + /** 686 + * phy_package_read_mmd - read MMD reg relative to PHY package base addr 687 + * @phydev: The phy_device struct 688 + * @addr_offset: The offset to be added to PHY package base_addr 689 + * @devad: The MMD to read from 690 + * @regnum: The register on the MMD to read 691 + * 692 + * Convenience helper for reading a register of an MMD on a given PHY 693 + * using the PHY package base address. The base address is added to 694 + * the addr_offset value. 695 + * 696 + * Same calling rules as for phy_read(); 697 + * 698 + * NOTE: It's assumed that the entire PHY package is either C22 or C45. 699 + */ 700 + int phy_package_read_mmd(struct phy_device *phydev, 701 + unsigned int addr_offset, int devad, 702 + u32 regnum) 703 + { 704 + int addr = phy_package_address(phydev, addr_offset); 705 + int val; 706 + 707 + if (addr < 0) 708 + return addr; 709 + 710 + if (regnum > (u16)~0 || devad > 32) 711 + return -EINVAL; 712 + 713 + phy_lock_mdio_bus(phydev); 714 + val = mmd_phy_read(phydev->mdio.bus, addr, phydev->is_c45, devad, 715 + regnum); 716 + phy_unlock_mdio_bus(phydev); 717 + 718 + return val; 719 + } 720 + EXPORT_SYMBOL(phy_package_read_mmd); 721 + 722 + /** 723 + * __phy_package_write_mmd - write MMD reg relative to PHY package base addr 724 + * @phydev: The phy_device struct 725 + * @addr_offset: The offset to be added to PHY package base_addr 726 + * @devad: The MMD to write to 727 + * @regnum: The register on the MMD to write 728 + * @val: value to write to @regnum 729 + * 730 + * Convenience helper for writing a register of an MMD on a given PHY 731 + * using the PHY package base address. The base address is added to 732 + * the addr_offset value. 733 + * 734 + * Same calling rules as for __phy_write(); 735 + * 736 + * NOTE: It's assumed that the entire PHY package is either C22 or C45. 737 + */ 738 + int __phy_package_write_mmd(struct phy_device *phydev, 739 + unsigned int addr_offset, int devad, 740 + u32 regnum, u16 val) 741 + { 742 + int addr = phy_package_address(phydev, addr_offset); 743 + 744 + if (addr < 0) 745 + return addr; 746 + 747 + if (regnum > (u16)~0 || devad > 32) 748 + return -EINVAL; 749 + 750 + return mmd_phy_write(phydev->mdio.bus, addr, phydev->is_c45, devad, 751 + regnum, val); 752 + } 753 + EXPORT_SYMBOL(__phy_package_write_mmd); 754 + 755 + /** 756 + * phy_package_write_mmd - write MMD reg relative to PHY package base addr 757 + * @phydev: The phy_device struct 758 + * @addr_offset: The offset to be added to PHY package base_addr 759 + * @devad: The MMD to write to 760 + * @regnum: The register on the MMD to write 761 + * @val: value to write to @regnum 762 + * 763 + * Convenience helper for writing a register of an MMD on a given PHY 764 + * using the PHY package base address. The base address is added to 765 + * the addr_offset value. 766 + * 767 + * Same calling rules as for phy_write(); 768 + * 769 + * NOTE: It's assumed that the entire PHY package is either C22 or C45. 770 + */ 771 + int phy_package_write_mmd(struct phy_device *phydev, 772 + unsigned int addr_offset, int devad, 773 + u32 regnum, u16 val) 774 + { 775 + int addr = phy_package_address(phydev, addr_offset); 776 + int ret; 777 + 778 + if (addr < 0) 779 + return addr; 780 + 781 + if (regnum > (u16)~0 || devad > 32) 782 + return -EINVAL; 783 + 784 + phy_lock_mdio_bus(phydev); 785 + ret = mmd_phy_write(phydev->mdio.bus, addr, phydev->is_c45, devad, 786 + regnum, val); 787 + phy_unlock_mdio_bus(phydev); 788 + 789 + return ret; 790 + } 791 + EXPORT_SYMBOL(phy_package_write_mmd); 792 + 793 + /** 654 794 * phy_modify_changed - Function for modifying a PHY register 655 795 * @phydev: the phy_device struct 656 796 * @regnum: register number to modify
+16
include/linux/phy.h
··· 2064 2064 return __mdiobus_write(phydev->mdio.bus, addr, regnum, val); 2065 2065 } 2066 2066 2067 + int __phy_package_read_mmd(struct phy_device *phydev, 2068 + unsigned int addr_offset, int devad, 2069 + u32 regnum); 2070 + 2071 + int phy_package_read_mmd(struct phy_device *phydev, 2072 + unsigned int addr_offset, int devad, 2073 + u32 regnum); 2074 + 2075 + int __phy_package_write_mmd(struct phy_device *phydev, 2076 + unsigned int addr_offset, int devad, 2077 + u32 regnum, u16 val); 2078 + 2079 + int phy_package_write_mmd(struct phy_device *phydev, 2080 + unsigned int addr_offset, int devad, 2081 + u32 regnum, u16 val); 2082 + 2067 2083 static inline bool __phy_package_set_once(struct phy_device *phydev, 2068 2084 unsigned int b) 2069 2085 {