From 78c1f0a06551f6ff61bfd7c1a9302115a8135a62 Mon Sep 17 00:00:00 2001 From: Steve Hodgson Date: Sun, 29 Nov 2009 03:43:00 +0000 Subject: sfc: Generalise link state monitoring Use the efx_nic_type::monitor operation or event handling as appropriate. Signed-off-by: Ben Hutchings Signed-off-by: David S. Miller --- drivers/net/sfc/efx.c | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) (limited to 'drivers/net/sfc/efx.c') diff --git a/drivers/net/sfc/efx.c b/drivers/net/sfc/efx.c index 4210121eeff9..14ef27fa8416 100644 --- a/drivers/net/sfc/efx.c +++ b/drivers/net/sfc/efx.c @@ -1174,10 +1174,18 @@ static void efx_start_all(struct efx_nic *efx) falcon_enable_interrupts(efx); - /* Start the hardware monitor (if there is one) if we're in RUNNING */ - if (efx->state == STATE_RUNNING && efx->type->monitor != NULL) + /* Start the hardware monitor if there is one. Otherwise (we're link + * event driven), we have to poll the PHY because after an event queue + * flush, we could have a missed a link state change */ + if (efx->type->monitor != NULL) { queue_delayed_work(efx->workqueue, &efx->monitor_work, efx_monitor_interval); + } else { + mutex_lock(&efx->mac_lock); + if (efx->phy_op->poll(efx)) + efx_link_status_changed(efx); + mutex_unlock(&efx->mac_lock); + } efx->type->start_stats(efx); } @@ -1421,6 +1429,10 @@ static int efx_net_open(struct net_device *net_dev) if (efx->phy_mode & PHY_MODE_SPECIAL) return -EBUSY; + /* Notify the kernel of the link state polled during driver load, + * before the monitor starts running */ + efx_link_status_changed(efx); + efx_start_all(efx); return 0; } -- cgit v1.2.3-59-g8ed1b