aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/sfc/nic.c
diff options
context:
space:
mode:
authorSteve Hodgson <shodgson@solarflare.com>2010-06-01 07:19:39 -0400
committerDavid S. Miller <davem@davemloft.net>2010-06-02 05:21:08 -0400
commit90d683afd1395016775c8d90508614f8d3000b81 (patch)
tree33c239c5cd1e607a22dca1af0fd3615cee584ef9 /drivers/net/sfc/nic.c
parentd730dc527a5abd4717f6320e82cfce54edc882a3 (diff)
sfc: Remove efx_rx_queue::add_lock
Ensure that efx_fast_push_rx_descriptors() must only run from efx_process_channel() [NAPI], or when napi_disable() has been executed. Reimplement the slow fill by sending an event to the channel, so that NAPI runs, and hanging the subsequent fast fill off the event handler. Replace the sfc_refill workqueue and delayed work items with a timer. We do not need to stop this timer in efx_flush_all() because it's safe to send the event always; receiving it will be delayed until NAPI is restarted. Signed-off-by: Ben Hutchings <bhutchings@solarflare.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/sfc/nic.c')
-rw-r--r--drivers/net/sfc/nic.c49
1 files changed, 39 insertions, 10 deletions
diff --git a/drivers/net/sfc/nic.c b/drivers/net/sfc/nic.c
index ca9cf1a3380..0ee6fd367e6 100644
--- a/drivers/net/sfc/nic.c
+++ b/drivers/net/sfc/nic.c
@@ -79,10 +79,14 @@ 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() */ 82/* Generated event code for efx_generate_test_event() */
83#define EFX_CHANNEL_MAGIC(_channel) \ 83#define EFX_CHANNEL_MAGIC_TEST(_channel) \
84 (0x00010100 + (_channel)->channel) 84 (0x00010100 + (_channel)->channel)
85 85
86/* Generated event code for efx_generate_fill_event() */
87#define EFX_CHANNEL_MAGIC_FILL(_channel) \
88 (0x00010200 + (_channel)->channel)
89
86/************************************************************************** 90/**************************************************************************
87 * 91 *
88 * Solarstorm hardware access 92 * Solarstorm hardware access
@@ -854,6 +858,26 @@ efx_handle_rx_event(struct efx_channel *channel, const efx_qword_t *event)
854 checksummed, discard); 858 checksummed, discard);
855} 859}
856 860
861static void
862efx_handle_generated_event(struct efx_channel *channel, efx_qword_t *event)
863{
864 struct efx_nic *efx = channel->efx;
865 unsigned code;
866
867 code = EFX_QWORD_FIELD(*event, FSF_AZ_DRV_GEN_EV_MAGIC);
868 if (code == EFX_CHANNEL_MAGIC_TEST(channel))
869 ++channel->magic_count;
870 else if (code == EFX_CHANNEL_MAGIC_FILL(channel))
871 /* The queue must be empty, so we won't receive any rx
872 * events, so efx_process_channel() won't refill the
873 * queue. Refill it here */
874 efx_fast_push_rx_descriptors(&efx->rx_queue[channel->channel]);
875 else
876 EFX_LOG(efx, "channel %d received generated "
877 "event "EFX_QWORD_FMT"\n", channel->channel,
878 EFX_QWORD_VAL(*event));
879}
880
857/* Global events are basically PHY events */ 881/* Global events are basically PHY events */
858static void 882static void
859efx_handle_global_event(struct efx_channel *channel, efx_qword_t *event) 883efx_handle_global_event(struct efx_channel *channel, efx_qword_t *event)
@@ -997,13 +1021,7 @@ int efx_nic_process_eventq(struct efx_channel *channel, int budget)
997 } 1021 }
998 break; 1022 break;
999 case FSE_AZ_EV_CODE_DRV_GEN_EV: 1023 case FSE_AZ_EV_CODE_DRV_GEN_EV:
1000 if (EFX_QWORD_FIELD(event, FSF_AZ_DRV_GEN_EV_MAGIC) 1024 efx_handle_generated_event(channel, &event);
1001 == EFX_CHANNEL_MAGIC(channel))
1002 ++channel->magic_count;
1003
1004 EFX_LOG(channel->efx, "channel %d received generated "
1005 "event "EFX_QWORD_FMT"\n", channel->channel,
1006 EFX_QWORD_VAL(event));
1007 break; 1025 break;
1008 case FSE_AZ_EV_CODE_GLOBAL_EV: 1026 case FSE_AZ_EV_CODE_GLOBAL_EV:
1009 efx_handle_global_event(channel, &event); 1027 efx_handle_global_event(channel, &event);
@@ -1096,7 +1114,18 @@ void efx_nic_remove_eventq(struct efx_channel *channel)
1096 1114
1097void efx_nic_generate_test_event(struct efx_channel *channel) 1115void efx_nic_generate_test_event(struct efx_channel *channel)
1098{ 1116{
1099 unsigned int magic = EFX_CHANNEL_MAGIC(channel); 1117 unsigned int magic = EFX_CHANNEL_MAGIC_TEST(channel);
1118 efx_qword_t test_event;
1119
1120 EFX_POPULATE_QWORD_2(test_event, FSF_AZ_EV_CODE,
1121 FSE_AZ_EV_CODE_DRV_GEN_EV,
1122 FSF_AZ_DRV_GEN_EV_MAGIC, magic);
1123 efx_generate_event(channel, &test_event);
1124}
1125
1126void efx_nic_generate_fill_event(struct efx_channel *channel)
1127{
1128 unsigned int magic = EFX_CHANNEL_MAGIC_FILL(channel);
1100 efx_qword_t test_event; 1129 efx_qword_t test_event;
1101 1130
1102 EFX_POPULATE_QWORD_2(test_event, FSF_AZ_EV_CODE, 1131 EFX_POPULATE_QWORD_2(test_event, FSF_AZ_EV_CODE,