diff options
author | Kittipon Meesompop <kmeesomp@linux.vnet.ibm.com> | 2018-04-26 03:42:22 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2018-04-27 13:38:49 -0400 |
commit | 571f9dd8026b44fe52d9ca9ed6a68c53aad1f3ba (patch) | |
tree | f416457ad6ff96730b6ba225d86ed121945b1ae0 /drivers/s390/net/qeth_l2_main.c | |
parent | a8155b009f133445e874fb84c43f85091b345617 (diff) |
s390/qeth: add IPv6 TX checksum offload support
Check if a qeth device supports IPv6 TX checksum offload, and advertise
NETIF_F_IPV6_CSUM accordingly. Add support for setting the relevant bits
in IPv6 packet descriptors.
Currently this has only limited use (ie. UDP, or Jumbo Frames). For any
TCP traffic with a standard MSS, the TCP checksum gets calculated
as part of the linear GSO segmentation.
Signed-off-by: Kittipon Meesompop <kmeesomp@linux.vnet.ibm.com>
Signed-off-by: Julian Wiedmann <jwi@linux.vnet.ibm.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/s390/net/qeth_l2_main.c')
-rw-r--r-- | drivers/s390/net/qeth_l2_main.c | 14 |
1 files changed, 10 insertions, 4 deletions
diff --git a/drivers/s390/net/qeth_l2_main.c b/drivers/s390/net/qeth_l2_main.c index 945df56434fd..5b1780fa4cb5 100644 --- a/drivers/s390/net/qeth_l2_main.c +++ b/drivers/s390/net/qeth_l2_main.c | |||
@@ -660,7 +660,8 @@ out: | |||
660 | } | 660 | } |
661 | 661 | ||
662 | static int qeth_l2_xmit_osa(struct qeth_card *card, struct sk_buff *skb, | 662 | static int qeth_l2_xmit_osa(struct qeth_card *card, struct sk_buff *skb, |
663 | struct qeth_qdio_out_q *queue, int cast_type) | 663 | struct qeth_qdio_out_q *queue, int cast_type, |
664 | int ipv) | ||
664 | { | 665 | { |
665 | int push_len = sizeof(struct qeth_hdr); | 666 | int push_len = sizeof(struct qeth_hdr); |
666 | unsigned int elements, nr_frags; | 667 | unsigned int elements, nr_frags; |
@@ -699,7 +700,7 @@ static int qeth_l2_xmit_osa(struct qeth_card *card, struct sk_buff *skb, | |||
699 | } | 700 | } |
700 | qeth_l2_fill_header(hdr, skb, cast_type, skb->len - push_len); | 701 | qeth_l2_fill_header(hdr, skb, cast_type, skb->len - push_len); |
701 | if (skb->ip_summed == CHECKSUM_PARTIAL) { | 702 | if (skb->ip_summed == CHECKSUM_PARTIAL) { |
702 | qeth_tx_csum(skb, &hdr->hdr.l2.flags[1]); | 703 | qeth_tx_csum(skb, &hdr->hdr.l2.flags[1], ipv); |
703 | if (card->options.performance_stats) | 704 | if (card->options.performance_stats) |
704 | card->perf_stats.tx_csum++; | 705 | card->perf_stats.tx_csum++; |
705 | } | 706 | } |
@@ -754,6 +755,7 @@ static netdev_tx_t qeth_l2_hard_start_xmit(struct sk_buff *skb, | |||
754 | { | 755 | { |
755 | struct qeth_card *card = dev->ml_priv; | 756 | struct qeth_card *card = dev->ml_priv; |
756 | int cast_type = qeth_l2_get_cast_type(card, skb); | 757 | int cast_type = qeth_l2_get_cast_type(card, skb); |
758 | int ipv = qeth_get_ip_version(skb); | ||
757 | struct qeth_qdio_out_q *queue; | 759 | struct qeth_qdio_out_q *queue; |
758 | int tx_bytes = skb->len; | 760 | int tx_bytes = skb->len; |
759 | int rc; | 761 | int rc; |
@@ -761,7 +763,7 @@ static netdev_tx_t qeth_l2_hard_start_xmit(struct sk_buff *skb, | |||
761 | if (card->qdio.do_prio_queueing || (cast_type && | 763 | if (card->qdio.do_prio_queueing || (cast_type && |
762 | card->info.is_multicast_different)) | 764 | card->info.is_multicast_different)) |
763 | queue = card->qdio.out_qs[qeth_get_priority_queue(card, skb, | 765 | queue = card->qdio.out_qs[qeth_get_priority_queue(card, skb, |
764 | qeth_get_ip_version(skb), cast_type)]; | 766 | ipv, cast_type)]; |
765 | else | 767 | else |
766 | queue = card->qdio.out_qs[card->qdio.default_out_queue]; | 768 | queue = card->qdio.out_qs[card->qdio.default_out_queue]; |
767 | 769 | ||
@@ -784,7 +786,7 @@ static netdev_tx_t qeth_l2_hard_start_xmit(struct sk_buff *skb, | |||
784 | rc = qeth_l2_xmit_iqd(card, skb, queue, cast_type); | 786 | rc = qeth_l2_xmit_iqd(card, skb, queue, cast_type); |
785 | break; | 787 | break; |
786 | default: | 788 | default: |
787 | rc = qeth_l2_xmit_osa(card, skb, queue, cast_type); | 789 | rc = qeth_l2_xmit_osa(card, skb, queue, cast_type, ipv); |
788 | } | 790 | } |
789 | 791 | ||
790 | if (!rc) { | 792 | if (!rc) { |
@@ -995,6 +997,10 @@ static int qeth_l2_setup_netdev(struct qeth_card *card) | |||
995 | card->dev->vlan_features |= NETIF_F_RXCSUM; | 997 | card->dev->vlan_features |= NETIF_F_RXCSUM; |
996 | } | 998 | } |
997 | } | 999 | } |
1000 | if (qeth_is_supported6(card, IPA_OUTBOUND_CHECKSUM_V6)) { | ||
1001 | card->dev->hw_features |= NETIF_F_IPV6_CSUM; | ||
1002 | card->dev->vlan_features |= NETIF_F_IPV6_CSUM; | ||
1003 | } | ||
998 | 1004 | ||
999 | card->info.broadcast_capable = 1; | 1005 | card->info.broadcast_capable = 1; |
1000 | qeth_l2_request_initial_mac(card); | 1006 | qeth_l2_request_initial_mac(card); |