diff options
author | Ben Hutchings <bhutchings@solarflare.com> | 2008-09-01 07:48:08 -0400 |
---|---|---|
committer | Jeff Garzik <jgarzik@redhat.com> | 2008-09-03 09:53:47 -0400 |
commit | 42cbe2d73c9bc2574f86d63c2b57da93e3b3060d (patch) | |
tree | 8a85d4e92eeefbe3c55b921ac920527d12c33461 /drivers/net | |
parent | d3074025345ae27fbb076a92425f28b40b6fa4c0 (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')
-rw-r--r-- | drivers/net/sfc/efx.c | 27 | ||||
-rw-r--r-- | drivers/net/sfc/falcon.c | 30 | ||||
-rw-r--r-- | drivers/net/sfc/falcon.h | 2 |
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 | */ |
161 | static int efx_process_channel(struct efx_channel *channel, int rx_quota) | 161 | static 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 | */ |
955 | static int falcon_handle_rx_event(struct efx_channel *channel, | 955 | static 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 | ||
1112 | int falcon_process_eventq(struct efx_channel *channel, int *rx_quota) | 1108 | int 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 | ||
1175 | void falcon_set_int_moderation(struct efx_channel *channel) | 1169 | void 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); | |||
57 | extern int falcon_init_eventq(struct efx_channel *channel); | 57 | extern int falcon_init_eventq(struct efx_channel *channel); |
58 | extern void falcon_fini_eventq(struct efx_channel *channel); | 58 | extern void falcon_fini_eventq(struct efx_channel *channel); |
59 | extern void falcon_remove_eventq(struct efx_channel *channel); | 59 | extern void falcon_remove_eventq(struct efx_channel *channel); |
60 | extern int falcon_process_eventq(struct efx_channel *channel, int *rx_quota); | 60 | extern int falcon_process_eventq(struct efx_channel *channel, int rx_quota); |
61 | extern void falcon_eventq_read_ack(struct efx_channel *channel); | 61 | extern void falcon_eventq_read_ack(struct efx_channel *channel); |
62 | 62 | ||
63 | /* Ports */ | 63 | /* Ports */ |