aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/sfc
diff options
context:
space:
mode:
authorBen Hutchings <bhutchings@solarflare.com>2008-09-01 07:48:08 -0400
committerJeff Garzik <jgarzik@redhat.com>2008-09-03 09:53:47 -0400
commit42cbe2d73c9bc2574f86d63c2b57da93e3b3060d (patch)
tree8a85d4e92eeefbe3c55b921ac920527d12c33461 /drivers/net/sfc
parentd3074025345ae27fbb076a92425f28b40b6fa4c0 (diff)
sfc: Cleanup RX event processing
Make efx_process_channel() and falcon_process_eventq() return the number of packets received rather than updating the quota, consistent with new NAPI. Since channels and RX queues are mapped one-to-one, remove return value from falcon_handle_rx_event() and add a warning for events with the wrong RX queue number. Signed-off-by: Ben Hutchings <bhutchings@solarflare.com> Signed-off-by: Jeff Garzik <jgarzik@redhat.com>
Diffstat (limited to 'drivers/net/sfc')
-rw-r--r--drivers/net/sfc/efx.c27
-rw-r--r--drivers/net/sfc/falcon.c30
-rw-r--r--drivers/net/sfc/falcon.h2
3 files changed, 23 insertions, 36 deletions
diff --git a/drivers/net/sfc/efx.c b/drivers/net/sfc/efx.c
index 22004a612d2c..864095ea5b37 100644
--- a/drivers/net/sfc/efx.c
+++ b/drivers/net/sfc/efx.c
@@ -160,14 +160,16 @@ static void efx_fini_channels(struct efx_nic *efx);
160 */ 160 */
161static int efx_process_channel(struct efx_channel *channel, int rx_quota) 161static int efx_process_channel(struct efx_channel *channel, int rx_quota)
162{ 162{
163 int rxdmaqs; 163 struct efx_nic *efx = channel->efx;
164 struct efx_rx_queue *rx_queue; 164 int rx_packets;
165 165
166 if (unlikely(channel->efx->reset_pending != RESET_TYPE_NONE || 166 if (unlikely(efx->reset_pending != RESET_TYPE_NONE ||
167 !channel->enabled)) 167 !channel->enabled))
168 return rx_quota; 168 return 0;
169 169
170 rxdmaqs = falcon_process_eventq(channel, &rx_quota); 170 rx_packets = falcon_process_eventq(channel, rx_quota);
171 if (rx_packets == 0)
172 return 0;
171 173
172 /* Deliver last RX packet. */ 174 /* Deliver last RX packet. */
173 if (channel->rx_pkt) { 175 if (channel->rx_pkt) {
@@ -179,16 +181,9 @@ static int efx_process_channel(struct efx_channel *channel, int rx_quota)
179 efx_flush_lro(channel); 181 efx_flush_lro(channel);
180 efx_rx_strategy(channel); 182 efx_rx_strategy(channel);
181 183
182 /* Refill descriptor rings as necessary */ 184 efx_fast_push_rx_descriptors(&efx->rx_queue[channel->channel]);
183 rx_queue = &channel->efx->rx_queue[0];
184 while (rxdmaqs) {
185 if (rxdmaqs & 0x01)
186 efx_fast_push_rx_descriptors(rx_queue);
187 rx_queue++;
188 rxdmaqs >>= 1;
189 }
190 185
191 return rx_quota; 186 return rx_packets;
192} 187}
193 188
194/* Mark channel as finished processing 189/* Mark channel as finished processing
@@ -218,14 +213,12 @@ static int efx_poll(struct napi_struct *napi, int budget)
218 struct efx_channel *channel = 213 struct efx_channel *channel =
219 container_of(napi, struct efx_channel, napi_str); 214 container_of(napi, struct efx_channel, napi_str);
220 struct net_device *napi_dev = channel->napi_dev; 215 struct net_device *napi_dev = channel->napi_dev;
221 int unused;
222 int rx_packets; 216 int rx_packets;
223 217
224 EFX_TRACE(channel->efx, "channel %d NAPI poll executing on CPU %d\n", 218 EFX_TRACE(channel->efx, "channel %d NAPI poll executing on CPU %d\n",
225 channel->channel, raw_smp_processor_id()); 219 channel->channel, raw_smp_processor_id());
226 220
227 unused = efx_process_channel(channel, budget); 221 rx_packets = efx_process_channel(channel, budget);
228 rx_packets = (budget - unused);
229 222
230 if (rx_packets < budget) { 223 if (rx_packets < budget) {
231 /* There is no race here; although napi_disable() will 224 /* There is no race here; although napi_disable() will
diff --git a/drivers/net/sfc/falcon.c b/drivers/net/sfc/falcon.c
index 7b1c387ff8ef..96cb5d031ed7 100644
--- a/drivers/net/sfc/falcon.c
+++ b/drivers/net/sfc/falcon.c
@@ -952,10 +952,10 @@ static void falcon_handle_rx_bad_index(struct efx_rx_queue *rx_queue,
952 * Also "is multicast" and "matches multicast filter" flags can be used to 952 * Also "is multicast" and "matches multicast filter" flags can be used to
953 * discard non-matching multicast packets. 953 * discard non-matching multicast packets.
954 */ 954 */
955static int falcon_handle_rx_event(struct efx_channel *channel, 955static void falcon_handle_rx_event(struct efx_channel *channel,
956 const efx_qword_t *event) 956 const efx_qword_t *event)
957{ 957{
958 unsigned int rx_ev_q_label, rx_ev_desc_ptr, rx_ev_byte_cnt; 958 unsigned int rx_ev_desc_ptr, rx_ev_byte_cnt;
959 unsigned int rx_ev_hdr_type, rx_ev_mcast_pkt; 959 unsigned int rx_ev_hdr_type, rx_ev_mcast_pkt;
960 unsigned expected_ptr; 960 unsigned expected_ptr;
961 bool rx_ev_pkt_ok, discard = false, checksummed; 961 bool rx_ev_pkt_ok, discard = false, checksummed;
@@ -968,16 +968,14 @@ static int falcon_handle_rx_event(struct efx_channel *channel,
968 rx_ev_hdr_type = EFX_QWORD_FIELD(*event, RX_EV_HDR_TYPE); 968 rx_ev_hdr_type = EFX_QWORD_FIELD(*event, RX_EV_HDR_TYPE);
969 WARN_ON(EFX_QWORD_FIELD(*event, RX_EV_JUMBO_CONT)); 969 WARN_ON(EFX_QWORD_FIELD(*event, RX_EV_JUMBO_CONT));
970 WARN_ON(EFX_QWORD_FIELD(*event, RX_EV_SOP) != 1); 970 WARN_ON(EFX_QWORD_FIELD(*event, RX_EV_SOP) != 1);
971 WARN_ON(EFX_QWORD_FIELD(*event, RX_EV_Q_LABEL) != channel->channel);
971 972
972 rx_ev_q_label = EFX_QWORD_FIELD(*event, RX_EV_Q_LABEL); 973 rx_queue = &efx->rx_queue[channel->channel];
973 rx_queue = &efx->rx_queue[rx_ev_q_label];
974 974
975 rx_ev_desc_ptr = EFX_QWORD_FIELD(*event, RX_EV_DESC_PTR); 975 rx_ev_desc_ptr = EFX_QWORD_FIELD(*event, RX_EV_DESC_PTR);
976 expected_ptr = rx_queue->removed_count & FALCON_RXD_RING_MASK; 976 expected_ptr = rx_queue->removed_count & FALCON_RXD_RING_MASK;
977 if (unlikely(rx_ev_desc_ptr != expected_ptr)) { 977 if (unlikely(rx_ev_desc_ptr != expected_ptr))
978 falcon_handle_rx_bad_index(rx_queue, rx_ev_desc_ptr); 978 falcon_handle_rx_bad_index(rx_queue, rx_ev_desc_ptr);
979 return rx_ev_q_label;
980 }
981 979
982 if (likely(rx_ev_pkt_ok)) { 980 if (likely(rx_ev_pkt_ok)) {
983 /* If packet is marked as OK and packet type is TCP/IPv4 or 981 /* If packet is marked as OK and packet type is TCP/IPv4 or
@@ -1003,8 +1001,6 @@ static int falcon_handle_rx_event(struct efx_channel *channel,
1003 /* Handle received packet */ 1001 /* Handle received packet */
1004 efx_rx_packet(rx_queue, rx_ev_desc_ptr, rx_ev_byte_cnt, 1002 efx_rx_packet(rx_queue, rx_ev_desc_ptr, rx_ev_byte_cnt,
1005 checksummed, discard); 1003 checksummed, discard);
1006
1007 return rx_ev_q_label;
1008} 1004}
1009 1005
1010/* Global events are basically PHY events */ 1006/* Global events are basically PHY events */
@@ -1109,13 +1105,12 @@ static void falcon_handle_driver_event(struct efx_channel *channel,
1109 } 1105 }
1110} 1106}
1111 1107
1112int falcon_process_eventq(struct efx_channel *channel, int *rx_quota) 1108int falcon_process_eventq(struct efx_channel *channel, int rx_quota)
1113{ 1109{
1114 unsigned int read_ptr; 1110 unsigned int read_ptr;
1115 efx_qword_t event, *p_event; 1111 efx_qword_t event, *p_event;
1116 int ev_code; 1112 int ev_code;
1117 int rxq; 1113 int rx_packets = 0;
1118 int rxdmaqs = 0;
1119 1114
1120 read_ptr = channel->eventq_read_ptr; 1115 read_ptr = channel->eventq_read_ptr;
1121 1116
@@ -1137,9 +1132,8 @@ int falcon_process_eventq(struct efx_channel *channel, int *rx_quota)
1137 1132
1138 switch (ev_code) { 1133 switch (ev_code) {
1139 case RX_IP_EV_DECODE: 1134 case RX_IP_EV_DECODE:
1140 rxq = falcon_handle_rx_event(channel, &event); 1135 falcon_handle_rx_event(channel, &event);
1141 rxdmaqs |= (1 << rxq); 1136 ++rx_packets;
1142 (*rx_quota)--;
1143 break; 1137 break;
1144 case TX_IP_EV_DECODE: 1138 case TX_IP_EV_DECODE:
1145 falcon_handle_tx_event(channel, &event); 1139 falcon_handle_tx_event(channel, &event);
@@ -1166,10 +1160,10 @@ int falcon_process_eventq(struct efx_channel *channel, int *rx_quota)
1166 /* Increment read pointer */ 1160 /* Increment read pointer */
1167 read_ptr = (read_ptr + 1) & FALCON_EVQ_MASK; 1161 read_ptr = (read_ptr + 1) & FALCON_EVQ_MASK;
1168 1162
1169 } while (*rx_quota); 1163 } while (rx_packets < rx_quota);
1170 1164
1171 channel->eventq_read_ptr = read_ptr; 1165 channel->eventq_read_ptr = read_ptr;
1172 return rxdmaqs; 1166 return rx_packets;
1173} 1167}
1174 1168
1175void falcon_set_int_moderation(struct efx_channel *channel) 1169void falcon_set_int_moderation(struct efx_channel *channel)
diff --git a/drivers/net/sfc/falcon.h b/drivers/net/sfc/falcon.h
index a72f50e3e6eb..4cf05d0b5cfa 100644
--- a/drivers/net/sfc/falcon.h
+++ b/drivers/net/sfc/falcon.h
@@ -57,7 +57,7 @@ extern int falcon_probe_eventq(struct efx_channel *channel);
57extern int falcon_init_eventq(struct efx_channel *channel); 57extern int falcon_init_eventq(struct efx_channel *channel);
58extern void falcon_fini_eventq(struct efx_channel *channel); 58extern void falcon_fini_eventq(struct efx_channel *channel);
59extern void falcon_remove_eventq(struct efx_channel *channel); 59extern void falcon_remove_eventq(struct efx_channel *channel);
60extern int falcon_process_eventq(struct efx_channel *channel, int *rx_quota); 60extern int falcon_process_eventq(struct efx_channel *channel, int rx_quota);
61extern void falcon_eventq_read_ack(struct efx_channel *channel); 61extern void falcon_eventq_read_ack(struct efx_channel *channel);
62 62
63/* Ports */ 63/* Ports */