Skip to content

Commit

Permalink
sis190: fix cable detect via link status poll
Browse files Browse the repository at this point in the history
Some sis190 devices don't report LinkChange, so do polling for
link status.

Fixes http://bugzilla.kernel.org/show_bug.cgi?id=11926

Signed-off-by: Herton Ronaldo Krzesinski <herton@mandriva.com.br>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
Herton Ronaldo Krzesinski authored and David S. Miller committed Mar 2, 2010
1 parent 4ab408d commit b88aafd
Showing 1 changed file with 18 additions and 5 deletions.
23 changes: 18 additions & 5 deletions drivers/net/sis190.c
Original file line number Diff line number Diff line change
Expand Up @@ -285,6 +285,11 @@ struct sis190_private {
struct list_head first_phy;
u32 features;
u32 negotiated_lpa;
enum {
LNK_OFF,
LNK_ON,
LNK_AUTONEG,
} link_status;
};

struct sis190_phy {
Expand Down Expand Up @@ -750,6 +755,7 @@ static irqreturn_t sis190_interrupt(int irq, void *__dev)

if (status & LinkChange) {
netif_info(tp, intr, dev, "link change\n");
del_timer(&tp->timer);
schedule_work(&tp->phy_task);
}

Expand Down Expand Up @@ -922,12 +928,15 @@ static void sis190_phy_task(struct work_struct *work)
if (val & BMCR_RESET) {
// FIXME: needlessly high ? -- FR 02/07/2005
mod_timer(&tp->timer, jiffies + HZ/10);
} else if (!(mdio_read_latched(ioaddr, phy_id, MII_BMSR) &
BMSR_ANEGCOMPLETE)) {
goto out_unlock;
}

val = mdio_read_latched(ioaddr, phy_id, MII_BMSR);
if (!(val & BMSR_ANEGCOMPLETE) && tp->link_status != LNK_AUTONEG) {
netif_carrier_off(dev);
netif_warn(tp, link, dev, "auto-negotiating...\n");
mod_timer(&tp->timer, jiffies + SIS190_PHY_TIMEOUT);
} else {
tp->link_status = LNK_AUTONEG;
} else if ((val & BMSR_LSTATUS) && tp->link_status != LNK_ON) {
/* Rejoice ! */
struct {
int val;
Expand Down Expand Up @@ -1000,7 +1009,10 @@ static void sis190_phy_task(struct work_struct *work)

netif_info(tp, link, dev, "link on %s mode\n", p->msg);
netif_carrier_on(dev);
}
tp->link_status = LNK_ON;
} else if (!(val & BMSR_LSTATUS) && tp->link_status != LNK_AUTONEG)
tp->link_status = LNK_OFF;
mod_timer(&tp->timer, jiffies + SIS190_PHY_TIMEOUT);

out_unlock:
rtnl_unlock();
Expand Down Expand Up @@ -1513,6 +1525,7 @@ static struct net_device * __devinit sis190_init_board(struct pci_dev *pdev)

tp->pci_dev = pdev;
tp->mmio_addr = ioaddr;
tp->link_status = LNK_OFF;

sis190_irq_mask_and_ack(ioaddr);

Expand Down

0 comments on commit b88aafd

Please sign in to comment.