ar71xx: detect link on LAN ports

SVN-Revision: 26922
This commit is contained in:
Matteo Croce 2011-05-17 11:12:56 +00:00
parent 8c2de891a9
commit 4deecea26b
3 changed files with 32 additions and 3 deletions

View file

@ -162,6 +162,7 @@ struct ag71xx {
int duplex;
struct work_struct restart_work;
struct delayed_work link_work;
struct timer_list oom_timer;
#ifdef CONFIG_AG71XX_DEBUG_FS

View file

@ -828,6 +828,30 @@ static struct ar7240sw *ar7240_probe(struct ag71xx *ag)
return as;
}
static void link_function(struct work_struct *work) {
struct ag71xx *ag = container_of(work, struct ag71xx, link_work.work);
unsigned long flags;
int i;
int status = 0;
for (i = 0; i < 4; i++) {
int link = ar7240sw_phy_read(ag->mii_bus, i, MII_BMSR);
if(link & BMSR_LSTATUS) {
status = 1;
break;
}
}
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 / 2);
}
void ag71xx_ar7240_start(struct ag71xx *ag)
{
struct ar7240sw *as = ag->phy_priv;
@ -836,15 +860,17 @@ void ag71xx_ar7240_start(struct ag71xx *ag)
ar7240sw_setup(as);
ag->speed = SPEED_1000;
ag->link = 1;
ag->duplex = 1;
ar7240_set_addr(as, ag->dev->dev_addr);
ar7240_hw_apply(&as->swdev);
schedule_delayed_work(&ag->link_work, HZ / 10);
}
void ag71xx_ar7240_stop(struct ag71xx *ag)
{
cancel_delayed_work_sync(&ag->link_work);
}
int __devinit ag71xx_ar7240_init(struct ag71xx *ag)
@ -858,6 +884,8 @@ int __devinit ag71xx_ar7240_init(struct ag71xx *ag)
ag->phy_priv = as;
ar7240sw_reset(as);
INIT_DELAYED_WORK(&ag->link_work, link_function);
return 0;
}

View file

@ -48,9 +48,9 @@ void ag71xx_phy_start(struct ag71xx *ag)
if (ag->phy_dev) {
phy_start(ag->phy_dev);
} else if (pdata->has_ar7240_switch) {
ag71xx_ar7240_start(ag);
} else {
if (pdata->has_ar7240_switch)
ag71xx_ar7240_start(ag);
ag->link = 1;
ag71xx_link_adjust(ag);
}