Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

Edward Cree and committed by
David S. Miller
fe0c4060 85d43fdb

+29 -2
+2 -1
drivers/net/ethernet/sfc/ptp.c
··· 43 43 #include "mcdi_pcol.h" 44 44 #include "io.h" 45 45 #include "farch_regs.h" 46 + #include "tx.h" 46 47 #include "nic.h" /* indirectly includes ptp.h */ 47 48 48 49 /* Maximum number of events expected to make up a PTP event */ ··· 1082 1081 /* Transmit a PTP packet via the dedicated hardware timestamped queue. */ 1083 1082 static void efx_ptp_xmit_skb_queue(struct efx_nic *efx, struct sk_buff *skb) 1084 1083 { 1085 - u8 type = skb->ip_summed == CHECKSUM_PARTIAL ? EFX_TXQ_TYPE_OUTER_CSUM : 0; 1086 1084 struct efx_ptp_data *ptp_data = efx->ptp_data; 1085 + u8 type = efx_tx_csum_type_skb(skb); 1087 1086 struct efx_tx_queue *tx_queue; 1088 1087 1089 1088 tx_queue = efx_channel_get_tx_queue(ptp_data->channel, type);
+1 -1
drivers/net/ethernet/sfc/tx.c
··· 506 506 EFX_WARN_ON_PARANOID(!netif_device_present(net_dev)); 507 507 508 508 index = skb_get_queue_mapping(skb); 509 - type = skb->ip_summed == CHECKSUM_PARTIAL ? EFX_TXQ_TYPE_OUTER_CSUM : 0; 509 + type = efx_tx_csum_type_skb(skb); 510 510 if (index >= efx->n_tx_channels) { 511 511 index -= efx->n_tx_channels; 512 512 type |= EFX_TXQ_TYPE_HIGHPRI;
+26
drivers/net/ethernet/sfc/tx.h
··· 18 18 u8 *efx_tx_get_copy_buffer_limited(struct efx_tx_queue *tx_queue, 19 19 struct efx_tx_buffer *buffer, size_t len); 20 20 21 + /* What TXQ type will satisfy the checksum offloads required for this skb? */ 22 + static inline unsigned int efx_tx_csum_type_skb(struct sk_buff *skb) 23 + { 24 + if (skb->ip_summed != CHECKSUM_PARTIAL) 25 + return 0; /* no checksum offload */ 26 + 27 + if (skb->encapsulation && 28 + skb_checksum_start_offset(skb) == skb_inner_transport_offset(skb)) { 29 + /* we only advertise features for IPv4 and IPv6 checksums on 30 + * encapsulated packets, so if the checksum is for the inner 31 + * packet, it must be one of them; no further checking required. 32 + */ 33 + 34 + /* Do we also need to offload the outer header checksum? */ 35 + if (skb_shinfo(skb)->gso_segs > 1 && 36 + !(skb_shinfo(skb)->gso_type & SKB_GSO_PARTIAL) && 37 + (skb_shinfo(skb)->gso_type & SKB_GSO_UDP_TUNNEL_CSUM)) 38 + return EFX_TXQ_TYPE_OUTER_CSUM | EFX_TXQ_TYPE_INNER_CSUM; 39 + return EFX_TXQ_TYPE_INNER_CSUM; 40 + } 41 + 42 + /* similarly, we only advertise features for IPv4 and IPv6 checksums, 43 + * so it must be one of them. No need for further checks. 44 + */ 45 + return EFX_TXQ_TYPE_OUTER_CSUM; 46 + } 21 47 #endif /* EFX_TX_H */