aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/sfc
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/sfc')
-rw-r--r--drivers/net/sfc/efx.c18
-rw-r--r--drivers/net/sfc/nic.c39
2 files changed, 33 insertions, 24 deletions
diff --git a/drivers/net/sfc/efx.c b/drivers/net/sfc/efx.c
index 1ad61b7bba40..5e3f944fdd95 100644
--- a/drivers/net/sfc/efx.c
+++ b/drivers/net/sfc/efx.c
@@ -225,17 +225,17 @@ static void efx_fini_channels(struct efx_nic *efx);
225 * never be concurrently called more than once on the same channel, 225 * never be concurrently called more than once on the same channel,
226 * though different channels may be being processed concurrently. 226 * though different channels may be being processed concurrently.
227 */ 227 */
228static int efx_process_channel(struct efx_channel *channel, int rx_quota) 228static int efx_process_channel(struct efx_channel *channel, int budget)
229{ 229{
230 struct efx_nic *efx = channel->efx; 230 struct efx_nic *efx = channel->efx;
231 int rx_packets; 231 int spent;
232 232
233 if (unlikely(efx->reset_pending != RESET_TYPE_NONE || 233 if (unlikely(efx->reset_pending != RESET_TYPE_NONE ||
234 !channel->enabled)) 234 !channel->enabled))
235 return 0; 235 return 0;
236 236
237 rx_packets = efx_nic_process_eventq(channel, rx_quota); 237 spent = efx_nic_process_eventq(channel, budget);
238 if (rx_packets == 0) 238 if (spent == 0)
239 return 0; 239 return 0;
240 240
241 /* Deliver last RX packet. */ 241 /* Deliver last RX packet. */
@@ -249,7 +249,7 @@ static int efx_process_channel(struct efx_channel *channel, int rx_quota)
249 249
250 efx_fast_push_rx_descriptors(&efx->rx_queue[channel->channel]); 250 efx_fast_push_rx_descriptors(&efx->rx_queue[channel->channel]);
251 251
252 return rx_packets; 252 return spent;
253} 253}
254 254
255/* Mark channel as finished processing 255/* Mark channel as finished processing
@@ -278,14 +278,14 @@ static int efx_poll(struct napi_struct *napi, int budget)
278{ 278{
279 struct efx_channel *channel = 279 struct efx_channel *channel =
280 container_of(napi, struct efx_channel, napi_str); 280 container_of(napi, struct efx_channel, napi_str);
281 int rx_packets; 281 int spent;
282 282
283 EFX_TRACE(channel->efx, "channel %d NAPI poll executing on CPU %d\n", 283 EFX_TRACE(channel->efx, "channel %d NAPI poll executing on CPU %d\n",
284 channel->channel, raw_smp_processor_id()); 284 channel->channel, raw_smp_processor_id());
285 285
286 rx_packets = efx_process_channel(channel, budget); 286 spent = efx_process_channel(channel, budget);
287 287
288 if (rx_packets < budget) { 288 if (spent < budget) {
289 struct efx_nic *efx = channel->efx; 289 struct efx_nic *efx = channel->efx;
290 290
291 if (channel->used_flags & EFX_USED_BY_RX && 291 if (channel->used_flags & EFX_USED_BY_RX &&
@@ -318,7 +318,7 @@ static int efx_poll(struct napi_struct *napi, int budget)
318 efx_channel_processed(channel); 318 efx_channel_processed(channel);
319 } 319 }
320 320
321 return rx_packets; 321 return spent;
322} 322}
323 323
324/* Process the eventq of the specified channel immediately on this CPU 324/* Process the eventq of the specified channel immediately on this CPU
diff --git a/drivers/net/sfc/nic.c b/drivers/net/sfc/nic.c
index 4105f9099c7c..f3226bbf9831 100644
--- a/drivers/net/sfc/nic.c
+++ b/drivers/net/sfc/nic.c
@@ -654,22 +654,23 @@ void efx_generate_event(struct efx_channel *channel, efx_qword_t *event)
654 * The NIC batches TX completion events; the message we receive is of 654 * The NIC batches TX completion events; the message we receive is of
655 * the form "complete all TX events up to this index". 655 * the form "complete all TX events up to this index".
656 */ 656 */
657static void 657static int
658efx_handle_tx_event(struct efx_channel *channel, efx_qword_t *event) 658efx_handle_tx_event(struct efx_channel *channel, efx_qword_t *event)
659{ 659{
660 unsigned int tx_ev_desc_ptr; 660 unsigned int tx_ev_desc_ptr;
661 unsigned int tx_ev_q_label; 661 unsigned int tx_ev_q_label;
662 struct efx_tx_queue *tx_queue; 662 struct efx_tx_queue *tx_queue;
663 struct efx_nic *efx = channel->efx; 663 struct efx_nic *efx = channel->efx;
664 int tx_packets = 0;
664 665
665 if (likely(EFX_QWORD_FIELD(*event, FSF_AZ_TX_EV_COMP))) { 666 if (likely(EFX_QWORD_FIELD(*event, FSF_AZ_TX_EV_COMP))) {
666 /* Transmit completion */ 667 /* Transmit completion */
667 tx_ev_desc_ptr = EFX_QWORD_FIELD(*event, FSF_AZ_TX_EV_DESC_PTR); 668 tx_ev_desc_ptr = EFX_QWORD_FIELD(*event, FSF_AZ_TX_EV_DESC_PTR);
668 tx_ev_q_label = EFX_QWORD_FIELD(*event, FSF_AZ_TX_EV_Q_LABEL); 669 tx_ev_q_label = EFX_QWORD_FIELD(*event, FSF_AZ_TX_EV_Q_LABEL);
669 tx_queue = &efx->tx_queue[tx_ev_q_label]; 670 tx_queue = &efx->tx_queue[tx_ev_q_label];
670 channel->irq_mod_score += 671 tx_packets = ((tx_ev_desc_ptr - tx_queue->read_count) &
671 (tx_ev_desc_ptr - tx_queue->read_count) & 672 EFX_TXQ_MASK);
672 EFX_TXQ_MASK; 673 channel->irq_mod_score += tx_packets;
673 efx_xmit_done(tx_queue, tx_ev_desc_ptr); 674 efx_xmit_done(tx_queue, tx_ev_desc_ptr);
674 } else if (EFX_QWORD_FIELD(*event, FSF_AZ_TX_EV_WQ_FF_FULL)) { 675 } else if (EFX_QWORD_FIELD(*event, FSF_AZ_TX_EV_WQ_FF_FULL)) {
675 /* Rewrite the FIFO write pointer */ 676 /* Rewrite the FIFO write pointer */
@@ -689,6 +690,8 @@ efx_handle_tx_event(struct efx_channel *channel, efx_qword_t *event)
689 EFX_QWORD_FMT"\n", channel->channel, 690 EFX_QWORD_FMT"\n", channel->channel,
690 EFX_QWORD_VAL(*event)); 691 EFX_QWORD_VAL(*event));
691 } 692 }
693
694 return tx_packets;
692} 695}
693 696
694/* Detect errors included in the rx_evt_pkt_ok bit. */ 697/* Detect errors included in the rx_evt_pkt_ok bit. */
@@ -947,16 +950,17 @@ efx_handle_driver_event(struct efx_channel *channel, efx_qword_t *event)
947 } 950 }
948} 951}
949 952
950int efx_nic_process_eventq(struct efx_channel *channel, int rx_quota) 953int efx_nic_process_eventq(struct efx_channel *channel, int budget)
951{ 954{
952 unsigned int read_ptr; 955 unsigned int read_ptr;
953 efx_qword_t event, *p_event; 956 efx_qword_t event, *p_event;
954 int ev_code; 957 int ev_code;
955 int rx_packets = 0; 958 int tx_packets = 0;
959 int spent = 0;
956 960
957 read_ptr = channel->eventq_read_ptr; 961 read_ptr = channel->eventq_read_ptr;
958 962
959 do { 963 for (;;) {
960 p_event = efx_event(channel, read_ptr); 964 p_event = efx_event(channel, read_ptr);
961 event = *p_event; 965 event = *p_event;
962 966
@@ -970,15 +974,23 @@ int efx_nic_process_eventq(struct efx_channel *channel, int rx_quota)
970 /* Clear this event by marking it all ones */ 974 /* Clear this event by marking it all ones */
971 EFX_SET_QWORD(*p_event); 975 EFX_SET_QWORD(*p_event);
972 976
977 /* Increment read pointer */
978 read_ptr = (read_ptr + 1) & EFX_EVQ_MASK;
979
973 ev_code = EFX_QWORD_FIELD(event, FSF_AZ_EV_CODE); 980 ev_code = EFX_QWORD_FIELD(event, FSF_AZ_EV_CODE);
974 981
975 switch (ev_code) { 982 switch (ev_code) {
976 case FSE_AZ_EV_CODE_RX_EV: 983 case FSE_AZ_EV_CODE_RX_EV:
977 efx_handle_rx_event(channel, &event); 984 efx_handle_rx_event(channel, &event);
978 ++rx_packets; 985 if (++spent == budget)
986 goto out;
979 break; 987 break;
980 case FSE_AZ_EV_CODE_TX_EV: 988 case FSE_AZ_EV_CODE_TX_EV:
981 efx_handle_tx_event(channel, &event); 989 tx_packets += efx_handle_tx_event(channel, &event);
990 if (tx_packets >= EFX_TXQ_SIZE) {
991 spent = budget;
992 goto out;
993 }
982 break; 994 break;
983 case FSE_AZ_EV_CODE_DRV_GEN_EV: 995 case FSE_AZ_EV_CODE_DRV_GEN_EV:
984 channel->eventq_magic = EFX_QWORD_FIELD( 996 channel->eventq_magic = EFX_QWORD_FIELD(
@@ -1001,14 +1013,11 @@ int efx_nic_process_eventq(struct efx_channel *channel, int rx_quota)
1001 " (data " EFX_QWORD_FMT ")\n", channel->channel, 1013 " (data " EFX_QWORD_FMT ")\n", channel->channel,
1002 ev_code, EFX_QWORD_VAL(event)); 1014 ev_code, EFX_QWORD_VAL(event));
1003 } 1015 }
1016 }
1004 1017
1005 /* Increment read pointer */ 1018out:
1006 read_ptr = (read_ptr + 1) & EFX_EVQ_MASK;
1007
1008 } while (rx_packets < rx_quota);
1009
1010 channel->eventq_read_ptr = read_ptr; 1019 channel->eventq_read_ptr = read_ptr;
1011 return rx_packets; 1020 return spent;
1012} 1021}
1013 1022
1014 1023