s390/qeth: add IPv6 RX checksum offload support
authorKittipon Meesompop <kmeesomp@linux.vnet.ibm.com>
Thu, 26 Apr 2018 07:42:23 +0000 (09:42 +0200)
committerDavid S. Miller <davem@davemloft.net>
Fri, 27 Apr 2018 17:38:49 +0000 (13:38 -0400)
Check if a qeth device supports IPv6 RX checksum offload, and hook it up
into the existing NETIF_F_RXCSUM support.
As NETIF_F_RXCSUM is now backed by a combination of HW Assists, we need
to be a little smarter when dealing with errors during a configuration
change:
- switching on NETIF_F_RXCSUM only makes sense if at least one HW Assist
  was enabled successfully.
- for switching off NETIF_F_RXCSUM, all available HW Assists need to be
  deactivated.

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>
drivers/s390/net/qeth_core_main.c
drivers/s390/net/qeth_core_mpc.h
drivers/s390/net/qeth_l2_main.c

index 55b05d9c1cb67e8fd2af898ee56709f0a19aa355..06415b6a8f68c9a8d9972a6fec9749cbac532c88 100644 (file)
@@ -6430,6 +6430,29 @@ static int qeth_set_ipa_tso(struct qeth_card *card, int on)
        return rc;
 }
 
+static int qeth_set_ipa_rx_csum(struct qeth_card *card, bool on)
+{
+       int rc_ipv4 = (on) ? -EOPNOTSUPP : 0;
+       int rc_ipv6;
+
+       if (qeth_is_supported(card, IPA_INBOUND_CHECKSUM))
+               rc_ipv4 = qeth_set_ipa_csum(card, on, IPA_INBOUND_CHECKSUM,
+                                           QETH_PROT_IPV4);
+       if (!qeth_is_supported6(card, IPA_INBOUND_CHECKSUM_V6))
+               /* no/one Offload Assist available, so the rc is trivial */
+               return rc_ipv4;
+
+       rc_ipv6 = qeth_set_ipa_csum(card, on, IPA_INBOUND_CHECKSUM,
+                                   QETH_PROT_IPV6);
+
+       if (on)
+               /* enable: success if any Assist is active */
+               return (rc_ipv6) ? rc_ipv4 : 0;
+
+       /* disable: failure if any Assist is still active */
+       return (rc_ipv6) ? rc_ipv6 : rc_ipv4;
+}
+
 #define QETH_HW_FEATURES (NETIF_F_RXCSUM | NETIF_F_IP_CSUM | NETIF_F_TSO | \
                          NETIF_F_IPV6_CSUM)
 /**
@@ -6477,9 +6500,8 @@ int qeth_set_features(struct net_device *dev, netdev_features_t features)
                if (rc)
                        changed ^= NETIF_F_IPV6_CSUM;
        }
-       if ((changed & NETIF_F_RXCSUM)) {
-               rc = qeth_set_ipa_csum(card, features & NETIF_F_RXCSUM,
-                                      IPA_INBOUND_CHECKSUM, QETH_PROT_IPV4);
+       if (changed & NETIF_F_RXCSUM) {
+               rc = qeth_set_ipa_rx_csum(card, features & NETIF_F_RXCSUM);
                if (rc)
                        changed ^= NETIF_F_RXCSUM;
        }
@@ -6508,7 +6530,8 @@ netdev_features_t qeth_fix_features(struct net_device *dev,
                features &= ~NETIF_F_IP_CSUM;
        if (!qeth_is_supported6(card, IPA_OUTBOUND_CHECKSUM_V6))
                features &= ~NETIF_F_IPV6_CSUM;
-       if (!qeth_is_supported(card, IPA_INBOUND_CHECKSUM))
+       if (!qeth_is_supported(card, IPA_INBOUND_CHECKSUM) &&
+           !qeth_is_supported6(card, IPA_INBOUND_CHECKSUM_V6))
                features &= ~NETIF_F_RXCSUM;
        if (!qeth_is_supported(card, IPA_OUTBOUND_TSO))
                features &= ~NETIF_F_TSO;
index af3c35fbfa9e45a2f6ad075a0665108b7fe343dd..878e62f3516915081c7a4f834724a67afd8485f4 100644 (file)
@@ -246,6 +246,7 @@ enum qeth_ipa_funcs {
        IPA_QUERY_ARP_ASSIST    = 0x00040000L,
        IPA_INBOUND_TSO         = 0x00080000L,
        IPA_OUTBOUND_TSO        = 0x00100000L,
+       IPA_INBOUND_CHECKSUM_V6 = 0x00400000L,
        IPA_OUTBOUND_CHECKSUM_V6 = 0x00800000L,
 };
 
index 5b1780fa4cb52e06e36352521b2bff058c1ab417..810d69bd9991a4d0bd3fa3121ddb60b7cdb27f73 100644 (file)
@@ -992,15 +992,16 @@ static int qeth_l2_setup_netdev(struct qeth_card *card)
                        card->dev->hw_features |= NETIF_F_IP_CSUM;
                        card->dev->vlan_features |= NETIF_F_IP_CSUM;
                }
-               if (qeth_is_supported(card, IPA_INBOUND_CHECKSUM)) {
-                       card->dev->hw_features |= NETIF_F_RXCSUM;
-                       card->dev->vlan_features |= NETIF_F_RXCSUM;
-               }
        }
        if (qeth_is_supported6(card, IPA_OUTBOUND_CHECKSUM_V6)) {
                card->dev->hw_features |= NETIF_F_IPV6_CSUM;
                card->dev->vlan_features |= NETIF_F_IPV6_CSUM;
        }
+       if (qeth_is_supported(card, IPA_INBOUND_CHECKSUM) ||
+           qeth_is_supported6(card, IPA_INBOUND_CHECKSUM_V6)) {
+               card->dev->hw_features |= NETIF_F_RXCSUM;
+               card->dev->vlan_features |= NETIF_F_RXCSUM;
+       }
 
        card->info.broadcast_capable = 1;
        qeth_l2_request_initial_mac(card);