diff options
author | Ben Hutchings <bhutchings@solarflare.com> | 2012-02-28 18:37:35 -0500 |
---|---|---|
committer | Ben Hutchings <bhutchings@solarflare.com> | 2012-03-06 13:14:15 -0500 |
commit | eee6f6a9e0c83811de77a137989d4a3289e297cc (patch) | |
tree | 88f5a56b976c0c26177eeaf2b0f115e9153b92d1 | |
parent | ed74f48087d1b1cf7cf534dad03bf1584eee783d (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.c | 8 | ||||
-rw-r--r-- | drivers/net/ethernet/sfc/nic.h | 13 | ||||
-rw-r--r-- | drivers/net/ethernet/sfc/selftest.c | 14 |
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 | ||
1335 | void efx_nic_generate_test_event(struct efx_channel *channel) | 1335 | void 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 | */ |
1385 | void efx_nic_generate_interrupt(struct efx_nic *efx) | 1387 | void 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 */ |
302 | extern int efx_nic_init_interrupt(struct efx_nic *efx); | 302 | extern int efx_nic_init_interrupt(struct efx_nic *efx); |
303 | extern void efx_nic_enable_interrupts(struct efx_nic *efx); | 303 | extern void efx_nic_enable_interrupts(struct efx_nic *efx); |
304 | extern void efx_nic_generate_test_event(struct efx_channel *channel); | 304 | extern void efx_nic_event_test_start(struct efx_channel *channel); |
305 | extern void efx_nic_generate_interrupt(struct efx_nic *efx); | 305 | extern void efx_nic_irq_test_start(struct efx_nic *efx); |
306 | extern void efx_nic_disable_interrupts(struct efx_nic *efx); | 306 | extern void efx_nic_disable_interrupts(struct efx_nic *efx); |
307 | extern void efx_nic_fini_interrupt(struct efx_nic *efx); | 307 | extern void efx_nic_fini_interrupt(struct efx_nic *efx); |
308 | extern irqreturn_t efx_nic_fatal_interrupt(struct efx_nic *efx); | 308 | extern irqreturn_t efx_nic_fatal_interrupt(struct efx_nic *efx); |
309 | extern irqreturn_t falcon_legacy_interrupt_a1(int irq, void *dev_id); | 309 | extern irqreturn_t falcon_legacy_interrupt_a1(int irq, void *dev_id); |
310 | extern void falcon_irq_ack_a1(struct efx_nic *efx); | 310 | extern void falcon_irq_ack_a1(struct efx_nic *efx); |
311 | 311 | ||
312 | static inline int efx_nic_event_test_irq_cpu(struct efx_channel *channel) | ||
313 | { | ||
314 | return ACCESS_ONCE(channel->last_irq_cpu); | ||
315 | } | ||
316 | static 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 */ |
313 | extern int efx_nic_flush_queues(struct efx_nic *efx); | 322 | extern int efx_nic_flush_queues(struct efx_nic *efx); |
314 | extern void falcon_start_nic_stats(struct efx_nic *efx); | 323 | extern 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); |