aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/net/ethernet/sfc/efx.c6
-rw-r--r--drivers/net/ethernet/sfc/efx.h1
-rw-r--r--drivers/net/ethernet/sfc/net_driver.h3
-rw-r--r--drivers/net/ethernet/sfc/rx.c13
4 files changed, 21 insertions, 2 deletions
diff --git a/drivers/net/ethernet/sfc/efx.c b/drivers/net/ethernet/sfc/efx.c
index 342a1f31e5b8..8b79a6413fe4 100644
--- a/drivers/net/ethernet/sfc/efx.c
+++ b/drivers/net/ethernet/sfc/efx.c
@@ -734,6 +734,7 @@ static void efx_remove_channel(struct efx_channel *channel)
734 efx_for_each_possible_channel_tx_queue(tx_queue, channel) 734 efx_for_each_possible_channel_tx_queue(tx_queue, channel)
735 efx_remove_tx_queue(tx_queue); 735 efx_remove_tx_queue(tx_queue);
736 efx_remove_eventq(channel); 736 efx_remove_eventq(channel);
737 channel->type->post_remove(channel);
737} 738}
738 739
739static void efx_remove_channels(struct efx_nic *efx) 740static void efx_remove_channels(struct efx_nic *efx)
@@ -852,6 +853,7 @@ void efx_schedule_slow_fill(struct efx_rx_queue *rx_queue)
852 853
853static const struct efx_channel_type efx_default_channel_type = { 854static const struct efx_channel_type efx_default_channel_type = {
854 .pre_probe = efx_channel_dummy_op_int, 855 .pre_probe = efx_channel_dummy_op_int,
856 .post_remove = efx_channel_dummy_op_void,
855 .get_name = efx_get_channel_name, 857 .get_name = efx_get_channel_name,
856 .copy = efx_copy_channel, 858 .copy = efx_copy_channel,
857 .keep_eventq = false, 859 .keep_eventq = false,
@@ -862,6 +864,10 @@ int efx_channel_dummy_op_int(struct efx_channel *channel)
862 return 0; 864 return 0;
863} 865}
864 866
867void efx_channel_dummy_op_void(struct efx_channel *channel)
868{
869}
870
865/************************************************************************** 871/**************************************************************************
866 * 872 *
867 * Port handling 873 * Port handling
diff --git a/drivers/net/ethernet/sfc/efx.h b/drivers/net/ethernet/sfc/efx.h
index 70755c97251a..f11170bc48bf 100644
--- a/drivers/net/ethernet/sfc/efx.h
+++ b/drivers/net/ethernet/sfc/efx.h
@@ -102,6 +102,7 @@ static inline void efx_filter_rfs_expire(struct efx_channel *channel) {}
102 102
103/* Channels */ 103/* Channels */
104extern int efx_channel_dummy_op_int(struct efx_channel *channel); 104extern int efx_channel_dummy_op_int(struct efx_channel *channel);
105extern void efx_channel_dummy_op_void(struct efx_channel *channel);
105extern void efx_process_channel_now(struct efx_channel *channel); 106extern void efx_process_channel_now(struct efx_channel *channel);
106extern int 107extern int
107efx_realloc_channels(struct efx_nic *efx, u32 rxq_entries, u32 txq_entries); 108efx_realloc_channels(struct efx_nic *efx, u32 rxq_entries, u32 txq_entries);
diff --git a/drivers/net/ethernet/sfc/net_driver.h b/drivers/net/ethernet/sfc/net_driver.h
index 24a78a35bddb..0f0926e68963 100644
--- a/drivers/net/ethernet/sfc/net_driver.h
+++ b/drivers/net/ethernet/sfc/net_driver.h
@@ -393,14 +393,17 @@ struct efx_channel {
393 * @get_name: Generate the channel's name (used for its IRQ handler) 393 * @get_name: Generate the channel's name (used for its IRQ handler)
394 * @copy: Copy the channel state prior to reallocation. May be %NULL if 394 * @copy: Copy the channel state prior to reallocation. May be %NULL if
395 * reallocation is not supported. 395 * reallocation is not supported.
396 * @receive_skb: Handle an skb ready to be passed to netif_receive_skb()
396 * @keep_eventq: Flag for whether event queue should be kept initialised 397 * @keep_eventq: Flag for whether event queue should be kept initialised
397 * while the device is stopped 398 * while the device is stopped
398 */ 399 */
399struct efx_channel_type { 400struct efx_channel_type {
400 void (*handle_no_channel)(struct efx_nic *); 401 void (*handle_no_channel)(struct efx_nic *);
401 int (*pre_probe)(struct efx_channel *); 402 int (*pre_probe)(struct efx_channel *);
403 void (*post_remove)(struct efx_channel *);
402 void (*get_name)(struct efx_channel *, char *buf, size_t len); 404 void (*get_name)(struct efx_channel *, char *buf, size_t len);
403 struct efx_channel *(*copy)(const struct efx_channel *); 405 struct efx_channel *(*copy)(const struct efx_channel *);
406 void (*receive_skb)(struct efx_channel *, struct sk_buff *);
404 bool keep_eventq; 407 bool keep_eventq;
405}; 408};
406 409
diff --git a/drivers/net/ethernet/sfc/rx.c b/drivers/net/ethernet/sfc/rx.c
index e997f83f14f5..9e0ad1b75c33 100644
--- a/drivers/net/ethernet/sfc/rx.c
+++ b/drivers/net/ethernet/sfc/rx.c
@@ -575,7 +575,10 @@ static void efx_rx_deliver(struct efx_channel *channel,
575 skb_record_rx_queue(skb, channel->rx_queue.core_index); 575 skb_record_rx_queue(skb, channel->rx_queue.core_index);
576 576
577 /* Pass the packet up */ 577 /* Pass the packet up */
578 netif_receive_skb(skb); 578 if (channel->type->receive_skb)
579 channel->type->receive_skb(channel, skb);
580 else
581 netif_receive_skb(skb);
579 582
580 /* Update allocation strategy method */ 583 /* Update allocation strategy method */
581 channel->rx_alloc_level += RX_ALLOC_FACTOR_SKB; 584 channel->rx_alloc_level += RX_ALLOC_FACTOR_SKB;
@@ -617,7 +620,8 @@ void __efx_rx_packet(struct efx_channel *channel, struct efx_rx_buffer *rx_buf)
617 if (unlikely(!(efx->net_dev->features & NETIF_F_RXCSUM))) 620 if (unlikely(!(efx->net_dev->features & NETIF_F_RXCSUM)))
618 rx_buf->flags &= ~EFX_RX_PKT_CSUMMED; 621 rx_buf->flags &= ~EFX_RX_PKT_CSUMMED;
619 622
620 if (likely(rx_buf->flags & (EFX_RX_BUF_PAGE | EFX_RX_PKT_CSUMMED))) 623 if (likely(rx_buf->flags & (EFX_RX_BUF_PAGE | EFX_RX_PKT_CSUMMED)) &&
624 !channel->type->receive_skb)
621 efx_rx_packet_gro(channel, rx_buf, eh); 625 efx_rx_packet_gro(channel, rx_buf, eh);
622 else 626 else
623 efx_rx_deliver(channel, rx_buf); 627 efx_rx_deliver(channel, rx_buf);
@@ -627,6 +631,11 @@ void efx_rx_strategy(struct efx_channel *channel)
627{ 631{
628 enum efx_rx_alloc_method method = rx_alloc_method; 632 enum efx_rx_alloc_method method = rx_alloc_method;
629 633
634 if (channel->type->receive_skb) {
635 channel->rx_alloc_push_pages = false;
636 return;
637 }
638
630 /* Only makes sense to use page based allocation if GRO is enabled */ 639 /* Only makes sense to use page based allocation if GRO is enabled */
631 if (!(channel->efx->net_dev->features & NETIF_F_GRO)) { 640 if (!(channel->efx->net_dev->features & NETIF_F_GRO)) {
632 method = RX_ALLOC_METHOD_SKB; 641 method = RX_ALLOC_METHOD_SKB;