Blob Blame History Raw
From: Julian Wiedmann <jwi@linux.ibm.com>
Subject: s390/qeth: fix up protocol headers early
Patch-mainline: v4.20-rc1
Git-commit: 2d3986d1ceda2c00255c924940207a1cdfd65f1c
References: FATE#326377, LTC#169210, bsc#1115382

Summary:        qeth: Full-blown TCP Segmentation Offload
Description:    As of now, qeth only supports TCP Segmentation Offload (TSO)
                for IPv4 in Layer3 devices. This feature extends the existing
                support to IPv6, and adds support for TSO in both IP variants
                for Layer2.

                To cleanly pull in all the necessary changes to the transmit
                code, update the qeth driver to the current 4.20 level.


Upstream-Description:

             s390/qeth: fix up protocol headers early

             When qeth_add_hw_header() falls back to the HW header cache, it also
             copies over the necessary protocol headers. Thus any manipulation to
             the protocol headers needs to happen before adding the HW header.

             For current usage this doesn't matter, but it becomes relevant when
             moving TSO transmission over to the faster code path.

             Signed-off-by: Julian Wiedmann <jwi@linux.ibm.com>
             Signed-off-by: David S. Miller <davem@davemloft.net>

Signed-off-by: Julian Wiedmann <jwi@linux.ibm.com>
Acked-by: Petr Tesarik <ptesarik@suse.com>
---
 drivers/s390/net/qeth_l3_main.c |   14 +++++++++++---
 1 file changed, 11 insertions(+), 3 deletions(-)

--- a/drivers/s390/net/qeth_l3_main.c
+++ b/drivers/s390/net/qeth_l3_main.c
@@ -2056,10 +2056,8 @@ static void qeth_l3_fill_header(struct q
 	if (!skb_is_gso(skb) && skb->ip_summed == CHECKSUM_PARTIAL) {
 		qeth_tx_csum(skb, &hdr->hdr.l3.ext_flags, ipv);
 		/* some HW requires combined L3+L4 csum offload: */
-		if (ipv == 4) {
+		if (ipv == 4)
 			hdr->hdr.l3.ext_flags |= QETH_HDR_EXT_CSUM_HDR_REQ;
-			ip_hdr(skb)->check = 0;
-		}
 		if (card->options.performance_stats)
 			card->perf_stats.tx_csum++;
 	}
@@ -2174,6 +2172,15 @@ static int qeth_l3_get_elements_no_tso(s
 	return elements;
 }
 
+static void qeth_l3_fixup_headers(struct sk_buff *skb)
+{
+	struct iphdr *iph = ip_hdr(skb);
+
+	/* this is safe, IPv6 traffic takes a different path */
+	if (skb->ip_summed == CHECKSUM_PARTIAL)
+		iph->check = 0;
+}
+
 static int qeth_l3_xmit_offload(struct qeth_card *card, struct sk_buff *skb,
 				struct qeth_qdio_out_q *queue, int ipv,
 				int cast_type)
@@ -2194,6 +2201,7 @@ static int qeth_l3_xmit_offload(struct q
 	skb_pull(skb, ETH_HLEN);
 	frame_len = skb->len;
 
+	qeth_l3_fixup_headers(skb);
 	push_len = qeth_add_hw_header(card, skb, &hdr, hw_hdr_len, 0,
 				      &elements);
 	if (push_len < 0)