Merge branch 'drm-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/airlied...
[pandora-kernel.git] / drivers / net / sfc / selftest.c
index 0ebfb99..50ad3bc 100644 (file)
@@ -1,7 +1,7 @@
 /****************************************************************************
  * Driver for Solarflare Solarstorm network controllers and boards
  * Copyright 2005-2006 Fen Systems Ltd.
- * Copyright 2006-2009 Solarflare Communications Inc.
+ * Copyright 2006-2010 Solarflare Communications Inc.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License version 2 as published
@@ -131,8 +131,6 @@ static int efx_test_chip(struct efx_nic *efx, struct efx_self_tests *tests)
 static int efx_test_interrupts(struct efx_nic *efx,
                               struct efx_self_tests *tests)
 {
-       struct efx_channel *channel;
-
        netif_dbg(efx, drv, efx->net_dev, "testing interrupts\n");
        tests->interrupt = -1;
 
@@ -140,15 +138,6 @@ static int efx_test_interrupts(struct efx_nic *efx,
        efx->last_irq_cpu = -1;
        smp_wmb();
 
-       /* ACK each interrupting event queue. Receiving an interrupt due to
-        * traffic before a test event is raised is considered a pass */
-       efx_for_each_channel(channel, efx) {
-               if (channel->work_pending)
-                       efx_process_channel_now(channel);
-               if (efx->last_irq_cpu >= 0)
-                       goto success;
-       }
-
        efx_nic_generate_interrupt(efx);
 
        /* Wait for arrival of test interrupt. */
@@ -173,13 +162,13 @@ static int efx_test_eventq_irq(struct efx_channel *channel,
                               struct efx_self_tests *tests)
 {
        struct efx_nic *efx = channel->efx;
-       unsigned int magic_count, count;
+       unsigned int read_ptr, count;
 
        tests->eventq_dma[channel->channel] = -1;
        tests->eventq_int[channel->channel] = -1;
        tests->eventq_poll[channel->channel] = -1;
 
-       magic_count = channel->magic_count;
+       read_ptr = channel->eventq_read_ptr;
        channel->efx->last_irq_cpu = -1;
        smp_wmb();
 
@@ -190,10 +179,7 @@ static int efx_test_eventq_irq(struct efx_channel *channel,
        do {
                schedule_timeout_uninterruptible(HZ / 100);
 
-               if (channel->work_pending)
-                       efx_process_channel_now(channel);
-
-               if (channel->magic_count != magic_count)
+               if (ACCESS_ONCE(channel->eventq_read_ptr) != read_ptr)
                        goto eventq_ok;
        } while (++count < 2);
 
@@ -211,8 +197,7 @@ static int efx_test_eventq_irq(struct efx_channel *channel,
        }
 
        /* Check to see if event was received even if interrupt wasn't */
-       efx_process_channel_now(channel);
-       if (channel->magic_count != magic_count) {
+       if (efx_nic_event_present(channel)) {
                netif_err(efx, drv, efx->net_dev,
                          "channel %d event was generated, but "
                          "failed to trigger an interrupt\n", channel->channel);
@@ -644,7 +629,7 @@ static int efx_test_loopbacks(struct efx_nic *efx, struct efx_self_tests *tests,
                        goto out;
                }
 
-               /* Test both types of TX queue */
+               /* Test all enabled types of TX queue */
                efx_for_each_channel_tx_queue(tx_queue, channel) {
                        state->offload_csum = (tx_queue->queue &
                                               EFX_TXQ_TYPE_OFFLOAD);
@@ -770,6 +755,8 @@ int efx_selftest(struct efx_nic *efx, struct efx_self_tests *tests,
        __efx_reconfigure_port(efx);
        mutex_unlock(&efx->mac_lock);
 
+       netif_tx_wake_all_queues(efx->net_dev);
+
        return rc_test;
 }