rendered paste bodyIndex: target/linux/ar71xx/files/arch/mips/ar71xx/mach-ubnt.c===================================================================--- target/linux/ar71xx/files/arch/mips/ar71xx/mach-ubnt.c (revisione 26891)+++ target/linux/ar71xx/files/arch/mips/ar71xx/mach-ubnt.c (copia locale)@@ -288,6 +288,7 @@ ar71xx_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_RMII; ar71xx_eth1_data.speed = SPEED_1000; ar71xx_eth1_data.duplex = DUPLEX_FULL;+ ar71xx_eth1_data.phy_mask = UBNT_M_LAN_PHYMASK; ar71xx_add_device_eth(1); }Index: target/linux/ar71xx/files/drivers/net/ag71xx/ag71xx_phy.c===================================================================--- target/linux/ar71xx/files/drivers/net/ag71xx/ag71xx_phy.c (revisione 26891)+++ target/linux/ar71xx/files/drivers/net/ag71xx/ag71xx_phy.c (copia locale)@@ -49,8 +49,10 @@ if (ag->phy_dev) { phy_start(ag->phy_dev); } else {- if (pdata->has_ar7240_switch)+ if (pdata->has_ar7240_switch) {+ schedule_delayed_work(&ag->link_work, HZ); ag71xx_ar7240_start(ag);+ } ag->link = 1; ag71xx_link_adjust(ag); }@@ -63,8 +65,10 @@ if (ag->phy_dev) { phy_stop(ag->phy_dev); } else {- if (pdata->has_ar7240_switch)+ if (pdata->has_ar7240_switch) {+ cancel_delayed_work(&ag->link_work); ag71xx_ar7240_stop(ag);+ } ag->link = 0; ag71xx_link_adjust(ag); }@@ -96,6 +100,51 @@ return ret; } +static void link_function(struct work_struct *work) {+ struct ag71xx *ag = container_of(work, struct ag71xx, link_work);+ unsigned long flags;+ int status;++ status = ar7240sw_phy_read(ag->mii_bus, ag->phyaddr, MII_BMSR);+ status = !!(status & BMSR_LSTATUS);++ spin_lock_irqsave(&ag->lock, flags);+ if(status != ag->link) {+ ag->link = status;+ ag71xx_link_adjust(ag);+ }+ spin_unlock_irqrestore(&ag->lock, flags);++ schedule_delayed_work(&ag->link_work, HZ);+}++static int ag71xx_phy_connect_fake(struct ag71xx *ag)+{+ struct net_device *dev = ag->dev;+ struct ag71xx_platform_data *pdata = ag71xx_get_pdata(ag);+ int phy_addr;++ for (phy_addr = 0; phy_addr < PHY_MAX_ADDR; phy_addr++) {+ if ((pdata->phy_mask & BIT(phy_addr))) {+ ag->link = 1;+ ag->speed = SPEED_1000;+ ag->duplex = DUPLEX_FULL;++ printk("setting phy%d to Fake\n", phy_addr);++ ag->phyaddr = phy_addr;++ INIT_DELAYED_WORK(&ag->link_work, link_function);++ return 0;+ }+ }++ printk(KERN_ERR "%s: no PHY found with phy_mask=%08x\n",+ dev->name, pdata->phy_mask);+ return -ENODEV;+}+ static int ag71xx_phy_connect_multi(struct ag71xx *ag) { struct net_device *dev = ag->dev;@@ -208,8 +257,10 @@ mutex_unlock(&ag->mii_bus->mdio_lock); } - if (pdata->has_ar7240_switch)+ if (pdata->has_ar7240_switch) {+ ag71xx_phy_connect_fake(ag); return ag71xx_ar7240_init(ag);+ } if (pdata->phy_mask) return ag71xx_phy_connect_multi(ag);Index: target/linux/ar71xx/files/drivers/net/ag71xx/ag71xx.h===================================================================--- target/linux/ar71xx/files/drivers/net/ag71xx/ag71xx.h (revisione 26891)+++ target/linux/ar71xx/files/drivers/net/ag71xx/ag71xx.h (copia locale)@@ -156,12 +156,14 @@ struct mii_bus *mii_bus; struct phy_device *phy_dev; void *phy_priv;+ int phyaddr; unsigned int link; unsigned int speed; int duplex; struct work_struct restart_work;+ struct delayed_work link_work; struct timer_list oom_timer; #ifdef CONFIG_AG71XX_DEBUG_FS