aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBen Hutchings <bhutchings@solarflare.com>2012-02-28 18:37:35 -0500
committerBen Hutchings <bhutchings@solarflare.com>2012-03-06 13:14:15 -0500
commiteee6f6a9e0c83811de77a137989d4a3289e297cc (patch)
tree88f5a56b976c0c26177eeaf2b0f115e9153b92d1
parented74f48087d1b1cf7cf534dad03bf1584eee783d (diff)
sfc: Encapsulate access to efx_{channel,nic}::last_irq_cpu in self-test
Cleanup in preparation for doing an event test on ifup. Signed-off-by: Ben Hutchings <bhutchings@solarflare.com>
-rw-r--r--drivers/net/ethernet/sfc/nic.c8
-rw-r--r--drivers/net/ethernet/sfc/nic.h13
-rw-r--r--drivers/net/ethernet/sfc/selftest.c14
3 files changed, 21 insertions, 14 deletions
diff --git a/drivers/net/ethernet/sfc/nic.c b/drivers/net/ethernet/sfc/nic.c
index 5da8af5e7501..4c47b7569145 100644
--- a/drivers/net/ethernet/sfc/nic.c
+++ b/drivers/net/ethernet/sfc/nic.c
@@ -1332,8 +1332,10 @@ void efx_nic_remove_eventq(struct efx_channel *channel)
1332} 1332}
1333 1333
1334 1334
1335void efx_nic_generate_test_event(struct efx_channel *channel) 1335void efx_nic_event_test_start(struct efx_channel *channel)
1336{ 1336{
1337 channel->last_irq_cpu = -1;
1338 smp_wmb();
1337 efx_magic_event(channel, EFX_CHANNEL_MAGIC_TEST(channel)); 1339 efx_magic_event(channel, EFX_CHANNEL_MAGIC_TEST(channel));
1338} 1340}
1339 1341
@@ -1382,8 +1384,10 @@ void efx_nic_disable_interrupts(struct efx_nic *efx)
1382 * Interrupt must already have been enabled, otherwise nasty things 1384 * Interrupt must already have been enabled, otherwise nasty things
1383 * may happen. 1385 * may happen.
1384 */ 1386 */
1385void efx_nic_generate_interrupt(struct efx_nic *efx) 1387void efx_nic_irq_test_start(struct efx_nic *efx)
1386{ 1388{
1389 efx->last_irq_cpu = -1;
1390 smp_wmb();
1387 efx_nic_interrupts(efx, true, true); 1391 efx_nic_interrupts(efx, true, true);
1388} 1392}
1389 1393
diff --git a/drivers/net/ethernet/sfc/nic.h b/drivers/net/ethernet/sfc/nic.h
index ac12f7f7f35b..e0e8596f4d10 100644
--- a/drivers/net/ethernet/sfc/nic.h
+++ b/drivers/net/ethernet/sfc/nic.h
@@ -301,14 +301,23 @@ extern void falcon_update_stats_xmac(struct efx_nic *efx);
301/* Interrupts and test events */ 301/* Interrupts and test events */
302extern int efx_nic_init_interrupt(struct efx_nic *efx); 302extern int efx_nic_init_interrupt(struct efx_nic *efx);
303extern void efx_nic_enable_interrupts(struct efx_nic *efx); 303extern void efx_nic_enable_interrupts(struct efx_nic *efx);
304extern void efx_nic_generate_test_event(struct efx_channel *channel); 304extern void efx_nic_event_test_start(struct efx_channel *channel);
305extern void efx_nic_generate_interrupt(struct efx_nic *efx); 305extern void efx_nic_irq_test_start(struct efx_nic *efx);
306extern void efx_nic_disable_interrupts(struct efx_nic *efx); 306extern void efx_nic_disable_interrupts(struct efx_nic *efx);
307extern void efx_nic_fini_interrupt(struct efx_nic *efx); 307extern void efx_nic_fini_interrupt(struct efx_nic *efx);
308extern irqreturn_t efx_nic_fatal_interrupt(struct efx_nic *efx); 308extern irqreturn_t efx_nic_fatal_interrupt(struct efx_nic *efx);
309extern irqreturn_t falcon_legacy_interrupt_a1(int irq, void *dev_id); 309extern irqreturn_t falcon_legacy_interrupt_a1(int irq, void *dev_id);
310extern void falcon_irq_ack_a1(struct efx_nic *efx); 310extern void falcon_irq_ack_a1(struct efx_nic *efx);
311 311
312static inline int efx_nic_event_test_irq_cpu(struct efx_channel *channel)
313{
314 return ACCESS_ONCE(channel->last_irq_cpu);
315}
316static inline int efx_nic_irq_test_irq_cpu(struct efx_nic *efx)
317{
318 return ACCESS_ONCE(efx->last_irq_cpu);
319}
320
312/* Global Resources */ 321/* Global Resources */
313extern int efx_nic_flush_queues(struct efx_nic *efx); 322extern int efx_nic_flush_queues(struct efx_nic *efx);
314extern void falcon_start_nic_stats(struct efx_nic *efx); 323extern void falcon_start_nic_stats(struct efx_nic *efx);
diff --git a/drivers/net/ethernet/sfc/selftest.c b/drivers/net/ethernet/sfc/selftest.c
index e4b4c8a3abc6..aa4ab53cac57 100644
--- a/drivers/net/ethernet/sfc/selftest.c
+++ b/drivers/net/ethernet/sfc/selftest.c
@@ -149,11 +149,7 @@ static int efx_test_interrupts(struct efx_nic *efx,
149 netif_dbg(efx, drv, efx->net_dev, "testing interrupts\n"); 149 netif_dbg(efx, drv, efx->net_dev, "testing interrupts\n");
150 tests->interrupt = -1; 150 tests->interrupt = -1;
151 151
152 /* Reset interrupt flag */ 152 efx_nic_irq_test_start(efx);
153 efx->last_irq_cpu = -1;
154 smp_wmb();
155
156 efx_nic_generate_interrupt(efx);
157 timeout = jiffies + IRQ_TIMEOUT; 153 timeout = jiffies + IRQ_TIMEOUT;
158 wait = 1; 154 wait = 1;
159 155
@@ -161,7 +157,7 @@ static int efx_test_interrupts(struct efx_nic *efx,
161 netif_dbg(efx, drv, efx->net_dev, "waiting for test interrupt\n"); 157 netif_dbg(efx, drv, efx->net_dev, "waiting for test interrupt\n");
162 do { 158 do {
163 schedule_timeout_uninterruptible(wait); 159 schedule_timeout_uninterruptible(wait);
164 cpu = ACCESS_ONCE(efx->last_irq_cpu); 160 cpu = efx_nic_irq_test_irq_cpu(efx);
165 if (cpu >= 0) 161 if (cpu >= 0)
166 goto success; 162 goto success;
167 wait *= 2; 163 wait *= 2;
@@ -192,9 +188,7 @@ static int efx_test_eventq_irq(struct efx_nic *efx,
192 read_ptr[channel->channel] = channel->eventq_read_ptr; 188 read_ptr[channel->channel] = channel->eventq_read_ptr;
193 set_bit(channel->channel, &dma_pend); 189 set_bit(channel->channel, &dma_pend);
194 set_bit(channel->channel, &int_pend); 190 set_bit(channel->channel, &int_pend);
195 channel->last_irq_cpu = -1; 191 efx_nic_event_test_start(channel);
196 smp_wmb();
197 efx_nic_generate_test_event(channel);
198 } 192 }
199 193
200 timeout = jiffies + IRQ_TIMEOUT; 194 timeout = jiffies + IRQ_TIMEOUT;
@@ -216,7 +210,7 @@ static int efx_test_eventq_irq(struct efx_nic *efx,
216 } else { 210 } else {
217 if (efx_nic_event_present(channel)) 211 if (efx_nic_event_present(channel))
218 clear_bit(channel->channel, &dma_pend); 212 clear_bit(channel->channel, &dma_pend);
219 if (ACCESS_ONCE(channel->last_irq_cpu) >= 0) 213 if (efx_nic_event_test_irq_cpu(channel) >= 0)
220 clear_bit(channel->channel, &int_pend); 214 clear_bit(channel->channel, &int_pend);
221 } 215 }
222 napi_enable(&channel->napi_str); 216 napi_enable(&channel->napi_str);