diff options
author | Ben Hutchings <bhutchings@solarflare.com> | 2012-06-21 21:44:01 -0400 |
---|---|---|
committer | Ben Hutchings <bhutchings@solarflare.com> | 2012-08-24 15:10:17 -0400 |
commit | 9714284f83387d330496758e5c10a649fd9a677d (patch) | |
tree | 1e2baa7525f00903eebafeea7e7f066fb982a5cb /drivers/net/ethernet/sfc | |
parent | 53cb13c680b98c637d95dd731b01bc284b3aa33d (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.c | 28 |
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. */ |
826 | static void tso_start(struct tso_state *st, const struct sk_buff *skb) | 826 | static 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 | } |