2012.08.25. 16:51 keltezéssel, Mark Mentovai írta: > Is there a way to make the link state drop on an ag71xx interface, so that > it appears to whatever equipment is connected to the port that the cable > has been disconnected? > > I've got a WNDR3700-family device and I need to make it appear to the > equipment connected to its eth1 interface that the cable has been > disconnected. "ifconfig eth1 down" doesn't alter the link state at all. > It'd be OK if the state just dropped momentarily and then returned. So > far, the best I've been able to do is reboot the entire WNDR3700. That's a > more drastic approach than I'd like to use, as there are other things > happening on the system that I'd rather not interrupt. > > I'm very open to the possibility of ag71xx driver changes to make this > work (either as a local change or something for wider distribution) but I > haven't found any data sheets for this device, so I'd basically be > starting by stabbing around in the dark. > > Does anyone have any pointers? >
The problem is that PHYLIB in Linux does not fully stops the PHY device when a driver issues a phy_stop call. Copy the attached patches into 'target/linux/ar71xx/patches-3.3', then do a 'make target/linux/clean world'. With these patches, the PHY of the WAN port will be powered down after 'ifconfig eth1 down' (on the WNDR3700 at least). Regards, Gabor
--- a/include/linux/phy.h +++ b/include/linux/phy.h @@ -510,6 +510,18 @@ static inline int phy_read_status(struct return phydev->drv->read_status(phydev); } +static inline void phy_suspend(struct phy_device *phydev) +{ + if (phydev->drv->suspend) + phydev->drv->suspend(phydev); +} + +static inline void phy_resume(struct phy_device *phydev) +{ + if (phydev->drv->resume) + phydev->drv->resume(phydev); +} + int genphy_restart_aneg(struct phy_device *phydev); int genphy_config_aneg(struct phy_device *phydev); int genphy_update_link(struct phy_device *phydev);
--- a/drivers/net/ethernet/atheros/ag71xx/ag71xx_phy.c +++ b/drivers/net/ethernet/atheros/ag71xx/ag71xx_phy.c @@ -47,6 +47,7 @@ void ag71xx_phy_start(struct ag71xx *ag) struct ag71xx_platform_data *pdata = ag71xx_get_pdata(ag); if (ag->phy_dev) { + phy_resume(ag->phy_dev); phy_start(ag->phy_dev); } else if (pdata->switch_data) { ag71xx_ar7240_start(ag); @@ -61,10 +62,12 @@ void ag71xx_phy_stop(struct ag71xx *ag) struct ag71xx_platform_data *pdata = ag71xx_get_pdata(ag); unsigned long flags; - if (ag->phy_dev) + if (ag->phy_dev) { phy_stop(ag->phy_dev); - else if (pdata->switch_data) + phy_suspend(ag->phy_dev); + } else if (pdata->switch_data) { ag71xx_ar7240_stop(ag); + } spin_lock_irqsave(&ag->lock, flags); if (ag->link) {
_______________________________________________ openwrt-devel mailing list openwrt-devel@lists.openwrt.org https://lists.openwrt.org/mailman/listinfo/openwrt-devel