POE双网口问题
背景
- Platform: RK3399
- OS: Android7.1.2
- Kernel: v4.4.103
- Switch Phy: ksz8463
问题
单独用POE供电,网络不通
分析
双网口设计:一个为”进”(机器默认绑定的active Phy),一个为”出”。
硬件设计:设计在”出”的网口上。
POE要设计在”进”的网口上,机器的网络才能正常,所以需要硬件交换POE的设计,或者软件交换机器的active Phy
追踪代码:drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c
文件中的stmmac_mdio_register
函数:
默认bind到MAC的phy(plat->phy_addr
)是最先找到的phy,伪代码:
for(addr = 0; addr < PHY_MAX_ADDR; addr++) {
struct phy_device *phydev = new_bus->phy_map[addr];
if(phydev) {
//....
/*
* If we're going to bind the MAC to this PHY bus,
* and no PHY number was provided to the MAC,
* use the one probed here.
*/
if (priv->plat->phy_addr == -1)
priv->plat->phy_addr = addr;
act = (priv->plat->phy_addr == addr);
//....
pr_info("%s: PHY ID %08x at %d IRQ %s (%s)%s\n",
ndev->name, phydev->phy_id, addr,
irq_str, dev_name(&phydev->dev),
act ? " active" : "");
found = 1;
}
}
而plat->phy_addr
是从dts中的snps,phy-addr
节点获取:drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
文件中stmmac_probe_config_dt
函数:
/* "snps,phy-addr" is not a standard property. Mark it as deprecated
* and warn of its use. Remove this when phy node support is added.
*/
if (of_property_read_u32(np, "snps,phy-addr", &plat->phy_addr) == 0)
dev_warn(&pdev->dev, "snps,phy-addr property is deprecated\n");
解决
以下方法二选一
修改snps,phy-addr
实现
dts中指定MAC绑定的phy addr:
&gmac {
phy-supply = <&vcc_phy>;
phy-mode = "rmii";
clock_in_out = "output";
snps,reset-gpio = <&gpio3 15 GPIO_ACTIVE_LOW>;
snps,reset-active-low;
snps,reset-delays-us = <0 10000 50000>;
snps,phy-addr = <2>; /*指定 active phy addr*/
assigned-clocks = <&cru SCLK_RMII_SRC>;
assigned-clock-parents = <&cru SCLK_MAC>;
pinctrl-names = "default";
pinctrl-0 = <&rmii_pins>;
tx_delay = <0x28>;
rx_delay = <0x1B>;
status = "okay";
};
修改for
循环轮询实现
stmmac_mdio_register
函数中,
由for (addr = 0; addr < PHY_MAX_ADDR; addr++)
改为for (addr = PHY_MAX_ADDR-1; addr >= 0; addr--)
效果
原始效果:
[ 0.489796] eth%d: PHY ID 00221430 at 1 IRQ POLL (stmmac-0:01) active
[ 0.489815] eth%d: PHY ID 00221430 at 2 IRQ POLL (stmmac-0:02)
修改for
循环效果:
[ 0.489796] eth%d: PHY ID 00221430 at 2 IRQ POLL (stmmac-0:02) active
[ 0.489815] eth%d: PHY ID 00221430 at 1 IRQ POLL (stmmac-0:01)
修改snps,phy-addr
效果:
[ 0.496949] eth%d: PHY ID 00221430 at 1 IRQ POLL (stmmac-0:01)
[ 0.496963] eth%d: PHY ID 00221430 at 2 IRQ POLL (stmmac-0:02) active
扩展
主要是mdiobus_register()
: 不是总线的注册,而是调用mdiobus_scan
扫描PHY设备, phy_device_create
创建phy设备,
‐‐> mdiobus_register
‐‐> device_register
‐‐> mdiobus_scan
‐‐> get_phy_device
‐‐> get_phy_id // 读寄存器
‐‐> phy_device_create // 创建phy设备
‐‐> INIT_DELAYED_WORK(&dev‐>state_queue, phy_state_machine); //初始化状态机
参考: Linux phy system
评论