diff options
-rw-r--r-- | drivers/net/ethernet/sfc/efx.c | 6 | ||||
-rw-r--r-- | drivers/net/ethernet/sfc/efx.h | 1 | ||||
-rw-r--r-- | drivers/net/ethernet/sfc/net_driver.h | 3 | ||||
-rw-r--r-- | drivers/net/ethernet/sfc/rx.c | 13 |
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 | ||
739 | static void efx_remove_channels(struct efx_nic *efx) | 740 | static 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 | ||
853 | static const struct efx_channel_type efx_default_channel_type = { | 854 | static 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 | ||
867 | void 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 */ |
104 | extern int efx_channel_dummy_op_int(struct efx_channel *channel); | 104 | extern int efx_channel_dummy_op_int(struct efx_channel *channel); |
105 | extern void efx_channel_dummy_op_void(struct efx_channel *channel); | ||
105 | extern void efx_process_channel_now(struct efx_channel *channel); | 106 | extern void efx_process_channel_now(struct efx_channel *channel); |
106 | extern int | 107 | extern int |
107 | efx_realloc_channels(struct efx_nic *efx, u32 rxq_entries, u32 txq_entries); | 108 | efx_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 | */ |
399 | struct efx_channel_type { | 400 | struct 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; |