diff options
author | Steve Hodgson <shodgson@solarflare.com> | 2010-06-01 07:19:09 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2010-06-02 05:21:07 -0400 |
commit | d730dc527a5abd4717f6320e82cfce54edc882a3 (patch) | |
tree | ff9ec087fc5f9a30d992a114b29b42b8cc3f1bf0 | |
parent | 901d3fe848d8c34988699592c9f4b98c2ce10a8b (diff) |
sfc: Allow DRV_GEN events to be used outside of selftests
Formerly, efx_test_eventq_irq() assumed it was the only user of
driver generated events. Allow it to interoperate with other users.
We can create more than 16 channels, so align event codes with
a multiple of 256 not 16.
Signed-off-by: Ben Hutchings <bhutchings@solarflare.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | drivers/net/sfc/net_driver.h | 4 | ||||
-rw-r--r-- | drivers/net/sfc/nic.c | 17 | ||||
-rw-r--r-- | drivers/net/sfc/nic.h | 3 | ||||
-rw-r--r-- | drivers/net/sfc/selftest.c | 16 |
4 files changed, 18 insertions, 22 deletions
diff --git a/drivers/net/sfc/net_driver.h b/drivers/net/sfc/net_driver.h index 2e6fd89f2a72..ee0ea01c847e 100644 --- a/drivers/net/sfc/net_driver.h +++ b/drivers/net/sfc/net_driver.h | |||
@@ -336,7 +336,7 @@ enum efx_rx_alloc_method { | |||
336 | * @eventq: Event queue buffer | 336 | * @eventq: Event queue buffer |
337 | * @eventq_read_ptr: Event queue read pointer | 337 | * @eventq_read_ptr: Event queue read pointer |
338 | * @last_eventq_read_ptr: Last event queue read pointer value. | 338 | * @last_eventq_read_ptr: Last event queue read pointer value. |
339 | * @eventq_magic: Event queue magic value for driver-generated test events | 339 | * @magic_count: Event queue test event count |
340 | * @irq_count: Number of IRQs since last adaptive moderation decision | 340 | * @irq_count: Number of IRQs since last adaptive moderation decision |
341 | * @irq_mod_score: IRQ moderation score | 341 | * @irq_mod_score: IRQ moderation score |
342 | * @rx_alloc_level: Watermark based heuristic counter for pushing descriptors | 342 | * @rx_alloc_level: Watermark based heuristic counter for pushing descriptors |
@@ -367,7 +367,7 @@ struct efx_channel { | |||
367 | struct efx_special_buffer eventq; | 367 | struct efx_special_buffer eventq; |
368 | unsigned int eventq_read_ptr; | 368 | unsigned int eventq_read_ptr; |
369 | unsigned int last_eventq_read_ptr; | 369 | unsigned int last_eventq_read_ptr; |
370 | unsigned int eventq_magic; | 370 | unsigned int magic_count; |
371 | 371 | ||
372 | unsigned int irq_count; | 372 | unsigned int irq_count; |
373 | unsigned int irq_mod_score; | 373 | unsigned int irq_mod_score; |
diff --git a/drivers/net/sfc/nic.c b/drivers/net/sfc/nic.c index ec0bb80f5ae8..ca9cf1a33803 100644 --- a/drivers/net/sfc/nic.c +++ b/drivers/net/sfc/nic.c | |||
@@ -79,6 +79,10 @@ MODULE_PARM_DESC(rx_xon_thresh_bytes, "RX fifo XON threshold"); | |||
79 | /* Depth of RX flush request fifo */ | 79 | /* Depth of RX flush request fifo */ |
80 | #define EFX_RX_FLUSH_COUNT 4 | 80 | #define EFX_RX_FLUSH_COUNT 4 |
81 | 81 | ||
82 | /* Magic value for efx_generate_test_event() */ | ||
83 | #define EFX_CHANNEL_MAGIC(_channel) \ | ||
84 | (0x00010100 + (_channel)->channel) | ||
85 | |||
82 | /************************************************************************** | 86 | /************************************************************************** |
83 | * | 87 | * |
84 | * Solarstorm hardware access | 88 | * Solarstorm hardware access |
@@ -993,8 +997,10 @@ int efx_nic_process_eventq(struct efx_channel *channel, int budget) | |||
993 | } | 997 | } |
994 | break; | 998 | break; |
995 | case FSE_AZ_EV_CODE_DRV_GEN_EV: | 999 | case FSE_AZ_EV_CODE_DRV_GEN_EV: |
996 | channel->eventq_magic = EFX_QWORD_FIELD( | 1000 | if (EFX_QWORD_FIELD(event, FSF_AZ_DRV_GEN_EV_MAGIC) |
997 | event, FSF_AZ_DRV_GEN_EV_MAGIC); | 1001 | == EFX_CHANNEL_MAGIC(channel)) |
1002 | ++channel->magic_count; | ||
1003 | |||
998 | EFX_LOG(channel->efx, "channel %d received generated " | 1004 | EFX_LOG(channel->efx, "channel %d received generated " |
999 | "event "EFX_QWORD_FMT"\n", channel->channel, | 1005 | "event "EFX_QWORD_FMT"\n", channel->channel, |
1000 | EFX_QWORD_VAL(event)); | 1006 | EFX_QWORD_VAL(event)); |
@@ -1088,12 +1094,9 @@ void efx_nic_remove_eventq(struct efx_channel *channel) | |||
1088 | } | 1094 | } |
1089 | 1095 | ||
1090 | 1096 | ||
1091 | /* Generates a test event on the event queue. A subsequent call to | 1097 | void efx_nic_generate_test_event(struct efx_channel *channel) |
1092 | * process_eventq() should pick up the event and place the value of | ||
1093 | * "magic" into channel->eventq_magic; | ||
1094 | */ | ||
1095 | void efx_nic_generate_test_event(struct efx_channel *channel, unsigned int magic) | ||
1096 | { | 1098 | { |
1099 | unsigned int magic = EFX_CHANNEL_MAGIC(channel); | ||
1097 | efx_qword_t test_event; | 1100 | efx_qword_t test_event; |
1098 | 1101 | ||
1099 | EFX_POPULATE_QWORD_2(test_event, FSF_AZ_EV_CODE, | 1102 | EFX_POPULATE_QWORD_2(test_event, FSF_AZ_EV_CODE, |
diff --git a/drivers/net/sfc/nic.h b/drivers/net/sfc/nic.h index bbc2c0c2f843..186aab564c4a 100644 --- a/drivers/net/sfc/nic.h +++ b/drivers/net/sfc/nic.h | |||
@@ -190,8 +190,7 @@ extern int efx_nic_rx_xoff_thresh, efx_nic_rx_xon_thresh; | |||
190 | /* Interrupts and test events */ | 190 | /* Interrupts and test events */ |
191 | extern int efx_nic_init_interrupt(struct efx_nic *efx); | 191 | extern int efx_nic_init_interrupt(struct efx_nic *efx); |
192 | extern void efx_nic_enable_interrupts(struct efx_nic *efx); | 192 | extern void efx_nic_enable_interrupts(struct efx_nic *efx); |
193 | extern void efx_nic_generate_test_event(struct efx_channel *channel, | 193 | extern void efx_nic_generate_test_event(struct efx_channel *channel); |
194 | unsigned int magic); | ||
195 | extern void efx_nic_generate_interrupt(struct efx_nic *efx); | 194 | extern void efx_nic_generate_interrupt(struct efx_nic *efx); |
196 | extern void efx_nic_disable_interrupts(struct efx_nic *efx); | 195 | extern void efx_nic_disable_interrupts(struct efx_nic *efx); |
197 | extern void efx_nic_fini_interrupt(struct efx_nic *efx); | 196 | extern void efx_nic_fini_interrupt(struct efx_nic *efx); |
diff --git a/drivers/net/sfc/selftest.c b/drivers/net/sfc/selftest.c index 52ac14af83a4..c088740e3493 100644 --- a/drivers/net/sfc/selftest.c +++ b/drivers/net/sfc/selftest.c | |||
@@ -161,23 +161,17 @@ static int efx_test_interrupts(struct efx_nic *efx, | |||
161 | static int efx_test_eventq_irq(struct efx_channel *channel, | 161 | static int efx_test_eventq_irq(struct efx_channel *channel, |
162 | struct efx_self_tests *tests) | 162 | struct efx_self_tests *tests) |
163 | { | 163 | { |
164 | unsigned int magic, count; | 164 | unsigned int magic_count, count; |
165 | |||
166 | /* Channel specific code, limited to 20 bits */ | ||
167 | magic = (0x00010150 + channel->channel); | ||
168 | EFX_LOG(channel->efx, "channel %d testing event queue with code %x\n", | ||
169 | channel->channel, magic); | ||
170 | 165 | ||
171 | tests->eventq_dma[channel->channel] = -1; | 166 | tests->eventq_dma[channel->channel] = -1; |
172 | tests->eventq_int[channel->channel] = -1; | 167 | tests->eventq_int[channel->channel] = -1; |
173 | tests->eventq_poll[channel->channel] = -1; | 168 | tests->eventq_poll[channel->channel] = -1; |
174 | 169 | ||
175 | /* Reset flag and zero magic word */ | 170 | magic_count = channel->magic_count; |
176 | channel->efx->last_irq_cpu = -1; | 171 | channel->efx->last_irq_cpu = -1; |
177 | channel->eventq_magic = 0; | ||
178 | smp_wmb(); | 172 | smp_wmb(); |
179 | 173 | ||
180 | efx_nic_generate_test_event(channel, magic); | 174 | efx_nic_generate_test_event(channel); |
181 | 175 | ||
182 | /* Wait for arrival of interrupt */ | 176 | /* Wait for arrival of interrupt */ |
183 | count = 0; | 177 | count = 0; |
@@ -187,7 +181,7 @@ static int efx_test_eventq_irq(struct efx_channel *channel, | |||
187 | if (channel->work_pending) | 181 | if (channel->work_pending) |
188 | efx_process_channel_now(channel); | 182 | efx_process_channel_now(channel); |
189 | 183 | ||
190 | if (channel->eventq_magic == magic) | 184 | if (channel->magic_count != magic_count) |
191 | goto eventq_ok; | 185 | goto eventq_ok; |
192 | } while (++count < 2); | 186 | } while (++count < 2); |
193 | 187 | ||
@@ -204,7 +198,7 @@ static int efx_test_eventq_irq(struct efx_channel *channel, | |||
204 | 198 | ||
205 | /* Check to see if event was received even if interrupt wasn't */ | 199 | /* Check to see if event was received even if interrupt wasn't */ |
206 | efx_process_channel_now(channel); | 200 | efx_process_channel_now(channel); |
207 | if (channel->eventq_magic == magic) { | 201 | if (channel->magic_count != magic_count) { |
208 | EFX_ERR(channel->efx, "channel %d event was generated, but " | 202 | EFX_ERR(channel->efx, "channel %d event was generated, but " |
209 | "failed to trigger an interrupt\n", channel->channel); | 203 | "failed to trigger an interrupt\n", channel->channel); |
210 | tests->eventq_dma[channel->channel] = 1; | 204 | tests->eventq_dma[channel->channel] = 1; |