diff options
Diffstat (limited to 'drivers/net/sfc/selftest.c')
-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 | ||