以太网PHY芯片中SMI(Serial Management Interface)串行管理接口,也称MDIO(Management Data Input/Output),通常作为MII管理接口(MII Management Interface)。有两根线,分别为双向的MDIO和单向的MDC,用于以太网设备中上层对物理层(PHY)的管理。
MDIO接口有两种协议:C22(Clause 22)和C45(Clause 45)。C22由最初是IEEE RFC802.3定义的,最初的定义中,一个单独的MDIO接口可以访问32个不同的PHY设备中的32个通用寄存器,这些寄存器提供状态和控制信息。
为了满足以太网设备的普及发展,在IEEE 802.3ae 定义了C45可以访问,满足更多的扩展寄存器访问。
MDC频率范围为2.5MHz至50MHz,MDIO的C22和C45协议定义这里不赘述,想学习的同学可以通过虚拟逻辑分析仪(Kinggs)抓取波形进行分析,如下是C45抓取的一个波形情况。
通用标准寄存器
一共32个PHY寄存器,IEEE802.3 定义了地址为0-15 这16个寄存器的功能,地址16-31的寄存器留给芯片制造商自由定义。这些寄存器通常能被C22直接被访问到。
MMD扩展寄存器
由于phy寄存器越来越多,32个标准寄存器已不满足厂家需求,PHY 芯片采用分页技术来扩展地址空间以定义更多的寄存器,这些通常由C45能直接访问到,因为C45的协议里会携带DEVAD(MMD设备号)。寄存器的定义不通厂家也有区别,需要查看datasheet。
新标准定义了MMD的Device号值所代表不同类型寄存器,不限于如下。
C22 方式访问MMD扩展寄存器
这是本文的重点。如果C45协议出现异常,MMD扩展寄存器也可以通过C22协议访问到,换句话说,能被间接访问到。
通用寄存器里,13和14号就是实现C22间接访问MMD寄存器的控制和数据寄存器。先通过配置reg13,给出控制信息和device addr,再配置reg14给出响应数据/地址。
linux内核里的实现
如何间接访问,我们先看下linux
内核代码有这部分的接口实现。
文件路径:drivers/net/phy/phy-core.c
__phy_read_mmd、__phy_write_mmd
:是封装后的phy读写接口,devad即为MMD设备号。
__mdiobus_write、__mdiobus_read
:为底层的C22 读写phy接口。
#define MII_MMD_CTRL 0x0d /* MMD Access Control Register */
#define MII_MMD_DATA 0x0e /* MMD Access Data Register */
int __phy_write_mmd(struct phy_device *phydev, int devad, u32 regnum, u16 val)
{
int ret;
if (regnum >