aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorSteve Hodgson <shodgson@solarflare.com>2010-06-01 07:19:09 -0400
committerDavid S. Miller <davem@davemloft.net>2010-06-02 05:21:07 -0400
commitd730dc527a5abd4717f6320e82cfce54edc882a3 (patch)
treeff9ec087fc5f9a30d992a114b29b42b8cc3f1bf0 /drivers
parent901d3fe848d8c34988699592c9f4b98c2ce10a8b (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>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/net/sfc/net_driver.h4
-rw-r--r--drivers/net/sfc/nic.c17
-rw-r--r--drivers/net/sfc/nic.h3
-rw-r--r--drivers/net/sfc/selftest.c16
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 1097void 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 */
1095void 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 */
191extern int efx_nic_init_interrupt(struct efx_nic *efx); 191extern int efx_nic_init_interrupt(struct efx_nic *efx);
192extern void efx_nic_enable_interrupts(struct efx_nic *efx); 192extern void efx_nic_enable_interrupts(struct efx_nic *efx);
193extern void efx_nic_generate_test_event(struct efx_channel *channel, 193extern void efx_nic_generate_test_event(struct efx_channel *channel);
194 unsigned int magic);
195extern void efx_nic_generate_interrupt(struct efx_nic *efx); 194extern void efx_nic_generate_interrupt(struct efx_nic *efx);
196extern void efx_nic_disable_interrupts(struct efx_nic *efx); 195extern void efx_nic_disable_interrupts(struct efx_nic *efx);
197extern void efx_nic_fini_interrupt(struct efx_nic *efx); 196extern 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,
161static int efx_test_eventq_irq(struct efx_channel *channel, 161static 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;