diff options
author | Ben Dooks <ben-linux@fluff.org> | 2008-06-24 22:16:04 +0100 |
---|---|---|
committer | Jeff Garzik <jgarzik@redhat.com> | 2008-06-24 22:58:07 -0400 |
commit | f8dd0ecbb74d4b220b105d77c0633945ebb5453e (patch) | |
tree | 967cf1edddd83c99f3b579747dd2f70c7f96aadc /drivers/net/dm9000.c | |
parent | aa1eb452e8d8a97ee65ace0054e7a733ae12cf6d (diff) | |
download | linux-f8dd0ecbb74d4b220b105d77c0633945ebb5453e.tar.bz2 |
DM9000: Allow the use of the NSR register to get link status.
The DM9000's internal PHY reports a copy of the link status
in the NSR register of the chip. Reading the status when
polling for link status is faster as it eliminates the need
to sleep, but does not print as much information.
Add an platform flag to force this behaviour, and a Kconfig
option to allow it to be forced to the faster method always.
Signed-off-by: Ben Dooks <ben-linux@fluff.org>
Signed-off-by: Jeff Garzik <jgarzik@redhat.com>
Diffstat (limited to 'drivers/net/dm9000.c')
-rw-r--r-- | drivers/net/dm9000.c | 41 |
1 files changed, 39 insertions, 2 deletions
diff --git a/drivers/net/dm9000.c b/drivers/net/dm9000.c index 7c38f6129b55..5ad2ec537684 100644 --- a/drivers/net/dm9000.c +++ b/drivers/net/dm9000.c @@ -552,15 +552,48 @@ static const struct ethtool_ops dm9000_ethtool_ops = { .set_eeprom = dm9000_set_eeprom, }; +static void dm9000_show_carrier(board_info_t *db, + unsigned carrier, unsigned nsr) +{ + struct net_device *ndev = db->ndev; + unsigned ncr = dm9000_read_locked(db, DM9000_NCR); + + if (carrier) + dev_info(db->dev, "%s: link up, %dMbps, %s-duplex, no LPA\n", + ndev->name, (nsr & NSR_SPEED) ? 10 : 100, + (ncr & NCR_FDX) ? "full" : "half"); + else + dev_info(db->dev, "%s: link down\n", ndev->name); +} + static void dm9000_poll_work(struct work_struct *w) { struct delayed_work *dw = container_of(w, struct delayed_work, work); board_info_t *db = container_of(dw, board_info_t, phy_poll); + struct net_device *ndev = db->ndev; + + if (db->flags & DM9000_PLATF_SIMPLE_PHY && + !(db->flags & DM9000_PLATF_EXT_PHY)) { + unsigned nsr = dm9000_read_locked(db, DM9000_NSR); + unsigned old_carrier = netif_carrier_ok(ndev) ? 1 : 0; + unsigned new_carrier; - mii_check_media(&db->mii, netif_msg_link(db), 0); + new_carrier = (nsr & NSR_LINKST) ? 1 : 0; + + if (old_carrier != new_carrier) { + if (netif_msg_link(db)) + dm9000_show_carrier(db, new_carrier, nsr); + + if (!new_carrier) + netif_carrier_off(ndev); + else + netif_carrier_on(ndev); + } + } else + mii_check_media(&db->mii, netif_msg_link(db), 0); - if (netif_running(db->ndev)) + if (netif_running(ndev)) dm9000_schedule_poll(db); } @@ -1267,6 +1300,10 @@ dm9000_probe(struct platform_device *pdev) db->flags = pdata->flags; } +#ifdef CONFIG_DM9000_FORCE_SIMPLE_PHY_POLL + db->flags |= DM9000_PLATF_SIMPLE_PHY; +#endif + dm9000_reset(db); /* try multiple times, DM9000 sometimes gets the read wrong */ |