aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/ethernet/sfc
diff options
context:
space:
mode:
authorBen Hutchings <bhutchings@solarflare.com>2012-06-21 21:44:01 -0400
committerBen Hutchings <bhutchings@solarflare.com>2012-08-24 15:10:17 -0400
commit9714284f83387d330496758e5c10a649fd9a677d (patch)
tree1e2baa7525f00903eebafeea7e7f066fb982a5cb /drivers/net/ethernet/sfc
parent53cb13c680b98c637d95dd731b01bc284b3aa33d (diff)
sfc: Stash header offsets for TSO in struct tso_state
Signed-off-by: Ben Hutchings <bhutchings@solarflare.com>
Diffstat (limited to 'drivers/net/ethernet/sfc')
-rw-r--r--drivers/net/ethernet/sfc/tx.c28
1 files changed, 12 insertions, 16 deletions
diff --git a/drivers/net/ethernet/sfc/tx.c b/drivers/net/ethernet/sfc/tx.c
index d9dbebc9f819..ebca75ed78dc 100644
--- a/drivers/net/ethernet/sfc/tx.c
+++ b/drivers/net/ethernet/sfc/tx.c
@@ -613,10 +613,6 @@ void efx_remove_tx_queue(struct efx_tx_queue *tx_queue)
613#endif 613#endif
614 614
615#define PTR_DIFF(p1, p2) ((u8 *)(p1) - (u8 *)(p2)) 615#define PTR_DIFF(p1, p2) ((u8 *)(p1) - (u8 *)(p2))
616#define ETH_HDR_LEN(skb) (skb_network_header(skb) - (skb)->data)
617#define SKB_TCP_OFF(skb) PTR_DIFF(tcp_hdr(skb), (skb)->data)
618#define SKB_IPV4_OFF(skb) PTR_DIFF(ip_hdr(skb), (skb)->data)
619#define SKB_IPV6_OFF(skb) PTR_DIFF(ipv6_hdr(skb), (skb)->data)
620 616
621/** 617/**
622 * struct tso_state - TSO state for an SKB 618 * struct tso_state - TSO state for an SKB
@@ -630,6 +626,8 @@ void efx_remove_tx_queue(struct efx_tx_queue *tx_queue)
630 * @unmap_addr: DMA address of SKB fragment 626 * @unmap_addr: DMA address of SKB fragment
631 * @dma_flags: TX buffer flags for DMA mapping - %EFX_TX_BUF_MAP_SINGLE or 0 627 * @dma_flags: TX buffer flags for DMA mapping - %EFX_TX_BUF_MAP_SINGLE or 0
632 * @protocol: Network protocol (after any VLAN header) 628 * @protocol: Network protocol (after any VLAN header)
629 * @ip_off: Offset of IP header
630 * @tcp_off: Offset of TCP header
633 * @header_len: Number of bytes of header 631 * @header_len: Number of bytes of header
634 * @ip_base_len: IPv4 tot_len or IPv6 payload_len, before TCP payload 632 * @ip_base_len: IPv4 tot_len or IPv6 payload_len, before TCP payload
635 * 633 *
@@ -651,6 +649,8 @@ struct tso_state {
651 unsigned short dma_flags; 649 unsigned short dma_flags;
652 650
653 __be16 protocol; 651 __be16 protocol;
652 unsigned int ip_off;
653 unsigned int tcp_off;
654 unsigned header_len; 654 unsigned header_len;
655 unsigned int ip_base_len; 655 unsigned int ip_base_len;
656}; 656};
@@ -825,17 +825,14 @@ static void efx_enqueue_unwind(struct efx_tx_queue *tx_queue)
825/* Parse the SKB header and initialise state. */ 825/* Parse the SKB header and initialise state. */
826static void tso_start(struct tso_state *st, const struct sk_buff *skb) 826static void tso_start(struct tso_state *st, const struct sk_buff *skb)
827{ 827{
828 /* All ethernet/IP/TCP headers combined size is TCP header size 828 st->ip_off = skb_network_header(skb) - skb->data;
829 * plus offset of TCP header relative to start of packet. 829 st->tcp_off = skb_transport_header(skb) - skb->data;
830 */ 830 st->header_len = st->tcp_off + (tcp_hdr(skb)->doff << 2u);
831 st->header_len = ((tcp_hdr(skb)->doff << 2u)
832 + PTR_DIFF(tcp_hdr(skb), skb->data));
833
834 if (st->protocol == htons(ETH_P_IP)) { 831 if (st->protocol == htons(ETH_P_IP)) {
835 st->ip_base_len = st->header_len - ETH_HDR_LEN(skb); 832 st->ip_base_len = st->header_len - st->ip_off;
836 st->ipv4_id = ntohs(ip_hdr(skb)->id); 833 st->ipv4_id = ntohs(ip_hdr(skb)->id);
837 } else { 834 } else {
838 st->ip_base_len = tcp_hdr(skb)->doff << 2u; 835 st->ip_base_len = st->header_len - st->tcp_off;
839 st->ipv4_id = 0; 836 st->ipv4_id = 0;
840 } 837 }
841 st->seqnum = ntohl(tcp_hdr(skb)->seq); 838 st->seqnum = ntohl(tcp_hdr(skb)->seq);
@@ -959,7 +956,7 @@ static int tso_start_new_packet(struct efx_tx_queue *tx_queue,
959 if (!header) 956 if (!header)
960 return -ENOMEM; 957 return -ENOMEM;
961 958
962 tsoh_th = (struct tcphdr *)(header + SKB_TCP_OFF(skb)); 959 tsoh_th = (struct tcphdr *)(header + st->tcp_off);
963 960
964 /* Copy and update the headers. */ 961 /* Copy and update the headers. */
965 memcpy(header, skb->data, st->header_len); 962 memcpy(header, skb->data, st->header_len);
@@ -980,8 +977,7 @@ static int tso_start_new_packet(struct efx_tx_queue *tx_queue,
980 ip_length = st->ip_base_len + st->packet_space; 977 ip_length = st->ip_base_len + st->packet_space;
981 978
982 if (st->protocol == htons(ETH_P_IP)) { 979 if (st->protocol == htons(ETH_P_IP)) {
983 struct iphdr *tsoh_iph = 980 struct iphdr *tsoh_iph = (struct iphdr *)(header + st->ip_off);
984 (struct iphdr *)(header + SKB_IPV4_OFF(skb));
985 981
986 tsoh_iph->tot_len = htons(ip_length); 982 tsoh_iph->tot_len = htons(ip_length);
987 983
@@ -990,7 +986,7 @@ static int tso_start_new_packet(struct efx_tx_queue *tx_queue,
990 st->ipv4_id++; 986 st->ipv4_id++;
991 } else { 987 } else {
992 struct ipv6hdr *tsoh_iph = 988 struct ipv6hdr *tsoh_iph =
993 (struct ipv6hdr *)(header + SKB_IPV6_OFF(skb)); 989 (struct ipv6hdr *)(header + st->ip_off);
994 990
995 tsoh_iph->payload_len = htons(ip_length); 991 tsoh_iph->payload_len = htons(ip_length);
996 } 992 }