Switch TSO over to the faster transmit path, and remove all the unused
old TSO code.

Signed-off-by: Julian Wiedmann <j...@linux.ibm.com>
---
 drivers/s390/net/qeth_core.h      |   1 -
 drivers/s390/net/qeth_core_main.c |   3 +-
 drivers/s390/net/qeth_l3_main.c   | 151 ++------------------------------------
 3 files changed, 6 insertions(+), 149 deletions(-)

diff --git a/drivers/s390/net/qeth_core.h b/drivers/s390/net/qeth_core.h
index d86eea9db2a7..1c9fce609eb9 100644
--- a/drivers/s390/net/qeth_core.h
+++ b/drivers/s390/net/qeth_core.h
@@ -1004,7 +1004,6 @@ int qeth_send_control_data(struct qeth_card *, int, 
struct qeth_cmd_buffer *,
        int (*reply_cb)(struct qeth_card *, struct qeth_reply*, unsigned long),
        void *reply_param);
 unsigned int qeth_count_elements(struct sk_buff *skb, unsigned int 
data_offset);
-int qeth_get_elements_for_frags(struct sk_buff *);
 int qeth_do_send_packet_fast(struct qeth_qdio_out_q *queue, struct sk_buff 
*skb,
                             struct qeth_hdr *hdr, unsigned int offset,
                             unsigned int hd_len);
diff --git a/drivers/s390/net/qeth_core_main.c 
b/drivers/s390/net/qeth_core_main.c
index 460ffdf1b200..7426167eace2 100644
--- a/drivers/s390/net/qeth_core_main.c
+++ b/drivers/s390/net/qeth_core_main.c
@@ -3788,7 +3788,7 @@ EXPORT_SYMBOL_GPL(qeth_get_priority_queue);
  * Returns the number of pages, and thus QDIO buffer elements, needed to cover
  * fragmented part of the SKB. Returns zero for linear SKB.
  */
-int qeth_get_elements_for_frags(struct sk_buff *skb)
+static int qeth_get_elements_for_frags(struct sk_buff *skb)
 {
        int cnt, elements = 0;
 
@@ -3801,7 +3801,6 @@ int qeth_get_elements_for_frags(struct sk_buff *skb)
        }
        return elements;
 }
-EXPORT_SYMBOL_GPL(qeth_get_elements_for_frags);
 
 /**
  * qeth_count_elements() -     Counts the number of QDIO buffer elements needed
diff --git a/drivers/s390/net/qeth_l3_main.c b/drivers/s390/net/qeth_l3_main.c
index fe55218802d7..5d7e2921ab36 100644
--- a/drivers/s390/net/qeth_l3_main.c
+++ b/drivers/s390/net/qeth_l3_main.c
@@ -33,7 +33,6 @@
 #include <net/ipv6.h>
 #include <net/ip6_route.h>
 #include <net/ip6_fib.h>
-#include <net/ip6_checksum.h>
 #include <net/iucv/af_iucv.h>
 #include <linux/hashtable.h>
 
@@ -2118,70 +2117,6 @@ static void qeth_l3_fill_tso_ext(struct qeth_hdr_tso 
*hdr,
        ext->dg_hdr_len = proto_len;
 }
 
-static void qeth_tso_fill_header(struct qeth_card *card,
-               struct qeth_hdr *qhdr, struct sk_buff *skb)
-{
-       struct qeth_hdr_tso *hdr = (struct qeth_hdr_tso *)qhdr;
-       struct tcphdr *tcph = tcp_hdr(skb);
-       struct iphdr *iph = ip_hdr(skb);
-       struct ipv6hdr *ip6h = ipv6_hdr(skb);
-
-       /*set values which are fix for the first approach ...*/
-       hdr->ext.hdr_tot_len = (__u16) sizeof(struct qeth_hdr_ext_tso);
-       hdr->ext.imb_hdr_no  = 1;
-       hdr->ext.hdr_type    = 1;
-       hdr->ext.hdr_version = 1;
-       hdr->ext.hdr_len     = 28;
-       /*insert non-fix values */
-       hdr->ext.mss = skb_shinfo(skb)->gso_size;
-       hdr->ext.dg_hdr_len = (__u16)(ip_hdrlen(skb) + tcp_hdrlen(skb));
-       hdr->ext.payload_len = (__u16)(skb->len - hdr->ext.dg_hdr_len -
-                                      sizeof(struct qeth_hdr_tso));
-       tcph->check = 0;
-       if (be16_to_cpu(skb->protocol) == ETH_P_IPV6) {
-               ip6h->payload_len = 0;
-               tcph->check = ~csum_ipv6_magic(&ip6h->saddr, &ip6h->daddr,
-                                              0, IPPROTO_TCP, 0);
-       } else {
-               /*OSA want us to set these values ...*/
-               tcph->check = ~csum_tcpudp_magic(iph->saddr, iph->daddr,
-                                        0, IPPROTO_TCP, 0);
-               iph->tot_len = 0;
-               iph->check = 0;
-       }
-}
-
-/**
- * qeth_l3_get_elements_no_tso() - find number of SBALEs for skb data for tso
- * @card:                         qeth card structure, to check max. elems.
- * @skb:                          SKB address
- * @extra_elems:                  extra elems needed, to check against max.
- *
- * Returns the number of pages, and thus QDIO buffer elements, needed to cover
- * skb data, including linear part and fragments, but excluding TCP header.
- * Checks if the result plus extra_elems fits under the limit for the card.
- * Returns 0 if it does not.
- * Note: extra_elems is not included in the returned result.
- */
-static int qeth_l3_get_elements_no_tso(struct qeth_card *card,
-                       struct sk_buff *skb, int extra_elems)
-{
-       addr_t start = (addr_t)tcp_hdr(skb) + tcp_hdrlen(skb);
-       addr_t end = (addr_t)skb->data + skb_headlen(skb);
-       int elements = qeth_get_elements_for_frags(skb);
-
-       if (start != end)
-               elements += qeth_get_elements_for_range(start, end);
-
-       if ((elements + extra_elems) > QETH_MAX_BUFFER_ELEMENTS(card)) {
-               QETH_DBF_MESSAGE(2,
-       "Invalid size of TSO IP packet (Number=%d / Length=%d). Discarded.\n",
-                               elements + extra_elems, skb->len);
-               return 0;
-       }
-       return elements;
-}
-
 static void qeth_l3_fixup_headers(struct sk_buff *skb)
 {
        struct iphdr *iph = ip_hdr(skb);
@@ -2196,9 +2131,8 @@ static void qeth_l3_fixup_headers(struct sk_buff *skb)
        }
 }
 
-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)
+static int qeth_l3_xmit(struct qeth_card *card, struct sk_buff *skb,
+                       struct qeth_qdio_out_q *queue, int ipv, int cast_type)
 {
        unsigned int hw_hdr_len, proto_len, frame_len, elements;
        unsigned char eth_hdr[ETH_HLEN];
@@ -2282,81 +2216,6 @@ static int qeth_l3_xmit_offload(struct qeth_card *card, 
struct sk_buff *skb,
        return rc;
 }
 
-static int qeth_l3_xmit(struct qeth_card *card, struct sk_buff *skb,
-                       struct qeth_qdio_out_q *queue, int ipv, int cast_type)
-{
-       struct qeth_hdr *hdr = NULL;
-       struct sk_buff *new_skb = NULL;
-       int tx_bytes = skb->len;
-       unsigned int hd_len;
-       int elements, rc;
-       bool is_sg;
-
-       /* create a clone with writeable headroom */
-       new_skb = skb_realloc_headroom(skb, sizeof(struct qeth_hdr_tso));
-       if (!new_skb)
-               return -ENOMEM;
-
-       skb_pull(new_skb, ETH_HLEN);
-
-       /* fix hardware limitation: as long as we do not have sbal
-        * chaining we can not send long frag lists
-        */
-       if (!qeth_l3_get_elements_no_tso(card, new_skb, 1)) {
-               rc = skb_linearize(new_skb);
-
-               if (card->options.performance_stats) {
-                       if (rc)
-                               card->perf_stats.tx_linfail++;
-                       else
-                               card->perf_stats.tx_lin++;
-               }
-               if (rc)
-                       goto out;
-       }
-
-       hdr = skb_push(new_skb, sizeof(struct qeth_hdr_tso));
-       memset(hdr, 0, sizeof(struct qeth_hdr_tso));
-       qeth_l3_fill_header(card, hdr, new_skb, ipv, cast_type,
-                           new_skb->len - sizeof(struct qeth_hdr_tso));
-       qeth_tso_fill_header(card, hdr, new_skb);
-
-       elements = qeth_l3_get_elements_no_tso(card, new_skb, 1);
-       if (!elements) {
-               rc = -E2BIG;
-               goto out;
-       }
-       elements++;
-
-       hd_len = sizeof(struct qeth_hdr_tso) + ip_hdrlen(new_skb) +
-                tcp_hdrlen(new_skb);
-
-       if (qeth_hdr_chk_and_bounce(new_skb, &hdr, hd_len)) {
-               rc = -EINVAL;
-               goto out;
-       }
-
-       is_sg = skb_is_nonlinear(new_skb);
-       rc = qeth_do_send_packet(card, queue, new_skb, hdr, hd_len, hd_len,
-                                elements);
-out:
-       if (!rc) {
-               if (new_skb != skb)
-                       dev_kfree_skb_any(skb);
-               if (card->options.performance_stats) {
-                       card->perf_stats.buf_elements_sent += elements;
-                       if (is_sg)
-                               card->perf_stats.sg_skbs_sent++;
-                       card->perf_stats.large_send_bytes += tx_bytes;
-                       card->perf_stats.large_send_cnt++;
-               }
-       } else {
-               if (new_skb != skb)
-                       dev_kfree_skb_any(new_skb);
-       }
-       return rc;
-}
-
 static netdev_tx_t qeth_l3_hard_start_xmit(struct sk_buff *skb,
                                           struct net_device *dev)
 {
@@ -2392,9 +2251,7 @@ static netdev_tx_t qeth_l3_hard_start_xmit(struct sk_buff 
*skb,
        }
        netif_stop_queue(dev);
 
-       if (IS_IQD(card) || (!skb_is_gso(skb) && ipv == 4))
-               rc = qeth_l3_xmit_offload(card, skb, queue, ipv, cast_type);
-       else if (skb_is_gso(skb))
+       if (ipv == 4 || IS_IQD(card))
                rc = qeth_l3_xmit(card, skb, queue, ipv, cast_type);
        else
                rc = qeth_xmit(card, skb, queue, ipv, cast_type,
@@ -2560,6 +2417,8 @@ static int qeth_l3_setup_netdev(struct qeth_card *card)
                card->dev->needed_headroom = sizeof(struct qeth_hdr);
                /* allow for de-acceleration of NETIF_F_HW_VLAN_CTAG_TX: */
                card->dev->needed_headroom += VLAN_HLEN;
+               if (qeth_is_supported(card, IPA_OUTBOUND_TSO))
+                       card->dev->needed_headroom = sizeof(struct 
qeth_hdr_tso);
 
                /*IPv6 address autoconfiguration stuff*/
                qeth_l3_get_unique_id(card);
-- 
2.16.4

Reply via email to