diff options
author | Ben Hutchings <bhutchings@solarflare.com> | 2008-12-13 00:59:24 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2008-12-13 00:59:24 -0500 |
commit | 766ca0fa6bf1600bdf4bc7726c74f14c8455c6b8 (patch) | |
tree | b1ea2df622753f2493b1053fda21c0db3f18a043 /drivers/net/sfc/tenxpress.c | |
parent | 04cc8cacb01c09fba2297faf1477cd570ba43f0b (diff) |
sfc: Rework MAC, PHY and board event handling
From: Steve Hodgson <shodgson@solarflare.com>
MAC, PHY and board events may be separately enabled and signalled.
Our current arrangement of chaining the polling functions can result
in events being missed. Change them to be more independent.
Signed-off-by: Ben Hutchings <bhutchings@solarflare.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/sfc/tenxpress.c')
-rw-r--r-- | drivers/net/sfc/tenxpress.c | 44 |
1 files changed, 14 insertions, 30 deletions
diff --git a/drivers/net/sfc/tenxpress.c b/drivers/net/sfc/tenxpress.c index 634ff9198823..7256ea4abf9c 100644 --- a/drivers/net/sfc/tenxpress.c +++ b/drivers/net/sfc/tenxpress.c | |||
@@ -348,50 +348,34 @@ static void tenxpress_phy_reconfigure(struct efx_nic *efx) | |||
348 | efx->link_fc = mdio_clause45_get_pause(efx); | 348 | efx->link_fc = mdio_clause45_get_pause(efx); |
349 | } | 349 | } |
350 | 350 | ||
351 | static void tenxpress_phy_clear_interrupt(struct efx_nic *efx) | ||
352 | { | ||
353 | /* Nothing done here - LASI interrupts aren't reliable so poll */ | ||
354 | } | ||
355 | |||
356 | |||
357 | /* Poll PHY for interrupt */ | 351 | /* Poll PHY for interrupt */ |
358 | static int tenxpress_phy_check_hw(struct efx_nic *efx) | 352 | static void tenxpress_phy_poll(struct efx_nic *efx) |
359 | { | 353 | { |
360 | struct tenxpress_phy_data *phy_data = efx->phy_data; | 354 | struct tenxpress_phy_data *phy_data = efx->phy_data; |
361 | bool link_ok; | 355 | bool change = false, link_ok; |
362 | int rc = 0; | 356 | unsigned link_fc; |
363 | 357 | ||
364 | link_ok = tenxpress_link_ok(efx); | 358 | link_ok = tenxpress_link_ok(efx); |
359 | if (link_ok != efx->link_up) { | ||
360 | change = true; | ||
361 | } else { | ||
362 | link_fc = mdio_clause45_get_pause(efx); | ||
363 | if (link_fc != efx->link_fc) | ||
364 | change = true; | ||
365 | } | ||
365 | tenxpress_check_bad_lp(efx, link_ok); | 366 | tenxpress_check_bad_lp(efx, link_ok); |
366 | 367 | ||
367 | if (link_ok != efx->link_up) | 368 | if (change) |
368 | falcon_sim_phy_event(efx); | 369 | falcon_sim_phy_event(efx); |
369 | 370 | ||
370 | if (phy_data->phy_mode != PHY_MODE_NORMAL) | 371 | if (phy_data->phy_mode != PHY_MODE_NORMAL) |
371 | return 0; | 372 | return; |
372 | 373 | ||
373 | if (atomic_read(&phy_data->bad_crc_count) > crc_error_reset_threshold) { | 374 | if (atomic_read(&phy_data->bad_crc_count) > crc_error_reset_threshold) { |
374 | EFX_ERR(efx, "Resetting XAUI due to too many CRC errors\n"); | 375 | EFX_ERR(efx, "Resetting XAUI due to too many CRC errors\n"); |
375 | falcon_reset_xaui(efx); | 376 | falcon_reset_xaui(efx); |
376 | atomic_set(&phy_data->bad_crc_count, 0); | 377 | atomic_set(&phy_data->bad_crc_count, 0); |
377 | } | 378 | } |
378 | |||
379 | rc = efx->board_info.monitor(efx); | ||
380 | if (rc) { | ||
381 | EFX_ERR(efx, "Board sensor %s; shutting down PHY\n", | ||
382 | (rc == -ERANGE) ? "reported fault" : "failed"); | ||
383 | if (efx->phy_mode & PHY_MODE_OFF) { | ||
384 | /* Assume that board has shut PHY off */ | ||
385 | phy_data->phy_mode = PHY_MODE_OFF; | ||
386 | } else { | ||
387 | efx->phy_mode |= PHY_MODE_LOW_POWER; | ||
388 | mdio_clause45_set_mmds_lpower(efx, true, | ||
389 | efx->phy_op->mmds); | ||
390 | phy_data->phy_mode |= PHY_MODE_LOW_POWER; | ||
391 | } | ||
392 | } | ||
393 | |||
394 | return rc; | ||
395 | } | 379 | } |
396 | 380 | ||
397 | static void tenxpress_phy_fini(struct efx_nic *efx) | 381 | static void tenxpress_phy_fini(struct efx_nic *efx) |
@@ -461,9 +445,9 @@ struct efx_phy_operations falcon_tenxpress_phy_ops = { | |||
461 | .macs = EFX_XMAC, | 445 | .macs = EFX_XMAC, |
462 | .init = tenxpress_phy_init, | 446 | .init = tenxpress_phy_init, |
463 | .reconfigure = tenxpress_phy_reconfigure, | 447 | .reconfigure = tenxpress_phy_reconfigure, |
464 | .check_hw = tenxpress_phy_check_hw, | 448 | .poll = tenxpress_phy_poll, |
465 | .fini = tenxpress_phy_fini, | 449 | .fini = tenxpress_phy_fini, |
466 | .clear_interrupt = tenxpress_phy_clear_interrupt, | 450 | .clear_interrupt = efx_port_dummy_op_void, |
467 | .test = tenxpress_phy_test, | 451 | .test = tenxpress_phy_test, |
468 | .get_settings = tenxpress_get_settings, | 452 | .get_settings = tenxpress_get_settings, |
469 | .set_settings = mdio_clause45_set_settings, | 453 | .set_settings = mdio_clause45_set_settings, |