diff options
author | Ben Hutchings <bhutchings@solarflare.com> | 2008-09-01 07:46:33 -0400 |
---|---|---|
committer | Jeff Garzik <jgarzik@redhat.com> | 2008-09-03 09:53:44 -0400 |
commit | b9aafb0e91a079ff9438ce3c532ea46d4cd2f0fc (patch) | |
tree | 083d74d62cb2e562ea2d20a3024173efa8a4b7e5 /drivers/net/sfc | |
parent | f8ea0b6743f00180ee3260d82f383a02a4dd9a78 (diff) |
sfc: Speed up loopback self-test
Add efx_poll_loopback() function to test for successful completion of test.
Change efx_test_loopback() to end the test after 1 ms if
efx_poll_loopback() indicates success, and otherwise to wait for 100 ms
as before.
While we're here, rename efx_{rx,tx}_loopback() to
efx_{begin,end}_loopback() which more accurately reflect their
purpose.
Signed-off-by: Ben Hutchings <bhutchings@solarflare.com>
Signed-off-by: Jeff Garzik <jgarzik@redhat.com>
Diffstat (limited to 'drivers/net/sfc')
-rw-r--r-- | drivers/net/sfc/selftest.c | 44 |
1 files changed, 29 insertions, 15 deletions
diff --git a/drivers/net/sfc/selftest.c b/drivers/net/sfc/selftest.c index 8ad517c61946..53fa4edf486c 100644 --- a/drivers/net/sfc/selftest.c +++ b/drivers/net/sfc/selftest.c | |||
@@ -400,7 +400,7 @@ static void efx_iterate_state(struct efx_nic *efx) | |||
400 | smp_wmb(); | 400 | smp_wmb(); |
401 | } | 401 | } |
402 | 402 | ||
403 | static int efx_tx_loopback(struct efx_tx_queue *tx_queue) | 403 | static int efx_begin_loopback(struct efx_tx_queue *tx_queue) |
404 | { | 404 | { |
405 | struct efx_nic *efx = tx_queue->efx; | 405 | struct efx_nic *efx = tx_queue->efx; |
406 | struct efx_selftest_state *state = efx->loopback_selftest; | 406 | struct efx_selftest_state *state = efx->loopback_selftest; |
@@ -449,8 +449,22 @@ static int efx_tx_loopback(struct efx_tx_queue *tx_queue) | |||
449 | return 0; | 449 | return 0; |
450 | } | 450 | } |
451 | 451 | ||
452 | static int efx_rx_loopback(struct efx_tx_queue *tx_queue, | 452 | static int efx_poll_loopback(struct efx_nic *efx) |
453 | struct efx_loopback_self_tests *lb_tests) | 453 | { |
454 | struct efx_selftest_state *state = efx->loopback_selftest; | ||
455 | struct efx_channel *channel; | ||
456 | |||
457 | /* NAPI polling is not enabled, so process channels | ||
458 | * synchronously */ | ||
459 | efx_for_each_channel_with_interrupt(channel, efx) { | ||
460 | if (channel->work_pending) | ||
461 | efx_process_channel_now(channel); | ||
462 | } | ||
463 | return atomic_read(&state->rx_good) == state->packet_count; | ||
464 | } | ||
465 | |||
466 | static int efx_end_loopback(struct efx_tx_queue *tx_queue, | ||
467 | struct efx_loopback_self_tests *lb_tests) | ||
454 | { | 468 | { |
455 | struct efx_nic *efx = tx_queue->efx; | 469 | struct efx_nic *efx = tx_queue->efx; |
456 | struct efx_selftest_state *state = efx->loopback_selftest; | 470 | struct efx_selftest_state *state = efx->loopback_selftest; |
@@ -513,8 +527,7 @@ efx_test_loopback(struct efx_tx_queue *tx_queue, | |||
513 | { | 527 | { |
514 | struct efx_nic *efx = tx_queue->efx; | 528 | struct efx_nic *efx = tx_queue->efx; |
515 | struct efx_selftest_state *state = efx->loopback_selftest; | 529 | struct efx_selftest_state *state = efx->loopback_selftest; |
516 | struct efx_channel *channel; | 530 | int i, begin_rc, end_rc; |
517 | int i, tx_rc, rx_rc; | ||
518 | 531 | ||
519 | for (i = 0; i < loopback_test_level; i++) { | 532 | for (i = 0; i < loopback_test_level; i++) { |
520 | /* Determine how many packets to send */ | 533 | /* Determine how many packets to send */ |
@@ -531,23 +544,24 @@ efx_test_loopback(struct efx_tx_queue *tx_queue, | |||
531 | state->packet_count); | 544 | state->packet_count); |
532 | 545 | ||
533 | efx_iterate_state(efx); | 546 | efx_iterate_state(efx); |
534 | tx_rc = efx_tx_loopback(tx_queue); | 547 | begin_rc = efx_begin_loopback(tx_queue); |
535 | 548 | ||
536 | /* NAPI polling is not enabled, so process channels synchronously */ | 549 | /* This will normally complete very quickly, but be |
537 | schedule_timeout_uninterruptible(HZ / 50); | 550 | * prepared to wait up to 100 ms. */ |
538 | efx_for_each_channel_with_interrupt(channel, efx) { | 551 | msleep(1); |
539 | if (channel->work_pending) | 552 | if (!efx_poll_loopback(efx)) { |
540 | efx_process_channel_now(channel); | 553 | msleep(100); |
554 | efx_poll_loopback(efx); | ||
541 | } | 555 | } |
542 | 556 | ||
543 | rx_rc = efx_rx_loopback(tx_queue, lb_tests); | 557 | end_rc = efx_end_loopback(tx_queue, lb_tests); |
544 | kfree(state->skbs); | 558 | kfree(state->skbs); |
545 | 559 | ||
546 | if (tx_rc || rx_rc) { | 560 | if (begin_rc || end_rc) { |
547 | /* Wait a while to ensure there are no packets | 561 | /* Wait a while to ensure there are no packets |
548 | * floating around after a failure. */ | 562 | * floating around after a failure. */ |
549 | schedule_timeout_uninterruptible(HZ / 10); | 563 | schedule_timeout_uninterruptible(HZ / 10); |
550 | return tx_rc ? tx_rc : rx_rc; | 564 | return begin_rc ? begin_rc : end_rc; |
551 | } | 565 | } |
552 | } | 566 | } |
553 | 567 | ||