mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-09-12 13:55:32 +00:00
sfc: select inner-csum-offload TX queues for skbs that need it
Won't actually be exercised until we start advertising the corresponding offload features. Signed-off-by: Edward Cree <ecree@solarflare.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
85d43fdb57
commit
fe0c4060c1
3 changed files with 29 additions and 2 deletions
|
@ -43,6 +43,7 @@
|
|||
#include "mcdi_pcol.h"
|
||||
#include "io.h"
|
||||
#include "farch_regs.h"
|
||||
#include "tx.h"
|
||||
#include "nic.h" /* indirectly includes ptp.h */
|
||||
|
||||
/* Maximum number of events expected to make up a PTP event */
|
||||
|
@ -1081,8 +1082,8 @@ static int efx_ptp_synchronize(struct efx_nic *efx, unsigned int num_readings)
|
|||
/* Transmit a PTP packet via the dedicated hardware timestamped queue. */
|
||||
static void efx_ptp_xmit_skb_queue(struct efx_nic *efx, struct sk_buff *skb)
|
||||
{
|
||||
u8 type = skb->ip_summed == CHECKSUM_PARTIAL ? EFX_TXQ_TYPE_OUTER_CSUM : 0;
|
||||
struct efx_ptp_data *ptp_data = efx->ptp_data;
|
||||
u8 type = efx_tx_csum_type_skb(skb);
|
||||
struct efx_tx_queue *tx_queue;
|
||||
|
||||
tx_queue = efx_channel_get_tx_queue(ptp_data->channel, type);
|
||||
|
|
|
@ -506,7 +506,7 @@ netdev_tx_t efx_hard_start_xmit(struct sk_buff *skb,
|
|||
EFX_WARN_ON_PARANOID(!netif_device_present(net_dev));
|
||||
|
||||
index = skb_get_queue_mapping(skb);
|
||||
type = skb->ip_summed == CHECKSUM_PARTIAL ? EFX_TXQ_TYPE_OUTER_CSUM : 0;
|
||||
type = efx_tx_csum_type_skb(skb);
|
||||
if (index >= efx->n_tx_channels) {
|
||||
index -= efx->n_tx_channels;
|
||||
type |= EFX_TXQ_TYPE_HIGHPRI;
|
||||
|
|
|
@ -18,4 +18,30 @@ unsigned int efx_tx_limit_len(struct efx_tx_queue *tx_queue,
|
|||
u8 *efx_tx_get_copy_buffer_limited(struct efx_tx_queue *tx_queue,
|
||||
struct efx_tx_buffer *buffer, size_t len);
|
||||
|
||||
/* What TXQ type will satisfy the checksum offloads required for this skb? */
|
||||
static inline unsigned int efx_tx_csum_type_skb(struct sk_buff *skb)
|
||||
{
|
||||
if (skb->ip_summed != CHECKSUM_PARTIAL)
|
||||
return 0; /* no checksum offload */
|
||||
|
||||
if (skb->encapsulation &&
|
||||
skb_checksum_start_offset(skb) == skb_inner_transport_offset(skb)) {
|
||||
/* we only advertise features for IPv4 and IPv6 checksums on
|
||||
* encapsulated packets, so if the checksum is for the inner
|
||||
* packet, it must be one of them; no further checking required.
|
||||
*/
|
||||
|
||||
/* Do we also need to offload the outer header checksum? */
|
||||
if (skb_shinfo(skb)->gso_segs > 1 &&
|
||||
!(skb_shinfo(skb)->gso_type & SKB_GSO_PARTIAL) &&
|
||||
(skb_shinfo(skb)->gso_type & SKB_GSO_UDP_TUNNEL_CSUM))
|
||||
return EFX_TXQ_TYPE_OUTER_CSUM | EFX_TXQ_TYPE_INNER_CSUM;
|
||||
return EFX_TXQ_TYPE_INNER_CSUM;
|
||||
}
|
||||
|
||||
/* similarly, we only advertise features for IPv4 and IPv6 checksums,
|
||||
* so it must be one of them. No need for further checks.
|
||||
*/
|
||||
return EFX_TXQ_TYPE_OUTER_CSUM;
|
||||
}
|
||||
#endif /* EFX_TX_H */
|
||||
|
|
Loading…
Reference in a new issue