Commit 740acc15 authored by Edward Cree's avatar Edward Cree Committed by David S. Miller
Browse files

sfc: commonise TSO fallback code



ef100 will need this if it gets GSO skbs it can't handle (e.g. too long
 header length).

Signed-off-by: default avatarEdward Cree <ecree@solarflare.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 80a0074e
Loading
Loading
Loading
Loading
+0 −28
Original line number Diff line number Diff line
@@ -268,34 +268,6 @@ static int efx_enqueue_skb_pio(struct efx_tx_queue *tx_queue,
}
#endif /* EFX_USE_PIO */

/*
 * Fallback to software TSO.
 *
 * This is used if we are unable to send a GSO packet through hardware TSO.
 * This should only ever happen due to per-queue restrictions - unsupported
 * packets should first be filtered by the feature flags.
 *
 * Returns 0 on success, error code otherwise.
 */
static int efx_tx_tso_fallback(struct efx_tx_queue *tx_queue,
			       struct sk_buff *skb)
{
	struct sk_buff *segments, *next;

	segments = skb_gso_segment(skb, 0);
	if (IS_ERR(segments))
		return PTR_ERR(segments);

	dev_consume_skb_any(skb);

	skb_list_walk_safe(segments, skb, next) {
		skb_mark_not_on_list(skb);
		efx_enqueue_skb(tx_queue, skb);
	}

	return 0;
}

/*
 * Add a socket buffer to a TX queue
 *
+27 −0
Original line number Diff line number Diff line
@@ -405,3 +405,30 @@ unsigned int efx_tx_max_skb_descs(struct efx_nic *efx)

	return max_descs;
}

/*
 * Fallback to software TSO.
 *
 * This is used if we are unable to send a GSO packet through hardware TSO.
 * This should only ever happen due to per-queue restrictions - unsupported
 * packets should first be filtered by the feature flags.
 *
 * Returns 0 on success, error code otherwise.
 */
int efx_tx_tso_fallback(struct efx_tx_queue *tx_queue, struct sk_buff *skb)
{
	struct sk_buff *segments, *next;

	segments = skb_gso_segment(skb, 0);
	if (IS_ERR(segments))
		return PTR_ERR(segments);

	dev_consume_skb_any(skb);

	skb_list_walk_safe(segments, skb, next) {
		skb_mark_not_on_list(skb);
		efx_enqueue_skb(tx_queue, skb);
	}

	return 0;
}
+1 −1
Original line number Diff line number Diff line
@@ -38,5 +38,5 @@ int efx_tx_map_data(struct efx_tx_queue *tx_queue, struct sk_buff *skb,
		    unsigned int segment_count);

unsigned int efx_tx_max_skb_descs(struct efx_nic *efx);

int efx_tx_tso_fallback(struct efx_tx_queue *tx_queue, struct sk_buff *skb);
#endif