linux内核驱动已经对PHY有很好的支持,一般PHY驱动用于对外部PHY进行配置,获取外部网络的连接状态、速度、双工属性等,但对于一些通用的switch芯片,一般与MPU是MAC-MAC的连接方式,另外还有些FPGA的关联应用,也是MAC-MAC,这种情况下,我们希望连接状态、链接速度、双工属性等参数为固定,因此内核提供了fixed-link的机制,用来固定外部PHY的属性。
1.fixed-link在设备树中的描述示例如下:
ethernet@1 { ...
fixed-link { speed = <1000>;
full-duplex;
link-gpios = <&gpio0 12 GPIO_ACTIVE_HIGH>; };
... };
其中“fixed-link”为固定的子节点,speed表示外部PHY的连接速度,如 1000,100,10;
full-duplex表示双工属性,如half duplex,full-duplex;
link-gpios用来指定表示检测网络连接状态的GPIO,驱动会读取gpio的值来决定网络状态,下面是SAMA5D3中对fixed-link的描述:
2.在内核中,首先需要使能FIXED-LINK的支持,meneconfig配置如下:
-> Device Drivers
-> Network device support
-> PHY Device support and infrastructure
-*- MDIO Bus/PHY emulation with fixed speed/link PHYs
3.MAC层驱动中对fixed-link的处理:
3.1 phy device注册:
fixed-link phy device注册使用of_phy_register_fixed_link接口,其phy-dev的bus被指定为fixed_mdio_bus类型的platform_fmb,该mdio bus为虚拟的bus。
3.2 匹配phy driver
前面of_phy_register_fixed_link已经注册phy-dev设备,后面需要调用of_phy_connect来匹配phy driver,如果没有指定phy driver,内核会加载通过驱动 "Generic PHY",需要注意,所有phy driver里面的mdio总线操作都是使用前面platform_fmb里面的方法,即都是虚拟的。
注:常规的phy device与phy driver匹配方式:通过mdio总线读取外部phy的id,与驱动中定义的id(如下)对比
下面是mac层驱动使用fixed-link的示例:
---------------------------------------------------------------------------------------
if (of_phy_is_fixed_link(np)) {
err = of_phy_register_fixed_link(np);
if (!err)
bp->phy_node = of_node_get(np);
}
if (bp->phy_node) {
err = -ENXIO;
dev->phydev = of_phy_connect(dev, bp->phy_node,
&macb_handle_link_change, 0,
bp->phy_interface);
if (dev->phydev) {
bp->link = 0;
bp->speed = 0;
bp->duplex = -1;
err = 0;
if (macb_is_gem(bp) && bp->caps & MACB_CAPS_GIGABIT_MODE_AVAILABLE)
dev->phydev->supported &= PHY_GBIT_FEATURES;
else
dev->phydev->supported &= PHY_BASIC_FEATURES;
if (bp->caps & MACB_CAPS_NO_GIGABIT_HALF)
dev->phydev->supported &= ~SUPPORTED_1000baseT_Half;
dev->phydev->advertising = dev->phydev->supported;
}
}